diff options
author | Diego Novillo <dnovillo@google.com> | 2014-03-14 21:58:59 +0000 |
---|---|---|
committer | Diego Novillo <dnovillo@google.com> | 2014-03-14 21:58:59 +0000 |
commit | 3f7c2f31ff0c47c68489e7fd87ef7a6277cd3085 (patch) | |
tree | fa2fa120267dda8d997be468a8e3183b53451384 /lib/Transforms/Scalar | |
parent | f90e07f6c33643279c3c6fde061ff98f22adf509 (diff) | |
download | llvm-3f7c2f31ff0c47c68489e7fd87ef7a6277cd3085.tar.gz llvm-3f7c2f31ff0c47c68489e7fd87ef7a6277cd3085.tar.bz2 llvm-3f7c2f31ff0c47c68489e7fd87ef7a6277cd3085.tar.xz |
Use DiagnosticInfo facility.
Summary:
The sample profiler pass emits several error messages. Instead of
just aborting the compiler with report_fatal_error, we can emit
better messages using DiagnosticInfo.
This adds a new sub-class of DiagnosticInfo to handle the sample
profiler.
Reviewers: chandlerc, qcolombet
CC: llvm-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D3086
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203976 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar')
-rw-r--r-- | lib/Transforms/Scalar/SampleProfile.cpp | 60 |
1 files changed, 46 insertions, 14 deletions
diff --git a/lib/Transforms/Scalar/SampleProfile.cpp b/lib/Transforms/Scalar/SampleProfile.cpp index ab26fa5b23..e8adc64eee 100644 --- a/lib/Transforms/Scalar/SampleProfile.cpp +++ b/lib/Transforms/Scalar/SampleProfile.cpp @@ -34,6 +34,7 @@ #include "llvm/Analysis/PostDominators.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstIterator.h" @@ -238,10 +239,11 @@ protected: /// be relative to the start of the function. class SampleModuleProfile { public: - SampleModuleProfile(StringRef F) : Profiles(0), Filename(F) {} + SampleModuleProfile(const Module &M, StringRef F) + : Profiles(0), Filename(F), M(M) {} void dump(); - void loadText(); + bool loadText(); void loadNative() { llvm_unreachable("not implemented"); } void printFunctionProfile(raw_ostream &OS, StringRef FName); void dumpFunctionProfile(StringRef FName); @@ -251,7 +253,8 @@ public: /// \brief Report a parse error message and stop compilation. void reportParseError(int64_t LineNumber, Twine Msg) const { - report_fatal_error(Filename + ":" + Twine(LineNumber) + ": " + Msg + "\n"); + DiagnosticInfoSampleProfile Diag(Filename.data(), LineNumber, Msg); + M.getContext().diagnose(Diag); } protected: @@ -269,6 +272,10 @@ protected: /// version of the profile format to be used in constructing test /// cases and debugging. StringRef Filename; + + /// \brief Module being compiled. Used mainly to access the current + /// LLVM context for diagnostics. + const Module &M; }; /// \brief Sample profile pass. @@ -282,7 +289,7 @@ public: static char ID; SampleProfileLoader(StringRef Name = SampleProfileFile) - : FunctionPass(ID), Profiler(), Filename(Name) { + : FunctionPass(ID), Profiler(), Filename(Name), ProfileIsValid(false) { initializeSampleProfileLoaderPass(*PassRegistry::getPassRegistry()); } @@ -307,6 +314,9 @@ protected: /// \brief Name of the profile file to load. StringRef Filename; + + /// \brief Flag indicating whether the profile input loaded succesfully. + bool ProfileIsValid; }; } @@ -437,11 +447,17 @@ void SampleModuleProfile::dump() { /// for debugging purposes, but it should not be used to generate /// profiles for large programs, as the representation is extremely /// inefficient. -void SampleModuleProfile::loadText() { +/// +/// \returns true if the file was loaded successfully, false otherwise. +bool SampleModuleProfile::loadText() { std::unique_ptr<MemoryBuffer> Buffer; error_code EC = MemoryBuffer::getFile(Filename, Buffer); - if (EC) - report_fatal_error("Could not open file " + Filename + ": " + EC.message()); + if (EC) { + std::string Msg(EC.message()); + DiagnosticInfoSampleProfile Diag(Filename.data(), Msg); + M.getContext().diagnose(Diag); + return false; + } line_iterator LineIt(*Buffer, '#'); // Read the profile of each function. Since each function may be @@ -457,9 +473,11 @@ void SampleModuleProfile::loadText() { // // See above for an explanation of each field. SmallVector<StringRef, 3> Matches; - if (!HeadRE.match(*LineIt, &Matches)) + if (!HeadRE.match(*LineIt, &Matches)) { reportParseError(LineIt.line_number(), "Expected 'mangled_name:NUM:NUM', found " + *LineIt); + return false; + } assert(Matches.size() == 4); StringRef FName = Matches[1]; unsigned NumSamples, NumHeadSamples; @@ -474,10 +492,12 @@ void SampleModuleProfile::loadText() { // Now read the body. The body of the function ends when we reach // EOF or when we see the start of the next function. while (!LineIt.is_at_eof() && isdigit((*LineIt)[0])) { - if (!LineSample.match(*LineIt, &Matches)) + if (!LineSample.match(*LineIt, &Matches)) { reportParseError( LineIt.line_number(), "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " + *LineIt); + return false; + } assert(Matches.size() == 5); unsigned LineOffset, NumSamples, Discriminator = 0; Matches[1].getAsInteger(10, LineOffset); @@ -497,6 +517,8 @@ void SampleModuleProfile::loadText() { ++LineIt; } } + + return true; } /// \brief Get the weight for an instruction. @@ -935,7 +957,8 @@ void SampleFunctionProfile::propagateWeights(Function &F) { /// /// \param F Function object to query. /// -/// \returns the line number where \p F is defined. +/// \returns the line number where \p F is defined. If it returns 0, +/// it means that there is no debug information available for \p F. unsigned SampleFunctionProfile::getFunctionLoc(Function &F) { NamedMDNode *CUNodes = F.getParent()->getNamedMetadata("llvm.dbg.cu"); if (CUNodes) { @@ -950,8 +973,10 @@ unsigned SampleFunctionProfile::getFunctionLoc(Function &F) { } } - report_fatal_error("No debug information found in function " + F.getName() + - "\n"); + DiagnosticInfoSampleProfile Diag("No debug information found in function " + + F.getName()); + F.getContext().diagnose(Diag); + return 0; } /// \brief Generate branch weight metadata for all branches in \p F. @@ -1001,6 +1026,8 @@ unsigned SampleFunctionProfile::getFunctionLoc(Function &F) { /// metadata on B using the computed values for each of its branches. /// /// \param F The function to query. +/// +/// \returns true if \p F was modified. Returns false, otherwise. bool SampleFunctionProfile::emitAnnotations(Function &F, DominatorTree *DomTree, PostDominatorTree *PostDomTree, LoopInfo *Loops) { @@ -1008,6 +1035,9 @@ bool SampleFunctionProfile::emitAnnotations(Function &F, DominatorTree *DomTree, // Initialize invariants used during computation and propagation. HeaderLineno = getFunctionLoc(F); + if (HeaderLineno == 0) + return false; + DEBUG(dbgs() << "Line number for the first instruction in " << F.getName() << ": " << HeaderLineno << "\n"); DT = DomTree; @@ -1040,8 +1070,8 @@ INITIALIZE_PASS_END(SampleProfileLoader, "sample-profile", "Sample Profile loader", false, false) bool SampleProfileLoader::doInitialization(Module &M) { - Profiler.reset(new SampleModuleProfile(Filename)); - Profiler->loadText(); + Profiler.reset(new SampleModuleProfile(M, Filename)); + ProfileIsValid = Profiler->loadText(); return true; } @@ -1054,6 +1084,8 @@ FunctionPass *llvm::createSampleProfileLoaderPass(StringRef Name) { } bool SampleProfileLoader::runOnFunction(Function &F) { + if (!ProfileIsValid) + return false; DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); PostDominatorTree *PDT = &getAnalysis<PostDominatorTree>(); LoopInfo *LI = &getAnalysis<LoopInfo>(); |