[LLVMdev] Cross-module function calls (code included)
Aaron Aaron
llvmification at gmail.com
Wed Jan 16 14:17:20 PST 2008
Hello,
I'm not sure what I am trying to do is possible. I'm trying to create
two modules, and call a function in one module from another module.
First, a reassurance that I'm not trying to do something completely
off the wall would be nice as I don't see any tutorials that do this.
Second, any help getting this to work would be wonderful. Thanks,
Aaron
In my code, you'll see that I have two functions, both of which return
an int and take no parameters. I can call the "utility function" with
no problem--I get back the desired answer "42" and print it to the
screen. When I try to call that function however, the function cannot
be resolved. I'm trying to resolve it by calling it "Utility
Function" in both the prototype and the actual definition. I can't
use llvm::Function pointers in my real code because the "Utility
Module" will be generated after the "Main Module", so I can't have
pointers to the utility functions. Here's the code:
#include <llvm/Module.h>
#include <llvm/ModuleProvider.h>
#include <llvm/Function.h>
#include <llvm/PassManager.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Assembly/PrintModulePass.h>
#include <llvm/Support/LLVMBuilder.h>
using namespace llvm;
void SetupModules();
Module* mainModule;
Module* utilityModule;
Function *mainFunction;
Function *utilityFunctionPrototype;
Function *utilityFunction;
int main(int argc, char**argv)
{
ExecutionEngine *executionEngine;
SetupModules();
verifyModule(*mainModule, PrintMessageAction);
verifyModule(*utilityModule, PrintMessageAction);
PassManager PM;
PM.add(new PrintModulePass(&llvm::cout));
PM.run(*mainModule);
PM.run(*utilityModule);
executionEngine = ExecutionEngine::create(mainModule);
executionEngine->addModuleProvider(new ExistingModuleProvider(utilityModule));
int (*fp)();
fp = (int (*)()) executionEngine->getPointerToFunction(utilityFunction);
printf("%d\n", fp());
fp = (int (*)()) executionEngine->getPointerToFunction(mainFunction);
printf("%d\n", fp());
return 0;
}
void SetupModules()
{
BasicBlock* entry;
std::vector<const Type *> params;
llvm::FunctionType * utilityFunctionType;
utilityFunctionType = llvm::FunctionType::get(llvm::Type::Int32Ty,
params, false);
mainModule = new Module("Main Module");
utilityFunctionPrototype = new llvm::Function(utilityFunctionType,
llvm::Function::ExternalLinkage, "Utility Function", mainModule);
mainFunction = cast<Function>(mainModule->getOrInsertFunction("Main
Function", llvm::Type::Int32Ty, NULL));
entry = new BasicBlock("entry", mainFunction);
llvm::Value * resultOfCall = new
llvm::CallInst(utilityFunctionPrototype, "", entry);
new llvm::ReturnInst(resultOfCall, entry);
utilityModule = new Module("Utility Module");
utilityFunction = new llvm::Function(utilityFunctionType,
llvm::Function::ExternalLinkage, "Utility Function", utilityModule);
entry = new BasicBlock("entry", utilityFunction);
new llvm::ReturnInst(llvm::ConstantInt::get(llvm::APInt(32, 42)), entry);
}
More information about the llvm-dev
mailing list