[llvm-dev] Add a mapping to a C++ lambda
Courtney Robinson via llvm-dev
llvm-dev at lists.llvm.org
Tue Oct 27 01:21:11 PDT 2015
Apologies for the noop question in advance (just getting started with
LLVM), and I'm not entirely sure if this is the right list to post to. is
it?
I have some lambda functions as member variables that I want to have my
LLVM language make calls to. I've added a mapping to them, but this doesn't
seem to enable LLVM to resolve the functions. I asked on stackoverflow but
the suggestion there didn't help. The minimal test case to reproduce what
I'm trying to do is:
#include "llvm/ExecutionEngine/GenericValue.h"#include
"llvm/ExecutionEngine/Interpreter.h"#include
"llvm/IR/Constants.h"#include "llvm/IR/IRBuilder.h"#include
"llvm/Support/ManagedStatic.h"#include "llvm/Support/TargetSelect.h"
using namespace llvm;
int main() {
InitializeNativeTarget();
LLVMContext Context;
std::unique_ptr<Module> Owner = make_unique<Module>("SomeModule", Context);
Module *M = Owner.get();
FunctionType *lambdaFT = FunctionType::get(Type::getInt32Ty(Context), false);
Function *lambdaFN = Function::Create(lambdaFT,
Function::ExternalLinkage, "lambda", Owner.get());
auto lambdaBody = []() { return 100; };
Function *mainF = cast<Function>(M->getOrInsertFunction("main",
Type::getInt32Ty(Context), (Type *) 0));
BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", mainF);
IRBuilder<> builder(BB);
CallInst *lambdaRes = builder.CreateCall(lambdaFN, std::vector<Value
*>(), "lambdaRetVar");
builder.CreateRet(lambdaRes);
ExecutionEngine *EE = EngineBuilder(std::move(Owner)).create();
EE->addGlobalMapping(lambdaFN, &lambdaBody);
outs() << "We just constructed this LLVM module:\n\n" << *M;
outs() << "\n\nRunning main: ";
std::vector<GenericValue> noargs;
GenericValue gv = EE->runFunction(mainF, noargs);
outs() << "Result: " << gv.IntVal << "\n";
llvm_shutdown();
delete EE;
return 0;}
The output is:
We just constructed this LLVM module:
; ModuleID = 'SomeModule'
declare i32 @lambda()
define i32 @main() {EntryBlock:
%lambdaRetVar = call i32 @lambda()
ret i32 %lambdaRetVar}
Running main:
LLVM ERROR: Tried to execute an unknown external function: lambda
The following suggestion was made on StackOveflow:
"
Your lambda body is a class. You must pass the address of its function call
operator, which you can do by converting it to a function pointer: auto
lambdaBody = +[]() { return 100; }; and passing it as a void*:
EE->addGlobalMapping(lambdaFN,
reinterpret_cast<void*>(lambdaBody));.
"
However, after doing that, I get the same LLVM error message. How do I get
LLVM to call to a lambda? I am likely to have some C functions loaded from
a dynamic lib (I'll know the name and signatures), is it the same process
to call these as it is for lambdas?
I know the Kaleidoscope example does std::sin so when it says it finds it
because it is within the same address space I thought this would work too...
No suggestions or code samples welcome.
Thanks in advance.
--
Courtney Robinson
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151027/6678eba6/attachment.html>
More information about the llvm-dev
mailing list