Browse Source

Basic block compilation in separated function

cl-refactor
Paweł Bylica 10 years ago
parent
commit
1367f89b84
  1. 96
      evmcc/Compiler.cpp
  2. 2
      evmcc/Compiler.h

96
evmcc/Compiler.cpp

@ -172,8 +172,52 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
for (auto basicBlockPairIt = basicBlocks.begin(); basicBlockPairIt != basicBlocks.end(); ++basicBlockPairIt)
{
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();
m_builder.SetInsertPoint(basicBlock);
m_builder.SetInsertPoint(basicBlock.llvm());
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");
// Assume the basic blocks are properly ordered:
auto nextBBIter = basicBlockPairIt;
++nextBBIter;
assert (nextBBIter != basicBlocks.end());
auto& followBlock = nextBBIter->second;
assert(nextBasicBlock); // FIXME: JUMPI can be last instruction
if (targetBlock)
{
stack.pop();
m_builder.CreateCondBr(cond, targetBlock->llvm(), followBlock.llvm());
m_builder.CreateCondBr(cond, targetBlock->llvm(), nextBasicBlock);
}
else
{
m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), followBlock.llvm());
m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), nextBasicBlock);
}
}
@ -831,47 +872,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
else
{
// Branch to the next block.
auto iterCopy = basicBlockPairIt;
++iterCopy;
auto& next = iterCopy->second;
m_builder.CreateBr(next);
}
assert(nextBasicBlock);
m_builder.CreateBr(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;
}

2
evmcc/Compiler.h

@ -28,6 +28,8 @@ private:
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();
llvm::IRBuilder<> m_builder;

Loading…
Cancel
Save