[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