Search code examples
llvmllvm-c++-api

LLVM: Access Global Variable from Function Pass


In learning the LLVM framework, I am trying to implement an 'optimization' pass that prints the name of each method at runtime when the method is called.

I read that global variables should only be created in a Module Pass, and I create the strings there (one per function), with

Constant* data = ConstantDataArray::getString(M.getContext(), F.getName());

GlobalVariable* gvar =
  new GlobalVariable(M, 
                     data->getType(), 
                     true,  
                     GlobalValue::ExternalLinkage, 
                     data, 
                     "fname_" + F.getName().str());

This works fine, insofar as the strings are laid out correctly in memory in the assembly file generated by the 'optimized' bitcode.

However, I have not found a way to insert calls to print these strings in the Function Pass. I want to use

Value* string = F.getValueSymbolTable().lookup("fname_" + F.getName().str());
CallInst* call = builder.CreateCall(emitPutS(string, builder, &TLI));

but string comes back as NULL. Is there a better way to look up global variables from a function?


Solution

  • Figured it out:

    Basic blocks have a getModule() method, and modules have a getGlobalVariable(StringRef Name) method.

    Alternatively, IRBuilder:CreateGlobalStringPtr(...) can be called from the function pass, and the Value* returned can be passed to emitPutS(...) directly. The module pass was not necessary.

    Note, CallInst* call = builder.CreateCall(emitPutS(string, builder, &TLI)); is incorrect. emitPutS(...) will create the call in the basic block already. The CreateCall is erroneous.