Browse Source

Implementation of ExecutionEngine with LLVM MCJIT

cl-refactor
Paweł Bylica 10 years ago
parent
commit
9ddc25a664
  1. 13
      evmcc/Compiler.cpp
  2. 4
      evmcc/Compiler.h
  3. 67
      evmcc/ExecutionEngine.cpp
  4. 4
      evmcc/ExecutionEngine.h
  5. 6
      evmcc/evmcc.cpp
  6. 16
      windows/evmcc.vcxproj

13
evmcc/Compiler.cpp

@ -2,7 +2,6 @@
#include "Compiler.h"
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/Module.h>
namespace evmcc
{
@ -29,13 +28,13 @@ Compiler::Compiler()
}
void Compiler::compile(const dev::bytes& bytecode)
std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
{
using namespace llvm;
auto& context = getGlobalContext();
Module* module = new Module("main", context);
auto module = std::make_unique<Module>("main", context);
IRBuilder<> builder(context);
// Create globals for memory, memory size, stack and stack top
@ -55,11 +54,11 @@ void Compiler::compile(const dev::bytes& bytecode)
// Create value for void* malloc(size_t)
std::vector<Type*> mallocArgTypes = { Types.size };
Value* mallocVal = Function::Create(FunctionType::get(Types.word8ptr, mallocArgTypes, false),
GlobalValue::LinkageTypes::ExternalLinkage, "malloc", module);
GlobalValue::LinkageTypes::ExternalLinkage, "malloc", module.get());
// Create main function
FunctionType* funcType = FunctionType::get(llvm::Type::getInt32Ty(context), false);
Function* mainFunc = Function::Create(funcType, Function::ExternalLinkage, "main", module);
Function* mainFunc = Function::Create(funcType, Function::ExternalLinkage, "main", module.get());
BasicBlock* entryBlock = BasicBlock::Create(context, "entry", mainFunc);
builder.SetInsertPoint(entryBlock);
@ -77,9 +76,9 @@ void Compiler::compile(const dev::bytes& bytecode)
builder.CreateStore(mallocCast, stackVal);
*/
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0));
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 13));
module->dump();
return module;
}
}

4
evmcc/Compiler.h

@ -1,6 +1,8 @@
#pragma once
#include <llvm/IR/Module.h>
#include <libdevcore/Common.h>
namespace evmcc
@ -12,7 +14,7 @@ public:
Compiler();
void compile(const dev::bytes& bytecode);
std::unique_ptr<llvm::Module> compile(const dev::bytes& bytecode);
};

67
evmcc/ExecutionEngine.cpp

@ -1,6 +1,18 @@
#include "ExecutionEngine.h"
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
#include <llvm/ADT/Triple.h>
#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/ExecutionEngine/SectionMemoryManager.h>
#include <llvm/ExecutionEngine/GenericValue.h>
#include <llvm/ExecutionEngine/MCJIT.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/Signals.h>
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Host.h>
namespace evmcc
{
@ -10,9 +22,60 @@ ExecutionEngine::ExecutionEngine()
}
int ExecutionEngine::run(const dev::bytes& bytecode)
int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
{
return 0;
auto module = _module.get(); // Keep ownership of the module in _module
llvm::sys::PrintStackTraceOnErrorSignal();
static const auto program = "evmcc";
llvm::PrettyStackTraceProgram X(1, &program);
auto&& context = llvm::getGlobalContext();
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetAsmParser();
std::string errorMsg;
llvm::EngineBuilder builder(module);
//builder.setMArch(MArch);
//builder.setMCPU(MCPU);
//builder.setMAttrs(MAttrs);
//builder.setRelocationModel(RelocModel);
//builder.setCodeModel(CMModel);
builder.setErrorStr(&errorMsg);
builder.setEngineKind(llvm::EngineKind::JIT);
builder.setUseMCJIT(true);
builder.setMCJITMemoryManager(new llvm::SectionMemoryManager());
builder.setOptLevel(llvm::CodeGenOpt::None);
auto triple = llvm::Triple(llvm::sys::getProcessTriple());
if (triple.getOS() == llvm::Triple::OSType::Win32)
triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format
module->setTargetTriple(triple.str());
auto exec = std::unique_ptr<llvm::ExecutionEngine>(builder.create());
if (!exec)
{
if (!errorMsg.empty())
std::cerr << "error creating EE: " << errorMsg << std::endl;
else
std::cerr << "unknown error creating llvm::ExecutionEngine" << std::endl;
exit(1);
}
_module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
exec->finalizeObject();
auto entryFunc = module->getFunction("main");
if (!entryFunc)
{
std::cerr << "main function not found\n";
exit(1);
}
auto result = exec->runFunction(entryFunc, {});
auto intResult = result.IntVal.getZExtValue();
return intResult;
}
}

4
evmcc/ExecutionEngine.h

@ -1,6 +1,8 @@
#pragma once
#include <llvm/IR/Module.h>
#include <libdevcore/Common.h>
namespace evmcc
@ -11,7 +13,7 @@ class ExecutionEngine
public:
ExecutionEngine();
int run(const dev::bytes& bytecode);
int run(std::unique_ptr<llvm::Module> module);
};
}

6
evmcc/evmcc.cpp

@ -87,13 +87,15 @@ int main(int argc, char** argv)
if (opt_compile)
{
evmcc::Compiler().compile(bytecode);
evmcc::Compiler().compile(bytecode)->dump();
}
if (opt_interpret)
{
auto engine = evmcc::ExecutionEngine();
auto result = engine.run(bytecode);
auto module = evmcc::Compiler().compile(bytecode);
module->dump();
auto result = engine.run(std::move(module));
return result;
}

16
windows/evmcc.vcxproj

@ -85,17 +85,21 @@
<LinkIncremental>true</LinkIncremental>
<IntDir>..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\</IntDir>
<OutDir>..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<IntDir>..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\</IntDir>
<OutDir>..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<RunCodeAnalysis>false</RunCodeAnalysis>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -106,12 +110,13 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
<EnablePREfast>false</EnablePREfast>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>../../builds/llvm3.5/Debug/lib;../../_build/LibEthereum/x64_Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>LibEthereum.lib;LLVMCore.lib;LLVMSupport.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>LibEthereum.lib;LLVMX86Disassembler.lib;LLVMX86AsmParser.lib;LLVMX86CodeGen.lib;LLVMSelectionDAG.lib;LLVMAsmPrinter.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMipa.lib;LLVMAnalysis.lib;LLVMX86Desc.lib;LLVMX86Info.lib;LLVMX86AsmPrinter.lib;LLVMX86Utils.lib;LLVMMCJIT.lib;LLVMTarget.lib;LLVMRuntimeDyld.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMExecutionEngine.lib;LLVMMC.lib;LLVMCore.lib;LLVMSupport.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@ -124,12 +129,13 @@
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>../../llvm-3.5.0/include;../../builds/llvm3.5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4068;4244;4267;4800</DisableSpecificWarnings>
<EnablePREfast>false</EnablePREfast>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>../../builds/llvm3.5/Debug/lib;../../_build/LibEthereum/x64_Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>LibEthereum.lib;LLVMCore.lib;LLVMSupport.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>LibEthereum.lib;LLVMX86Disassembler.lib;LLVMX86AsmParser.lib;LLVMX86CodeGen.lib;LLVMSelectionDAG.lib;LLVMAsmPrinter.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMipa.lib;LLVMAnalysis.lib;LLVMX86Desc.lib;LLVMX86Info.lib;LLVMX86AsmPrinter.lib;LLVMX86Utils.lib;LLVMMCJIT.lib;LLVMTarget.lib;LLVMRuntimeDyld.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMExecutionEngine.lib;LLVMMC.lib;LLVMCore.lib;LLVMSupport.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@ -142,6 +148,7 @@
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<EnablePREfast>false</EnablePREfast>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -149,7 +156,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>../../builds/llvm3.5/Debug/lib;../../_build/LibEthereum/x64_Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>LibEthereum.lib;LLVMCore.lib;LLVMSupport.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>LibEthereum.lib;LLVMX86Disassembler.lib;LLVMX86AsmParser.lib;LLVMX86CodeGen.lib;LLVMSelectionDAG.lib;LLVMAsmPrinter.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMipa.lib;LLVMAnalysis.lib;LLVMX86Desc.lib;LLVMX86Info.lib;LLVMX86AsmPrinter.lib;LLVMX86Utils.lib;LLVMMCJIT.lib;LLVMTarget.lib;LLVMRuntimeDyld.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMExecutionEngine.lib;LLVMMC.lib;LLVMCore.lib;LLVMSupport.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@ -164,6 +171,7 @@
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>../../llvm-3.5.0/include;../../builds/llvm3.5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4068;4244;4267;4800</DisableSpecificWarnings>
<EnablePREfast>false</EnablePREfast>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -171,7 +179,7 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalLibraryDirectories>../../builds/llvm3.5/Debug/lib;../../_build/LibEthereum/x64_Debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>LibEthereum.lib;LLVMCore.lib;LLVMSupport.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>LibEthereum.lib;LLVMX86Disassembler.lib;LLVMX86AsmParser.lib;LLVMX86CodeGen.lib;LLVMSelectionDAG.lib;LLVMAsmPrinter.lib;LLVMCodeGen.lib;LLVMScalarOpts.lib;LLVMInstCombine.lib;LLVMTransformUtils.lib;LLVMipa.lib;LLVMAnalysis.lib;LLVMX86Desc.lib;LLVMX86Info.lib;LLVMX86AsmPrinter.lib;LLVMX86Utils.lib;LLVMMCJIT.lib;LLVMTarget.lib;LLVMRuntimeDyld.lib;LLVMObject.lib;LLVMMCParser.lib;LLVMBitReader.lib;LLVMExecutionEngine.lib;LLVMMC.lib;LLVMCore.lib;LLVMSupport.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

Loading…
Cancel
Save