The code I am analyzing is :
int main()
{
int i = 0;
printf("hello world!");
printf( "%d" , i );
}
I want to get each place where printf is called, and the argument used
during that call.
so I write llvm pass code like:
void Myfunction( Function & F){
for( Function::iterator b = F.begin() , be = F.end() ;
b != be; ++b){
for(BasicBlock::iterator i = b.begin() , ie = b.end();
i != ie; i ++){
if( isa<CallInst>(&(*i)) || isa<InvokeInst>(&(*i))){
//how could I get the function name and argument
//used here
}
}
}
}
How could I get the function name and the arguments when I know an
Instruction is a function call?
thanks a lot!
Best wishes!
Linhai Song
_______________________________________________
LLVM Developers mailing list
LLV...@cs.uiuc.edu http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
There's a worked example at
http://wiki.llvm.org/HowTo:_Find_all_call_sites_of_a_function .
With the CallInst/InvokeInst you can query getArgOperand() to get the
arguments or getCallee() which return a Function -- or it might not. If
the call is an indirect call (ie., function pointer) then you don't know
what it's calling. Ignoring indirect calls, you can call getName() on a
function to get its name.
Personally, I rely heavily on the doxygen to find my way around the API:
http://llvm.org/doxygen/hierarchy.html . Look up "CallInst" for example.
The getName() method isn't on Function, but all the way on the base
class Value.
Nick
I can get the call place now. But still have problems in getting the
argument.
CallInst * pCall;
......
pCall->getArgOperand(0)->dump();
I can get "i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0)"
I think this means that the variable is a global constant string. Do you
know how to get the name of this global string, and how to use the name to
get the string value?
Btw: when I use pCall->getArgOperand(0)->getName(), I can only get "".
thanks a lot!
Linhai
I finally fix my problem.
My code is like this:
//CallInst* pCall pCall is a printf called in my situation
if( ConstantExpr * pCE = dyn_cast<ConstantExpr>( pCall->getArgOperand(0))){
if( GlobalVariable * pGV = dyn_cast<GlobalVariable>( pCE->getOperand(0))){
if( ConstantArray * pCA = dyn_cast<ConstantArray>(
pGV->getInitializer()
)){
Err << pCA->getAsString() << "\n";
}
}
}
I find dump() method is very useful, since it can get me some indications
about which class document I need to check.
thanks a lot!
Linhai
> On 1/17/2011 8:53 PM, son...@cs.wisc.edu wrote:
>> Thanks a lot!
>>
>> I can get the call place now. But still have problems in getting the
>> argument.
>>
>> CallInst * pCall;
>>
>> ......
>>
>> pCall->getArgOperand(0)->dump();
>>
>> I can get "i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0)"
>
> In this particular case, the argument to the call is an LLVM GEP
> Constant Expression. It's like a GEP instruction except that all of the
> GEP arguments are constant, so the result of the GEP is also a
> constant. In general, the argument to printf can an LLVM Value *, and
> there are lots of sub-classes derived from Value. For example, it could
> be a GEP ConstantExpr, a Cast ConstExpr, an Instruction, etc., etc.
>
> Look at the doxygen docs for the ConstantExpr class. You can use that
> information to figure out how to write code that peers into the
> ConstExpr to see what global value it is indexing off of.
>
> -- John T.
>
> P.S. I grew up in Wisconsin and like Badger Hockey at UW-Madison. Go
> Bucky!
I'm glad it works. On a related note, I noticed that your original code
iterates through all instructions within an LLVM Module looking for call
instructions and then only processes those that call printf().
It would probably be more efficient to get a Function * to the printf
function (Module::getFunction ()) and then iterate through its uses,
checking each use to see if it is a direct call to printf(). That way,
the run-time complexity is a linear function of the number of printf
calls and not a linear function of the size of the program.
-- John T.
It seems that I can't force some passes to run in llvm-ld as what I can do with opt.
$ ~/opt/bin/llvm-ld -reassociate
llvm-ld: Unknown command line argument '-reassociate. Try: 'opt/bin/llvm-ld -help'
llvm-ld definitely linked with scalaropts, and RegisterPass<ReassociatePass> is in the library.
Running with these passes with opt definitely work, but it'll take some time as my .bc is big (~40M).
I'll appreciate any ideas how to make llvm-ld run these passes.
Thanks.
Cheers,
Haohui
> It seems that I can't force some passes to run in llvm-ld as what I can do with opt.
>
> $ ~/opt/bin/llvm-ld -reassociate
> llvm-ld: Unknown command line argument '-reassociate. Try: 'opt/bin/llvm-ld -help'
>
> llvm-ld definitely linked with scalaropts, and RegisterPass<ReassociatePass> is in the library.
>
> Running with these passes with opt definitely work, but it'll take some time as my .bc is big (~40M).
>
> I'll appreciate any ideas how to make llvm-ld run these passes.
you can always have llvm-ld output a bitcode file which you then optimize
using opt. Alternatively you can modify createStandardLTOPasses in
StandardPasses.h, since these are the passes llvm-ld uses.
Ciao, Duncan.