diff --git a/evmjit/libevmjit/Compiler.cpp b/evmjit/libevmjit/Compiler.cpp index de48e8ef9..a0b634bdb 100644 --- a/evmjit/libevmjit/Compiler.cpp +++ b/evmjit/libevmjit/Compiler.cpp @@ -6,13 +6,10 @@ #include #include "preprocessor/llvm_includes_start.h" -#include #include #include #include #include -#include -#include #include "preprocessor/llvm_includes_end.h" #include "Instruction.h" @@ -230,14 +227,6 @@ std::unique_ptr Compiler::compile(code_iterator _begin, code_itera dumpCFGifRequired("blocks-sync.dot"); - if (m_jumpTableBlock && m_options.rewriteSwitchToBranches) - { - llvm::FunctionPassManager fpManager(module.get()); - fpManager.add(llvm::createLowerSwitchPass()); - fpManager.doInitialization(); - fpManager.run(*m_mainFunc); - } - auto compilationEndTime = std::chrono::high_resolution_clock::now(); clog(JIT) << "JIT: " << std::chrono::duration_cast(compilationEndTime - compilationStartTime).count(); return module; diff --git a/evmjit/libevmjit/ExecStats.cpp b/evmjit/libevmjit/ExecStats.cpp index 684f6d39a..ff8c05307 100644 --- a/evmjit/libevmjit/ExecStats.cpp +++ b/evmjit/libevmjit/ExecStats.cpp @@ -67,6 +67,7 @@ char const* getExecStateName(ExecState _state) case ExecState::CacheLoad: return "CacheLoad"; case ExecState::CacheWrite: return "CacheWrite"; case ExecState::Compilation: return "Compilation"; + case ExecState::Optimization: return "Optimization"; case ExecState::CodeGen: return "CodeGen"; case ExecState::Execution: return "Execution"; case ExecState::Return: return "Return"; diff --git a/evmjit/libevmjit/ExecutionEngine.cpp b/evmjit/libevmjit/ExecutionEngine.cpp index 1d2ff91b1..4402d133a 100644 --- a/evmjit/libevmjit/ExecutionEngine.cpp +++ b/evmjit/libevmjit/ExecutionEngine.cpp @@ -16,6 +16,7 @@ #include "Runtime.h" #include "Compiler.h" +#include "Optimizer.h" #include "Cache.h" #include "ExecStats.h" #include "Utils.h" @@ -70,6 +71,7 @@ bool showInfo() ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env) { + static auto optimizationEnabled = getEnvOption("EVMJIT_OPT", false); static auto debugDumpModule = getEnvOption("EVMJIT_DUMP", false); static auto objectCacheEnabled = getEnvOption("EVMJIT_CACHE", true); static auto statsCollectingEnabled = getEnvOption("EVMJIT_STATS", false); @@ -118,7 +120,13 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env) { listener->stateChanged(ExecState::Compilation); assert(_data->code || !_data->codeSize); //TODO: Is it good idea to execute empty code? - module = Compiler({}).compile(_data->code, _data->code + _data->codeSize, mainFuncName); + module = Compiler{{}}.compile(_data->code, _data->code + _data->codeSize, mainFuncName); + + if (optimizationEnabled) + { + listener->stateChanged(ExecState::Optimization); + optimize(*module); + } } if (debugDumpModule) module->dump(); diff --git a/evmjit/libevmjit/ExecutionEngine.h b/evmjit/libevmjit/ExecutionEngine.h index 4c2965e58..c0567828c 100644 --- a/evmjit/libevmjit/ExecutionEngine.h +++ b/evmjit/libevmjit/ExecutionEngine.h @@ -17,6 +17,7 @@ enum class ExecState CacheLoad, CacheWrite, Compilation, + Optimization, CodeGen, Execution, Return, diff --git a/evmjit/libevmjit/Optimizer.cpp b/evmjit/libevmjit/Optimizer.cpp new file mode 100644 index 000000000..2b8e41bd3 --- /dev/null +++ b/evmjit/libevmjit/Optimizer.cpp @@ -0,0 +1,24 @@ +#include "Optimizer.h" + +#include "preprocessor/llvm_includes_start.h" +#include +#include +#include "preprocessor/llvm_includes_end.h" + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +bool optimize(llvm::Module& _module) +{ + auto pm = llvm::PassManager{}; + pm.add(llvm::createLowerSwitchPass()); + return pm.run(_module); +} + +} +} +} diff --git a/evmjit/libevmjit/Optimizer.h b/evmjit/libevmjit/Optimizer.h new file mode 100644 index 000000000..4a3147a7f --- /dev/null +++ b/evmjit/libevmjit/Optimizer.h @@ -0,0 +1,19 @@ +#pragma once + +namespace llvm +{ + class Module; +} + +namespace dev +{ +namespace eth +{ +namespace jit +{ + +bool optimize(llvm::Module& _module); + +} +} +}