diff options
Diffstat (limited to 'lib/IR/LegacyPassManager.cpp')
-rw-r--r-- | lib/IR/LegacyPassManager.cpp | 94 |
1 files changed, 84 insertions, 10 deletions
diff --git a/lib/IR/LegacyPassManager.cpp b/lib/IR/LegacyPassManager.cpp index 8bd9ed6ef0fa..54d602d926e5 100644 --- a/lib/IR/LegacyPassManager.cpp +++ b/lib/IR/LegacyPassManager.cpp @@ -12,7 +12,9 @@ //===----------------------------------------------------------------------===// #include "llvm/IR/LegacyPassManager.h" +#include "llvm/ADT/MapVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManagers.h" @@ -28,7 +30,6 @@ #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> -#include <map> #include <unordered_set> using namespace llvm; using namespace llvm::legacy; @@ -86,7 +87,7 @@ static cl::opt<bool> PrintModuleScope("print-module-scope", cl::desc("When printing IR for print-[before|after]{-all} " "always print a module IR"), - cl::init(false)); + cl::init(false), cl::Hidden); static cl::list<std::string> PrintFuncsList("filter-print-funcs", cl::value_desc("function names"), @@ -134,8 +135,60 @@ bool PMDataManager::isPassDebuggingExecutionsOrMore() const { return PassDebugging >= Executions; } +unsigned PMDataManager::initSizeRemarkInfo(Module &M) { + // Only calculate getInstructionCount if the size-info remark is requested. + return M.getInstructionCount(); +} + +void PMDataManager::emitInstrCountChangedRemark(Pass *P, Module &M, + unsigned CountBefore) { + // We need a function containing at least one basic block in order to output + // remarks. Since it's possible that the first function in the module doesn't + // actually contain a basic block, we have to go and find one that's suitable + // for emitting remarks. + auto It = std::find_if(M.begin(), M.end(), + [](const Function &Fn) { return !Fn.empty(); }); + + // Didn't find a function. Quit. + if (It == M.end()) + return; + + // We found a function containing at least one basic block. + Function *F = &*It; + + // How many instructions are in the module now? + unsigned CountAfter = M.getInstructionCount(); + + // If there was no change, don't emit a remark. + if (CountBefore == CountAfter) + return; + // If it's a pass manager, don't emit a remark. (This hinges on the assumption + // that the only passes that return non-null with getAsPMDataManager are pass + // managers.) The reason we have to do this is to avoid emitting remarks for + // CGSCC passes. + if (P->getAsPMDataManager()) + return; + // Compute a possibly negative delta between the instruction count before + // running P, and after running P. + int64_t Delta = + static_cast<int64_t>(CountAfter) - static_cast<int64_t>(CountBefore); + + BasicBlock &BB = *F->begin(); + OptimizationRemarkAnalysis R("size-info", "IRSizeChange", + DiagnosticLocation(), &BB); + // FIXME: Move ore namespace to DiagnosticInfo so that we can use it. This + // would let us use NV instead of DiagnosticInfoOptimizationBase::Argument. + R << DiagnosticInfoOptimizationBase::Argument("Pass", P->getPassName()) + << ": IR instruction count changed from " + << DiagnosticInfoOptimizationBase::Argument("IRInstrsBefore", CountBefore) + << " to " + << DiagnosticInfoOptimizationBase::Argument("IRInstrsAfter", CountAfter) + << "; Delta: " + << DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", Delta); + F->getContext().diagnose(R); // Not using ORE for layering reasons. +} void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { if (!V && !M) @@ -355,8 +408,8 @@ public: for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { ModulePass *MP = getContainedPass(Index); MP->dumpPassStructure(Offset + 1); - std::map<Pass *, FunctionPassManagerImpl *>::const_iterator I = - OnTheFlyManagers.find(MP); + MapVector<Pass *, FunctionPassManagerImpl *>::const_iterator I = + OnTheFlyManagers.find(MP); if (I != OnTheFlyManagers.end()) I->second->dumpPassStructure(Offset + 2); dumpLastUses(MP, Offset+1); @@ -375,7 +428,7 @@ public: private: /// Collection of on the fly FPPassManagers. These managers manage /// function passes that are required by module passes. - std::map<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers; + MapVector<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers; }; char MPPassManager::ID = 0; @@ -486,7 +539,11 @@ public: Timer *&T = TimingData[P]; if (!T) { StringRef PassName = P->getPassName(); - T = new Timer(PassName, PassName, TG); + StringRef PassArgument; + if (const PassInfo *PI = Pass::lookupPassInfo(P->getPassID())) + PassArgument = PI->getPassArgument(); + T = new Timer(PassArgument.empty() ? PassName : PassArgument, PassName, + TG); } return T; } @@ -585,7 +642,7 @@ AnalysisUsage *PMTopLevelManager::findAnalysisUsage(Pass *P) { // of dependencies. AnalysisUsage AU; P->getAnalysisUsage(AU); - + AUFoldingSetNode* Node = nullptr; FoldingSetNodeID ID; AUFoldingSetNode::Profile(ID, AU); @@ -1284,7 +1341,10 @@ bool BBPassManager::runOnFunction(Function &F) { return false; bool Changed = doInitialization(F); + Module &M = *F.getParent(); + unsigned InstrCount = 0; + bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); for (BasicBlock &BB : F) for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { BasicBlockPass *BP = getContainedPass(Index); @@ -1299,8 +1359,11 @@ bool BBPassManager::runOnFunction(Function &F) { // If the pass crashes, remember this. PassManagerPrettyStackEntry X(BP, BB); TimeRegion PassTimer(getPassTimer(BP)); - + if (EmitICRemark) + InstrCount = initSizeRemarkInfo(M); LocalChanged |= BP->runOnBasicBlock(BB); + if (EmitICRemark) + emitInstrCountChangedRemark(BP, M, InstrCount); } Changed |= LocalChanged; @@ -1500,10 +1563,12 @@ bool FPPassManager::runOnFunction(Function &F) { return false; bool Changed = false; - + Module &M = *F.getParent(); // Collect inherited analysis from Module level pass manager. populateInheritedAnalysis(TPM->activeStack); + unsigned InstrCount = 0; + bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { FunctionPass *FP = getContainedPass(Index); bool LocalChanged = false; @@ -1516,8 +1581,11 @@ bool FPPassManager::runOnFunction(Function &F) { { PassManagerPrettyStackEntry X(FP, F); TimeRegion PassTimer(getPassTimer(FP)); - + if (EmitICRemark) + InstrCount = initSizeRemarkInfo(M); LocalChanged |= FP->runOnFunction(F); + if (EmitICRemark) + emitInstrCountChangedRemark(FP, M, InstrCount); } Changed |= LocalChanged; @@ -1581,6 +1649,8 @@ MPPassManager::runOnModule(Module &M) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) Changed |= getContainedPass(Index)->doInitialization(M); + unsigned InstrCount = 0; + bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { ModulePass *MP = getContainedPass(Index); bool LocalChanged = false; @@ -1594,7 +1664,11 @@ MPPassManager::runOnModule(Module &M) { PassManagerPrettyStackEntry X(MP, M); TimeRegion PassTimer(getPassTimer(MP)); + if (EmitICRemark) + InstrCount = initSizeRemarkInfo(M); LocalChanged |= MP->runOnModule(M); + if (EmitICRemark) + emitInstrCountChangedRemark(MP, M, InstrCount); } Changed |= LocalChanged; |