Interactions between module and loop passes

Hi all,

I have a code with three passes (one loop pass and two module passes) and my own pass manager. If I schedule the loop pass between the others, my code segfaults. Is there any explanation why loop passes cannot be scheduled between two module passes? Perhaps I misunderstood the behaviour of pass managers.

I paste here my "usage" information:

int main(...){

  Module m = ... //Read module
  PassManager pm;

  pm.add(new ModPass1);
  pm.add(new LoopPass);
  pm.add(new ModPass2);
  pm.run(m);

}

class ModPass1 : public ModulePass{

     virtual void getAnalysisUsage(AnalysisUsage&AU) const{
         AU.setPreservesAll();
     }
};

class LoopPass : public LoopPass{

  virtual void getAnalysisUsage(AnalysisUsage&AU) const{
    AU.setRequires<ModPass1>();
    AU.setPreservesAll();
     }
};

class ModPass2 : public ModulePass{

  virtual void getAnalysisUsage(AnalysisUsage&AU) const{

    AU.setRequires<LoopPass>();
    AU.setPreservesAll();
  }
};

If I remove any of the passes (updating the usage information), it's OK. If I transform the loop pass into a module pass, it also works.

Thanks ahead,

Hi Pablo,

I have a code with three passes (one loop pass and two module passes)
and my own pass manager. If I schedule the loop pass between the others,
my code segfaults.

when developing with LLVM you should configure with --enable-assertions.
That way you should get an assert failure with a helpful message rather
than a crash.

  Is there any explanation why loop passes cannot be

scheduled between two module passes? Perhaps I misunderstood the
behaviour of pass managers.

I paste here my "usage" information:

int main(...){

  Module m = ... //Read module
  PassManager pm;

  pm.add(new ModPass1);
  pm.add(new LoopPass);
  pm.add(new ModPass2);
  pm.run(m);

}

class ModPass1 : public ModulePass{

      virtual void getAnalysisUsage(AnalysisUsage&AU) const{
          AU.setPreservesAll();
      }
};

class LoopPass : public LoopPass{

  virtual void getAnalysisUsage(AnalysisUsage&AU) const{
    AU.setRequires<ModPass1>();

I'm pretty sure a LoopPass cannot require a ModulePass.

Ciao, Duncan.

Hi Duncan,

Hi Pablo,

I have a code with three passes (one loop pass and two module passes)
and my own pass manager. If I schedule the loop pass between the others,
my code segfaults.

when developing with LLVM you should configure with --enable-assertions.
That way you should get an assert failure with a helpful message rather
than a crash.

Sorry, I forgot to add the assertion failure:

PassManager.cpp:540: void llvm::PMTopLevelManager::setLastUser(const llvm::SmallVectorImpl<llvm::Pass*>&, llvm::Pass*): Assertion `AnalysisPass && "Expected analysis pass to exist."' failed.

class ModPass1 : public ModulePass{

       virtual void getAnalysisUsage(AnalysisUsage&AU) const{
           AU.setPreservesAll();
       }
};

class LoopPass : public LoopPass{

  virtual void getAnalysisUsage(AnalysisUsage&AU) const{
    AU.setRequires<ModPass1>();
I'm pretty sure a LoopPass cannot require a ModulePass.

Is it possible to overcome this limitation? I need to access and modify the loops in a function. Is it possible to do that from the function itself, or is the loop pass the only way to get Loop objects? If I can do it from a Module (or another) pass, I don't mind. Loop passes just sound to me like the most straightforward way.

Thanks for your time,