[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