Browse Source

Merge branch 'develop-evmcc' of github.com:imapp-pl/ethereum into develop-evmcc

cl-refactor
artur-zawlocki 10 years ago
parent
commit
49015515b2
  1. 8
      evmcc/Compiler.cpp
  2. 26
      evmcc/CompilerHelper.cpp
  3. 56
      evmcc/CompilerHelper.h
  4. 5
      evmcc/Ext.cpp
  5. 11
      evmcc/Ext.h
  6. 14
      evmcc/GasMeter.cpp
  7. 13
      evmcc/GasMeter.h
  8. 33
      evmcc/Memory.cpp
  9. 18
      evmcc/Memory.h
  10. 22
      evmcc/Utils.h
  11. 6
      windows/evmcc.vcxproj
  12. 2
      windows/evmcc.vcxproj.filters

8
evmcc/Compiler.cpp

@ -163,9 +163,9 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
createBasicBlocks(bytecode);
// Init runtime structures.
GasMeter gasMeter(m_builder, module.get());
Memory memory(m_builder, module.get(), gasMeter);
Ext ext(m_builder, module.get());
GasMeter gasMeter(m_builder);
Memory memory(m_builder, gasMeter);
Ext ext(m_builder);
m_builder.CreateBr(basicBlocks.begin()->second);
@ -714,7 +714,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, const bytes& bytecode,
auto srcIdx = stack.pop();
auto reqBytes = stack.pop();
auto srcPtr = ext.code();
auto srcPtr = ext.code(); // TODO: Code & its size are constants, feature #80814234
auto srcSize = ext.codesize();
memory.copyBytes(srcPtr, srcSize, srcIdx, destMemIdx, reqBytes);

26
evmcc/CompilerHelper.cpp

@ -0,0 +1,26 @@
#include "CompilerHelper.h"
#include <llvm/IR/Function.h>
namespace dev
{
namespace eth
{
namespace jit
{
CompilerHelper::CompilerHelper(llvm::IRBuilder<>& _builder) :
m_builder(_builder)
{}
llvm::Module* CompilerHelper::getModule()
{
assert(m_builder.GetInsertBlock());
assert(m_builder.GetInsertBlock()->getParent()); // BB must be in a function
return m_builder.GetInsertBlock()->getParent()->getParent();
}
}
}
}

56
evmcc/CompilerHelper.h

@ -0,0 +1,56 @@
#pragma once
#include <llvm/IR/IRBuilder.h>
namespace dev
{
namespace eth
{
namespace jit
{
/// Base class for compiler helpers like Memory, GasMeter, etc.
class CompilerHelper
{
protected:
CompilerHelper(llvm::IRBuilder<>& _builder);
CompilerHelper(const CompilerHelper&) = delete;
void operator=(CompilerHelper) = delete;
/// Reference to the IR module being compiled
llvm::Module* getModule();
/// Reference to parent compiler IR builder
llvm::IRBuilder<>& m_builder;
};
/// Saves the insert point of the IR builder and restores it when destructed
struct InsertPointGuard
{
InsertPointGuard(llvm::IRBuilder<>& _builder) :
m_builder(_builder),
m_insertBB(m_builder.GetInsertBlock()),
m_insertPt(m_builder.GetInsertPoint())
{}
InsertPointGuard(const InsertPointGuard&) = delete;
void operator=(InsertPointGuard) = delete;
~InsertPointGuard()
{
m_builder.SetInsertPoint(m_insertBB, m_insertPt);
}
private:
llvm::IRBuilder<>& m_builder;
llvm::BasicBlock* m_insertBB;
llvm::BasicBlock::iterator m_insertPt;
};
}
}
}

5
evmcc/Ext.cpp

@ -43,10 +43,11 @@ struct ExtData
const byte* code;
};
Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module)
: m_builder(_builder)
Ext::Ext(llvm::IRBuilder<>& _builder):
CompilerHelper(_builder)
{
auto&& ctx = _builder.getContext();
auto module = getModule();
auto i256Ty = m_builder.getIntNTy(256);
auto i256PtrTy = i256Ty->getPointerTo();

11
evmcc/Ext.h

@ -1,10 +1,10 @@
#pragma once
#include <llvm/IR/IRBuilder.h>
#include <libevm/ExtVMFace.h>
#include "CompilerHelper.h"
namespace dev
{
namespace eth
@ -12,11 +12,10 @@ namespace eth
namespace jit
{
class Ext
class Ext : public CompilerHelper
{
public:
Ext(llvm::IRBuilder<>& _builder, llvm::Module* module);
static void init(std::unique_ptr<ExtVMFace> _ext);
Ext(llvm::IRBuilder<>& _builder);
llvm::Value* store(llvm::Value* _index);
void setStore(llvm::Value* _index, llvm::Value* _value);
@ -54,8 +53,6 @@ private:
llvm::Value* bswap(llvm::Value*);
private:
llvm::IRBuilder<>& m_builder;
llvm::Value* m_args[2];
llvm::Value* m_arg2;
llvm::Value* m_arg3;

14
evmcc/GasMeter.cpp

@ -9,7 +9,6 @@
#include <libevm/FeeStructure.h>
#include "Type.h"
#include "Utils.h"
#include "Ext.h"
namespace dev
@ -80,13 +79,14 @@ bool isCostBlockEnd(Instruction _inst)
}
GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module) :
m_builder(_builder)
GasMeter::GasMeter(llvm::IRBuilder<>& _builder) :
CompilerHelper(_builder)
{
m_gas = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas");
auto module = getModule();
m_gas = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas");
m_gas->setUnnamedAddr(true); // Address is not important
m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", _module);
m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", module);
InsertPointGuard guard(m_builder);
auto checkBB = llvm::BasicBlock::Create(_builder.getContext(), "Check", m_gasCheckFunc);
@ -103,9 +103,9 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module) :
m_builder.SetInsertPoint(outOfGasBB);
//auto longjmpFunc = llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::eh_sjlj_longjmp);
auto extJmpBuf = new llvm::GlobalVariable(*_module, Type::BytePtr, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "rt_jmpBuf");
auto extJmpBuf = new llvm::GlobalVariable(*module, Type::BytePtr, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "rt_jmpBuf");
llvm::Type* args[] = {Type::BytePtr, m_builder.getInt32Ty()};
auto longjmpNative = llvm::Function::Create(llvm::FunctionType::get(Type::Void, args, false), llvm::Function::ExternalLinkage, "longjmp", _module);
auto longjmpNative = llvm::Function::Create(llvm::FunctionType::get(Type::Void, args, false), llvm::Function::ExternalLinkage, "longjmp", module);
m_builder.CreateCall2(longjmpNative, m_builder.CreateLoad(extJmpBuf), Constant::get(ReturnCode::OutOfGas));
m_builder.CreateUnreachable();

13
evmcc/GasMeter.h

@ -1,10 +1,10 @@
#pragma once
#include <llvm/IR/IRBuilder.h>
#include <libevmface/Instruction.h>
#include "CompilerHelper.h"
namespace dev
{
namespace eth
@ -12,13 +12,10 @@ namespace eth
namespace jit
{
class GasMeter
class GasMeter : public CompilerHelper
{
public:
GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module);
GasMeter(const GasMeter&) = delete;
void operator=(GasMeter) = delete;
GasMeter(llvm::IRBuilder<>& _builder);
/// Count step cost of instruction
void count(Instruction _inst);
@ -42,7 +39,7 @@ private:
/// Cumulative gas cost of a block of instructions
/// @TODO Handle overflow
uint64_t m_blockCost = 0;
llvm::IRBuilder<>& m_builder;
llvm::CallInst* m_checkCall = nullptr;
llvm::GlobalVariable* m_gas;
llvm::Function* m_gasCheckFunc;

33
evmcc/Memory.cpp

@ -22,41 +22,42 @@ namespace eth
namespace jit
{
Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module, GasMeter& _gasMeter):
m_builder(_builder)
Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter):
CompilerHelper(_builder)
{
auto module = getModule();
auto i64Ty = m_builder.getInt64Ty();
llvm::Type* argTypes[] = {i64Ty, i64Ty};
auto dumpTy = llvm::FunctionType::get(m_builder.getVoidTy(), llvm::ArrayRef<llvm::Type*>(argTypes), false);
m_memDump = llvm::Function::Create(dumpTy, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
"evmccrt_memory_dump", _module);
"evmccrt_memory_dump", module);
m_data = new llvm::GlobalVariable(*_module, Type::BytePtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::BytePtr), "mem.data");
m_data = new llvm::GlobalVariable(*module, Type::BytePtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::BytePtr), "mem.data");
m_data->setUnnamedAddr(true); // Address is not important
m_size = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, Constant::get(0), "mem.size");
m_size = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, Constant::get(0), "mem.size");
m_size->setUnnamedAddr(true); // Address is not important
m_returnDataOffset = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataOffset");
m_returnDataOffset = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataOffset");
m_returnDataOffset->setUnnamedAddr(true); // Address is not important
m_returnDataSize = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataSize");
m_returnDataSize = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataSize");
m_returnDataSize->setUnnamedAddr(true); // Address is not important
m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, Type::WordPtr, false), llvm::Function::ExternalLinkage, "mem_resize", _module);
m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, Type::WordPtr, false), llvm::Function::ExternalLinkage, "mem_resize", module);
llvm::AttrBuilder attrBuilder;
attrBuilder.addAttribute(llvm::Attribute::NoAlias).addAttribute(llvm::Attribute::NoCapture).addAttribute(llvm::Attribute::NonNull).addAttribute(llvm::Attribute::ReadOnly);
m_resize->setAttributes(llvm::AttributeSet::get(m_resize->getContext(), 1, attrBuilder));
m_require = createRequireFunc(_module, _gasMeter);
m_loadWord = createFunc(false, Type::i256, _module, _gasMeter);
m_storeWord = createFunc(true, Type::i256, _module, _gasMeter);
m_storeByte = createFunc(true, Type::Byte, _module, _gasMeter);
m_require = createRequireFunc(_gasMeter);
m_loadWord = createFunc(false, Type::i256, _gasMeter);
m_storeWord = createFunc(true, Type::i256, _gasMeter);
m_storeByte = createFunc(true, Type::Byte, _gasMeter);
}
llvm::Function* Memory::createRequireFunc(llvm::Module* _module, GasMeter& _gasMeter)
llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter)
{
auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "mem.require", _module);
auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "mem.require", getModule());
auto checkBB = llvm::BasicBlock::Create(func->getContext(), "check", func);
auto resizeBB = llvm::BasicBlock::Create(func->getContext(), "resize", func);
@ -91,14 +92,14 @@ llvm::Function* Memory::createRequireFunc(llvm::Module* _module, GasMeter& _gasM
return func;
}
llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, llvm::Module* _module, GasMeter& _gasMeter)
llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMeter& _gasMeter)
{
auto isWord = _valueType == Type::i256;
llvm::Type* storeArgs[] = {Type::i256, _valueType};
auto name = _isStore ? isWord ? "mstore" : "mstore8" : "mload";
auto funcType = _isStore ? llvm::FunctionType::get(Type::Void, storeArgs, false) : llvm::FunctionType::get(Type::i256, Type::i256, false);
auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, _module);
auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, getModule());
InsertPointGuard guard(m_builder); // Restores insert point at function exit

18
evmcc/Memory.h

@ -1,9 +1,9 @@
#pragma once
#include <llvm/IR/IRBuilder.h>
#include <libdevcore/Common.h>
#include "CompilerHelper.h"
namespace dev
{
namespace eth
@ -11,14 +11,10 @@ namespace eth
namespace jit
{
class GasMeter;
class Memory
class Memory : public CompilerHelper
{
public:
Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module, GasMeter& _gasMeter);
Memory(const Memory&) = delete;
void operator=(Memory) = delete;
Memory(llvm::IRBuilder<>& _builder, class GasMeter& _gasMeter);
llvm::Value* loadWord(llvm::Value* _addr);
void storeWord(llvm::Value* _addr, llvm::Value* _word);
@ -40,12 +36,10 @@ public:
void dump(uint64_t _begin, uint64_t _end = 0);
private:
llvm::Function* createFunc(bool _isStore, llvm::Type* _type, llvm::Module* _module, GasMeter& _gasMeter);
llvm::Function* createRequireFunc(llvm::Module* _module, GasMeter& _gasMeter);
llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter);
llvm::Function* createRequireFunc(GasMeter& _gasMeter);
private:
llvm::IRBuilder<>& m_builder;
llvm::GlobalVariable* m_data;
llvm::GlobalVariable* m_size;

22
evmcc/Utils.h

@ -26,28 +26,6 @@ static_assert(sizeof(i256) == 32, "Wrong i265 size");
u256 llvm2eth(i256);
i256 eth2llvm(u256);
struct InsertPointGuard
{
InsertPointGuard(llvm::IRBuilder<>& _builder) :
m_builder(_builder),
m_insertBB(m_builder.GetInsertBlock()),
m_insertPt(m_builder.GetInsertPoint())
{}
~InsertPointGuard()
{
m_builder.SetInsertPoint(m_insertBB, m_insertPt);
}
private:
llvm::IRBuilder<>& m_builder;
llvm::BasicBlock* m_insertBB;
llvm::BasicBlock::iterator m_insertPt;
InsertPointGuard(const InsertPointGuard&) = delete;
void operator=(InsertPointGuard) = delete;
};
#define ANY_PUSH PUSH1: \
case Instruction::PUSH2: \
case Instruction::PUSH3: \

6
windows/evmcc.vcxproj

@ -21,6 +21,7 @@
<ItemGroup>
<ClCompile Include="..\evmcc\BasicBlock.cpp" />
<ClCompile Include="..\evmcc\Compiler.cpp" />
<ClCompile Include="..\evmcc\CompilerHelper.cpp" />
<ClCompile Include="..\evmcc\evmcc.cpp" />
<ClCompile Include="..\evmcc\ExecutionEngine.cpp" />
<ClCompile Include="..\evmcc\Ext.cpp" />
@ -33,6 +34,7 @@
<ItemGroup>
<ClInclude Include="..\evmcc\BasicBlock.h" />
<ClInclude Include="..\evmcc\Compiler.h" />
<ClInclude Include="..\evmcc\CompilerHelper.h" />
<ClInclude Include="..\evmcc\ExecutionEngine.h" />
<ClInclude Include="..\evmcc\Ext.h" />
<ClInclude Include="..\evmcc\GasMeter.h" />
@ -123,8 +125,9 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>../</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../llvm-3.5.0/include;../../builds/llvm3.5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<EnablePREfast>false</EnablePREfast>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@ -144,6 +147,7 @@
<AdditionalIncludeDirectories>../../llvm-3.5.0/include;../../builds/llvm3.5/include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<DisableSpecificWarnings>4068;4244;4267;4800</DisableSpecificWarnings>
<EnablePREfast>false</EnablePREfast>
<TreatWarningAsError>false</TreatWarningAsError>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>

2
windows/evmcc.vcxproj.filters

@ -11,6 +11,7 @@
<ClCompile Include="..\evmcc\BasicBlock.cpp" />
<ClCompile Include="..\evmcc\GasMeter.cpp" />
<ClCompile Include="..\evmcc\Type.cpp" />
<ClCompile Include="..\evmcc\CompilerHelper.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\evmcc\Compiler.h" />
@ -22,5 +23,6 @@
<ClInclude Include="..\evmcc\BasicBlock.h" />
<ClInclude Include="..\evmcc\GasMeter.h" />
<ClInclude Include="..\evmcc\Type.h" />
<ClInclude Include="..\evmcc\CompilerHelper.h" />
</ItemGroup>
</Project>
Loading…
Cancel
Save