mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Basic block compilation in separated function
This commit is contained in:
parent
e094ba9e67
commit
1463897efb
2 changed files with 671 additions and 665 deletions
|
|
@ -172,8 +172,52 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
||||||
for (auto basicBlockPairIt = basicBlocks.begin(); basicBlockPairIt != basicBlocks.end(); ++basicBlockPairIt)
|
for (auto basicBlockPairIt = basicBlocks.begin(); basicBlockPairIt != basicBlocks.end(); ++basicBlockPairIt)
|
||||||
{
|
{
|
||||||
auto& basicBlock = basicBlockPairIt->second;
|
auto& basicBlock = basicBlockPairIt->second;
|
||||||
|
auto iterCopy = basicBlockPairIt;
|
||||||
|
++iterCopy;
|
||||||
|
auto nextBasicBlock = (iterCopy != basicBlocks.end()) ? iterCopy->second.llvm() : nullptr;
|
||||||
|
compileBasicBlock(basicBlock, bytecode, memory, ext, gasMeter, nextBasicBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code for special blocks:
|
||||||
|
// TODO: move to separate function.
|
||||||
|
// Note: Right now the codegen for special blocks depends only on createBasicBlock(),
|
||||||
|
// not on the codegen for 'regular' blocks. But it has to be done before linkBasicBlocks().
|
||||||
|
m_builder.SetInsertPoint(m_stopBB);
|
||||||
|
m_builder.CreateRet(Constant::get(ReturnCode::Stop));
|
||||||
|
|
||||||
|
m_builder.SetInsertPoint(m_badJumpBlock->llvm());
|
||||||
|
m_builder.CreateRet(Constant::get(ReturnCode::BadJumpDestination));
|
||||||
|
|
||||||
|
m_builder.SetInsertPoint(m_jumpTableBlock->llvm());
|
||||||
|
if (m_indirectJumpTargets.size() > 0)
|
||||||
|
{
|
||||||
|
auto& stack = m_jumpTableBlock->getStack();
|
||||||
|
|
||||||
|
auto dest = stack.pop();
|
||||||
|
auto switchInstr = m_builder.CreateSwitch(dest, m_badJumpBlock->llvm(),
|
||||||
|
m_indirectJumpTargets.size());
|
||||||
|
for (auto it = m_indirectJumpTargets.cbegin(); it != m_indirectJumpTargets.cend(); ++it)
|
||||||
|
{
|
||||||
|
auto& bb = *it;
|
||||||
|
auto dest = Constant::get(bb->begin());
|
||||||
|
switchInstr->addCase(dest, bb->llvm());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_builder.CreateBr(m_badJumpBlock->llvm());
|
||||||
|
}
|
||||||
|
|
||||||
|
linkBasicBlocks();
|
||||||
|
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Compiler::compileBasicBlock(BasicBlock& basicBlock, const bytes& bytecode, Memory& memory, Ext& ext, GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock)
|
||||||
|
{
|
||||||
auto& stack = basicBlock.getStack();
|
auto& stack = basicBlock.getStack();
|
||||||
m_builder.SetInsertPoint(basicBlock);
|
m_builder.SetInsertPoint(basicBlock.llvm());
|
||||||
|
|
||||||
for (auto currentPC = basicBlock.begin(); currentPC != basicBlock.end(); ++currentPC)
|
for (auto currentPC = basicBlock.begin(); currentPC != basicBlock.end(); ++currentPC)
|
||||||
{
|
{
|
||||||
|
|
@ -557,19 +601,16 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
||||||
auto cond = m_builder.CreateICmpNE(val, zero, "nonzero");
|
auto cond = m_builder.CreateICmpNE(val, zero, "nonzero");
|
||||||
|
|
||||||
// Assume the basic blocks are properly ordered:
|
// Assume the basic blocks are properly ordered:
|
||||||
auto nextBBIter = basicBlockPairIt;
|
assert(nextBasicBlock); // FIXME: JUMPI can be last instruction
|
||||||
++nextBBIter;
|
|
||||||
assert (nextBBIter != basicBlocks.end());
|
|
||||||
auto& followBlock = nextBBIter->second;
|
|
||||||
|
|
||||||
if (targetBlock)
|
if (targetBlock)
|
||||||
{
|
{
|
||||||
stack.pop();
|
stack.pop();
|
||||||
m_builder.CreateCondBr(cond, targetBlock->llvm(), followBlock.llvm());
|
m_builder.CreateCondBr(cond, targetBlock->llvm(), nextBasicBlock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), followBlock.llvm());
|
m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), nextBasicBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -831,49 +872,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Branch to the next block.
|
// Branch to the next block.
|
||||||
auto iterCopy = basicBlockPairIt;
|
assert(nextBasicBlock);
|
||||||
++iterCopy;
|
m_builder.CreateBr(nextBasicBlock);
|
||||||
auto& next = iterCopy->second;
|
|
||||||
m_builder.CreateBr(next);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code for special blocks:
|
|
||||||
// TODO: move to separate function.
|
|
||||||
// Note: Right now the codegen for special blocks depends only on createBasicBlock(),
|
|
||||||
// not on the codegen for 'regular' blocks. But it has to be done before linkBasicBlocks().
|
|
||||||
m_builder.SetInsertPoint(m_stopBB);
|
|
||||||
m_builder.CreateRet(Constant::get(ReturnCode::Stop));
|
|
||||||
|
|
||||||
m_builder.SetInsertPoint(m_badJumpBlock->llvm());
|
|
||||||
m_builder.CreateRet(Constant::get(ReturnCode::BadJumpDestination));
|
|
||||||
|
|
||||||
m_builder.SetInsertPoint(m_jumpTableBlock->llvm());
|
|
||||||
if (m_indirectJumpTargets.size() > 0)
|
|
||||||
{
|
|
||||||
auto& stack = m_jumpTableBlock->getStack();
|
|
||||||
|
|
||||||
auto dest = stack.pop();
|
|
||||||
auto switchInstr = m_builder.CreateSwitch(dest, m_badJumpBlock->llvm(),
|
|
||||||
m_indirectJumpTargets.size());
|
|
||||||
for (auto it = m_indirectJumpTargets.cbegin(); it != m_indirectJumpTargets.cend(); ++it)
|
|
||||||
{
|
|
||||||
auto& bb = *it;
|
|
||||||
auto dest = Constant::get(bb->begin());
|
|
||||||
switchInstr->addCase(dest, bb->llvm());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_builder.CreateBr(m_badJumpBlock->llvm());
|
|
||||||
}
|
|
||||||
|
|
||||||
linkBasicBlocks();
|
|
||||||
|
|
||||||
return module;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Compiler::linkBasicBlocks()
|
void Compiler::linkBasicBlocks()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@ private:
|
||||||
|
|
||||||
void createBasicBlocks(const bytes& bytecode);
|
void createBasicBlocks(const bytes& bytecode);
|
||||||
|
|
||||||
|
void compileBasicBlock(BasicBlock& basicBlock, const bytes& bytecode, class Memory& memory, class Ext& ext, class GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock);
|
||||||
|
|
||||||
void linkBasicBlocks();
|
void linkBasicBlocks();
|
||||||
|
|
||||||
llvm::IRBuilder<> m_builder;
|
llvm::IRBuilder<> m_builder;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue