Browse Source

Move LocalStack out of BasicBlock.

cl-refactor
Paweł Bylica 10 years ago
parent
commit
c80ded8f97
  1. 22
      evmjit/libevmjit/BasicBlock.cpp
  2. 67
      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_end(_end),
m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {isJumpDest ? jumpDestName : basicBlockName, std::to_string(_firstInstrIdx)}, _mainFunc)),
m_stack(*this),
m_builder(_builder),
m_isJumpDest(isJumpDest)
{}
BasicBlock::BasicBlock(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest) :
m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), _name, _mainFunc)),
m_stack(*this),
m_builder(_builder),
m_isJumpDest(isJumpDest)
{}
BasicBlock::LocalStack::LocalStack(BasicBlock& _owner) :
m_bblock(_owner)
LocalStack::LocalStack(BasicBlock& _owner, Stack& _globalStack) :
m_bblock(_owner),
m_global(_globalStack)
{}
void BasicBlock::LocalStack::push(llvm::Value* _value)
void LocalStack::push(llvm::Value* _value)
{
assert(_value->getType() == Type::Word);
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());
}
llvm::Value* BasicBlock::LocalStack::pop()
llvm::Value* LocalStack::pop()
{
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).
*/
void BasicBlock::LocalStack::dup(size_t _index)
void LocalStack::dup(size_t _index)
{
auto val = get(_index);
push(val);
@ -76,7 +75,7 @@ void BasicBlock::LocalStack::dup(size_t _index)
* Swaps tos with _index-th element (tos is 0-th elem).
* _index must be > 0.
*/
void BasicBlock::LocalStack::swap(size_t _index)
void LocalStack::swap(size_t _index)
{
assert(_index > 0);
auto val = get(_index);
@ -85,7 +84,7 @@ void BasicBlock::LocalStack::swap(size_t _index)
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;
if (_index < currentStack.size())
@ -98,7 +97,7 @@ std::vector<llvm::Value*>::iterator BasicBlock::LocalStack::getItemIterator(size
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 itemIter = getItemIterator(_index);
@ -124,7 +123,7 @@ llvm::Value* BasicBlock::LocalStack::get(size_t _index)
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);
*itemIter = _word;
@ -388,4 +387,3 @@ void BasicBlock::dump(std::ostream& _out, bool _dotOutput)
}
}
}

67
evmjit/libevmjit/BasicBlock.h

@ -14,47 +14,48 @@ namespace jit
using namespace evmjit;
using instr_idx = uint64_t;
class BasicBlock
class BasicBlock;
class LocalStack
{
public:
class LocalStack
{
public:
/// Pushes value on stack
void push(llvm::Value* _value);
LocalStack(BasicBlock& _owner, Stack& _globalStack);
LocalStack(LocalStack const&) = delete;
void operator=(LocalStack const&) = delete;
/// Pops and returns top value
llvm::Value* pop();
/// Pushes value on stack
void push(llvm::Value* _value);
/// Duplicates _index'th value on stack
void dup(size_t _index);
/// Pops and returns top value
llvm::Value* pop();
/// Swaps _index'th value on stack with a value on stack top.
/// @param _index Index of value to be swaped. Must be > 0.
void swap(size_t _index);
/// Duplicates _index'th value on stack
void dup(size_t _index);
size_t getMaxSize() const { return m_maxSize; }
int getDiff() const { return m_bblock.m_tosOffset; }
/// Swaps _index'th value on stack with a value on stack top.
/// @param _index Index of value to be swaped. Must be > 0.
void swap(size_t _index);
private:
LocalStack(BasicBlock& _owner);
LocalStack(LocalStack const&) = delete;
void operator=(LocalStack const&) = delete;
friend BasicBlock;
size_t getMaxSize() const { return m_maxSize; }
/// Gets _index'th value from top (counting from 0)
llvm::Value* get(size_t _index);
private:
/// Gets _index'th value from top (counting from 0)
llvm::Value* get(size_t _index);
/// Sets _index'th value from top (counting from 0)
void set(size_t _index, llvm::Value* _value);
/// Sets _index'th value from top (counting from 0)
void set(size_t _index, llvm::Value* _value);
std::vector<llvm::Value*>::iterator getItemIterator(size_t _index);
std::vector<llvm::Value*>::iterator getItemIterator(size_t _index);
private:
BasicBlock& m_bblock;
size_t m_maxSize = 0; ///< Max size reached by the stack.
};
private:
BasicBlock& m_bblock;
Stack& m_global;
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(std::string _name, llvm::Function* _mainFunc, llvm::IRBuilder<>& _builder, bool isJumpDest);
@ -72,7 +73,7 @@ public:
llvm::Value* getJumpTarget() const { return m_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
/// to avoid excessive pushing/popping on the EVM stack.
@ -93,10 +94,6 @@ private:
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;
/// 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
/// top of the stack or changes existing items.
std::vector<llvm::Value*> m_currentStack;
friend class LocalStack;
/// How many items higher is the current stack than the initial one.
/// 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;
++iterCopy;
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:
@ -224,13 +224,13 @@ std::unique_ptr<llvm::Module> Compiler::compile(code_iterator _begin, code_itera
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
_nextBasicBlock = m_stopBB;
m_builder.SetInsertPoint(_basicBlock.llvm());
auto& stack = _basicBlock.localStack();
LocalStack stack{_basicBlock, _globalStack};
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.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 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();

Loading…
Cancel
Save