mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 12:16:44 +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);
|
||||
|
||||
// Init runtime structures.
|
||||
auto stack = Stack(builder, module.get());
|
||||
auto globalStack = Stack(builder, module.get());
|
||||
auto memory = Memory(builder, module.get());
|
||||
auto ext = Ext(builder, module.get());
|
||||
|
||||
BasicBlock* currentBlock = entryBlock;
|
||||
BBStack stack; // Stack for current block
|
||||
|
||||
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);
|
||||
builder.SetInsertPoint(nextBlock);
|
||||
currentBlock = nextBlock;
|
||||
stack = BBStack(); // Reset stack
|
||||
}
|
||||
|
||||
assert(currentBlock != nullptr);
|
||||
|
|
@ -498,9 +500,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
case Instruction::DUP15:
|
||||
case Instruction::DUP16:
|
||||
{
|
||||
auto index = static_cast<uint32_t>(inst) - static_cast<uint32_t>(Instruction::DUP1);
|
||||
auto value = stack.get(index);
|
||||
stack.push(value);
|
||||
auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::DUP1);
|
||||
stack.dup(index);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -521,11 +522,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
case Instruction::SWAP15:
|
||||
case Instruction::SWAP16:
|
||||
{
|
||||
auto index = static_cast<uint32_t>(inst) - static_cast<uint32_t>(Instruction::SWAP1) + 1;
|
||||
auto loValue = stack.get(index);
|
||||
auto hiValue = stack.get(0);
|
||||
stack.set(index, hiValue);
|
||||
stack.set(0, loValue);
|
||||
auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::SWAP1) + 1;
|
||||
stack.swap(index);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,30 @@
|
|||
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)
|
||||
: m_builder(_builder)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
|
||||
namespace evmcc
|
||||
|
|
@ -26,4 +28,24 @@ private:
|
|||
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