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