Cross-module function calls (code included)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Cross-module function calls (code included)

Aaron Aaron
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);
}
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev