25 #define DEBUG_TYPE "sample-profile"
82 SampleProfile(
StringRef F) : Profiles(0), Filename(F) {}
89 void dumpFunctionProfile(
StringRef FName);
100 struct FunctionProfile {
105 unsigned TotalSamples;
108 unsigned TotalHeadSamples;
115 BodySampleMap BodySamples;
121 BlockWeightMap BlockWeights;
124 uint32_t getInstWeight(
Instruction &
I,
unsigned FirstLineno,
125 BodySampleMap &BodySamples);
126 uint32_t computeBlockWeight(
BasicBlock *B,
unsigned FirstLineno,
127 BodySampleMap &BodySamples);
154 class ExternalProfileTextLoader {
156 ExternalProfileTextLoader(
StringRef F) : Filename(F) {
162 FP = Buffer->getBufferStart();
169 const char *start = FP;
170 while (FP != Buffer->getBufferEnd() && *FP !=
'\n') {
174 if (FP != Buffer->getBufferEnd())
181 bool atEOF()
const {
return FP == Buffer->getBufferEnd(); }
184 void reportParseError(
Twine Msg)
const {
217 virtual bool doInitialization(
Module &M);
219 void dump() { Profiler->dump(); }
221 virtual const char *getPassName()
const {
return "Sample profile pass"; }
223 virtual bool runOnFunction(
Function &F);
243 FunctionProfile FProfile = Profiles[FName];
244 OS <<
"Function: " << FName <<
", " << FProfile.TotalSamples <<
", "
245 << FProfile.TotalHeadSamples <<
", " << FProfile.BodySamples.size()
246 <<
" sampled lines\n";
247 for (BodySampleMap::const_iterator SI = FProfile.BodySamples.begin(),
248 SE = FProfile.BodySamples.end();
250 OS <<
"\tline offset: " << SI->first
251 <<
", number of samples: " << SI->second <<
"\n";
258 void SampleProfile::dumpFunctionProfile(
StringRef FName) {
259 printFunctionProfile(
dbgs(), FName);
267 dumpFunctionProfile(
I->getKey());
300 void SampleProfile::loadText() {
301 ExternalProfileTextLoader Loader(Filename);
305 if (Line !=
"symbol table")
306 Loader.reportParseError(
"Expected 'symbol table', found " + Line);
308 Line = Loader.readLine();
310 Loader.reportParseError(
"Expected a number, found " + Line);
311 for (
int I = 0;
I < NumSymbols;
I++) {
313 FunctionProfile &FProfile = Profiles[FName];
314 FProfile.BodySamples.clear();
315 FProfile.TotalSamples = 0;
316 FProfile.TotalHeadSamples = 0;
322 Regex HeadRE(
"^([^:]+):([0-9]+):([0-9]+):([0-9]+)$");
323 Regex LineSample(
"^([0-9]+): ([0-9]+)$");
324 while (!Loader.atEOF()) {
326 Line = Loader.readLine();
327 if (!HeadRE.match(Line, &Matches))
328 Loader.reportParseError(
"Expected 'mangled_name:NUM:NUM:NUM', found " +
330 assert(Matches.
size() == 5);
332 unsigned NumSamples, NumHeadSamples, NumSampledLines;
333 Matches[2].getAsInteger(10, NumSamples);
334 Matches[3].getAsInteger(10, NumHeadSamples);
335 Matches[4].getAsInteger(10, NumSampledLines);
336 FunctionProfile &FProfile = Profiles[FName];
337 FProfile.TotalSamples += NumSamples;
338 FProfile.TotalHeadSamples += NumHeadSamples;
339 BodySampleMap &SampleMap = FProfile.BodySamples;
341 for (I = 0; I < NumSampledLines && !Loader.atEOF(); I++) {
342 Line = Loader.readLine();
343 if (!LineSample.match(Line, &Matches))
344 Loader.reportParseError(
"Expected 'NUM: NUM', found " + Line);
345 assert(Matches.
size() == 3);
346 unsigned LineOffset, NumSamples;
347 Matches[1].getAsInteger(10, LineOffset);
348 Matches[2].getAsInteger(10, NumSamples);
349 SampleMap[LineOffset] += NumSamples;
352 if (I < NumSampledLines)
353 Loader.reportParseError(
"Unexpected end of file");
370 uint32_t SampleProfile::getInstWeight(
Instruction &Inst,
unsigned FirstLineno,
371 BodySampleMap &BodySamples) {
373 return BodySamples.lookup(LOffset);
388 uint32_t SampleProfile::computeBlockWeight(
BasicBlock *B,
unsigned FirstLineno,
389 BodySampleMap &BodySamples) {
392 FunctionProfile &FProfile = Profiles[F->
getName()];
393 std::pair<BlockWeightMap::iterator, bool> Entry =
394 FProfile.BlockWeights.insert(std::make_pair(B, 0));
396 return Entry.first->second;
401 uint32_t InstWeight = getInstWeight(*I, FirstLineno, BodySamples);
402 if (InstWeight > Weight)
405 Entry.first->second = Weight;
423 bool SampleProfile::emitAnnotations(
Function &F) {
424 bool Changed =
false;
425 FunctionProfile &FProfile = Profiles[F.
getName()];
426 unsigned FirstLineno =
inst_begin(F)->getDebugLoc().getLine();
430 FProfile.BlockWeights.clear();
439 if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI))
444 for (
unsigned I = 0; I < NSuccs; ++
I) {
447 computeBlockWeight(Succ, FirstLineno, FProfile.BodySamples);
452 MDB.createBranchWeights(Weights));
464 return Profiler->emitAnnotations(F);
467 bool SampleProfileLoader::doInitialization(
Module &M) {
468 Profiler.reset(
new SampleProfile(Filename));
469 Profiler->loadText();
478 return new SampleProfileLoader(Name);
void push_back(const T &Elt)
static PassRegistry * getPassRegistry()
LLVMContext & getContext() const
INITIALIZE_PASS(SampleProfileLoader,"sample-profile","Sample Profile loader", false, false) bool SampleProfileLoader
The main container class for the LLVM Intermediate Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(const char *reason, bool gen_crash_diag=true)
StringRef getName() const
inst_iterator inst_begin(Function *F)
#define llvm_unreachable(msg)
ID
LLVM Calling Convention Representation.
static cl::opt< std::string > SampleProfileFile("sample-profile-file", cl::init(""), cl::value_desc("filename"), cl::desc("Profile file loaded by -sample-profile"), cl::Hidden)
unsigned getNumSuccessors() const
initializer< Ty > init(const Ty &Val)
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
LLVM Basic Block Representation.
BasicBlock * getSuccessor(unsigned idx) const
const DebugLoc & getDebugLoc() const
getDebugLoc - Return the debug location for this node as a DebugLoc.
enable_if_c< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
void setMetadata(unsigned KindID, MDNode *Node)
static error_code getFile(Twine Filename, OwningPtr< MemoryBuffer > &result, int64_t FileSize=-1, bool RequiresNullTerminator=true)
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
std::string message() const
FunctionPass * createSampleProfileLoaderPass()
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
void initializeSampleProfileLoaderPass(PassRegistry &)