mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46:44 +00:00
Improve basic blocks linking implementation
This commit is contained in:
parent
7a3f3f9079
commit
16ea3bf543
4 changed files with 20 additions and 20 deletions
|
|
@ -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))
|
||||
{}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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…
Reference in a new issue