mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46:44 +00:00
Merge branch 'develop-evmcc' of github.com:imapp-pl/ethereum into develop-evmcc
Conflicts: evmcc/Compiler.cpp
This commit is contained in:
commit
e22238f148
5 changed files with 56 additions and 27 deletions
|
|
@ -465,6 +465,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
{
|
||||
auto inOff = stack.pop();
|
||||
auto inSize = stack.pop();
|
||||
memory.require(inOff, inSize);
|
||||
auto hash = ext.sha3(inOff, inSize);
|
||||
stack.push(hash);
|
||||
}
|
||||
|
|
@ -837,6 +838,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
auto endowment = stack.pop();
|
||||
auto initOff = stack.pop();
|
||||
auto initSize = stack.pop();
|
||||
memory.require(initOff, initSize);
|
||||
|
||||
auto address = ext.create(endowment, initOff, initSize);
|
||||
stack.push(address);
|
||||
|
|
@ -854,6 +856,14 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
auto outSize = stack.pop();
|
||||
|
||||
gasMeter.commitCostBlock(gas);
|
||||
|
||||
// Require memory for the max of in and out buffers
|
||||
auto inSizeReq = builder.CreateAdd(inOff, inSize, "inSizeReq");
|
||||
auto outSizeReq = builder.CreateAdd(outOff, outSize, "outSizeReq");
|
||||
auto cmp = builder.CreateICmpUGT(inSizeReq, outSizeReq);
|
||||
auto sizeReq = builder.CreateSelect(cmp, inSizeReq, outSizeReq, "sizeReq");
|
||||
memory.require(sizeReq);
|
||||
|
||||
auto ret = ext.call(gas, receiveAddress, value, inOff, inSize, outOff, outSize);
|
||||
gasMeter.giveBack(gas);
|
||||
stack.push(ret);
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <libevm/FeeStructure.h>
|
||||
|
||||
#include "Type.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace evmcc
|
||||
{
|
||||
|
|
@ -81,17 +82,14 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module):
|
|||
m_gas = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas");
|
||||
m_gas->setUnnamedAddr(true); // Address is not important
|
||||
|
||||
auto pt = m_builder.GetInsertPoint();
|
||||
auto bb = m_builder.GetInsertBlock();
|
||||
m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", _module);
|
||||
auto gasCheckBB = llvm::BasicBlock::Create(_builder.getContext(), {}, m_gasCheckFunc);
|
||||
m_builder.SetInsertPoint(gasCheckBB);
|
||||
InsertPointGuard guard(m_builder);
|
||||
m_builder.SetInsertPoint(llvm::BasicBlock::Create(_builder.getContext(), {}, m_gasCheckFunc));
|
||||
llvm::Value* cost = m_gasCheckFunc->arg_begin();
|
||||
llvm::Value* gas = m_builder.CreateLoad(m_gas);
|
||||
gas = m_builder.CreateSub(gas, cost);
|
||||
m_builder.CreateStore(gas, m_gas);
|
||||
m_builder.CreateRetVoid();
|
||||
m_builder.SetInsertPoint(bb, pt);
|
||||
}
|
||||
|
||||
void GasMeter::count(Instruction _inst)
|
||||
|
|
|
|||
|
|
@ -54,30 +54,32 @@ llvm::Function* Memory::createRequireFunc(llvm::Module* _module, GasMeter& _gasM
|
|||
auto resizeBB = llvm::BasicBlock::Create(func->getContext(), "resize", func);
|
||||
auto returnBB = llvm::BasicBlock::Create(func->getContext(), "return", func);
|
||||
|
||||
InsertPointGuard guard(m_builder); // Restores insert point at function exit
|
||||
|
||||
// BB "check"
|
||||
llvm::IRBuilder<> builder(checkBB);
|
||||
m_builder.SetInsertPoint(checkBB);
|
||||
llvm::Value* sizeRequired = func->arg_begin();
|
||||
sizeRequired->setName("sizeRequired");
|
||||
auto size = builder.CreateLoad(m_size, "size");
|
||||
auto resizeNeeded = builder.CreateICmpULE(size, sizeRequired, "resizeNeeded");
|
||||
builder.CreateCondBr(resizeNeeded, resizeBB, returnBB); // OPT branch weights?
|
||||
auto size = m_builder.CreateLoad(m_size, "size");
|
||||
auto resizeNeeded = m_builder.CreateICmpULE(size, sizeRequired, "resizeNeeded");
|
||||
m_builder.CreateCondBr(resizeNeeded, resizeBB, returnBB); // OPT branch weights?
|
||||
|
||||
// BB "resize"
|
||||
builder.SetInsertPoint(resizeBB);
|
||||
m_builder.SetInsertPoint(resizeBB);
|
||||
// Check gas first
|
||||
auto wordsRequired = builder.CreateUDiv(builder.CreateAdd(sizeRequired, Constant::get(31)), Constant::get(32), "wordsRequired");
|
||||
auto words = builder.CreateUDiv(builder.CreateAdd(size, Constant::get(31)), Constant::get(32), "words");
|
||||
auto newWords = builder.CreateSub(wordsRequired, words, "addtionalWords");
|
||||
_gasMeter.checkMemory(newWords, builder);
|
||||
auto wordsRequired = m_builder.CreateUDiv(m_builder.CreateAdd(sizeRequired, Constant::get(31)), Constant::get(32), "wordsRequired");
|
||||
auto words = m_builder.CreateUDiv(m_builder.CreateAdd(size, Constant::get(31)), Constant::get(32), "words");
|
||||
auto newWords = m_builder.CreateSub(wordsRequired, words, "addtionalWords");
|
||||
_gasMeter.checkMemory(newWords, m_builder);
|
||||
// Resize
|
||||
builder.CreateStore(sizeRequired, m_size);
|
||||
auto newData = builder.CreateCall(m_resize, m_size, "newData");
|
||||
builder.CreateStore(newData, m_data);
|
||||
builder.CreateBr(returnBB);
|
||||
m_builder.CreateStore(sizeRequired, m_size);
|
||||
auto newData = m_builder.CreateCall(m_resize, m_size, "newData");
|
||||
m_builder.CreateStore(newData, m_data);
|
||||
m_builder.CreateBr(returnBB);
|
||||
|
||||
// BB "return"
|
||||
builder.SetInsertPoint(returnBB);
|
||||
builder.CreateRetVoid();
|
||||
m_builder.SetInsertPoint(returnBB);
|
||||
m_builder.CreateRetVoid();
|
||||
return func;
|
||||
}
|
||||
|
||||
|
|
@ -90,8 +92,7 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, llvm::
|
|||
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 origBB = m_builder.GetInsertBlock();
|
||||
auto origPt = m_builder.GetInsertPoint();
|
||||
InsertPointGuard guard(m_builder); // Restores insert point at function exit
|
||||
|
||||
m_builder.SetInsertPoint(llvm::BasicBlock::Create(func->getContext(), {}, func));
|
||||
llvm::Value* index = func->arg_begin();
|
||||
|
|
@ -116,8 +117,6 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, llvm::
|
|||
m_builder.CreateRet(ret);
|
||||
}
|
||||
|
||||
m_builder.SetInsertPoint(origBB, origPt);
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,11 +46,11 @@ private:
|
|||
llvm::GlobalVariable* m_returnDataOffset;
|
||||
llvm::GlobalVariable* m_returnDataSize;
|
||||
|
||||
llvm::Function* m_resize;
|
||||
llvm::Function* m_require;
|
||||
llvm::Function* m_loadWord;
|
||||
llvm::Function* m_storeWord;
|
||||
llvm::Function* m_storeByte;
|
||||
llvm::Function* m_require;
|
||||
llvm::Function* m_resize;
|
||||
|
||||
llvm::Function* m_memDump;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
|
||||
#include <libdevcore/Common.h>
|
||||
|
||||
|
|
@ -22,4 +22,26 @@ static_assert(sizeof(i256) == 32, "Wrong i265 size");
|
|||
dev::u256 llvm2eth(i256);
|
||||
i256 eth2llvm(dev::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;
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue