インターネットと Stackoverflow に関するいくつかの調査中、実行時に IR コードを実行する方法に関する唯一の例は、SOでのこの例でした。Visual Studio 2012 で llvm と clang をコンパイルしましclang File.cpp -S -emit-llvm -O3
た。出力が次のような通常の IR コードになるように、 「スクリプト」拡張機能に使用するいくつかのソース ファイルをコンパイルできました。
; ModuleID = '.\Test.cpp'
target datalayout = "/* ... */"
target triple = "i686-pc-win32"
define i32 @test() #0 {
ret i32 43
}
attributes #0 = { nounwind /* ... */ }
私が参照した投稿は非常に古いものであり、次の 2 つのことを知りたいと思います。
- エンジンを初期化し、llvm 3.2 で実行時に (C++ を使用して) そのようなコードを実行するにはどうすればよいですか? 同じ呼び出しが使用されていますか?
- コンパイル中に大量のライブラリが作成されました。リンクする必要があるものをどのように知ることができますか?
動作し、最適化が必要な可能性がある私のコード
#include <iostream>
#include <llvm/IR/LLVMContext.h>
#include <llvm/ADT/Triple.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/CodeGen/LinkAllCodegenComponents.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/Interpreter.h>
#include <llvm/ExecutionEngine/JIT.h>
#include <llvm/ExecutionEngine/JITEventListener.h>
#include <llvm/ExecutionEngine/JITMemoryManager.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/IR/Module.h>
#include <llvm/IR/Type.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/Debug.h>
#include <llvm/Support/DynamicLibrary.h>
#include <llvm/Support/Format.h>
#include <llvm/Support/IRReader.h>
#include <llvm/Support/ManagedStatic.h>
#include <llvm/Support/MathExtras.h>
#include <llvm/Support/Memory.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/PluginLoader.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Process.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>
#pragma comment(lib, "LLVMMCJIT.lib")
#pragma comment(lib, "LLVMInterpreter.lib")
#pragma comment(lib, "LLVMBitReader.lib")
#pragma comment(lib, "LLVMAsmParser.lib")
#pragma comment(lib, "LLVMX86CodeGen.lib")
#pragma comment(lib, "LLVMX86AsmParser.lib")
#pragma comment(lib, "LLVMX86Disassembler.lib")
#pragma comment(lib, "LLVMJIT.lib")
#pragma comment(lib, "LLVMAsmPrinter.lib")
#pragma comment(lib, "LLVMSelectionDAG.lib")
#pragma comment(lib, "LLVMX86Desc.lib")
#pragma comment(lib, "LLVMExecutionEngine.lib")
#pragma comment(lib, "LLVMRuntimeDyld.lib")
#pragma comment(lib, "LLVMMCParser.lib")
#pragma comment(lib, "LLVMCodeGen.lib")
#pragma comment(lib, "LLVMX86AsmPrinter.lib")
#pragma comment(lib, "LLVMX86Info.lib")
#pragma comment(lib, "LLVMObjCARCOpts.lib")
#pragma comment(lib, "LLVMScalarOpts.lib")
#pragma comment(lib, "LLVMX86Utils.lib")
#pragma comment(lib, "LLVMInstCombine.lib")
#pragma comment(lib, "LLVMTransformUtils.lib")
#pragma comment(lib, "LLVMipa.lib")
#pragma comment(lib, "LLVMAnalysis.lib")
#pragma comment(lib, "LLVMTarget.lib")
#pragma comment(lib, "LLVMCore.lib")
#pragma comment(lib, "LLVMMC.lib")
#pragma comment(lib, "LLVMObject.lib")
#pragma comment(lib, "LLVMSupport.lib")
using namespace llvm;
int main(int argc, char **argv) {
InitializeNativeTarget();
LLVMContext &context = getGlobalContext();
ExecutionEngine *ee;
SMDiagnostic diag;
Module *m = ParseIRFile("Script.s", diag, context);
if(!m) {
diag.print("LLVMSandbox", errs());
return 1;
}
m->MaterializeAllPermanently();
ee = EngineBuilder(m).create();
Function *func = ee->FindFunctionNamed("main");
typedef int (*PFN)();
PFN pfn = reinterpret_cast<PFN>(ee->getPointerToFunction(func));
int i = pfn();
std::cout << i;
std::cin.get();
delete ee;
return 0;
}