mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 12:16: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
|
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))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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…
Reference in a new issue