From 5e01d3228631ac0e15b05558b7e69d995dedd3a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 17 Feb 2015 18:58:18 +0100 Subject: [PATCH] Use llvm/CommandLine library for JIT options --- libevmjit/ExecutionEngine.cpp | 53 +++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 4402d133a..8cc311ba6 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -1,7 +1,7 @@ #include "ExecutionEngine.h" #include -#include // env options +#include #include #include "preprocessor/llvm_includes_start.h" @@ -12,6 +12,7 @@ #include #include #include +#include #include "preprocessor/llvm_includes_end.h" #include "Runtime.h" @@ -49,39 +50,43 @@ std::string codeHash(i256 const& _hash) return str; } -bool getEnvOption(char const* _name, bool _default) +void printVersion() { - auto var = std::getenv(_name); - if (!var) - return _default; - return std::strtol(var, nullptr, 10) != 0; + std::cout << "Ethereum EVM JIT Compiler (http://github.com/ethereum/evmjit):\n" + << " EVMJIT version " << EVMJIT_VERSION << "\n" +#ifdef NDEBUG + << " Optimized build, " EVMJIT_VERSION_FULL "\n" +#else + << " DEBUG build, " EVMJIT_VERSION_FULL "\n" +#endif + << " Built " << __DATE__ << " (" << __TIME__ << ")\n" + << std::endl; } -bool showInfo() +namespace cl = llvm::cl; +cl::opt g_optimize{"O", cl::desc{"Optimize"}}; +cl::opt g_cache{"cache", cl::desc{"Cache compiled EVM code on disk"}, cl::init(true)}; +cl::opt g_stats{"st", cl::desc{"Statistics"}}; +cl::opt g_dump{"dump", cl::desc{"Dump LLVM IR module"}}; + +void parseOptions() { - auto show = getEnvOption("EVMJIT_INFO", false); - if (show) - { - std::cout << "The Ethereum EVM JIT " EVMJIT_VERSION_FULL " LLVM " LLVM_VERSION << std::endl; - } - return show; + cl::AddExtraVersionPrinter(printVersion); + cl::ParseEnvironmentOptions("evmjit", "EVMJIT", "Ethereum EVM JIT Compiler"); } } + 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); - static auto infoShown = showInfo(); - (void) infoShown; + static std::once_flag flag; + std::call_once(flag, parseOptions); std::unique_ptr listener{new ExecStats}; listener->stateChanged(ExecState::Started); - auto objectCache = objectCacheEnabled ? Cache::getObjectCache(listener.get()) : nullptr; + auto objectCache = g_cache ? Cache::getObjectCache(listener.get()) : nullptr; static std::unique_ptr ee; if (!ee) @@ -93,7 +98,7 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env) llvm::EngineBuilder builder(module.get()); builder.setEngineKind(llvm::EngineKind::JIT); builder.setUseMCJIT(true); - builder.setOptLevel(llvm::CodeGenOpt::None); + builder.setOptLevel(g_optimize ? llvm::CodeGenOpt::Default : llvm::CodeGenOpt::None); auto triple = llvm::Triple(llvm::sys::getProcessTriple()); if (triple.getOS() == llvm::Triple::OSType::Win32) @@ -122,13 +127,13 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env) assert(_data->code || !_data->codeSize); //TODO: Is it good idea to execute empty code? module = Compiler{{}}.compile(_data->code, _data->code + _data->codeSize, mainFuncName); - if (optimizationEnabled) + if (g_optimize) { listener->stateChanged(ExecState::Optimization); optimize(*module); } } - if (debugDumpModule) + if (g_dump) module->dump(); ee->addModule(module.get()); @@ -150,7 +155,7 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env) } listener->stateChanged(ExecState::Finished); - if (statsCollectingEnabled) + if (g_stats) statsCollector.stats.push_back(std::move(listener)); return returnCode;