2

C++ メソッド呼び出しをラップする一連のラムダがあり、これらを LLVM で呼び出したいと考えています。タイプを宣言し、グローバル マッピングをラムダに追加した後でも、LLVM エラーが発生します。私が試したことを再現するための最小限のコードは次のとおりです。

#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());
  //this is what the original question had
  //auto lambdaBody = []() { return 100; };
  //this is an edit after Johannes Schaub's answer
  int32_t ( *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;
}

これにより、次の出力が得られます。

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

私は何を間違っていますか?LLVM を使用する3.7.0(タグが存在しない)

4

2 に答える 2

1

あなたのラムダ本体はクラスです。関数呼び出し演算子のアドレスを渡す必要があります。これは、関数ポインターに変換し、 :auto lambdaBody = +[]() { return 100; };として渡すことで実行できます。void*EE->addGlobalMapping(lambdaFN, reinterpret_cast<void*>(lambdaBody));

于 2015-10-25T11:04:40.580 に答える