mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Basic stack implementation for basic block. Values on stack are not preserved between basic blocks (jumps)
This commit is contained in:
parent
3cba3a2dca
commit
33e36ce6cc
3 changed files with 53 additions and 9 deletions
|
|
@ -188,11 +188,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
createBasicBlocks(bytecode);
|
createBasicBlocks(bytecode);
|
||||||
|
|
||||||
// Init runtime structures.
|
// Init runtime structures.
|
||||||
auto stack = Stack(builder, module.get());
|
auto globalStack = Stack(builder, module.get());
|
||||||
auto memory = Memory(builder, module.get());
|
auto memory = Memory(builder, module.get());
|
||||||
auto ext = Ext(builder, module.get());
|
auto ext = Ext(builder, module.get());
|
||||||
|
|
||||||
BasicBlock* currentBlock = entryBlock;
|
BasicBlock* currentBlock = entryBlock;
|
||||||
|
BBStack stack; // Stack for current block
|
||||||
|
|
||||||
for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc)
|
for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc)
|
||||||
{
|
{
|
||||||
|
|
@ -211,6 +212,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
mainFunc->getBasicBlockList().push_back(nextBlock);
|
mainFunc->getBasicBlockList().push_back(nextBlock);
|
||||||
builder.SetInsertPoint(nextBlock);
|
builder.SetInsertPoint(nextBlock);
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
|
stack = BBStack(); // Reset stack
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(currentBlock != nullptr);
|
assert(currentBlock != nullptr);
|
||||||
|
|
@ -498,9 +500,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
case Instruction::DUP15:
|
case Instruction::DUP15:
|
||||||
case Instruction::DUP16:
|
case Instruction::DUP16:
|
||||||
{
|
{
|
||||||
auto index = static_cast<uint32_t>(inst) - static_cast<uint32_t>(Instruction::DUP1);
|
auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::DUP1);
|
||||||
auto value = stack.get(index);
|
stack.dup(index);
|
||||||
stack.push(value);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -521,11 +522,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
case Instruction::SWAP15:
|
case Instruction::SWAP15:
|
||||||
case Instruction::SWAP16:
|
case Instruction::SWAP16:
|
||||||
{
|
{
|
||||||
auto index = static_cast<uint32_t>(inst) - static_cast<uint32_t>(Instruction::SWAP1) + 1;
|
auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::SWAP1) + 1;
|
||||||
auto loValue = stack.get(index);
|
stack.swap(index);
|
||||||
auto hiValue = stack.get(0);
|
|
||||||
stack.set(index, hiValue);
|
|
||||||
stack.set(0, loValue);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,30 @@
|
||||||
namespace evmcc
|
namespace evmcc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void BBStack::push(llvm::Value* _value)
|
||||||
|
{
|
||||||
|
m_state.push_back(_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
llvm::Value* BBStack::pop()
|
||||||
|
{
|
||||||
|
auto top = m_state.back();
|
||||||
|
m_state.pop_back();
|
||||||
|
return top;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBStack::dup(size_t _index)
|
||||||
|
{
|
||||||
|
auto value = *(m_state.rbegin() + _index);
|
||||||
|
m_state.push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BBStack::swap(size_t _index)
|
||||||
|
{
|
||||||
|
assert(_index != 0);
|
||||||
|
std::swap(*m_state.rbegin(), *(m_state.rbegin() + _index));
|
||||||
|
}
|
||||||
|
|
||||||
Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
|
Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
|
||||||
: m_builder(_builder)
|
: m_builder(_builder)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <llvm/IR/IRBuilder.h>
|
#include <llvm/IR/IRBuilder.h>
|
||||||
|
|
||||||
namespace evmcc
|
namespace evmcc
|
||||||
|
|
@ -26,4 +28,24 @@ private:
|
||||||
llvm::Function* m_stackSet;
|
llvm::Function* m_stackSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Stack adapter for Basic Block
|
||||||
|
|
||||||
|
Transforms stack to SSA: tracks values and their positions on the imaginary stack used inside a basic block.
|
||||||
|
*/
|
||||||
|
class BBStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
//BBStack(llvm::IRBuilder<>& _builder, llvm::Module* _module);
|
||||||
|
|
||||||
|
void push(llvm::Value* _value);
|
||||||
|
llvm::Value* pop();
|
||||||
|
void dup(size_t _index);
|
||||||
|
void swap(size_t _index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<llvm::Value*> m_state; ///< Basic black state vector - current values and their positions
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue