2

インターネットと 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 つのことを知りたいと思います。

  1. エンジンを初期化し、llvm 3.2 で実行時に (C++ を使用して) そのようなコードを実行するにはどうすればよいですか? 同じ呼び出しが使用されていますか?
  2. コンパイル中に大量のライブラリが作成されました。リンクする必要があるものをどのように知ることができますか?

動作し、最適化が必要な可能性がある私のコード

#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;
}
4

1 に答える 1

4

LLVM は猛烈なペースで進化しており、ついていくのは困難です。したがって、LLVM が前進し続ける一方で動作し続けるコードを見つける最善の方法は、LLVM でビルドおよびテストされたコードを調べることです。

この場合、lliツール (tools/lliコード内) が必要です。これは、インタープリターまたは JIT エンジンのいずれかを使用する、LLVM IR の一般的な「エグゼキューター」です。Windows でも動作するはずです。必要なすべての LLVM 機構 (C++ コードに関して) をインスタンス化するための例としても、新しいスタンドアロン ツールを構築するための例としても使用できます (makefile または を模倣できますCMakeLists.txt) 。

于 2013-02-26T14:44:56.423 に答える