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 namespace evmcc
{ {
const char* BasicBlock::NamePrefix = "Instr.";
BasicBlock::BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc): BasicBlock::BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc):
m_beginInstIdx(_beginInstIdx), 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: public:
using State = std::vector<llvm::Value*>; using State = std::vector<llvm::Value*>;
static const char* NamePrefix;
explicit BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc); explicit BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc);
BasicBlock(const BasicBlock&) = delete; 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() void Compiler::linkBasicBlocks()
{ {
/// Helper function that finds basic block given LLVM basic block pointer /// 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) // Name is used to get basic block index (index of first instruction)
{ // TODO: If basicBlocs are still a map - multikey map can be used
if (bb.second.llvm() == _llvmBB) auto&& idxStr = _llbb->getName().substr(sizeof(BasicBlock::NamePrefix) - 2);
return &bb.second; auto idx = std::stoul(idxStr);
} return basicBlocks.find(idx)->second;
return (BasicBlock*)nullptr;
}; };
// Link basic blocks // Link basic blocks
@ -813,19 +812,16 @@ void Compiler::linkBasicBlocks()
BasicBlock& bb = p.second; BasicBlock& bb = p.second;
llvm::BasicBlock* llvmBB = bb.llvm(); llvm::BasicBlock* llvmBB = bb.llvm();
size_t i = 0; size_t valueIdx = 0;
for (auto& inst : *llvmBB) 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) auto& predBB = findBasicBlock(*predIt);
{ assert(valueIdx < predBB.getState().size()); // TODO: Report error
llvm::BasicBlock* preBB = *preIt; phi->addIncoming(*(predBB.getState().rbegin() + valueIdx), predBB);
auto pbb = findBB(preBB);
assert(i < pbb->getState().size()); // TODO: Report error
phi->addIncoming(*(pbb->getState().rbegin() + i), preBB);
}
++i;
} }
} }
} }

2
evmcc/Stack.cpp

@ -23,7 +23,7 @@ llvm::Value* BBStack::pop()
// Create PHI node // Create PHI node
auto i256Ty = llvm::Type::getIntNTy(m_block->llvm()->getContext(), 256); auto i256Ty = llvm::Type::getIntNTy(m_block->llvm()->getContext(), 256);
auto llvmBB = m_block->llvm(); 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, {}, m_block->llvm());
return llvm::PHINode::Create(i256Ty, 0, {}, llvmBB->getFirstNonPHI()); return llvm::PHINode::Create(i256Ty, 0, {}, llvmBB->getFirstNonPHI());
} }

Loading…
Cancel
Save