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 @@
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 namespaceLastly, 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"); }
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
The doIninitialize method is allowed to do most of the things that
@@ -574,14 +582,14 @@ otherwise. 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.
+
+ 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. 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. 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: 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: 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. 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: 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:
- virtual bool doInitialization(Module &M);
+ virtual bool doInitialization(CallGraph &CG);
- virtual bool doFinalization(Module &M);
+ virtual bool doFinalization(CallGraph &CG);
+ virtual bool doInitialization(Loop *, LPPassManager &LPM);
+
+ virtual bool runOnLoop(Loop *, LPPassManager &LPM) = 0;
+
+ virtual bool doFinalization();
+
-
-
-
- virtual void print(std::ostream &O, const Module *M) const;
+ virtual void print(llvm::OStream &O, const Module *M) const;
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);
}
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);
}
- #include ""llvm/CodeGen/RegAllocRegistry.h""
+ #include "llvm/CodeGen/RegAllocRegistry.h"
-(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]