Browse Source

Move LocalStack out of BasicBlock.

cl-refactor
Paweł Bylica 10 years ago
parent
commit
c80ded8f97
  1. 22
      evmjit/libevmjit/BasicBlock.cpp
  2. 27
      evmjit/libevmjit/BasicBlock.h
  3. 8
      evmjit/libevmjit/Compiler.cpp
  4. 2
      evmjit/libevmjit/Compiler.h

22
evmjit/libevmjit/BasicBlock.cpp

@ -28,23 +28,22 @@ BasicBlock::BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iter
m_begin(_begin), m_begin(_begin),
m_end(_end), m_end(_end),
m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {isJumpDest ? jumpDestName : basicBlockName, std::to_string(_firstInstrIdx)}, _mainFunc)), m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {isJumpDest ? jumpDestName : basicBlockName, std::to_string(_firstInstrIdx)}, _mainFunc)),
m_stack(*this),
m_builder(_builder), m_builder(_builder),
m_isJumpDest(isJumpDest) m_isJumpDest(isJumpDest)
{} {}
BasicBlock::BasicBlock(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest) : BasicBlock::BasicBlock(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest) :
m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), _name, _mainFunc)), m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), _name, _mainFunc)),
m_stack(*this),
m_builder(_builder), m_builder(_builder),
m_isJumpDest(isJumpDest) m_isJumpDest(isJumpDest)
{} {}
BasicBlock::LocalStack::LocalStack(BasicBlock& _owner) : LocalStack::LocalStack(BasicBlock& _owner, Stack& _globalStack) :
m_bblock(_owner) m_bblock(_owner),
m_global(_globalStack)
{} {}
void BasicBlock::LocalStack::push(llvm::Value* _value) void LocalStack::push(llvm::Value* _value)
{ {
assert(_value->getType() == Type::Word); assert(_value->getType() == Type::Word);
m_bblock.m_currentStack.push_back(_value); m_bblock.m_currentStack.push_back(_value);
@ -52,7 +51,7 @@ void BasicBlock::LocalStack::push(llvm::Value* _value)
m_maxSize = std::max(m_maxSize, m_bblock.m_currentStack.size()); m_maxSize = std::max(m_maxSize, m_bblock.m_currentStack.size());
} }
llvm::Value* BasicBlock::LocalStack::pop() llvm::Value* LocalStack::pop()
{ {
auto result = get(0); auto result = get(0);
@ -66,7 +65,7 @@ llvm::Value* BasicBlock::LocalStack::pop()
/** /**
* Pushes a copy of _index-th element (tos is 0-th elem). * Pushes a copy of _index-th element (tos is 0-th elem).
*/ */
void BasicBlock::LocalStack::dup(size_t _index) void LocalStack::dup(size_t _index)
{ {
auto val = get(_index); auto val = get(_index);
push(val); push(val);
@ -76,7 +75,7 @@ void BasicBlock::LocalStack::dup(size_t _index)
* Swaps tos with _index-th element (tos is 0-th elem). * Swaps tos with _index-th element (tos is 0-th elem).
* _index must be > 0. * _index must be > 0.
*/ */
void BasicBlock::LocalStack::swap(size_t _index) void LocalStack::swap(size_t _index)
{ {
assert(_index > 0); assert(_index > 0);
auto val = get(_index); auto val = get(_index);
@ -85,7 +84,7 @@ void BasicBlock::LocalStack::swap(size_t _index)
set(0, val); set(0, val);
} }
std::vector<llvm::Value*>::iterator BasicBlock::LocalStack::getItemIterator(size_t _index) std::vector<llvm::Value*>::iterator LocalStack::getItemIterator(size_t _index)
{ {
auto& currentStack = m_bblock.m_currentStack; auto& currentStack = m_bblock.m_currentStack;
if (_index < currentStack.size()) if (_index < currentStack.size())
@ -98,7 +97,7 @@ std::vector<llvm::Value*>::iterator BasicBlock::LocalStack::getItemIterator(size
return currentStack.end() - _index - 1; return currentStack.end() - _index - 1;
} }
llvm::Value* BasicBlock::LocalStack::get(size_t _index) llvm::Value* LocalStack::get(size_t _index)
{ {
auto& initialStack = m_bblock.m_initialStack; auto& initialStack = m_bblock.m_initialStack;
auto itemIter = getItemIterator(_index); auto itemIter = getItemIterator(_index);
@ -124,7 +123,7 @@ llvm::Value* BasicBlock::LocalStack::get(size_t _index)
return *itemIter; return *itemIter;
} }
void BasicBlock::LocalStack::set(size_t _index, llvm::Value* _word) void LocalStack::set(size_t _index, llvm::Value* _word)
{ {
auto itemIter = getItemIterator(_index); auto itemIter = getItemIterator(_index);
*itemIter = _word; *itemIter = _word;
@ -388,4 +387,3 @@ void BasicBlock::dump(std::ostream& _out, bool _dotOutput)
} }
} }
} }

27
evmjit/libevmjit/BasicBlock.h

@ -14,12 +14,15 @@ namespace jit
using namespace evmjit; using namespace evmjit;
using instr_idx = uint64_t; using instr_idx = uint64_t;
class BasicBlock class BasicBlock;
{
public:
class LocalStack class LocalStack
{ {
public: public:
LocalStack(BasicBlock& _owner, Stack& _globalStack);
LocalStack(LocalStack const&) = delete;
void operator=(LocalStack const&) = delete;
/// Pushes value on stack /// Pushes value on stack
void push(llvm::Value* _value); void push(llvm::Value* _value);
@ -34,14 +37,8 @@ public:
void swap(size_t _index); void swap(size_t _index);
size_t getMaxSize() const { return m_maxSize; } size_t getMaxSize() const { return m_maxSize; }
int getDiff() const { return m_bblock.m_tosOffset; }
private: private:
LocalStack(BasicBlock& _owner);
LocalStack(LocalStack const&) = delete;
void operator=(LocalStack const&) = delete;
friend BasicBlock;
/// Gets _index'th value from top (counting from 0) /// Gets _index'th value from top (counting from 0)
llvm::Value* get(size_t _index); llvm::Value* get(size_t _index);
@ -52,9 +49,13 @@ public:
private: private:
BasicBlock& m_bblock; BasicBlock& m_bblock;
Stack& m_global;
size_t m_maxSize = 0; ///< Max size reached by the stack. size_t m_maxSize = 0; ///< Max size reached by the stack.
}; };
class BasicBlock
{
public:
explicit BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest); explicit BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest);
explicit BasicBlock(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest); explicit BasicBlock(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest);
@ -72,7 +73,7 @@ public:
llvm::Value* getJumpTarget() const { return m_jumpTarget; } llvm::Value* getJumpTarget() const { return m_jumpTarget; }
void setJumpTarget(llvm::Value* _jumpTarget) { m_jumpTarget = _jumpTarget; } void setJumpTarget(llvm::Value* _jumpTarget) { m_jumpTarget = _jumpTarget; }
LocalStack& localStack() { return m_stack; } int getDiff() const { return m_tosOffset; }
/// Optimization: propagates values between local stacks in basic blocks /// Optimization: propagates values between local stacks in basic blocks
/// to avoid excessive pushing/popping on the EVM stack. /// to avoid excessive pushing/popping on the EVM stack.
@ -93,10 +94,6 @@ private:
llvm::BasicBlock* const m_llvmBB; llvm::BasicBlock* const m_llvmBB;
/// Basic black state vector (stack) - current/end values and their positions on stack
/// @internal Must be AFTER m_llvmBB
LocalStack m_stack;
llvm::IRBuilder<>& m_builder; llvm::IRBuilder<>& m_builder;
/// This stack contains LLVM values that correspond to items found at /// This stack contains LLVM values that correspond to items found at
@ -111,6 +108,7 @@ private:
/// executes. It may grow on both sides, as the code pushes items on /// executes. It may grow on both sides, as the code pushes items on
/// top of the stack or changes existing items. /// top of the stack or changes existing items.
std::vector<llvm::Value*> m_currentStack; std::vector<llvm::Value*> m_currentStack;
friend class LocalStack;
/// How many items higher is the current stack than the initial one. /// How many items higher is the current stack than the initial one.
/// May be negative. /// May be negative.
@ -127,4 +125,3 @@ private:
} }
} }
} }

8
evmjit/libevmjit/Compiler.cpp

@ -163,7 +163,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_itera
auto iterCopy = basicBlockPairIt; auto iterCopy = basicBlockPairIt;
++iterCopy; ++iterCopy;
auto nextBasicBlock = (iterCopy != m_basicBlocks.end()) ? iterCopy->second.llvm() : nullptr; auto nextBasicBlock = (iterCopy != m_basicBlocks.end()) ? iterCopy->second.llvm() : nullptr;
compileBasicBlock(basicBlock, runtimeManager, arith, memory, ext, gasMeter, nextBasicBlock); compileBasicBlock(basicBlock, runtimeManager, arith, memory, ext, gasMeter, nextBasicBlock, stack);
} }
// Code for special blocks: // Code for special blocks:
@ -224,13 +224,13 @@ std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_itera
void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runtimeManager, void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runtimeManager,
Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock) Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock, Stack& _globalStack)
{ {
if (!_nextBasicBlock) // this is the last block in the code if (!_nextBasicBlock) // this is the last block in the code
_nextBasicBlock = m_stopBB; _nextBasicBlock = m_stopBB;
m_builder.SetInsertPoint(_basicBlock.llvm()); m_builder.SetInsertPoint(_basicBlock.llvm());
auto& stack = _basicBlock.localStack(); LocalStack stack{_basicBlock, _globalStack};
for (auto it = _basicBlock.begin(); it != _basicBlock.end(); ++it) for (auto it = _basicBlock.begin(); it != _basicBlock.end(); ++it)
{ {
@ -857,7 +857,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runti
m_builder.CreateBr(_nextBasicBlock); m_builder.CreateBr(_nextBasicBlock);
m_builder.SetInsertPoint(_basicBlock.llvm()->getFirstNonPHI()); m_builder.SetInsertPoint(_basicBlock.llvm()->getFirstNonPHI());
_runtimeManager.checkStackLimit(_basicBlock.localStack().getMaxSize(), _basicBlock.localStack().getDiff()); _runtimeManager.checkStackLimit(stack.getMaxSize(), _basicBlock.getDiff());
} }

2
evmjit/libevmjit/Compiler.h

@ -35,7 +35,7 @@ private:
void createBasicBlocks(code_iterator _begin, code_iterator _end); void createBasicBlocks(code_iterator _begin, code_iterator _end);
void compileBasicBlock(BasicBlock& _basicBlock, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock); void compileBasicBlock(BasicBlock& _basicBlock, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock, class Stack& _globalStack);
llvm::BasicBlock* getJumpTableBlock(); llvm::BasicBlock* getJumpTableBlock();

Loading…
Cancel
Save