X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2FWritingAnLLVMPass.html;h=3b116074b716bcb6792022300bb2f58c68d39819;hb=43e607303be9c3162c1d06af180efb3bdafadc02;hp=71dc4926ac31d128db64fe8415feb2424e8e0bae;hpb=5fa8fff8d21d98896957f3a891968c3ffc66c096;p=oota-llvm.git diff --git a/docs/WritingAnLLVMPass.html b/docs/WritingAnLLVMPass.html index 71dc4926ac3..3b116074b71 100644 --- a/docs/WritingAnLLVMPass.html +++ b/docs/WritingAnLLVMPass.html @@ -18,8 +18,7 @@
  • Pass classes and requirements
  • The CallGraphSCCPass class
  • The FunctionPass class @@ -44,6 +43,14 @@
  • The doFinalization(Module &) method
  • +
  • The LoopPass class +
  • The BasicBlockPass class
    • The doInitialization(Function @@ -102,8 +109,8 @@ @@ -127,6 +134,7 @@ from Pass. Depending on how your pass works, you should inherit from the ModulePass, CallGraphSCCPass, FunctionPass, or LoopPass, or BasicBlockPass classes, which gives the system more information about what your pass does, and how it can be combined with other passes. One of the main features of the LLVM Pass Framework is that it @@ -178,13 +186,15 @@ LEVEL = ../../.. # Name of the library to build LIBRARYNAME = Hello -# Build a dynamically linkable shared object -SHARED_LIBRARY = 1 - # Make the shared library become a loadable module so the tools can # dlopen/dlsym on the resulting library. LOADABLE_MODULE = 1 +# Tell the build system which LLVM libraries your pass needs. You'll probably +# need at least LLVMSystem.a, LLVMSupport.a, LLVMCore.a but possibly several +# others too. +LLVMLIBS = LLVMCore.a LLVMSupport.a LLVMSystem.a + # Include the makefile implementation stuff include $(LEVEL)/Makefile.common @@ -192,7 +202,7 @@ include $(LEVEL)/Makefile.common

      This makefile specifies that all of the .cpp files in the current directory are to be compiled and linked together into a Debug/lib/Hello.so shared object that can be dynamically loaded by -the opt or analyze tools via their -load options. +the opt or bugpoint tools via their -load options. If your operating system uses a suffix other than .so (such as windows or Mac OS/X), the appropriate extension will be used.

      @@ -256,7 +266,7 @@ time.

           virtual bool runOnFunction(Function &F) {
      -      std::cerr << "Hello: " << F.getName() << "\n";
      +      llvm::cerr << "Hello: " << F.getName() << "\n";
             return false;
           }
         };  // end of struct Hello
      @@ -269,15 +279,13 @@ to do our thing, so we just print out our message with the name of each
       function.

      -  RegisterOpt<Hello> X("hello", "Hello World Pass");
      +  RegisterPass<Hello> X("hello", "Hello World Pass");
       }  // end of anonymous namespace
       
      -

      Lastly, we register our class Hello, giving it a command line -argument "hello", and a name "Hello World Pass". There are -several different ways of registering your pass, -depending on what it is to be used for. For "optimizations" we use the -RegisterOpt template.

      +

      Lastly, we register our class Hello, +giving it a command line +argument "hello", and a name "Hello World Pass".

      As a whole, the .cpp file looks like:

      @@ -290,12 +298,12 @@ depending on what it is to be used for. For "optimizations" we use the namespace { struct Hello : public FunctionPass { virtual bool runOnFunction(Function &F) { - std::cerr << "Hello: " << F.getName() << "\n"; + llvm::cerr << "Hello: " << F.getName() << "\n"; return false; } }; - RegisterOpt<Hello> X("hello", "Hello World Pass"); + RegisterPass<Hello> X("hello", "Hello World Pass"); }
      @@ -310,14 +318,14 @@ them) to be useful.

      Now that you have a brand new shiny shared object file, we can use the opt command to run an LLVM program through your pass. Because you -registered your pass with the RegisterOpt template, you will be able to +registered your pass with the RegisterPass template, you will be able to use the opt tool to access it, once loaded.

      To test it, follow the example at the end of the

      -  virtual bool doInitialization(Module &M);
      +  virtual bool doInitialization(CallGraph &CG);
       

      The doIninitialize method is allowed to do most of the things that @@ -574,14 +582,14 @@ otherwise.

      -  virtual bool doFinalization(Module &M);
      +  virtual bool doFinalization(CallGraph &CG);
       

      The doFinalization method is an infrequently used method that is @@ -688,6 +696,85 @@ program being compiled.

      + + + +
      + +

      All LoopPass execute on each loop in the function independent of +all of the other loops in the function. LoopPass processes loops in +loop nest order such that outer most loop is processed last.

      + +

      LoopPass subclasses are allowed to update loop nest using +LPPassManager interface. Implementing a loop pass is usually +straightforward. Looppass's may overload three virtual methods to +do their work. All these methods should return true if they modified the +program, or false if they didn't.

      +
      + + + + +
      + +
      +  virtual bool doInitialization(Loop *, LPPassManager &LPM);
      +
      + +The doInitialization method is designed to do simple initialization +type of stuff that does not depend on the functions being processed. The +doInitialization method call is not scheduled to overlap with any +other pass executions (thus it should be very fast). LPPassManager +interface should be used to access Function or Module level analysis +information.

      + +
      + + + + + +
      + +
      +  virtual bool runOnLoop(Loop *, LPPassManager &LPM) = 0;
      +

      + +

      The runOnLoop method must be implemented by your subclass to do +the transformation or analysis work of your pass. As usual, a true value should +be returned if the function is modified. LPPassManager interface +should be used to update loop nest.

      + +
      + + + + +
      + +
      +  virtual bool doFinalization();
      +
      + +

      The doFinalization method is an infrequently used method that is +called when the pass framework has finished calling runOnLoop for every loop in the +program being compiled.

      + +
      + + +
      The BasicBlockPass class @@ -842,37 +929,17 @@ remember, you may not modify the LLVM Function or its contents from a pass registration works, and discussed some of the reasons that it is used and what it does. Here we discuss how and why passes are registered.

      -

      Passes can be registered in several different ways. Depending on the general -classification of the pass, you should use one of the following templates to -register the pass:

      - -
        -
      • RegisterOpt - This template should be used when you are -registering a pass that logically should be available for use in the -'opt' utility.
      • - -
      • RegisterAnalysis - This template should be used when you are -registering a pass that logically should be available for use in the -'analyze' utility.
      • - -
      • RegisterPass - This is the generic form of the -Register* templates that should be used if you want your pass listed by -multiple or no utilities. This template takes an extra third argument that -specifies which tools it should be listed in. See the PassSupport.h -file for more information.
      • - -
      - -

      Regardless of how you register your pass, you must specify at least two +

      As we saw above, passes are registered with the RegisterPass +template, which requires you to pass at least two parameters. The first parameter is the name of the pass that is to be used on the command line to specify that the pass should be added to a program (for -example opt or analyze). The second argument is the name of -the pass, which is to be used for the --help output of programs, as +example, with opt or bugpoint). The second argument is the +name of the pass, which is to be used for the --help output of +programs, as well as for debug output generated by the --debug-pass option.

      -

      If a pass is registered to be used by the analyze utility, you -should implement the virtual print method:

      +

      If you want your pass to be easily dumpable, you should +implement the virtual print method:

      @@ -884,15 +951,15 @@ should implement the virtual print method:

      -  virtual void print(std::ostream &O, const Module *M) const;
      +  virtual void print(llvm::OStream &O, const Module *M) const;
       

      The print method must be implemented by "analyses" in order to print a human readable version of the analysis results. This is useful for debugging an analysis itself, as well as for other people to figure out how an analysis -works. The analyze tool uses this method to generate its output.

      +works. Use the opt -analyze argument to invoke this method.

      -

      The ostream parameter specifies the stream to write the results on, +

      The llvm::OStream parameter specifies the stream to write the results on, and the Module parameter gives a pointer to the top level module of the program that has been analyzed. Note however that this pointer may be null in certain circumstances (such as calling the Pass::dump() from a @@ -1179,11 +1246,11 @@ implementations of the interface by using the following code:

       namespace {
         // Analysis Group implementations must be registered normally...
      -  RegisterOpt<FancyAA>
      +  RegisterPass<FancyAA>
         B("somefancyaa", "A more complex alias analysis implementation");
       
         // Declare that we implement the AliasAnalysis interface
      -  RegisterAnalysisGroup<AliasAnalysis, FancyAA> C;
      +  RegisterAnalysisGroup<AliasAnalysis> C(B);
       }
       
      @@ -1197,11 +1264,11 @@ no problem.

       namespace {
         // Analysis Group implementations must be registered normally...
      -  RegisterOpt<BasicAliasAnalysis>
      +  RegisterPass<BasicAliasAnalysis>
         D("basicaa", "Basic Alias Analysis (default AA impl)");
       
         // Declare that we implement the AliasAnalysis interface
      -  RegisterAnalysisGroup<AliasAnalysis, BasicAliasAnalysis, true> E;
      +  RegisterAnalysisGroup<AliasAnalysis, true> E(D);
       }
       
      @@ -1482,7 +1549,7 @@ allocator machine pass.

      .cpp file add the following include;

      -  #include ""llvm/CodeGen/RegAllocRegistry.h""
      +  #include "llvm/CodeGen/RegAllocRegistry.h"
       

      Also in your register allocator .cpp file, define a creator function in the @@ -1520,8 +1587,8 @@ $ llc --help

      And that's it. The user is now free to use -regalloc=myregalloc as an option. Registering instruction schedulers is similar except use the -RegisterRegAlloc class. Note that the -RegisterRegAlloc::FunctionPassCtor is significantly different from +RegisterScheduler class. Note that the +RegisterScheduler::FunctionPassCtor is significantly different from RegisterRegAlloc::FunctionPassCtor.

      To force the load/linking of your register allocator into the llc/lli tools, @@ -1614,7 +1681,7 @@ object. The most foolproof way of doing this is to set a breakpoint in want:

      -(gdb) break PassManager::run
      +(gdb) break llvm::PassManager::run
       Breakpoint 1 at 0x2413bc: file Pass.cpp, line 70.
       (gdb) run test.bc -load $(LLVMTOP)/llvm/Debug/lib/[libname].so -[passoption]
       Starting program: opt test.bc -load $(LLVMTOP)/llvm/Debug/lib/[libname].so -[passoption]