mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Merge branch 'develop-evmcc' of github.com:imapp-pl/ethereum into develop-evmcc
This commit is contained in:
commit
ad43b92d97
5 changed files with 67 additions and 14 deletions
|
|
@ -33,19 +33,29 @@ void BasicBlock::Stack::push(llvm::Value* _value)
|
||||||
|
|
||||||
llvm::Value* BasicBlock::Stack::pop()
|
llvm::Value* BasicBlock::Stack::pop()
|
||||||
{
|
{
|
||||||
if (m_backend.empty())
|
auto top = get(0);
|
||||||
{
|
|
||||||
// Create PHI node
|
|
||||||
if (m_llvmBB->empty())
|
|
||||||
return llvm::PHINode::Create(Type::i256, 0, {}, m_llvmBB);
|
|
||||||
return llvm::PHINode::Create(Type::i256, 0, {}, m_llvmBB->getFirstNonPHI());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto top = m_backend.back();
|
|
||||||
m_backend.pop_back();
|
m_backend.pop_back();
|
||||||
return top;
|
return top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::Value* BasicBlock::Stack::get(size_t _index)
|
||||||
|
{
|
||||||
|
if (_index >= m_backend.size())
|
||||||
|
{
|
||||||
|
// Create PHI node for missing values
|
||||||
|
auto nMissingVals = _index - m_backend.size() + 1;
|
||||||
|
m_backend.insert(m_backend.begin(), nMissingVals, nullptr);
|
||||||
|
for (decltype(nMissingVals) i = 0; i < nMissingVals; ++i)
|
||||||
|
{
|
||||||
|
m_backend[i] = m_llvmBB->empty() ?
|
||||||
|
llvm::PHINode::Create(Type::i256, 0, {}, m_llvmBB) :
|
||||||
|
llvm::PHINode::Create(Type::i256, 0, {}, m_llvmBB->getFirstNonPHI());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return *(m_backend.rbegin() + _index);
|
||||||
|
}
|
||||||
|
|
||||||
void BasicBlock::Stack::dup(size_t _index)
|
void BasicBlock::Stack::dup(size_t _index)
|
||||||
{
|
{
|
||||||
m_backend.push_back(get(_index));
|
m_backend.push_back(get(_index));
|
||||||
|
|
@ -54,7 +64,8 @@ void BasicBlock::Stack::dup(size_t _index)
|
||||||
void BasicBlock::Stack::swap(size_t _index)
|
void BasicBlock::Stack::swap(size_t _index)
|
||||||
{
|
{
|
||||||
assert(_index != 0);
|
assert(_index != 0);
|
||||||
std::swap(get(0), get(_index));
|
get(_index); // Create PHI nodes
|
||||||
|
std::swap(*m_backend.rbegin(), *(m_backend.rbegin() + _index));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ public:
|
||||||
llvm::Value* pop();
|
llvm::Value* pop();
|
||||||
|
|
||||||
/// Gets _index'th value from top (counting from 0)
|
/// Gets _index'th value from top (counting from 0)
|
||||||
llvm::Value*& get(size_t _index) { return *(m_backend.rbegin() + _index); }
|
llvm::Value* get(size_t _index);
|
||||||
|
|
||||||
/// Duplicates _index'th value on stack.
|
/// Duplicates _index'th value on stack.
|
||||||
void dup(size_t _index);
|
void dup(size_t _index);
|
||||||
|
|
|
||||||
|
|
@ -213,8 +213,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
{
|
{
|
||||||
auto inst = static_cast<Instruction>(bytecode[currentPC]);
|
auto inst = static_cast<Instruction>(bytecode[currentPC]);
|
||||||
|
|
||||||
// Disable for now
|
gasMeter.check(inst);
|
||||||
//gasMeter.check(inst);
|
|
||||||
|
|
||||||
switch (inst)
|
switch (inst)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,33 @@ uint64_t getStepCost(dev::eth::Instruction inst) // TODO: Add this function to F
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isCommitTrigger(Instruction _inst)
|
||||||
|
{
|
||||||
|
switch (_inst)
|
||||||
|
{
|
||||||
|
case Instruction::STOP:
|
||||||
|
case Instruction::CALLDATACOPY:
|
||||||
|
case Instruction::CODECOPY:
|
||||||
|
case Instruction::MLOAD:
|
||||||
|
case Instruction::MSTORE:
|
||||||
|
case Instruction::MSTORE8:
|
||||||
|
case Instruction::SSTORE:
|
||||||
|
case Instruction::JUMP:
|
||||||
|
case Instruction::JUMPI:
|
||||||
|
case Instruction::JUMPDEST:
|
||||||
|
case Instruction::GAS:
|
||||||
|
case Instruction::CREATE:
|
||||||
|
case Instruction::CALL:
|
||||||
|
case Instruction::CALLCODE:
|
||||||
|
case Instruction::RETURN:
|
||||||
|
case Instruction::SUICIDE:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module):
|
GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module):
|
||||||
|
|
@ -72,8 +99,20 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module):
|
||||||
|
|
||||||
void GasMeter::check(Instruction _inst)
|
void GasMeter::check(Instruction _inst)
|
||||||
{
|
{
|
||||||
|
if (!m_checkCall)
|
||||||
|
{
|
||||||
|
m_checkCall = m_builder.CreateCall(m_gasCheckFunc, m_builder.getIntN(256, 0));
|
||||||
|
}
|
||||||
|
|
||||||
auto stepCost = getStepCost(_inst);
|
auto stepCost = getStepCost(_inst);
|
||||||
m_builder.CreateCall(m_gasCheckFunc, m_builder.getIntN(256, stepCost));
|
m_blockCost += stepCost;
|
||||||
|
|
||||||
|
auto isTrigger = isCommitTrigger(_inst);
|
||||||
|
if (isTrigger)
|
||||||
|
{
|
||||||
|
m_checkCall->setArgOperand(0, m_builder.getIntN(256, m_blockCost));
|
||||||
|
m_checkCall = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -19,7 +19,11 @@ public:
|
||||||
void check(dev::eth::Instruction _inst);
|
void check(dev::eth::Instruction _inst);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/// Cumulative gas cost of a block of instructions
|
||||||
|
/// @TODO Handle overflow
|
||||||
|
uint64_t m_blockCost = 0;
|
||||||
llvm::IRBuilder<>& m_builder;
|
llvm::IRBuilder<>& m_builder;
|
||||||
|
llvm::CallInst* m_checkCall;
|
||||||
llvm::GlobalVariable* m_gas;
|
llvm::GlobalVariable* m_gas;
|
||||||
llvm::Function* m_gasCheckFunc;
|
llvm::Function* m_gasCheckFunc;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue