Browse Source

Improve basic blocks linking implementation

cl-refactor
Paweł Bylica 10 years ago
parent
commit
16ea3bf543
  1. 4
      evmcc/BasicBlock.cpp
  2. 2
      evmcc/BasicBlock.h
  3. 32
      evmcc/Compiler.cpp
  4. 2
      evmcc/Stack.cpp

4
evmcc/BasicBlock.cpp

@ -6,9 +6,11 @@
namespace evmcc
{
const char* BasicBlock::NamePrefix = "Instr.";
BasicBlock::BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc):
m_beginInstIdx(_beginInstIdx),
m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {"Instr.", std::to_string(_beginInstIdx)}, _mainFunc))
m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {NamePrefix, std::to_string(_beginInstIdx)}, _mainFunc))
{}
}

2
evmcc/BasicBlock.h

@ -13,6 +13,8 @@ class BasicBlock
public:
using State = std::vector<llvm::Value*>;
static const char* NamePrefix;
explicit BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc);
BasicBlock(const BasicBlock&) = delete;

32
evmcc/Compiler.cpp

@ -797,14 +797,13 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
void Compiler::linkBasicBlocks()
{
/// Helper function that finds basic block given LLVM basic block pointer
auto findBB = [this](llvm::BasicBlock* _llvmBB)
auto findBasicBlock = [this](llvm::BasicBlock* _llbb) -> BasicBlock&
{
for (auto&& bb : basicBlocks)
{
if (bb.second.llvm() == _llvmBB)
return &bb.second;
}
return (BasicBlock*)nullptr;
// Name is used to get basic block index (index of first instruction)
// TODO: If basicBlocs are still a map - multikey map can be used
auto&& idxStr = _llbb->getName().substr(sizeof(BasicBlock::NamePrefix) - 2);
auto idx = std::stoul(idxStr);
return basicBlocks.find(idx)->second;
};
// Link basic blocks
@ -813,19 +812,16 @@ void Compiler::linkBasicBlocks()
BasicBlock& bb = p.second;
llvm::BasicBlock* llvmBB = bb.llvm();
size_t i = 0;
for (auto& inst : *llvmBB)
size_t valueIdx = 0;
auto firstNonPhi = llvmBB->getFirstNonPHI();
for (auto instIt = llvmBB->begin(); &*instIt != firstNonPhi; ++instIt, ++valueIdx)
{
if (auto phi = llvm::dyn_cast<llvm::PHINode>(&inst))
auto phi = llvm::cast<llvm::PHINode>(instIt);
for (auto predIt = llvm::pred_begin(llvmBB); predIt != llvm::pred_end(llvmBB); ++predIt)
{
for (auto preIt = llvm::pred_begin(llvmBB); preIt != llvm::pred_end(llvmBB); ++preIt)
{
llvm::BasicBlock* preBB = *preIt;
auto pbb = findBB(preBB);
assert(i < pbb->getState().size()); // TODO: Report error
phi->addIncoming(*(pbb->getState().rbegin() + i), preBB);
}
++i;
auto& predBB = findBasicBlock(*predIt);
assert(valueIdx < predBB.getState().size()); // TODO: Report error
phi->addIncoming(*(predBB.getState().rbegin() + valueIdx), predBB);
}
}
}

2
evmcc/Stack.cpp

@ -23,7 +23,7 @@ llvm::Value* BBStack::pop()
// Create PHI node
auto i256Ty = llvm::Type::getIntNTy(m_block->llvm()->getContext(), 256);
auto llvmBB = m_block->llvm();
if (llvmBB->getInstList().empty())
if (llvmBB->empty())
return llvm::PHINode::Create(i256Ty, 0, {}, m_block->llvm());
return llvm::PHINode::Create(i256Ty, 0, {}, llvmBB->getFirstNonPHI());
}

Loading…
Cancel
Save