|
|
@ -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) |
|
|
|
{ |
|
|
|
using dev::eth::Instruction; |
|
|
|
auto& basicBlock = basicBlockPairIt->second; |
|
|
|
|
|
|
|
ProgramCounter currentPC = pc - bytecode.cbegin(); |
|
|
|
BBStack stack; |
|
|
|
stack.setBasicBlock(basicBlock); |
|
|
|
builder.SetInsertPoint(basicBlock); |
|
|
|
|
|
|
|
// Change basic block
|
|
|
|
auto blockIter = basicBlocks.find(currentPC); |
|
|
|
if (blockIter != basicBlocks.end()) |
|
|
|
for (auto currentPC = basicBlock.begin(); currentPC != basicBlock.end(); ++currentPC) |
|
|
|
{ |
|
|
|
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); |
|
|
|
using dev::eth::Instruction; |
|
|
|
auto inst = static_cast<Instruction>(bytecode[currentPC]); |
|
|
|
switch (inst) |
|
|
|
{ |
|
|
|
|
|
|
@ -463,9 +452,9 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode) |
|
|
|
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); |
|
|
@ -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(); |
|
|
|
|
|
|
|