summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/CallGraphSCCPass.cpp6
-rw-r--r--llvm/lib/Analysis/LoopPass.cpp4
-rw-r--r--llvm/lib/IR/Function.cpp8
-rw-r--r--llvm/lib/IR/LegacyPassManager.cpp69
-rw-r--r--llvm/lib/IR/Module.cpp7
5 files changed, 90 insertions, 4 deletions
diff --git a/llvm/lib/Analysis/CallGraphSCCPass.cpp b/llvm/lib/Analysis/CallGraphSCCPass.cpp
index 4bb181e352d..ef61c65463f 100644
--- a/llvm/lib/Analysis/CallGraphSCCPass.cpp
+++ b/llvm/lib/Analysis/CallGraphSCCPass.cpp
@@ -120,6 +120,7 @@ bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
bool &DevirtualizedCall) {
bool Changed = false;
PMDataManager *PM = P->getAsPMDataManager();
+ Module &M = CG.getModule();
if (!PM) {
CallGraphSCCPass *CGSP = (CallGraphSCCPass*)P;
@@ -130,7 +131,12 @@ bool CGPassManager::RunPassOnSCC(Pass *P, CallGraphSCC &CurSCC,
{
TimeRegion PassTimer(getPassTimer(CGSP));
+ unsigned InstrCount = initSizeRemarkInfo(M);
Changed = CGSP->runOnSCC(CurSCC);
+
+ // If the pass modified the module, it may have modified the instruction
+ // count of the module. Try emitting a remark.
+ emitInstrCountChangedRemark(P, M, InstrCount);
}
// After the CGSCCPass is done, when assertions are enabled, use
diff --git a/llvm/lib/Analysis/LoopPass.cpp b/llvm/lib/Analysis/LoopPass.cpp
index 208bd53a3a8..00d88e8189e 100644
--- a/llvm/lib/Analysis/LoopPass.cpp
+++ b/llvm/lib/Analysis/LoopPass.cpp
@@ -151,6 +151,7 @@ void LPPassManager::markLoopAsDeleted(Loop &L) {
bool LPPassManager::runOnFunction(Function &F) {
auto &LIWP = getAnalysis<LoopInfoWrapperPass>();
LI = &LIWP.getLoopInfo();
+ Module &M = *F.getParent();
#if 0
DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
#endif
@@ -200,8 +201,9 @@ bool LPPassManager::runOnFunction(Function &F) {
{
PassManagerPrettyStackEntry X(P, *CurrentLoop->getHeader());
TimeRegion PassTimer(getPassTimer(P));
-
+ unsigned InstrCount = initSizeRemarkInfo(M);
Changed |= P->runOnLoop(CurrentLoop, *this);
+ emitInstrCountChangedRemark(P, M, InstrCount);
}
if (Changed)
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 20619167bae..4c7b6b74205 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -194,6 +194,14 @@ LLVMContext &Function::getContext() const {
return getType()->getContext();
}
+unsigned Function::getInstructionCount() {
+ unsigned NumInstrs = 0;
+ for (BasicBlock &BB : BasicBlocks)
+ NumInstrs += std::distance(BB.instructionsWithoutDebug().begin(),
+ BB.instructionsWithoutDebug().end());
+ return NumInstrs;
+}
+
void Function::removeFromParent() {
getParent()->getFunctionList().remove(getIterator());
}
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index c13e710dd3b..74481b0e501 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -13,6 +13,7 @@
#include "llvm/IR/LegacyPassManager.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"
@@ -134,8 +135,65 @@ bool PMDataManager::isPassDebuggingExecutionsOrMore() const {
return PassDebugging >= Executions;
}
+unsigned PMDataManager::initSizeRemarkInfo(Module &M) {
+ // Only calculate getInstructionCount if the size-info remark is requested.
+ if (M.getContext().getDiagHandlerPtr()->isAnalysisRemarkEnabled("size-info"))
+ return M.getInstructionCount();
+ return 0;
+}
+
+void PMDataManager::emitInstrCountChangedRemark(Pass *P, Module &M,
+ unsigned CountBefore) {
+ // Did the user request the remark? If not, quit.
+ if (!M.getContext().getDiagHandlerPtr()->isAnalysisRemarkEnabled("size-info"))
+ return;
+
+ // 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 = (int64_t)CountAfter - (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)
@@ -1284,6 +1342,7 @@ bool BBPassManager::runOnFunction(Function &F) {
return false;
bool Changed = doInitialization(F);
+ Module &M = *F.getParent();
for (BasicBlock &BB : F)
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
@@ -1299,8 +1358,9 @@ bool BBPassManager::runOnFunction(Function &F) {
// If the pass crashes, remember this.
PassManagerPrettyStackEntry X(BP, BB);
TimeRegion PassTimer(getPassTimer(BP));
-
+ unsigned InstrCount = initSizeRemarkInfo(M);
LocalChanged |= BP->runOnBasicBlock(BB);
+ emitInstrCountChangedRemark(BP, M, InstrCount);
}
Changed |= LocalChanged;
@@ -1500,7 +1560,7 @@ 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);
@@ -1516,8 +1576,9 @@ bool FPPassManager::runOnFunction(Function &F) {
{
PassManagerPrettyStackEntry X(FP, F);
TimeRegion PassTimer(getPassTimer(FP));
-
+ unsigned InstrCount = initSizeRemarkInfo(M);
LocalChanged |= FP->runOnFunction(F);
+ emitInstrCountChangedRemark(FP, M, InstrCount);
}
Changed |= LocalChanged;
@@ -1594,7 +1655,9 @@ MPPassManager::runOnModule(Module &M) {
PassManagerPrettyStackEntry X(MP, M);
TimeRegion PassTimer(getPassTimer(MP));
+ unsigned InstrCount = initSizeRemarkInfo(M);
LocalChanged |= MP->runOnModule(M);
+ emitInstrCountChangedRemark(MP, M, InstrCount);
}
Changed |= LocalChanged;
diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp
index 9f1e6096932..f1802406353 100644
--- a/llvm/lib/IR/Module.cpp
+++ b/llvm/lib/IR/Module.cpp
@@ -464,6 +464,13 @@ unsigned Module::getCodeViewFlag() const {
return cast<ConstantInt>(Val->getValue())->getZExtValue();
}
+unsigned Module::getInstructionCount() {
+ unsigned NumInstrs = 0;
+ for (Function &F : FunctionList)
+ NumInstrs += F.getInstructionCount();
+ return NumInstrs;
+}
+
Comdat *Module::getOrInsertComdat(StringRef Name) {
auto &Entry = *ComdatSymTab.insert(std::make_pair(Name, Comdat())).first;
Entry.second.Name = &Entry;
OpenPOWER on IntegriCloud