... here is some generally useful information I should have cc'd to llvmdev in the first place ... -Chris -- http://nondot.org/sabre/ http://llvm.cs.uiuc.edu/ ---------- Forwarded message ---------- Date: Sun, 10 Jul 2005 21:41:55 -0500 (CDT) From: Chris Lattner <sabre at nondot.org> To: Sean Peisert <peisert at gmail.com> Subject: Re: [LLVMdev] Getting started with LLVM Passes On Fri, 8 Jul 2005, Sean Peisert wrote:> Hi Chris, > >>> I'm now off on to addressing my own code transformations. The ones >>> that I may begin with are the '=' operator, as well as sbrk and mmap >>> syscalls. It isn't completely obvious to me which pass class to use >>> for these. Would you recommend the FunctionPass classes for both of >>> these? >> >> I don't understand what you would like your transform to do, can you >> explain it a bit more? > > Absolutely. I'd eventually like to implement a large number of > transforms. For starters, I'd like to implement a transform such that > the compiler inserts code into any binary (including libraries) which > forces the binary to keep track of the time, size, and location of any > write to memory by way of an operation which ultimately results in an > assignment in the IR or AST, as well as the size and location of all > memory allocations by way of the sbrk and mmap syscalls.Ok, this shouldn't be hard. Take a look at the existing LLVM instrumentation passes in lib/Transforms/Instrumentation. These add various bits of instrumentation (duh) code to track things like the # of times a BB executes. It would be simple to track other things.> You suggested in the past that instrumenting the LLVM store might be > the proper way to do this, but I've not yet seen reference to > what/where that precisely might be. Could you possibly point me in > the right direction for this?Sure, check out the code in that dir for examples of generic instrumentation stuff.> How might one get at the LLVM stores,Look in the programmers manual for how to traverse the IR. Basically do this: for each instruction: if (isa<StoreInst>(I)) { ... add instrumentation ... }> or do transforms in the IR or syscall level?syscalls look just like normal calls, I'm not sure what you mean by the IR level. Another good example would be this simple pass: http://illuvium.com/cgi-bin/cvsweb.cgi/llvm-poolalloc/lib/PoolAllocate/AccessTrace.cpp?rev=1.3 It basically loops over all of the loads in the program, filters out ones it doesn't want, then adds a call immediately before the load to a library function. My guess is that this is exactly the sort of thing you want to do. -Chris -- http://nondot.org/sabre/ http://llvm.cs.uiuc.edu/
Chris, I've now figured out how to track and single out specific instructions, which was ridiculously easy. Thanks! I'm now on to trying to find more detail about those instructions, such as the values and addresses of the operands in memory (or, in the case of operands which are pointers, trying to get the pointer values, addresses, and values stored at location specified by the pointer values, etc..). Would you suggest having LLVM add code after each instruction to get this, or is there another way to do this? I've tried writing some code, as follows (where i is an inst_iterator, but the results are not what I would have expected: for (User::op_iterator j = i->op_begin(), f = i->op_end(); j != f; + +j) { std::cerr << "Operand: " << (j->getUser())->getOperand(0) << "\n"; } or for (User::op_iterator j = i->op_begin(), f = i->op_end(); j != f; + +j) { std::cerr << "Operand: " << j << "\n"; } Thanks, Sean
On Tue, 12 Jul 2005, Sean Peisert wrote:> Chris,Hi Sean, sorry for the delay, this got buried in my mail.> I've now figured out how to track and single out specific instructions, which > was ridiculously easy. Thanks!:)> I'm now on to trying to find more detail about those instructions, such as > the values and addresses of the operands in memory (or, in the case of > operands which are pointers, trying to get the pointer values, addresses, and > values stored at location specified by the pointer values, etc..). > > Would you suggest having LLVM add code after each instruction to get this, or > is there another way to do this? I've tried writing some code, as follows > (where i is an inst_iterator, but the results are not what I would have > expected: > > for (User::op_iterator j = i->op_begin(), f = i->op_end(); j != f; ++j) { > std::cerr << "Operand: " << (j->getUser())->getOperand(0) << "\n"; > } > or > for (User::op_iterator j = i->op_begin(), f = i->op_end(); j != f; ++j) { > std::cerr << "Operand: " << j << "\n"; > }This sort of thing isn't really what you want to do. Consider an instruction like this: %X = load int* %P This will iterate over the operands of the instructions (in this case, only %P), and print out the address of the IR node for that operand. From what I understand, you want a dynamic trace of the values as the program executes. In this case, I would suggest adding some instrumentation like this: %X = load int* %P ; original instruction call %mytracefn(int* %P) ; Do something to trace the value being loaded ... then run the program. -Chris -- http://nondot.org/sabre/ http://llvm.org/