HowTo: Insert a function call

From LLVM

Jump to: navigation, search

The following code implements an optimization pass that can be invoked via "opt" with the flag "-insertcall". This pass inserts the function "void functionName(int)" into the symbol table of the program and inserts a call to this function before the terminator instruction of the last bask block of every function of the program.

#include "llvm/Pass.h"
#include "llvm/Function.h"
#include "llvm/Module.h"
#include "llvm/CallingConv.h"
#include "llvm/DerivedTypes.h"
#include "llvm/InstrTypes.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
 
using namespace llvm;
 
////////////////////////////////////////////////////////////////////////////////////////////////////
namespace {
  struct InsertCall : public FunctionPass {
    Constant *fcall;
    public:
    static char ID; // Pass identification, replacement for typeid
    InsertCall() : FunctionPass(&ID) {}
 
    //////////////////////////////////////////////////////////////////////
    virtual bool doInitialization(Module &mdl) {
 
        fcall = mdl.getOrInsertFunction("functionName",
                  /* return type */     Type::VoidTy,
                  /* actual 1 type */   IntegerType::get(32),
                                        NULL);
        if( !fcall ){
            cerr << "### Error: fcall is NULL\n" << std::endl;
        }
 
        // Set the calling convention to C, so we interoperate properly with C code.
        Function *tmp = cast<Function>(fcall);
        tmp->setCallingConv(CallingConv::C);
 
        return true;
    }
 
 
    //////////////////////////////////////////////////////////////////////
    virtual bool runOnFunction(Function &func) {
        Value *param;
 
        // Find the instruction before which you want to insert the function call
        Instruction *nextInstr = func.back().getTerminator();
 
        // Create the actual parameter for the function call
        param = ConstantInt::get(Type::Int32Ty, 555);
 
        // create and insert the function call
        CallInst::Create(fcall, param, "", nextInstr);
 
        // indicates that we changed the code
        return true;
    }
 
    // optimization passes should implement the following function to be efficient.
    // virtual void getAnalysisUsage(AnalysisUsage &AU) const {
    // }
 
  };
}
 
char InsertCall::ID = 0;
static RegisterPass<InsertCall> IC("insertcall", "This pass inserts a function call");
Personal tools