How to get the name and argument of a function

Hi everyone:

   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

songlh@cs.wisc.edu wrote:

Hi everyone:

    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?

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

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)"

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

Thanks a lot!

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

Thanks a lot!

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.

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.

Hi All,

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

Hi 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.