loadable passes with dependencies?

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_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?

Thank you


you can have a look at the approach taken in Polly [1]. Here the relevant file in the git repository:


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.


[1] http://polly.grosser.es/

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) {
          // create my own createHelloPass() method?

        static llvm::RegisterStandardPasses

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);
74 initializePoccPass(Registry);
75 #endif
76 initializeRegionSimplifyPass(Registry);
77 initializeScopDetectionPass(Registry);
78 initializeScopInfoPass(Registry);
79 initializeTempScopInfoPass(Registry);
80 }
82 // Statically register all Polly passes such that they are available after
83 // loading Polly.
84 class StaticInitializer {
86 public:
87 StaticInitializer() {
88 PassRegistry &Registry = *PassRegistry::getPassRegistry();
89 initializePollyPasses(Registry);
90 }
91 };
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.


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 {

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_END(Hello, "hello", "Hello World Pass", false, true)

class StaticInitializer {
  StaticInitializer() {
    PassRegistry &Registry = *PassRegistry::getPassRegistry();

static StaticInitializer InitializeEverything;

Thanks again

Looks good to me. Are you sure you call getAnalysis only for the DominatorTree? What is the output of "grep getAnalysis YourPass.cpp"?


Just shows me what I expect
  void getAnalysisUsage(AnalysisUsage &AU) const {
    DominatorTree *dt = &getAnalysis<DominatorTree>();

So I'm only using it for DominatorTree(so I can use PromoteMemToReg).


Interesting. Is the same assert triggered when you use RegisterPass to register the pass? Is getAnalysisUsage() called at all?

My definition of getAnalysisUsage looks like:

virtual void getAnalysisUsage(AnalysisUsage &AU) const

Why do you omit the 'virtual'?


I changed it to virtual void getAnalysisUsage(AnalysisUsage &AU) const
with no luck.

The function does get called, I see the errs() call I inserted before
the asserted is tripped. Really not sure how to go about debugging
this now.

Thanks again

Something’s different here, earlier in the thread you said you had:
void getAnalysisUsage(AnalysisUsage &AU) const {


Now you have:
void getAnalysisUsage(AnalysisUsage &AU) const {
DominatorTree *dt = &getAnalysis();

I’m sort of confused, why did this change happen? I think the “AU.addRequired” was correct to have in getAnalysisUsage, and the “getAnalysis” goes e.g. in the top of runOnFunction/Module/Whatever. Sorry if I misunderstood what’s going on.

I still have the addRequired:
        virtual void getAnalysisUsage(AnalysisUsage &AU) const {

The other line
        DominatorTree *dt = &getAnalysis<DominatorTree>();
Is for later use when I try to use PromoteMemToReg

I still have the addRequired:
         virtual void getAnalysisUsage(AnalysisUsage&AU) const {

The other line
         DominatorTree *dt =&getAnalysis<DominatorTree>();
Is for later use when I try to use PromoteMemToReg

Isn't DominatorTree a FunctionPass? If your pass is a ModulePass, you need to pass a Function * or Function & to getAnalysis<>():


-- John T.

Awesome, that let me get far enough to trip:

Assertion failed: (ResultPass && "Unable to find requested analysis
info"), function getAnalysisID

Is there something else I forgot?

Make sure that the function F is not a declaration before calling getAnalysis<>().