From 0cba3d90054716d6c62f1f312818ba54e553c839 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 7 Oct 2014 17:27:45 +0200 Subject: [PATCH] Improve basic blocks linking implementation --- evmcc/BasicBlock.cpp | 4 +++- evmcc/BasicBlock.h | 2 ++ evmcc/Compiler.cpp | 32 ++++++++++++++------------------ evmcc/Stack.cpp | 2 +- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/evmcc/BasicBlock.cpp b/evmcc/BasicBlock.cpp index 19e1d68ec..9bdd6d31d 100644 --- a/evmcc/BasicBlock.cpp +++ b/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)) {} } \ No newline at end of file diff --git a/evmcc/BasicBlock.h b/evmcc/BasicBlock.h index 793dfaea2..83df5da24 100644 --- a/evmcc/BasicBlock.h +++ b/evmcc/BasicBlock.h @@ -13,6 +13,8 @@ class BasicBlock public: using State = std::vector; + static const char* NamePrefix; + explicit BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc); BasicBlock(const BasicBlock&) = delete; diff --git a/evmcc/Compiler.cpp b/evmcc/Compiler.cpp index e5fe6db8b..2ae7ab1e7 100644 --- a/evmcc/Compiler.cpp +++ b/evmcc/Compiler.cpp @@ -797,14 +797,13 @@ std::unique_ptr 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(&inst)) + auto phi = llvm::cast(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); } } } diff --git a/evmcc/Stack.cpp b/evmcc/Stack.cpp index 86b39316c..fc359f103 100644 --- a/evmcc/Stack.cpp +++ b/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()); }