Question about insert function or instruction.

Hi llvmer,

I am trying to learn how to use llvm. My question is
described as the following,
there has already a testcase code, and I get bytecode
by using llvmgcc. What I want to do is to insert a
call funcation into each basic block, which is for
statistic some information.
1) I implement call function in another c/cpp file and
can I insert the external call function to existed
bytecode ? if it is valid. Can you give me a simple
example to show how to do it or just give me a url
which can show how to do it?

2) If I'd like to insert the function in the same
bytecode, how to do it?

3) for opt commamnd, there have -trace -tracem options
,how can I see the detailed direction to use it.

I went through a LowerInvoke.cpp and EdgeCode.cpp file
which have examples to do what I want. Although I can
learn the main flow how to insert a call funcation or
instruction, but I still cannot implement it. Shame.
Another thing is that I am not sure the method I used
is correct or not? Can you give me some suggestion?

Thanks in advance for any response.

--fengy--

The following code is what I do
#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/Instruction.h"
#include "llvm/iOther.h"

namespace llvm {

  struct cntPass : public FunctionPass{
    virtual bool runOnFunction(Function &F){
      std::cerr <<"funtion name : "<<
F.getName()<<"\n";
      for(Function::iterator BB = F.begin(),E=F.end();
BB != E;++BB){
  std::cerr<< "BB name : "<<BB->getName()<<"\n";
      // here, the problem is how can I get external
function pointer.
      //Instruction *callInst = new
CallInst(pCallfunction, "","");
      //BB->getInstList().push_back(callInst);
      //BB->getInstList().insert(callInst);
      }

      return false;
    }
    // can I insert print() function?
    void print(){
      printf("Insert test\n");
    }
  };
  RegisterOpt<cntPass> X("cntPass", "insert printf
function");
}

What I want to do is to insert a call funcation into each basic
block, which is for statistic some information.

I recommend that you look at the various pieces of code under
llvm/lib/Transforms/Instrumentation, e.g. BlockProfiling.cpp and
TraceBasicBlocks.cpp. They do essentially the same thing as you are
trying to do.

1) I implement call function in another c/cpp file and
can I insert the external call function to existed
bytecode ? if it is valid. Can you give me a simple
example to show how to do it or just give me a url
which can show how to do it?

Yes; in the case of BlockProfiling, it calls into the library defined
in llvm/runtime/libprofile, which is linked against the resulting LLVM
binary.

2) If I'd like to insert the function in the same
bytecode, how to do it?

In the above example, you would generate a bytecode version of
libprofile using the standard Makefile, then link it with the bytecode
version of your program using gccld or llvm-link.

3) for opt commamnd, there have -trace -tracem options
,how can I see the detailed direction to use it.

Short answer:

1. Compile the program in question to bytecode using llvmgcc.
Assume the result is

2. Run the bytecode of the program through opt -tracem, and then
generate C code for the result.
% opt -tracem bytecode.llvm.bc | llc -f -march=c -o bytecode.tracem.cbe.c

3. Compile the C code with tracing instrumentation using gcc.
% gcc -o bytecode.tracem.cbe bytecode.tracem.cbe.c
You may have to link it with the libtrace library provided in
llvm/runtime/libtrace, in addition to any other libraries that
the program needs.

      // here, the problem is how can I get external
function pointer.

Look at the 'getOrInsertFunction' method of class llvm::Module.

      //Instruction *callInst = new
CallInst(pCallfunction, "","");
      //BB->getInstList().push_back(callInst);

This is basically OK.

      //BB->getInstList().insert(callInst);

This second insert is not necessary.

-Brian Gaeke

1. Compile the program in question to bytecode using llvmgcc.
Assume the result is

I meant to say "Assume the result is in the bytecode file named
bytecode.llvm.bc".

2. Run the bytecode of the program through opt -tracem, and then
generate C code for the result.
% opt -tracem bytecode.llvm.bc | llc -f -march=c -o bytecode.tracem.cbe.c

-Brian