mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Cleanup Compiler
This commit is contained in:
parent
b273b863b1
commit
bb1954089c
2 changed files with 569 additions and 580 deletions
|
|
@ -25,7 +25,8 @@ public:
|
|||
|
||||
State& getState() { return m_state; }
|
||||
|
||||
void setEnd(ProgramCounter _endInstIdx) { m_endInstIdx = _endInstIdx; }
|
||||
ProgramCounter begin() { return m_beginInstIdx; }
|
||||
ProgramCounter end() { return m_endInstIdx; }
|
||||
|
||||
private:
|
||||
ProgramCounter m_beginInstIdx;
|
||||
|
|
|
|||
|
|
@ -181,32 +181,21 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
auto memory = Memory(builder, module.get());
|
||||
auto ext = Ext(builder, module.get());
|
||||
|
||||
BasicBlock* currentBlock = &basicBlocks.find(0)->second; // Any value, just to create branch for %entry to %Instr.0
|
||||
BBStack stack; // Stack for current block
|
||||
// Jump to first instruction
|
||||
builder.CreateBr(basicBlocks.begin()->second);
|
||||
|
||||
for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc)
|
||||
for (auto basicBlockPairIt = basicBlocks.begin(); basicBlockPairIt != basicBlocks.end(); ++basicBlockPairIt)
|
||||
{
|
||||
auto& basicBlock = basicBlockPairIt->second;
|
||||
|
||||
BBStack stack;
|
||||
stack.setBasicBlock(basicBlock);
|
||||
builder.SetInsertPoint(basicBlock);
|
||||
|
||||
for (auto currentPC = basicBlock.begin(); currentPC != basicBlock.end(); ++currentPC)
|
||||
{
|
||||
using dev::eth::Instruction;
|
||||
|
||||
ProgramCounter currentPC = pc - bytecode.cbegin();
|
||||
|
||||
// Change basic block
|
||||
auto blockIter = basicBlocks.find(currentPC);
|
||||
if (blockIter != basicBlocks.end())
|
||||
{
|
||||
auto& nextBlock = blockIter->second;
|
||||
// Terminate the current block by jumping to the next one.
|
||||
if (currentBlock != nullptr)
|
||||
builder.CreateBr(nextBlock);
|
||||
// Insert the next block into the main function.
|
||||
builder.SetInsertPoint(nextBlock);
|
||||
currentBlock = &nextBlock;
|
||||
stack.setBasicBlock(*currentBlock);
|
||||
}
|
||||
|
||||
assert(currentBlock != nullptr);
|
||||
|
||||
auto inst = static_cast<Instruction>(*pc);
|
||||
auto inst = static_cast<Instruction>(bytecode[currentPC]);
|
||||
switch (inst)
|
||||
{
|
||||
|
||||
|
|
@ -459,13 +448,13 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
case Instruction::PUSH31:
|
||||
case Instruction::PUSH32:
|
||||
{
|
||||
auto numBytes = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::PUSH1) + 1;
|
||||
auto numBytes = static_cast<size_t>(inst)-static_cast<size_t>(Instruction::PUSH1) + 1;
|
||||
auto value = llvm::APInt(256, 0);
|
||||
for (decltype(numBytes) i = 0; i < numBytes; ++i) // TODO: Use pc as iterator
|
||||
{
|
||||
++pc;
|
||||
++currentPC;
|
||||
value <<= 8;
|
||||
value |= *pc;
|
||||
value |= bytecode[currentPC];
|
||||
}
|
||||
auto c = builder.getInt(value);
|
||||
stack.push(c);
|
||||
|
|
@ -489,7 +478,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
case Instruction::DUP15:
|
||||
case Instruction::DUP16:
|
||||
{
|
||||
auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::DUP1);
|
||||
auto index = static_cast<size_t>(inst)-static_cast<size_t>(Instruction::DUP1);
|
||||
stack.dup(index);
|
||||
break;
|
||||
}
|
||||
|
|
@ -511,7 +500,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
case Instruction::SWAP15:
|
||||
case Instruction::SWAP16:
|
||||
{
|
||||
auto index = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::SWAP1) + 1;
|
||||
auto index = static_cast<size_t>(inst)-static_cast<size_t>(Instruction::SWAP1) + 1;
|
||||
stack.swap(index);
|
||||
break;
|
||||
}
|
||||
|
|
@ -571,14 +560,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
|
||||
auto& targetBlock = basicBlocks.find(jumpTargets[currentPC])->second;
|
||||
builder.CreateBr(targetBlock);
|
||||
|
||||
currentBlock = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
case Instruction::JUMPI:
|
||||
{
|
||||
assert(pc + 1 < bytecode.cend());
|
||||
assert(currentPC + 1 < bytecode.size());
|
||||
|
||||
// The target address is computed at compile time,
|
||||
// just pop it without looking...
|
||||
|
|
@ -590,8 +577,6 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
auto& targetBlock = basicBlocks.find(jumpTargets[currentPC])->second;
|
||||
auto& followBlock = basicBlocks.find(currentPC + 1)->second;
|
||||
builder.CreateCondBr(cond, targetBlock, followBlock);
|
||||
|
||||
currentBlock = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -747,7 +732,6 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
ret = builder.CreateOr(ret, size);
|
||||
|
||||
builder.CreateRet(ret);
|
||||
currentBlock = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -760,24 +744,28 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
case Instruction::STOP:
|
||||
{
|
||||
builder.CreateRet(builder.getInt64(0));
|
||||
currentBlock = nullptr;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Generate the final basic block.
|
||||
auto finalPC = bytecode.size();
|
||||
auto it = basicBlocks.find(finalPC);
|
||||
assert(it != basicBlocks.end());
|
||||
auto& finalBlock = it->second;
|
||||
|
||||
if (currentBlock != nullptr)
|
||||
builder.CreateBr(finalBlock);
|
||||
|
||||
builder.SetInsertPoint(finalBlock);
|
||||
if (!builder.GetInsertBlock()->getTerminator()) // If block not terminated
|
||||
{
|
||||
if (basicBlock.begin() == bytecode.size()) // Special final block
|
||||
{
|
||||
builder.CreateRet(builder.getInt64(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
auto iterCopy = basicBlockPairIt;
|
||||
++iterCopy;
|
||||
auto& next = iterCopy->second;
|
||||
builder.CreateBr(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
linkBasicBlocks();
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue