X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=docs%2FWritingAnLLVMPass.html;h=07e736da691e55ae8a2aa1325e72dc0c9e2205f1;hb=371ca83d8b7875d30743d9e72fd16a85baacbe63;hp=71dc4926ac31d128db64fe8415feb2424e8e0bae;hpb=5fa8fff8d21d98896957f3a891968c3ffc66c096;p=oota-llvm.git diff --git a/docs/WritingAnLLVMPass.html b/docs/WritingAnLLVMPass.html index 71dc4926ac3..07e736da691 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 @@ -96,14 +103,12 @@
    • Future extensions planned
    • -

      Written by Chris Lattner, - Jim Laskey

      +

      Written by Chris Lattner and + Jim Laskey

      @@ -127,6 +132,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 +184,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 +200,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.

      @@ -254,9 +262,17 @@ href="#passtype">later, but for now, know that FunctionPass's operate a function at a time.

      +
      +     static char ID;
      +     Hello() : FunctionPass((intptr_t)&ID) {}
      +

      + +

      This declares pass identifier used by LLVM to identify pass. This allows LLVM to +avoid using expensive C++ runtime information.

      +
           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 +285,26 @@ to do our thing, so we just print out our message with the name of each
       function.

      -  RegisterOpt<Hello> X("hello", "Hello World Pass");
      +  char Hello::ID = 0;
      +
      + +

      We initialize pass ID here. LLVM uses ID's address to identify pass so +initialization value is not important.

      + +
      +  RegisterPass<Hello> X("hello", "Hello World Pass",
      +                        false /* Only looks at CFG */,
      +                        false /* Analysis 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". +Last two RegisterPass arguments are optional. Their default value is false. +If a pass walks CFG without modifying it then third argument is set to true. +If a pass is an analysis pass, for example dominator tree pass, then true +is supplied as fourth argument.

      As a whole, the .cpp file looks like:

      @@ -289,13 +316,18 @@ depending on what it is to be used for. For "optimizations" we use the namespace { struct Hello : public FunctionPass { + + static char ID; + Hello() : FunctionPass((intptr_t)&ID) {} + 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"); + char Hello::ID = 0; + RegisterPass<Hello> X("hello", "Hello World Pass"); }
      @@ -310,20 +342,20 @@ 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 Getting Started Guide to compile "Hello World" to -LLVM. We can now run the bytecode file (hello.bc) for the program -through our transformation like this (or course, any bytecode file will +LLVM. We can now run the bitcode file (hello.bc) for the program +through our transformation like this (or course, any bitcode file will work):

      @@ -347,7 +379,7 @@ interesting way, we just throw away the result of opt (sending it to
       $ opt -load ../../../Debug/lib/Hello.so --help
       OVERVIEW: llvm .bc -> .bc modular optimizer
       
      -USAGE: opt [options] <input bytecode>
      +USAGE: opt [options] <input bitcode>
       
       OPTIONS:
         Optimizations available:
      @@ -382,7 +414,7 @@ Hello: main
         Total Execution Time: 0.02 seconds (0.0479059 wall clock)
       
          ---User Time---   --System Time--   --User+System--   ---Wall Time---  --- Pass Name ---
      -   0.0100 (100.0%)   0.0000 (  0.0%)   0.0100 ( 50.0%)   0.0402 ( 84.0%)  Bytecode Writer
      +   0.0100 (100.0%)   0.0000 (  0.0%)   0.0100 ( 50.0%)   0.0402 ( 84.0%)  Bitcode Writer
          0.0000 (  0.0%)   0.0100 (100.0%)   0.0100 ( 50.0%)   0.0031 (  6.4%)  Dominator Set Construction
          0.0000 (  0.0%)   0.0000 (  0.0%)   0.0000 (  0.0%)   0.0013 (  2.7%)  Module Verifier
          0.0000 (  0.0%)   0.0000 (  0.0%)   0.0000 (  0.0%)   0.0033 (  6.9%)  Hello World Pass
      @@ -458,7 +490,9 @@ class is the most general of all superclasses that you can use.  Deriving from
       ModulePass indicates that your pass uses the entire program as a unit,
       refering to function bodies in no predictable order, or adding and removing
       functions.  Because nothing is known about the behavior of ModulePass
      -subclasses, no optimization can be done for their execution.

      +subclasses, no optimization can be done for their execution. A module pass +can use function level passes (e.g. dominators) using getAnalysis interface + getAnalysis<DominatorTree>(Function).

      To write a correct ModulePass subclass, derive from ModulePass and overload the runOnModule method with the @@ -510,7 +544,7 @@ href="#BasicBlockPass">BasicBlockPass, you should derive from

    • ... not allowed to modify any Functions that are not in the current SCC.
    • -
    • ... allowed to inspect any Function's other than those in the +
    • ... not allowed to inspect any Function's other than those in the current SCC and the direct callees of the SCC.
    • ... required to preserve the current CallGraph object, updating it @@ -535,14 +569,14 @@ false if they didn't.

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

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

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

      The doFinalization method is an infrequently used method that is @@ -688,6 +722,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 +955,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 +977,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 @@ -909,7 +1002,7 @@ depended on.

      -

      One of the main responsibilities of the PassManager is the make sure +

      One of the main responsibilities of the PassManager is to make sure that passes interact with each other correctly. Because PassManager tries to optimize the execution of passes it must know how the passes interact with each other and what dependencies exist between @@ -1060,7 +1153,21 @@ runtime assertion failure if you attempt to get an analysis that you did not declare as required in your getAnalysisUsage implementation. This method can be called by your run* method implementation, or by any -other local method invoked by your run* method.

      +other local method invoked by your run* method. + +A module level pass can use function level analysis info using this interface. +For example:

      + +
      +   bool ModuleLevelPass::runOnModule(Module &M) {
      +     ...
      +     DominatorTree &DT = getAnalysis<DominatorTree>(Func);
      +     ...
      +   }
      +
      + +

      In above example, runOnFunction for DominatorTree is called by pass manager +before returning a reference to the desired pass.

      If your pass is capable of updating analyses if they exist (e.g., @@ -1086,7 +1193,7 @@ it is active. For example:

      -

      Now that we understand the basics of how passes are defined, how the are +

      Now that we understand the basics of how passes are defined, how they are used, and how they are required from other passes, it's time to get a little bit fancier. All of the pass relationships that we have seen so far are very simple: one pass depends on one other specific pass to be run before it can run. @@ -1179,11 +1286,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,19 +1304,20 @@ 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);
       }
       

      Here we show how the default implementation is specified (using the extra argument to the RegisterAnalysisGroup template). There must be exactly one default implementation available at all times for an Analysis Group to be -used. Here we declare that the BasicAliasAnalysis +used. Only default implementation can derive from ImmutablePass. +Here we declare that the + BasicAliasAnalysis pass is the default implementation for the interface.

      @@ -1274,7 +1382,8 @@ the LLVM program representation for a single function at a time, instead of traversing the entire program. It reduces the memory consumption of compiler, because, for example, only one DominatorSet -needs to be calculated at a time. This also makes it possible some interesting enhancements in the future.

    • @@ -1312,8 +1421,8 @@ Module Pass Manager Module Verifier -- Dominator Set Construction -- Module Verifier - Bytecode Writer ---Bytecode Writer + Bitcode Writer +--Bitcode Writer

      This output shows us when passes are constructed and when the analysis @@ -1353,8 +1462,8 @@ Module Pass Manager Module Verifier -- Dominator Set Construction -- Module Verifier - Bytecode Writer ---Bytecode Writer + Bitcode Writer +--Bitcode Writer Hello: __main Hello: puts Hello: main @@ -1393,8 +1502,8 @@ Module Pass Manager Module Verifier -- Dominator Set Construction -- Module Verifier - Bytecode Writer ---Bytecode Writer + Bitcode Writer +--Bitcode Writer Hello: __main Hello: puts Hello: main @@ -1482,7 +1591,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 +1629,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 +1723,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]
      @@ -1699,29 +1808,6 @@ Despite that, we have kept the LLVM passes SMP ready, and you should too.

      - - - -
      - -

      Currently it is illegal for a ModulePass -to require a FunctionPass. This is because -there is only one instance of the FunctionPass object ever created, thus nowhere -to store information for all of the functions in the program at the same time. -Although this has come up a couple of times before, this has always been worked -around by factoring one big complicated pass into a global and an -interprocedural part, both of which are distinct. In the future, it would be -nice to have this though.

      - -

      Note that it is no problem for a FunctionPass to require the results of a ModulePass, only the other way around.

      - -
      -