Evan Driscoll
2013-Jun-24 23:45 UTC
[LLVMdev] Questions on writing a pass that adds instrumentation code
I'm an LLVM newbie, trying to write a pass that adds instrumentation to a program, and have a couple of questions. For purposes of this discussion, suppose I'm trying to add a per-function counter that is incremented each time a function is called. At the end of the target program's execution, I would like to output the value of each counter. My questions are as follows: 1. What's the best way to insert instrumentation code at the "beginning" of a function? I can add code before the function prologue easily enough (i.e. insert before func.getEntryBlock().begin()), but is this always correct, or could this overwrite stuff? (I never need to access local variables, of course.) If not, how can I detect the end of the prologue and put things at the "actual" start of the function? (Even though my goal, as phrased above, would work if I put the load/add/store instrumentation just before the terminator of the first basic block, that doesn't serve my broader goal.) 2. I currently create the global variables holding the counter by calling "module.getOrInsertGlobal(...)". Will this ensure that the global starts with the value 0, or do I have to do this via other means? (E.g. make an explicit GlobalVariable object instead of using that convenience function) 3. How can I add code that is called when the program exits? 4. Suppose I want to call a function 'foo()' instead of incrementing a counter, where 'foo()' is some instrumentation code that I would like to insert rather than something in the target program. *Ideally*, what I'd like to be able to do is write foo() in C or C++, compile it to LLVM bytecode, and then somehow pull that into programs that run my pass. Is there an easy way to do this (i.e. not using an IRBuilder to recreate the bytecode or something silly like that), or should I just say "if you want to use my thing, then compile foo.c into your program so the definition of foo() is available". Evan
Eric Lu
2013-Jun-26 07:08 UTC
[LLVMdev] Questions on writing a pass that adds instrumentation code
On Tue, Jun 25, 2013 at 7:45 AM, Evan Driscoll <driscoll at cs.wisc.edu> wrote:> I'm an LLVM newbie, trying to write a pass that adds instrumentation to > a program, and have a couple of questions. > > For purposes of this discussion, suppose I'm trying to add a > per-function counter that is incremented each time a function is called. > At the end of the target program's execution, I would like to output the > value of each counter. > > My questions are as follows: > > > 1. What's the best way to insert instrumentation code at the "beginning" > of a function? I can add code before the function prologue easily enough > (i.e. insert before func.getEntryBlock().begin()), but is this always > correct, or could this overwrite stuff? (I never need to access local > variables, of course.) If not, how can I detect the end of the prologue > and put things at the "actual" start of the function? > > (Even though my goal, as phrased above, would work if I put the > load/add/store instrumentation just before the terminator of the first > basic block, that doesn't serve my broader goal.) > >> > 2. I currently create the global variables holding the counter by > calling "module.getOrInsertGlobal(...)". Will this ensure that the > global starts with the value 0, or do I have to do this via other means? > (E.g. make an explicit GlobalVariable object instead of using that > convenience function) > >I think it is better to explicit create the global variable. Because if the Global Var will be accessed in different files, you should insert the external declare in some of these files.> > 3. How can I add code that is called when the program exits? > >You can employ the InstVisitor class, to define the method visitReturnInst() method. And you can do any instrument in this Method.> > 4. Suppose I want to call a function 'foo()' instead of incrementing a > counter, where 'foo()' is some instrumentation code that I would like to > insert rather than something in the target program. *Ideally*, what I'd > like to be able to do is write foo() in C or C++, compile it to LLVM > bytecode, and then somehow pull that into programs that run my pass. Is > there an easy way to do this (i.e. not using an IRBuilder to recreate > the bytecode or something silly like that), or should I just say "if you > want to use my thing, then compile foo.c into your program so the > definition of foo() is available". >You can define foo() in the runtime library, and insert the function call of foo() in the source code. So, the users can compile their code with linking to you runtime library, then can call the foo(). Hopes help you. Eric> > Evan > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >>-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130626/f0e93f3d/attachment.html>
Jonas Wagner
2013-Jun-26 07:47 UTC
[LLVMdev] Questions on writing a pass that adds instrumentation code
Hi, I suggest you have a look at lib/Transforms/Instrumentation/EdgeProfiling.cpp. This pass inserts counters for every edge in the program. you can probably copy many things from there. 2. I currently create the global variables holding the counter by> calling "module.getOrInsertGlobal(...)". Will this ensure that the > global starts with the value 0, or do I have to do this via other means? >See EdgeProfiler::runOnModule. There, a global is created by calling new GlobalVariable. It is automatically zero-initialized by virtue of being a global variable. The EdgeProfiler pass also inserts a call to llvm_start_edge_profiling at the beginning of the main function. This function calls atexit to register the handler that will process the counters when the application exits.> > 3. How can I add code that is called when the program exits? >See llvm_start_edge_profiling in runtime/libprofile/EdgeProfiling.c 4. Suppose I want to call a function 'foo()' instead of incrementing a> counter, where 'foo()' is some instrumentation code that I would like to > insert rather than something in the target program. *Ideally*, what I'd > like to be able to do is write foo() in C or C++, compile it to LLVM > bytecode, and then somehow pull that into programs that run my pass. Is > there an easy way to do this (i.e. not using an IRBuilder to recreate > the bytecode or something silly like that), or should I just say "if you > want to use my thing, then compile foo.c into your program so the > definition of foo() is available". >You could define your function foo() in a special runtime, and ensure that it gets linked in during the linking step. Again, I'd have a look at how the EdgeProfiler does this. Cheers, Jonas -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130626/f3bcc408/attachment.html>
Apparently Analagous Threads
- [LLVMdev] Problems with instrumentation
- [LLVMdev] Dynamic Profiling - Instrumentation basic query
- [LLVMdev] Dynamic Profiling - Instrumentation basic query
- [LLVMdev] How to codegen an LLVM-IR that has dynamic arrays in it?
- [LLVMdev] Dynamic Profiling - Instrumentation basic query