aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/LegacyPassManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/LegacyPassManager.cpp')
-rw-r--r--llvm/lib/IR/LegacyPassManager.cpp321
1 files changed, 211 insertions, 110 deletions
diff --git a/llvm/lib/IR/LegacyPassManager.cpp b/llvm/lib/IR/LegacyPassManager.cpp
index 90239bb76298..74869fa62c66 100644
--- a/llvm/lib/IR/LegacyPassManager.cpp
+++ b/llvm/lib/IR/LegacyPassManager.cpp
@@ -33,7 +33,6 @@
#include <algorithm>
#include <unordered_set>
using namespace llvm;
-using namespace llvm::legacy;
// See PassManagers.h for Pass Manager infrastructure overview.
@@ -132,7 +131,8 @@ bool llvm::forcePrintModuleIR() { return PrintModuleScope; }
bool llvm::isFunctionInPrintList(StringRef FunctionName) {
static std::unordered_set<std::string> PrintFuncNames(PrintFuncsList.begin(),
PrintFuncsList.end());
- return PrintFuncNames.empty() || PrintFuncNames.count(FunctionName);
+ return PrintFuncNames.empty() ||
+ PrintFuncNames.count(std::string(FunctionName));
}
/// isPassDebuggingExecutionsOrMore - Return true if -debug-pass=Executions
/// or higher is specified.
@@ -239,7 +239,7 @@ void PMDataManager::emitInstrCountChangedRemark(
// Helper lambda that emits a remark when the size of a function has changed.
auto EmitFunctionSizeChangedRemark = [&FunctionToInstrCount, &F, &BB,
- &PassName](const std::string &Fname) {
+ &PassName](StringRef Fname) {
unsigned FnCountBefore, FnCountAfter;
std::pair<unsigned, unsigned> &Change = FunctionToInstrCount[Fname];
std::tie(FnCountBefore, FnCountAfter) = Change;
@@ -386,8 +386,68 @@ public:
void FunctionPassManagerImpl::anchor() {}
char FunctionPassManagerImpl::ID = 0;
-} // End of legacy namespace
-} // End of llvm namespace
+
+//===----------------------------------------------------------------------===//
+// FunctionPassManagerImpl implementation
+//
+bool FunctionPassManagerImpl::doInitialization(Module &M) {
+ bool Changed = false;
+
+ dumpArguments();
+ dumpPasses();
+
+ for (ImmutablePass *ImPass : getImmutablePasses())
+ Changed |= ImPass->doInitialization(M);
+
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+ Changed |= getContainedManager(Index)->doInitialization(M);
+
+ return Changed;
+}
+
+bool FunctionPassManagerImpl::doFinalization(Module &M) {
+ bool Changed = false;
+
+ for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index)
+ Changed |= getContainedManager(Index)->doFinalization(M);
+
+ for (ImmutablePass *ImPass : getImmutablePasses())
+ Changed |= ImPass->doFinalization(M);
+
+ return Changed;
+}
+
+void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
+ if (!wasRun)
+ return;
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
+ FPPassManager *FPPM = getContainedManager(Index);
+ for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) {
+ FPPM->getContainedPass(Index)->releaseMemory();
+ }
+ }
+ wasRun = false;
+}
+
+// Execute all the passes managed by this top level manager.
+// Return true if any function is modified by a pass.
+bool FunctionPassManagerImpl::run(Function &F) {
+ bool Changed = false;
+
+ initializeAllAnalysisInfo();
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
+ Changed |= getContainedManager(Index)->runOnFunction(F);
+ F.getContext().yield();
+ }
+
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
+ getContainedManager(Index)->cleanup();
+
+ wasRun = true;
+ return Changed;
+}
+} // namespace legacy
+} // namespace llvm
namespace {
//===----------------------------------------------------------------------===//
@@ -405,7 +465,7 @@ public:
// Delete on the fly managers.
~MPPassManager() override {
for (auto &OnTheFlyManager : OnTheFlyManagers) {
- FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
+ legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
delete FPP;
}
}
@@ -436,7 +496,8 @@ public:
/// Return function pass corresponding to PassInfo PI, that is
/// required by module pass MP. Instantiate analysis pass, by using
/// its runOnFunction() for function F.
- Pass* getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F) override;
+ std::tuple<Pass *, bool> getOnTheFlyPass(Pass *MP, AnalysisID PI,
+ Function &F) override;
StringRef getPassName() const override { return "Module Pass Manager"; }
@@ -449,7 +510,7 @@ public:
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
ModulePass *MP = getContainedPass(Index);
MP->dumpPassStructure(Offset + 1);
- MapVector<Pass *, FunctionPassManagerImpl *>::const_iterator I =
+ MapVector<Pass *, legacy::FunctionPassManagerImpl *>::const_iterator I =
OnTheFlyManagers.find(MP);
if (I != OnTheFlyManagers.end())
I->second->dumpPassStructure(Offset + 2);
@@ -469,7 +530,7 @@ public:
private:
/// Collection of on the fly FPPassManagers. These managers manage
/// function passes that are required by module passes.
- MapVector<Pass *, FunctionPassManagerImpl *> OnTheFlyManagers;
+ MapVector<Pass *, legacy::FunctionPassManagerImpl *> OnTheFlyManagers;
};
char MPPassManager::ID = 0;
@@ -532,8 +593,35 @@ public:
void PassManagerImpl::anchor() {}
char PassManagerImpl::ID = 0;
-} // End of legacy namespace
-} // End of llvm namespace
+
+//===----------------------------------------------------------------------===//
+// PassManagerImpl implementation
+
+//
+/// run - Execute all of the passes scheduled for execution. Keep track of
+/// whether any of the passes modifies the module, and if so, return true.
+bool PassManagerImpl::run(Module &M) {
+ bool Changed = false;
+
+ dumpArguments();
+ dumpPasses();
+
+ for (ImmutablePass *ImPass : getImmutablePasses())
+ Changed |= ImPass->doInitialization(M);
+
+ initializeAllAnalysisInfo();
+ for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
+ Changed |= getContainedManager(Index)->runOnModule(M);
+ M.getContext().yield();
+ }
+
+ for (ImmutablePass *ImPass : getImmutablePasses())
+ Changed |= ImPass->doFinalization(M);
+
+ return Changed;
+}
+} // namespace legacy
+} // namespace llvm
//===----------------------------------------------------------------------===//
// PMTopLevelManager implementation
@@ -1289,7 +1377,8 @@ void PMDataManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
llvm_unreachable("Unable to schedule pass");
}
-Pass *PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI, Function &F) {
+std::tuple<Pass *, bool> PMDataManager::getOnTheFlyPass(Pass *P, AnalysisID PI,
+ Function &F) {
llvm_unreachable("Unable to find on the fly pass");
}
@@ -1306,17 +1395,20 @@ Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const {
return PM.findAnalysisPass(ID, dir);
}
-Pass *AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI,
- Function &F) {
+std::tuple<Pass *, bool>
+AnalysisResolver::findImplPass(Pass *P, AnalysisID AnalysisPI, Function &F) {
return PM.getOnTheFlyPass(P, AnalysisPI, F);
}
+namespace llvm {
+namespace legacy {
+
//===----------------------------------------------------------------------===//
// FunctionPassManager implementation
/// Create new Function pass manager
FunctionPassManager::FunctionPassManager(Module *m) : M(m) {
- FPM = new FunctionPassManagerImpl();
+ FPM = new legacy::FunctionPassManagerImpl();
// FPM is the top level manager.
FPM->setTopLevelManager(FPM);
@@ -1355,36 +1447,8 @@ bool FunctionPassManager::doInitialization() {
bool FunctionPassManager::doFinalization() {
return FPM->doFinalization(*M);
}
-
-//===----------------------------------------------------------------------===//
-// FunctionPassManagerImpl implementation
-//
-bool FunctionPassManagerImpl::doInitialization(Module &M) {
- bool Changed = false;
-
- dumpArguments();
- dumpPasses();
-
- for (ImmutablePass *ImPass : getImmutablePasses())
- Changed |= ImPass->doInitialization(M);
-
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
- Changed |= getContainedManager(Index)->doInitialization(M);
-
- return Changed;
-}
-
-bool FunctionPassManagerImpl::doFinalization(Module &M) {
- bool Changed = false;
-
- for (int Index = getNumContainedManagers() - 1; Index >= 0; --Index)
- Changed |= getContainedManager(Index)->doFinalization(M);
-
- for (ImmutablePass *ImPass : getImmutablePasses())
- Changed |= ImPass->doFinalization(M);
-
- return Changed;
-}
+} // namespace legacy
+} // namespace llvm
/// cleanup - After running all passes, clean up pass manager cache.
void FPPassManager::cleanup() {
@@ -1396,35 +1460,6 @@ void FPPassManager::cleanup() {
}
}
-void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
- if (!wasRun)
- return;
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
- FPPassManager *FPPM = getContainedManager(Index);
- for (unsigned Index = 0; Index < FPPM->getNumContainedPasses(); ++Index) {
- FPPM->getContainedPass(Index)->releaseMemory();
- }
- }
- wasRun = false;
-}
-
-// Execute all the passes managed by this top level manager.
-// Return true if any function is modified by a pass.
-bool FunctionPassManagerImpl::run(Function &F) {
- bool Changed = false;
-
- initializeAllAnalysisInfo();
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
- Changed |= getContainedManager(Index)->runOnFunction(F);
- F.getContext().yield();
- }
-
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index)
- getContainedManager(Index)->cleanup();
-
- wasRun = true;
- return Changed;
-}
//===----------------------------------------------------------------------===//
// FPPassManager implementation
@@ -1440,6 +1475,74 @@ void FPPassManager::dumpPassStructure(unsigned Offset) {
}
}
+#ifdef EXPENSIVE_CHECKS
+namespace {
+namespace details {
+
+// Basic hashing mechanism to detect structural change to the IR, used to verify
+// pass return status consistency with actual change. Loosely copied from
+// llvm/lib/Transforms/Utils/FunctionComparator.cpp
+
+class StructuralHash {
+ uint64_t Hash = 0x6acaa36bef8325c5ULL;
+
+ void update(uint64_t V) { Hash = hashing::detail::hash_16_bytes(Hash, V); }
+
+public:
+ StructuralHash() = default;
+
+ void update(Function &F) {
+ if (F.empty())
+ return;
+
+ update(F.isVarArg());
+ update(F.arg_size());
+
+ SmallVector<const BasicBlock *, 8> BBs;
+ SmallPtrSet<const BasicBlock *, 16> VisitedBBs;
+
+ BBs.push_back(&F.getEntryBlock());
+ VisitedBBs.insert(BBs[0]);
+ while (!BBs.empty()) {
+ const BasicBlock *BB = BBs.pop_back_val();
+ update(45798); // Block header
+ for (auto &Inst : *BB)
+ update(Inst.getOpcode());
+
+ const Instruction *Term = BB->getTerminator();
+ for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
+ if (!VisitedBBs.insert(Term->getSuccessor(i)).second)
+ continue;
+ BBs.push_back(Term->getSuccessor(i));
+ }
+ }
+ }
+
+ void update(Module &M) {
+ for (Function &F : M)
+ update(F);
+ }
+
+ uint64_t getHash() const { return Hash; }
+};
+
+} // namespace details
+
+uint64_t StructuralHash(Function &F) {
+ details::StructuralHash H;
+ H.update(F);
+ return H.getHash();
+}
+
+uint64_t StructuralHash(Module &M) {
+ details::StructuralHash H;
+ H.update(M);
+ return H.getHash();
+}
+
+} // end anonymous namespace
+
+#endif
/// Execute all of the passes scheduled for execution by invoking
/// runOnFunction method. Keep track of whether any of the passes modifies
@@ -1478,7 +1581,16 @@ bool FPPassManager::runOnFunction(Function &F) {
{
PassManagerPrettyStackEntry X(FP, F);
TimeRegion PassTimer(getPassTimer(FP));
+#ifdef EXPENSIVE_CHECKS
+ uint64_t RefHash = StructuralHash(F);
+#endif
LocalChanged |= FP->runOnFunction(F);
+
+#ifdef EXPENSIVE_CHECKS
+ assert((LocalChanged || (RefHash == StructuralHash(F))) &&
+ "Pass modifies its input and doesn't report it.");
+#endif
+
if (EmitICRemark) {
unsigned NewSize = F.getInstructionCount();
@@ -1551,7 +1663,7 @@ MPPassManager::runOnModule(Module &M) {
// Initialize on-the-fly passes
for (auto &OnTheFlyManager : OnTheFlyManagers) {
- FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
+ legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
Changed |= FPP->doInitialization(M);
}
@@ -1579,7 +1691,17 @@ MPPassManager::runOnModule(Module &M) {
PassManagerPrettyStackEntry X(MP, M);
TimeRegion PassTimer(getPassTimer(MP));
+#ifdef EXPENSIVE_CHECKS
+ uint64_t RefHash = StructuralHash(M);
+#endif
+
LocalChanged |= MP->runOnModule(M);
+
+#ifdef EXPENSIVE_CHECKS
+ assert((LocalChanged || (RefHash == StructuralHash(M))) &&
+ "Pass modifies its input and doesn't report it.");
+#endif
+
if (EmitICRemark) {
// Update the size of the module.
unsigned ModuleCount = M.getInstructionCount();
@@ -1612,7 +1734,7 @@ MPPassManager::runOnModule(Module &M) {
// Finalize on-the-fly passes
for (auto &OnTheFlyManager : OnTheFlyManagers) {
- FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
+ legacy::FunctionPassManagerImpl *FPP = OnTheFlyManager.second;
// We don't know when is the last time an on-the-fly pass is run,
// so we need to releaseMemory / finalize here
FPP->releaseMemoryOnTheFly();
@@ -1633,9 +1755,9 @@ void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
RequiredPass->getPotentialPassManagerType()) &&
"Unable to handle Pass that requires lower level Analysis pass");
- FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
+ legacy::FunctionPassManagerImpl *FPP = OnTheFlyManagers[P];
if (!FPP) {
- FPP = new FunctionPassManagerImpl();
+ FPP = new legacy::FunctionPassManagerImpl();
// FPP is the top level manager.
FPP->setTopLevelManager(FPP);
@@ -1664,42 +1786,19 @@ void MPPassManager::addLowerLevelRequiredPass(Pass *P, Pass *RequiredPass) {
/// Return function pass corresponding to PassInfo PI, that is
/// required by module pass MP. Instantiate analysis pass, by using
/// its runOnFunction() for function F.
-Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){
- FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
+std::tuple<Pass *, bool> MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI,
+ Function &F) {
+ legacy::FunctionPassManagerImpl *FPP = OnTheFlyManagers[MP];
assert(FPP && "Unable to find on the fly pass");
FPP->releaseMemoryOnTheFly();
- FPP->run(F);
- return ((PMTopLevelManager*)FPP)->findAnalysisPass(PI);
+ bool Changed = FPP->run(F);
+ return std::make_tuple(((PMTopLevelManager *)FPP)->findAnalysisPass(PI),
+ Changed);
}
-
-//===----------------------------------------------------------------------===//
-// PassManagerImpl implementation
-
-//
-/// run - Execute all of the passes scheduled for execution. Keep track of
-/// whether any of the passes modifies the module, and if so, return true.
-bool PassManagerImpl::run(Module &M) {
- bool Changed = false;
-
- dumpArguments();
- dumpPasses();
-
- for (ImmutablePass *ImPass : getImmutablePasses())
- Changed |= ImPass->doInitialization(M);
-
- initializeAllAnalysisInfo();
- for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
- Changed |= getContainedManager(Index)->runOnModule(M);
- M.getContext().yield();
- }
-
- for (ImmutablePass *ImPass : getImmutablePasses())
- Changed |= ImPass->doFinalization(M);
-
- return Changed;
-}
+namespace llvm {
+namespace legacy {
//===----------------------------------------------------------------------===//
// PassManager implementation
@@ -1724,6 +1823,8 @@ void PassManager::add(Pass *P) {
bool PassManager::run(Module &M) {
return PM->run(M);
}
+} // namespace legacy
+} // namespace llvm
//===----------------------------------------------------------------------===//
// PMStack implementation
@@ -1814,4 +1915,4 @@ void FunctionPass::assignPassManager(PMStack &PMS,
PM->add(this);
}
-PassManagerBase::~PassManagerBase() {}
+legacy::PassManagerBase::~PassManagerBase() {}