diff options
author | Jessica Paquette <jpaquette@apple.com> | 2018-09-06 21:19:54 +0000 |
---|---|---|
committer | Jessica Paquette <jpaquette@apple.com> | 2018-09-06 21:19:54 +0000 |
commit | a0aa5b35e7270973b113c9f3620ce6a1f174f2d6 (patch) | |
tree | 4f04f8c9617236742a16b0c8f57ba7fcb9a55335 /llvm/lib | |
parent | b23648cfdb5add073e968d76061b9e78f9cd2f10 (diff) | |
download | bcm5719-llvm-a0aa5b35e7270973b113c9f3620ce6a1f174f2d6.tar.gz bcm5719-llvm-a0aa5b35e7270973b113c9f3620ce6a1f174f2d6.zip |
Output per-function size-info remarks
This patch adds per-function size information remarks. Previously, passing
-Rpass-analysis=size-info would only give you per-module changes. By adding
the ability to do this per-function, it's easier to see which functions
contributed the most to size changes.
https://reviews.llvm.org/D51467
llvm-svn: 341588
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Analysis/CallGraphSCCPass.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/Analysis/LoopPass.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/IR/LegacyPassManager.cpp | 123 |
3 files changed, 119 insertions, 16 deletions
diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp index 24dbda05f4b..3e9226f91de 100644 --- a/llvm/lib/Analysis/CallGraphSCCPass.cpp +++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp @@ -132,10 +132,11 @@ bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC, { unsigned InstrCount, SCCCount = 0; + StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount; bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); TimeRegion PassTimer(getPassTimer(CGSP)); if (EmitICRemark) - InstrCount = initSizeRemarkInfo(M); + InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount); Changed = CGSP->runOnSCC(CurSCC); if (EmitICRemark) { @@ -146,7 +147,8 @@ bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC, // Yep. Emit a remark and update InstrCount. int64_t Delta = static_cast<int64_t>(SCCCount) - static_cast<int64_t>(InstrCount); - emitInstrCountChangedRemark(P, M, Delta, InstrCount); + emitInstrCountChangedRemark(P, M, Delta, InstrCount, + FunctionToInstrCount); InstrCount = SCCCount; } } diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp index 3629ae90da5..4c1bd7ab08e 100644 --- a/llvm/lib/Analysis/LoopPass.cpp +++ b/llvm/lib/Analysis/LoopPass.cpp @@ -195,10 +195,11 @@ bool LPPassManager::runOnFunction(Function &F) { // Walk Loops unsigned InstrCount, FunctionSize = 0; + StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount; bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); // Collect the initial size of the module and the function we're looking at. if (EmitICRemark) { - InstrCount = initSizeRemarkInfo(M); + InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount); FunctionSize = F.getInstructionCount(); } while (!LQ.empty()) { @@ -226,7 +227,8 @@ bool LPPassManager::runOnFunction(Function &F) { if (NewSize != FunctionSize) { int64_t Delta = static_cast<int64_t>(NewSize) - static_cast<int64_t>(FunctionSize); - emitInstrCountChangedRemark(P, M, Delta, InstrCount, &F); + emitInstrCountChangedRemark(P, M, Delta, InstrCount, + FunctionToInstrCount, &F); InstrCount = static_cast<int64_t>(InstrCount) + Delta; FunctionSize = NewSize; } diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp index 5435e07e688..3b0c49a4cab 100644 --- a/llvm/lib/IR/LegacyPassManager.cpp +++ b/llvm/lib/IR/LegacyPassManager.cpp @@ -136,15 +136,32 @@ bool PMDataManager::isPassDebuggingExecutionsOrMore() const { return PassDebugging >= Executions; } -unsigned PMDataManager::initSizeRemarkInfo(Module &M) { +unsigned PMDataManager::initSizeRemarkInfo( + Module &M, StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount) { // Only calculate getInstructionCount if the size-info remark is requested. - return M.getInstructionCount(); + unsigned InstrCount = 0; + + // Collect instruction counts for every function. We'll use this to emit + // per-function size remarks later. + for (Function &F : M) { + unsigned FCount = F.getInstructionCount(); + + // Insert a record into FunctionToInstrCount keeping track of the current + // size of the function as the first member of a pair. Set the second + // member to 0; if the function is deleted by the pass, then when we get + // here, we'll be able to let the user know that F no longer contributes to + // the module. + FunctionToInstrCount[F.getName().str()] = + std::pair<unsigned, unsigned>(FCount, 0); + InstrCount += FCount; + } + return InstrCount; } -void PMDataManager::emitInstrCountChangedRemark(Pass *P, Module &M, - int64_t Delta, - unsigned CountBefore, - Function *F) { +void PMDataManager::emitInstrCountChangedRemark( + Pass *P, Module &M, int64_t Delta, unsigned CountBefore, + StringMap<std::pair<unsigned, unsigned>> &FunctionToInstrCount, + Function *F) { // 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 @@ -155,6 +172,33 @@ void PMDataManager::emitInstrCountChangedRemark(Pass *P, Module &M, // Set to true if this isn't a module pass or CGSCC pass. bool CouldOnlyImpactOneFunction = (F != nullptr); + // Helper lambda that updates the changes to the size of some function. + auto UpdateFunctionChanges = + [&FunctionToInstrCount](Function &MaybeChangedFn) { + // Update the total module count. + unsigned FnSize = MaybeChangedFn.getInstructionCount(); + auto It = FunctionToInstrCount.find(MaybeChangedFn.getName()); + + // If we created a new function, then we need to add it to the map and + // say that it changed from 0 instructions to FnSize. + if (It == FunctionToInstrCount.end()) { + FunctionToInstrCount[MaybeChangedFn.getName()] = + std::pair<unsigned, unsigned>(0, FnSize); + return; + } + // Insert the new function size into the second member of the pair. This + // tells us whether or not this function changed in size. + It->second.second = FnSize; + }; + + // We need to initially update all of the function sizes. + // If no function was passed in, then we're either a module pass or an + // CGSCC pass. + if (!CouldOnlyImpactOneFunction) + std::for_each(M.begin(), M.end(), UpdateFunctionChanges); + else + UpdateFunctionChanges(*F); + // Do we have a function we can use to emit a remark? if (!CouldOnlyImpactOneFunction) { // We need a function containing at least one basic block in order to output @@ -185,6 +229,55 @@ void PMDataManager::emitInstrCountChangedRemark(Pass *P, Module &M, << "; Delta: " << DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", Delta); F->getContext().diagnose(R); // Not using ORE for layering reasons. + + // Emit per-function size change remarks separately. + std::string PassName = P->getPassName().str(); + + // Helper lambda that emits a remark when the size of a function has changed. + auto EmitFunctionSizeChangedRemark = [&FunctionToInstrCount, &F, &BB, + &PassName](const std::string &Fname) { + unsigned FnCountBefore, FnCountAfter; + std::pair<unsigned, unsigned> &Change = FunctionToInstrCount[Fname]; + std::tie(FnCountBefore, FnCountAfter) = Change; + int64_t FnDelta = static_cast<int64_t>(FnCountAfter) - + static_cast<int64_t>(FnCountBefore); + + if (FnDelta == 0) + return; + + // FIXME: We shouldn't use BB for the location here. Unfortunately, because + // the function that we're looking at could have been deleted, we can't use + // it for the source location. We *want* remarks when a function is deleted + // though, so we're kind of stuck here as is. (This remark, along with the + // whole-module size change remarks really ought not to have source + // locations at all.) + OptimizationRemarkAnalysis FR("size-info", "FunctionIRSizeChange", + DiagnosticLocation(), &BB); + FR << DiagnosticInfoOptimizationBase::Argument("Pass", PassName) + << ": Function: " + << DiagnosticInfoOptimizationBase::Argument("Function", Fname) + << ": IR instruction count changed from " + << DiagnosticInfoOptimizationBase::Argument("IRInstrsBefore", + FnCountBefore) + << " to " + << DiagnosticInfoOptimizationBase::Argument("IRInstrsAfter", + FnCountAfter) + << "; Delta: " + << DiagnosticInfoOptimizationBase::Argument("DeltaInstrCount", FnDelta); + F->getContext().diagnose(FR); + + // Update the function size. + Change.first = FnCountAfter; + }; + + // Are we looking at more than one function? If so, emit remarks for all of + // the functions in the module. Otherwise, only emit one remark. + if (!CouldOnlyImpactOneFunction) + std::for_each(FunctionToInstrCount.keys().begin(), + FunctionToInstrCount.keys().end(), + EmitFunctionSizeChangedRemark); + else + EmitFunctionSizeChangedRemark(F->getName().str()); } void PassManagerPrettyStackEntry::print(raw_ostream &OS) const { @@ -1284,9 +1377,10 @@ bool BBPassManager::runOnFunction(Function &F) { Module &M = *F.getParent(); unsigned InstrCount, BBSize = 0; + StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount; bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); if (EmitICRemark) - InstrCount = initSizeRemarkInfo(M); + InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount); for (BasicBlock &BB : F) { // Collect the initial size of the basic block. @@ -1313,7 +1407,8 @@ bool BBPassManager::runOnFunction(Function &F) { if (NewSize != BBSize) { int64_t Delta = static_cast<int64_t>(NewSize) - static_cast<int64_t>(BBSize); - emitInstrCountChangedRemark(BP, M, Delta, InstrCount, &F); + emitInstrCountChangedRemark(BP, M, Delta, InstrCount, + FunctionToInstrCount, &F); InstrCount = static_cast<int64_t>(InstrCount) + Delta; BBSize = NewSize; } @@ -1522,10 +1617,11 @@ bool FPPassManager::runOnFunction(Function &F) { populateInheritedAnalysis(TPM->activeStack); unsigned InstrCount, FunctionSize = 0; + StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount; bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); // Collect the initial size of the module. if (EmitICRemark) { - InstrCount = initSizeRemarkInfo(M); + InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount); FunctionSize = F.getInstructionCount(); } @@ -1550,7 +1646,8 @@ bool FPPassManager::runOnFunction(Function &F) { if (NewSize != FunctionSize) { int64_t Delta = static_cast<int64_t>(NewSize) - static_cast<int64_t>(FunctionSize); - emitInstrCountChangedRemark(FP, M, Delta, InstrCount, &F); + emitInstrCountChangedRemark(FP, M, Delta, InstrCount, + FunctionToInstrCount, &F); InstrCount = static_cast<int64_t>(InstrCount) + Delta; FunctionSize = NewSize; } @@ -1619,10 +1716,11 @@ MPPassManager::runOnModule(Module &M) { Changed |= getContainedPass(Index)->doInitialization(M); unsigned InstrCount, ModuleCount = 0; + StringMap<std::pair<unsigned, unsigned>> FunctionToInstrCount; bool EmitICRemark = M.shouldEmitInstrCountChangedRemark(); // Collect the initial size of the module. if (EmitICRemark) { - InstrCount = initSizeRemarkInfo(M); + InstrCount = initSizeRemarkInfo(M, FunctionToInstrCount); ModuleCount = InstrCount; } @@ -1646,7 +1744,8 @@ MPPassManager::runOnModule(Module &M) { if (ModuleCount != InstrCount) { int64_t Delta = static_cast<int64_t>(ModuleCount) - static_cast<int64_t>(InstrCount); - emitInstrCountChangedRemark(MP, M, Delta, InstrCount); + emitInstrCountChangedRemark(MP, M, Delta, InstrCount, + FunctionToInstrCount); InstrCount = ModuleCount; } } |