How to run the Function Pass before the Module Pass in LLVM?

I'm implementing several Passes on the LLVM in order to add original optimization, These Passes are based on FunctionPass and ModulePass. Now, each Pass is invoked by corresponding opt command option which is registerd by RegisterPass template.

In future, I'd like to these Passes to be invoked only by one opt command option. My idea is as follows:- - First,Function passes to run, and finally Module pass to run. - Each Function passes to use the former Function passes' analysis information. - The final Module pass to construct a new function using the former Function passes' result. - All of these Passes sequence to invoke by only one opt command option specifying the final Module pass.

I thought I could make it with addRequired method in the AnalysisUsage class. However, it doesn't seem to work:- - In the Function pass, several Function passes may be addRequired in the order. - In the Function pass, only one Module pass may be addRequired. - In the Function pass(X), Function pass and Module pass cannot be addRequired simultaneously. ie opt command execution with option X causes to a lock status. - In the Module pass, only one Module pass may be addRequired. - In the Module pass(Y), Function pass(Z) cannot be addRequired. ie opt command with option Y executes only Y, and Function pass(Z) is ignored.

I am not familiar to the Pass manager mechanism. Anybody help me how to run the Function pass before the Module pass with only one opt command option?


The case of execution is shown below:-

$ opt -stats -load ~/samples/tryPass4.so -MPass4 hello2.ll -S -o tryPass4.ll -debug-pass=Structure
Pass Arguments:  -targetlibinfo -datalayout -notti -basictti -x86tti -MPass4 -verify -verify-di -print-module
Target Library Information                                              ↑
Data Layout                              -FPass4 doesn't appear here
No target information
Target independent code generator's TTI
X86 Target Transform Info
  ModulePass Manager
    Module Pass
      Unnamed pass: implement Pass::getPassName()
    FunctionPass Manager
      Module Verifier
    Debug Info Verifier
    Print module to stderr
Pass Arguments:  -FPass4    <- here -FPass4 appears, but not executed
  FunctionPass Manager
    Function Pass


 ***** Module Name : hello2.ll  <- output from the Module pass

The source code for above is as follows:-

using namespace llvm;
namespace{
 class tryFPass4 : public FunctionPass { 
   public :
    static char ID;
    tryFPass4() : FunctionPass(ID){}
    ~tryFPass4(){}
    virtual bool runOnFunction(llvm::Function &F);
    virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const;
 };
 class tryMPass4 : public ModulePass { 
   public :
    static char ID;
    tryMPass4() : ModulePass(ID){}
    ~tryMPass4(){}
    virtual bool runOnModule(llvm::Module &M);
    virtual void getAnalysisUsage(llvm::AnalysisUsage &AU) const;
 };
}
bool tryFPass4::runOnFunction(Function &F) {
  bool change = false;
   ....  
  return change;
}
bool tryMPass4::runOnModule(Module &M) {
  bool change = false ;
   ....
  return change;
}

void tryFPass4::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesCFG(); 
}

void tryMPass4::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesCFG();
  AU.addRequired<tryFPass4>();
}
char tryFPass4::ID = 0;
static RegisterPass<tryFPass4> X("FPass4", "Function Pass", false, false);

char tryMPass4::ID = 0;
static RegisterPass<tryMPass4> Y("MPass4", "Module Pass", false, false);

I tried to simulate the problem here using LLVM 3.8.1.

I believe your Function pass gets to run here:

Module Pass
  Unnamed pass: implement Pass::getPassName()

I do not know why it is marked as unnamed although getPassName is overriden.

A fine detail that you need to watch is that in order for the function pass to actually execute its runOnFunction method, you need to invoke the Function & specific method of getAnalysis as in:

getAnalysis<tryFPass4>(f); // where f is the current Function operating on

It seems if the dependent pass operates on a small unit of IR than the pass that requires it, it needs to be executed explicitly. I might be mistaken since I have not yet tried it with a BasicBlockPass required by a FunctionPass .

链接地址: http://www.djcxy.com/p/68696.html

上一篇: Printf float与LLVM段错误

下一篇: 如何在模块通过LLVM之前运行函数通过?