I'm confused by your code. StaticInitializer seems to exist so you can create InitializeEverything, which doesn't get used. Do I need to do something along the lines of: static void registerPollyPasses(const llvm::PassManagerBuilder &Builder, llvm::PassManagerBase &PM) { PM.add(llvm::createPromoteMemoryToRegisterPass()); // create my own createHelloPass() method? } static llvm::RegisterStandardPasses PassRegister(llvm::PassManagerBuilder::EP_EarlyAsPossible, registerPollyPasses); I'm not sure how to code a possible createHelloPass, as the constructor for my class takes a argument(ID for ModulePass). Thanks On Tue, Nov 8, 2011 at 4:10 AM, Tobias Grosser <tobias at grosser.es> wrote:> On 11/08/2011 03:20 AM, ret val wrote: >> >> I'm writing a Pass that I would like to remain loadable by opt. The >> pass also requires DominatorTree(for PromoteMemToReg). >> >> Looking for examples the only way I found to require a dependecny is >> by doing something like this: >> char Hello::ID = 0; >> namespace llvm { void initializeHelloPass(llvm::PassRegistry&); } >> INITIALIZE_PASS_BEGIN(Hello, "hello", "Hello World Pass", false, >> true) >> INITIALIZE_PASS_DEPENDENCY(DominatorTree) >> INITIALIZE_PASS_END(Hello, "hello", "Hello World Pass", false, >> true) >> >> Unfortunately this gives me(when I try to run it). >> opt: Unknown command line argument '-hello'. >> >> If I instead using RegisterPass like in the guide the Pass is loaded >> fine, a assert is just tripped for not having DominatorTree info. I >> can not seem to mix these 2 ways together or find anything trying todo >> the same. >> >> How should this be done? > > Hi, > > you can have a look at the approach taken in Polly [1]. Here the relevant > file in the git repository: > > http://repo.or.cz/w/polly-mirror.git/blob/HEAD:/lib/RegisterPasses.cpp > > Basically we created a class polly::StaticInitializer which initializes in > its constructor all passes in the external library (in our case Polly). To > make sure the constructor is called when loading > the library, we create a global instance of the static initializer. > > I am not sure if this is the recommended way, but at least it works for us. > If there any comments on how to improve this, please let me know. > > Cheers > Tobi > > [1] http://polly.grosser.es/ >
On 11/08/2011 03:40 PM, ret val wrote:> I'm confused by your code. StaticInitializer seems to exist so you can > create InitializeEverything, which doesn't get used. > > Do I need to do something along the lines of: > static void registerPollyPasses(const llvm::PassManagerBuilder&Builder, > llvm::PassManagerBase&PM) { > PM.add(llvm::createPromoteMemoryToRegisterPass()); > // create my own createHelloPass() method? > } > > static llvm::RegisterStandardPasses > PassRegister(llvm::PassManagerBuilder::EP_EarlyAsPossible, > registerPollyPasses); > > I'm not sure how to code a possible createHelloPass, as the > constructor for my class takes a argument(ID for ModulePass).This is the code interesting to you: 66 void initializePollyPasses(PassRegistry &Registry) { 67 initializeCloogInfoPass(Registry); 68 initializeCodeGenerationPass(Registry); 69 initializeCodePreparationPass(Registry); 70 initializeDependencesPass(Registry); 71 initializeIndependentBlocksPass(Registry); 72 initializeIslScheduleOptimizerPass(Registry); 73 #ifdef SCOPLIB_FOUND 74 initializePoccPass(Registry); 75 #endif 76 initializeRegionSimplifyPass(Registry); 77 initializeScopDetectionPass(Registry); 78 initializeScopInfoPass(Registry); 79 initializeTempScopInfoPass(Registry); 80 } 81 82 // Statically register all Polly passes such that they are available after 83 // loading Polly. 84 class StaticInitializer { 85 86 public: 87 StaticInitializer() { 88 PassRegistry &Registry = *PassRegistry::getPassRegistry(); 89 initializePollyPasses(Registry); 90 } 91 }; 92 93 static StaticInitializer InitializeEverything; For your example, the INITIALIZE_PASS_ macros create for your Hello pass a function initializeHelloPass(PassRegistry &). This function initializes your pass and all dependent passes. It needs to be called before your pass is scheduled. To achieve this we create a class StaticInitializer, which does this in its constructor. It get's the global pass registry and uses the pass registry as a parameter for the intialize*Pass() functions. As we create a static variable of type StaticIntializer, its constructor is called as soon as the module is loaded such that the intialization is performed on load. Let me know if this helped you. Cheers Tobi
Sorry to keep dragging this out on you. Im now getting: Assertion failed: (ResultPass && "getAnalysis*() called on an analysis that was not " "'required' by pass!"), function getAnalysisID But I already have: void getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired<DominatorTree>(); } And changed the bottom of my pass too: char Hello::ID = 0; namespace llvm { void initializeHelloPass(llvm::PassRegistry&); } INITIALIZE_PASS_BEGIN(Hello, "hello", "Hello World Pass", false, true) INITIALIZE_PASS_DEPENDENCY(DominatorTree) INITIALIZE_PASS_END(Hello, "hello", "Hello World Pass", false, true) class StaticInitializer { public: StaticInitializer() { PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeHelloPass(Registry); } }; static StaticInitializer InitializeEverything; Thanks again On Tue, Nov 8, 2011 at 10:18 AM, Tobias Grosser <tobias at grosser.es> wrote:> On 11/08/2011 03:40 PM, ret val wrote: >> >> I'm confused by your code. StaticInitializer seems to exist so you can >> create InitializeEverything, which doesn't get used. >> >> Do I need to do something along the lines of: >> static void registerPollyPasses(const >> llvm::PassManagerBuilder&Builder, >> llvm::PassManagerBase&PM) { >> PM.add(llvm::createPromoteMemoryToRegisterPass()); >> // create my own createHelloPass() method? >> } >> >> static llvm::RegisterStandardPasses >> PassRegister(llvm::PassManagerBuilder::EP_EarlyAsPossible, >> registerPollyPasses); >> >> I'm not sure how to code a possible createHelloPass, as the >> constructor for my class takes a argument(ID for ModulePass). > > This is the code interesting to you: > > 66 void initializePollyPasses(PassRegistry &Registry) { > 67 initializeCloogInfoPass(Registry); > 68 initializeCodeGenerationPass(Registry); > 69 initializeCodePreparationPass(Registry); > 70 initializeDependencesPass(Registry); > 71 initializeIndependentBlocksPass(Registry); > 72 initializeIslScheduleOptimizerPass(Registry); > 73 #ifdef SCOPLIB_FOUND > 74 initializePoccPass(Registry); > 75 #endif > 76 initializeRegionSimplifyPass(Registry); > 77 initializeScopDetectionPass(Registry); > 78 initializeScopInfoPass(Registry); > 79 initializeTempScopInfoPass(Registry); > 80 } > 81 > 82 // Statically register all Polly passes such that they are available > after > 83 // loading Polly. > 84 class StaticInitializer { > 85 > 86 public: > 87 StaticInitializer() { > 88 PassRegistry &Registry = *PassRegistry::getPassRegistry(); > 89 initializePollyPasses(Registry); > 90 } > 91 }; > 92 > 93 static StaticInitializer InitializeEverything; > > For your example, the INITIALIZE_PASS_ macros create for your Hello pass a > function initializeHelloPass(PassRegistry &). This function initializes your > pass and all dependent passes. It needs to be called > before your pass is scheduled. > > To achieve this we create a class StaticInitializer, which does this in its > constructor. It get's the global pass registry and uses the pass registry as > a parameter for the intialize*Pass() functions. As we create a static > variable of type StaticIntializer, its constructor is called as soon as the > module is loaded such that the intialization is performed on load. > > Let me know if this helped you. > > Cheers > Tobi > >