From: Chandler Carruth Date: Wed, 20 Nov 2013 04:39:16 +0000 (+0000) Subject: [PM] Make the function pass manager more regular. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d14894059fa4bbf67ae74caa64fa5f5a23272d63;p=oota-llvm.git [PM] Make the function pass manager more regular. The FunctionPassManager is now itself a function pass. When run over a function, it runs all N of its passes over that function. This is the 1:N mapping in the pass dimension only. This allows it to be used in either a ModulePassManager or potentially some other manager that works on IR units which are supersets of Functions. This commit also adds the obvious adaptor to map from a module pass to a function pass, running the function pass across every function in the module. The test has been updated to use this new pattern. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195192 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/PassManager.h b/include/llvm/IR/PassManager.h index 4a64f20c49a..2664657694f 100644 --- a/include/llvm/IR/PassManager.h +++ b/include/llvm/IR/PassManager.h @@ -189,7 +189,7 @@ public: Passes.push_back(new FunctionPassModel(llvm_move(Pass))); } - bool run(Module *M); + bool run(Function *F); private: // Pull in the concept type and model template specialized for functions. @@ -204,6 +204,36 @@ private: std::vector > Passes; }; +/// \brief Trivial adaptor that maps from a module to its functions. +/// +/// Designed to allow composition of a FunctionPass(Manager) and a +/// ModulePassManager. +template +class ModuleToFunctionPassAdaptor { +public: + explicit ModuleToFunctionPassAdaptor(FunctionPassT Pass) + : Pass(llvm_move(Pass)) {} + + /// \brief Runs the function pass across every function in the module. + bool run(Module *M) { + bool Changed = false; + for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) + Changed |= Pass.run(I); + return Changed; + } + +private: + FunctionPassT Pass; +}; + +/// \brief A function to deduce a function pass type and wrap it in the +/// templated adaptor. +template +ModuleToFunctionPassAdaptor +createModuleToFunctionPassAdaptor(FunctionPassT Pass) { + return ModuleToFunctionPassAdaptor(llvm_move(Pass)); +} + /// \brief A module analysis pass manager with lazy running and caching of /// results. class ModuleAnalysisManager { diff --git a/lib/IR/PassManager.cpp b/lib/IR/PassManager.cpp index b53a2b9671d..35fc534151a 100644 --- a/lib/IR/PassManager.cpp +++ b/lib/IR/PassManager.cpp @@ -53,15 +53,14 @@ void ModuleAnalysisManager::invalidateImpl(void *PassID, Module *M) { ModuleAnalysisResults.erase(PassID); } -bool FunctionPassManager::run(Module *M) { +bool FunctionPassManager::run(Function *F) { bool Changed = false; - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) - if (Passes[Idx]->run(I)) { - Changed = true; - if (AM) - AM->invalidateAll(I); - } + for (unsigned Idx = 0, Size = Passes.size(); Idx != Size; ++Idx) + if (Passes[Idx]->run(F)) { + Changed = true; + if (AM) + AM->invalidateAll(F); + } return Changed; } diff --git a/unittests/IR/PassManagerTest.cpp b/unittests/IR/PassManagerTest.cpp index cf7b6e47488..1e02d6ba02b 100644 --- a/unittests/IR/PassManagerTest.cpp +++ b/unittests/IR/PassManagerTest.cpp @@ -120,7 +120,7 @@ TEST_F(PassManagerTest, Basic) { int FunctionPassRunCount = 0; int AnalyzedInstrCount = 0; FPM.addPass(TestFunctionPass(AM, FunctionPassRunCount, AnalyzedInstrCount)); - MPM.addPass(FPM); + MPM.addPass(createModuleToFunctionPassAdaptor(FPM)); MPM.run(M.get()); EXPECT_EQ(1, ModulePassRunCount);