mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Provide end instruction to basic block
This commit is contained in:
parent
16ea3bf543
commit
b273b863b1
5 changed files with 26 additions and 31 deletions
|
|
@ -8,8 +8,9 @@ namespace evmcc
|
||||||
|
|
||||||
const char* BasicBlock::NamePrefix = "Instr.";
|
const char* BasicBlock::NamePrefix = "Instr.";
|
||||||
|
|
||||||
BasicBlock::BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc):
|
BasicBlock::BasicBlock(ProgramCounter _beginInstIdx, ProgramCounter _endInstIdx, llvm::Function* _mainFunc) :
|
||||||
m_beginInstIdx(_beginInstIdx),
|
m_beginInstIdx(_beginInstIdx),
|
||||||
|
m_endInstIdx(_endInstIdx),
|
||||||
m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {NamePrefix, std::to_string(_beginInstIdx)}, _mainFunc))
|
m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {NamePrefix, std::to_string(_beginInstIdx)}, _mainFunc))
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ public:
|
||||||
|
|
||||||
static const char* NamePrefix;
|
static const char* NamePrefix;
|
||||||
|
|
||||||
explicit BasicBlock(ProgramCounter _beginInstIdx, llvm::Function* _mainFunc);
|
explicit BasicBlock(ProgramCounter _beginInstIdx, ProgramCounter _endInstIdx, llvm::Function* _mainFunc);
|
||||||
|
|
||||||
BasicBlock(const BasicBlock&) = delete;
|
BasicBlock(const BasicBlock&) = delete;
|
||||||
void operator=(const BasicBlock&) = delete;
|
void operator=(const BasicBlock&) = delete;
|
||||||
|
|
@ -25,8 +25,11 @@ public:
|
||||||
|
|
||||||
State& getState() { return m_state; }
|
State& getState() { return m_state; }
|
||||||
|
|
||||||
|
void setEnd(ProgramCounter _endInstIdx) { m_endInstIdx = _endInstIdx; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ProgramCounter m_beginInstIdx;
|
ProgramCounter m_beginInstIdx;
|
||||||
|
ProgramCounter m_endInstIdx;
|
||||||
llvm::BasicBlock* m_llvmBB;
|
llvm::BasicBlock* m_llvmBB;
|
||||||
|
|
||||||
/// Basic black state vector - current/end values and their positions
|
/// Basic black state vector - current/end values and their positions
|
||||||
|
|
|
||||||
|
|
@ -40,20 +40,10 @@ Compiler::Compiler()
|
||||||
Types.WordLowPrecision = llvm::Type::getIntNTy(context, 64);
|
Types.WordLowPrecision = llvm::Type::getIntNTy(context, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicBlock& Compiler::getOrCreateBasicBlockAtPC(ProgramCounter pc)
|
|
||||||
{
|
|
||||||
auto blockIter = basicBlocks.find(pc);
|
|
||||||
if (blockIter == basicBlocks.end())
|
|
||||||
{
|
|
||||||
// Create a basic block at target pc directly in collection
|
|
||||||
blockIter = basicBlocks.emplace(std::piecewise_construct, std::forward_as_tuple(pc), std::forward_as_tuple(pc, m_mainFunc)).first;
|
|
||||||
}
|
|
||||||
return blockIter->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
||||||
{
|
{
|
||||||
getOrCreateBasicBlockAtPC(0); // First basic block
|
std::set<ProgramCounter> splitPoints; // Sorted collections of instruction indecies where basic blocks start/end
|
||||||
|
splitPoints.insert(0); // First basic block
|
||||||
|
|
||||||
for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr)
|
for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr)
|
||||||
{
|
{
|
||||||
|
|
@ -116,15 +106,15 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
||||||
if (next + 1 < bytecode.cend())
|
if (next + 1 < bytecode.cend())
|
||||||
{
|
{
|
||||||
ProgramCounter nextPC = (next + 1 - bytecode.cbegin());
|
ProgramCounter nextPC = (next + 1 - bytecode.cbegin());
|
||||||
getOrCreateBasicBlockAtPC(nextPC);
|
splitPoints.insert(nextPC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a block for the JUMP target.
|
// Create a block for the JUMP target.
|
||||||
ProgramCounter targetPC = val.convert_to<ProgramCounter>();
|
ProgramCounter targetPC = val.convert_to<ProgramCounter>();
|
||||||
auto& targetBlock = getOrCreateBasicBlockAtPC(targetPC);
|
splitPoints.insert(targetPC);
|
||||||
|
|
||||||
ProgramCounter jumpPC = (next - bytecode.cbegin());
|
ProgramCounter jumpPC = (next - bytecode.cbegin());
|
||||||
jumpTargets[jumpPC] = targetBlock;
|
jumpTargets[jumpPC] = targetPC;
|
||||||
|
|
||||||
curr += 1; // skip over JUMP
|
curr += 1; // skip over JUMP
|
||||||
}
|
}
|
||||||
|
|
@ -148,7 +138,7 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
||||||
if (curr + 1 < bytecode.cend())
|
if (curr + 1 < bytecode.cend())
|
||||||
{
|
{
|
||||||
ProgramCounter nextPC = (curr + 1 - bytecode.cbegin());
|
ProgramCounter nextPC = (curr + 1 - bytecode.cbegin());
|
||||||
getOrCreateBasicBlockAtPC(nextPC);
|
splitPoints.insert(nextPC);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +148,14 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getOrCreateBasicBlockAtPC(bytecode.size()); // Final basic block
|
splitPoints.insert(bytecode.size()); // For final block
|
||||||
|
for (auto it = splitPoints.cbegin(); it != splitPoints.cend();)
|
||||||
|
{
|
||||||
|
auto beginInstIdx = *it;
|
||||||
|
++it;
|
||||||
|
auto endInstIdx = it != splitPoints.cend() ? *it : beginInstIdx; // For final block
|
||||||
|
basicBlocks.emplace(std::piecewise_construct, std::forward_as_tuple(beginInstIdx), std::forward_as_tuple(beginInstIdx, endInstIdx, m_mainFunc));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
|
|
@ -572,7 +569,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
// just pop it without looking...
|
// just pop it without looking...
|
||||||
stack.pop();
|
stack.pop();
|
||||||
|
|
||||||
auto targetBlock = jumpTargets[currentPC];
|
auto& targetBlock = basicBlocks.find(jumpTargets[currentPC])->second;
|
||||||
builder.CreateBr(targetBlock);
|
builder.CreateBr(targetBlock);
|
||||||
|
|
||||||
currentBlock = nullptr;
|
currentBlock = nullptr;
|
||||||
|
|
@ -590,7 +587,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
auto top = stack.pop();
|
auto top = stack.pop();
|
||||||
auto zero = ConstantInt::get(Types.word256, 0);
|
auto zero = ConstantInt::get(Types.word256, 0);
|
||||||
auto cond = builder.CreateICmpNE(top, zero, "nonzero");
|
auto cond = builder.CreateICmpNE(top, zero, "nonzero");
|
||||||
auto targetBlock = jumpTargets[currentPC];
|
auto& targetBlock = basicBlocks.find(jumpTargets[currentPC])->second;
|
||||||
auto& followBlock = basicBlocks.find(currentPC + 1)->second;
|
auto& followBlock = basicBlocks.find(currentPC + 1)->second;
|
||||||
builder.CreateCondBr(cond, targetBlock, followBlock);
|
builder.CreateCondBr(cond, targetBlock, followBlock);
|
||||||
|
|
||||||
|
|
@ -743,12 +740,6 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
auto index = stack.pop();
|
auto index = stack.pop();
|
||||||
auto size = stack.pop();
|
auto size = stack.pop();
|
||||||
|
|
||||||
// MCJIT does not support returning structs
|
|
||||||
//auto index32 = builder.CreateTrunc(index, i32Ty, "index32");
|
|
||||||
//auto size32 = builder.CreateTrunc(size, i32Ty, "size32");
|
|
||||||
//auto ret = builder.CreateInsertValue(UndefValue::get(retType), index32, 0, "ret");
|
|
||||||
//ret = builder.CreateInsertValue(ret, size32, 1, "ret");
|
|
||||||
|
|
||||||
auto ret = builder.CreateTrunc(index, builder.getInt64Ty());
|
auto ret = builder.CreateTrunc(index, builder.getInt64Ty());
|
||||||
ret = builder.CreateShl(ret, 32);
|
ret = builder.CreateShl(ret, 32);
|
||||||
size = builder.CreateTrunc(size, i32Ty);
|
size = builder.CreateTrunc(size, i32Ty);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
BasicBlock& getOrCreateBasicBlockAtPC(ProgramCounter pc);
|
|
||||||
void createBasicBlocks(const dev::bytes& bytecode);
|
void createBasicBlocks(const dev::bytes& bytecode);
|
||||||
|
|
||||||
void linkBasicBlocks();
|
void linkBasicBlocks();
|
||||||
|
|
@ -33,16 +32,16 @@ private:
|
||||||
std::map<ProgramCounter, BasicBlock> basicBlocks;
|
std::map<ProgramCounter, BasicBlock> basicBlocks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps a pc at which there is a JUMP or JUMPI to the target block of the jump.
|
* Maps a pc at which there is a JUMP or JUMPI to the target pc of the jump.
|
||||||
*/
|
*/
|
||||||
std::map<ProgramCounter, llvm::BasicBlock*> jumpTargets;
|
std::map<ProgramCounter, ProgramCounter> jumpTargets;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Collection of basic blocks in program
|
/// Collection of basic blocks in program
|
||||||
//std::vector<BasicBlock> m_basicBlocks;
|
//std::vector<BasicBlock> m_basicBlocks;
|
||||||
|
|
||||||
/// Main program function
|
/// Main program function
|
||||||
llvm::Function* m_mainFunc;
|
llvm::Function* m_mainFunc = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ class BasicBlock;
|
||||||
Stack adapter for Basic Block
|
Stack adapter for Basic Block
|
||||||
|
|
||||||
Transforms stack to SSA: tracks values and their positions on the imaginary stack used inside a basic block.
|
Transforms stack to SSA: tracks values and their positions on the imaginary stack used inside a basic block.
|
||||||
|
TODO: Integrate into BasicBlock class
|
||||||
*/
|
*/
|
||||||
class BBStack
|
class BBStack
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue