mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46:44 +00:00
Placing IRBuilder in Compiler class (for future refactoring)
This commit is contained in:
parent
5586ff5bdc
commit
e094ba9e67
2 changed files with 90 additions and 91 deletions
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/IR/CFG.h>
|
||||
#include <llvm/ADT/PostOrderIterator.h>
|
||||
#include <llvm/IR/IntrinsicInst.h>
|
||||
|
|
@ -23,10 +23,10 @@ namespace eth
|
|||
namespace jit
|
||||
{
|
||||
|
||||
Compiler::Compiler()
|
||||
: m_badJumpBlock(nullptr)
|
||||
Compiler::Compiler():
|
||||
m_builder(llvm::getGlobalContext())
|
||||
{
|
||||
Type::init(llvm::getGlobalContext());
|
||||
Type::init(m_builder.getContext());
|
||||
}
|
||||
|
||||
void Compiler::createBasicBlocks(const bytes& bytecode)
|
||||
|
|
@ -151,31 +151,29 @@ void Compiler::createBasicBlocks(const bytes& bytecode)
|
|||
|
||||
std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
||||
{
|
||||
auto& context = llvm::getGlobalContext();
|
||||
auto module = std::make_unique<llvm::Module>("main", context);
|
||||
llvm::IRBuilder<> builder(context);
|
||||
auto module = std::make_unique<llvm::Module>("main", m_builder.getContext());
|
||||
|
||||
// Create main function
|
||||
m_mainFunc = llvm::Function::Create(llvm::FunctionType::get(Type::MainReturn, false), llvm::Function::ExternalLinkage, "main", module.get());
|
||||
|
||||
// Create the basic blocks.
|
||||
auto entryBlock = llvm::BasicBlock::Create(context, "entry", m_mainFunc);
|
||||
builder.SetInsertPoint(entryBlock);
|
||||
auto entryBlock = llvm::BasicBlock::Create(m_builder.getContext(), "entry", m_mainFunc);
|
||||
m_builder.SetInsertPoint(entryBlock);
|
||||
|
||||
createBasicBlocks(bytecode);
|
||||
|
||||
// Init runtime structures.
|
||||
GasMeter gasMeter(builder, module.get());
|
||||
Memory memory(builder, module.get(), gasMeter);
|
||||
Ext ext(builder, module.get());
|
||||
GasMeter gasMeter(m_builder, module.get());
|
||||
Memory memory(m_builder, module.get(), gasMeter);
|
||||
Ext ext(m_builder, module.get());
|
||||
|
||||
builder.CreateBr(basicBlocks.begin()->second);
|
||||
m_builder.CreateBr(basicBlocks.begin()->second);
|
||||
|
||||
for (auto basicBlockPairIt = basicBlocks.begin(); basicBlockPairIt != basicBlocks.end(); ++basicBlockPairIt)
|
||||
{
|
||||
auto& basicBlock = basicBlockPairIt->second;
|
||||
auto& stack = basicBlock.getStack();
|
||||
builder.SetInsertPoint(basicBlock);
|
||||
m_builder.SetInsertPoint(basicBlock);
|
||||
|
||||
for (auto currentPC = basicBlock.begin(); currentPC != basicBlock.end(); ++currentPC)
|
||||
{
|
||||
|
|
@ -190,7 +188,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto result = builder.CreateAdd(lhs, rhs);
|
||||
auto result = m_builder.CreateAdd(lhs, rhs);
|
||||
stack.push(result);
|
||||
break;
|
||||
}
|
||||
|
|
@ -199,7 +197,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto result = builder.CreateSub(lhs, rhs);
|
||||
auto result = m_builder.CreateSub(lhs, rhs);
|
||||
stack.push(result);
|
||||
break;
|
||||
}
|
||||
|
|
@ -208,10 +206,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs256 = stack.pop();
|
||||
auto rhs256 = stack.pop();
|
||||
auto lhs128 = builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = builder.CreateMul(lhs128, rhs128);
|
||||
auto res256 = builder.CreateZExt(res128, Type::i256);
|
||||
auto lhs128 = m_builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = m_builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = m_builder.CreateMul(lhs128, rhs128);
|
||||
auto res256 = m_builder.CreateZExt(res128, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -220,10 +218,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs256 = stack.pop();
|
||||
auto rhs256 = stack.pop();
|
||||
auto lhs128 = builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = builder.CreateUDiv(lhs128, rhs128);
|
||||
auto res256 = builder.CreateZExt(res128, Type::i256);
|
||||
auto lhs128 = m_builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = m_builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = m_builder.CreateUDiv(lhs128, rhs128);
|
||||
auto res256 = m_builder.CreateZExt(res128, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -232,10 +230,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs256 = stack.pop();
|
||||
auto rhs256 = stack.pop();
|
||||
auto lhs128 = builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = builder.CreateSDiv(lhs128, rhs128);
|
||||
auto res256 = builder.CreateSExt(res128, Type::i256);
|
||||
auto lhs128 = m_builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = m_builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = m_builder.CreateSDiv(lhs128, rhs128);
|
||||
auto res256 = m_builder.CreateSExt(res128, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -244,10 +242,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs256 = stack.pop();
|
||||
auto rhs256 = stack.pop();
|
||||
auto lhs128 = builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = builder.CreateURem(lhs128, rhs128);
|
||||
auto res256 = builder.CreateZExt(res128, Type::i256);
|
||||
auto lhs128 = m_builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = m_builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = m_builder.CreateURem(lhs128, rhs128);
|
||||
auto res256 = m_builder.CreateZExt(res128, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -256,10 +254,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs256 = stack.pop();
|
||||
auto rhs256 = stack.pop();
|
||||
auto lhs128 = builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = builder.CreateSRem(lhs128, rhs128);
|
||||
auto res256 = builder.CreateSExt(res128, Type::i256);
|
||||
auto lhs128 = m_builder.CreateTrunc(lhs256, Type::lowPrecision);
|
||||
auto rhs128 = m_builder.CreateTrunc(rhs256, Type::lowPrecision);
|
||||
auto res128 = m_builder.CreateSRem(lhs128, rhs128);
|
||||
auto res256 = m_builder.CreateSExt(res128, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -277,7 +275,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto top = stack.pop();
|
||||
auto zero = Constant::get(0);
|
||||
auto res = builder.CreateSub(zero, top);
|
||||
auto res = m_builder.CreateSub(zero, top);
|
||||
stack.push(res);
|
||||
break;
|
||||
}
|
||||
|
|
@ -286,8 +284,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto res1 = builder.CreateICmpULT(lhs, rhs);
|
||||
auto res256 = builder.CreateZExt(res1, Type::i256);
|
||||
auto res1 = m_builder.CreateICmpULT(lhs, rhs);
|
||||
auto res256 = m_builder.CreateZExt(res1, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -296,8 +294,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto res1 = builder.CreateICmpUGT(lhs, rhs);
|
||||
auto res256 = builder.CreateZExt(res1, Type::i256);
|
||||
auto res1 = m_builder.CreateICmpUGT(lhs, rhs);
|
||||
auto res256 = m_builder.CreateZExt(res1, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -306,8 +304,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto res1 = builder.CreateICmpSLT(lhs, rhs);
|
||||
auto res256 = builder.CreateZExt(res1, Type::i256);
|
||||
auto res1 = m_builder.CreateICmpSLT(lhs, rhs);
|
||||
auto res256 = m_builder.CreateZExt(res1, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -316,8 +314,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto res1 = builder.CreateICmpSGT(lhs, rhs);
|
||||
auto res256 = builder.CreateZExt(res1, Type::i256);
|
||||
auto res1 = m_builder.CreateICmpSGT(lhs, rhs);
|
||||
auto res256 = m_builder.CreateZExt(res1, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -326,8 +324,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto res1 = builder.CreateICmpEQ(lhs, rhs);
|
||||
auto res256 = builder.CreateZExt(res1, Type::i256);
|
||||
auto res1 = m_builder.CreateICmpEQ(lhs, rhs);
|
||||
auto res256 = m_builder.CreateZExt(res1, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -335,9 +333,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
case Instruction::NOT:
|
||||
{
|
||||
auto top = stack.pop();
|
||||
auto zero = Constant::get(0);
|
||||
auto iszero = builder.CreateICmpEQ(top, zero, "iszero");
|
||||
auto result = builder.CreateZExt(iszero, Type::i256);
|
||||
auto iszero = m_builder.CreateICmpEQ(top, Constant::get(0), "iszero");
|
||||
auto result = m_builder.CreateZExt(iszero, Type::i256);
|
||||
stack.push(result);
|
||||
break;
|
||||
}
|
||||
|
|
@ -346,7 +343,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto res = builder.CreateAnd(lhs, rhs);
|
||||
auto res = m_builder.CreateAnd(lhs, rhs);
|
||||
stack.push(res);
|
||||
break;
|
||||
}
|
||||
|
|
@ -355,7 +352,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto res = builder.CreateOr(lhs, rhs);
|
||||
auto res = m_builder.CreateOr(lhs, rhs);
|
||||
stack.push(res);
|
||||
break;
|
||||
}
|
||||
|
|
@ -364,7 +361,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto lhs = stack.pop();
|
||||
auto rhs = stack.pop();
|
||||
auto res = builder.CreateXor(lhs, rhs);
|
||||
auto res = m_builder.CreateXor(lhs, rhs);
|
||||
stack.push(res);
|
||||
break;
|
||||
}
|
||||
|
|
@ -386,12 +383,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
|
||||
// TODO: Shifting by 0 gives wrong results as of this bug http://llvm.org/bugs/show_bug.cgi?id=16439
|
||||
|
||||
auto shbits = builder.CreateShl(byteNum, Constant::get(3));
|
||||
value = builder.CreateShl(value, shbits);
|
||||
value = builder.CreateLShr(value, Constant::get(31 * 8));
|
||||
auto shbits = m_builder.CreateShl(byteNum, Constant::get(3));
|
||||
value = m_builder.CreateShl(value, shbits);
|
||||
value = m_builder.CreateLShr(value, Constant::get(31 * 8));
|
||||
|
||||
auto byteNumValid = builder.CreateICmpULT(byteNum, Constant::get(32));
|
||||
value = builder.CreateSelect(byteNumValid, value, Constant::get(0));
|
||||
auto byteNumValid = m_builder.CreateICmpULT(byteNum, Constant::get(32));
|
||||
value = m_builder.CreateSelect(byteNumValid, value, Constant::get(0));
|
||||
stack.push(value);
|
||||
|
||||
break;
|
||||
|
|
@ -401,13 +398,13 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto val1 = stack.pop();
|
||||
auto val2 = stack.pop();
|
||||
auto sum = builder.CreateAdd(val1, val2);
|
||||
auto sum = m_builder.CreateAdd(val1, val2);
|
||||
auto mod = stack.pop();
|
||||
|
||||
auto sum128 = builder.CreateTrunc(sum, Type::lowPrecision);
|
||||
auto mod128 = builder.CreateTrunc(mod, Type::lowPrecision);
|
||||
auto res128 = builder.CreateURem(sum128, mod128);
|
||||
auto res256 = builder.CreateZExt(res128, Type::i256);
|
||||
auto sum128 = m_builder.CreateTrunc(sum, Type::lowPrecision);
|
||||
auto mod128 = m_builder.CreateTrunc(mod, Type::lowPrecision);
|
||||
auto res128 = m_builder.CreateURem(sum128, mod128);
|
||||
auto res256 = m_builder.CreateZExt(res128, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -416,13 +413,13 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
{
|
||||
auto val1 = stack.pop();
|
||||
auto val2 = stack.pop();
|
||||
auto prod = builder.CreateMul(val1, val2);
|
||||
auto prod = m_builder.CreateMul(val1, val2);
|
||||
auto mod = stack.pop();
|
||||
|
||||
auto prod128 = builder.CreateTrunc(prod, Type::lowPrecision);
|
||||
auto mod128 = builder.CreateTrunc(mod, Type::lowPrecision);
|
||||
auto res128 = builder.CreateURem(prod128, mod128);
|
||||
auto res256 = builder.CreateZExt(res128, Type::i256);
|
||||
auto prod128 = m_builder.CreateTrunc(prod, Type::lowPrecision);
|
||||
auto mod128 = m_builder.CreateTrunc(mod, Type::lowPrecision);
|
||||
auto res128 = m_builder.CreateURem(prod128, mod128);
|
||||
auto res256 = m_builder.CreateZExt(res128, Type::i256);
|
||||
stack.push(res256);
|
||||
break;
|
||||
}
|
||||
|
|
@ -452,7 +449,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
value <<= 8;
|
||||
value |= bytecode[currentPC];
|
||||
}
|
||||
auto c = builder.getInt(value);
|
||||
auto c = m_builder.getInt(value);
|
||||
stack.push(c);
|
||||
break;
|
||||
}
|
||||
|
|
@ -543,13 +540,13 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
// The target address is computed at compile time,
|
||||
// just pop it without looking...
|
||||
stack.pop();
|
||||
builder.CreateBr(targetBlock->llvm());
|
||||
m_builder.CreateBr(targetBlock->llvm());
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: this get(0) is a temporary workaround to get some of the jump tests running.
|
||||
stack.get(0);
|
||||
builder.CreateBr(m_jumpTableBlock->llvm());
|
||||
m_builder.CreateBr(m_jumpTableBlock->llvm());
|
||||
}
|
||||
}
|
||||
else // JUMPI
|
||||
|
|
@ -557,7 +554,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
stack.swap(1);
|
||||
auto val = stack.pop();
|
||||
auto zero = Constant::get(0);
|
||||
auto cond = builder.CreateICmpNE(val, zero, "nonzero");
|
||||
auto cond = m_builder.CreateICmpNE(val, zero, "nonzero");
|
||||
|
||||
// Assume the basic blocks are properly ordered:
|
||||
auto nextBBIter = basicBlockPairIt;
|
||||
|
|
@ -568,11 +565,11 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
if (targetBlock)
|
||||
{
|
||||
stack.pop();
|
||||
builder.CreateCondBr(cond, targetBlock->llvm(), followBlock.llvm());
|
||||
m_builder.CreateCondBr(cond, targetBlock->llvm(), followBlock.llvm());
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), followBlock.llvm());
|
||||
m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), followBlock.llvm());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -780,10 +777,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
gasMeter.commitCostBlock(gas);
|
||||
|
||||
// Require memory for the max of in and out buffers
|
||||
auto inSizeReq = builder.CreateAdd(inOff, inSize, "inSizeReq");
|
||||
auto outSizeReq = builder.CreateAdd(outOff, outSize, "outSizeReq");
|
||||
auto cmp = builder.CreateICmpUGT(inSizeReq, outSizeReq);
|
||||
auto sizeReq = builder.CreateSelect(cmp, inSizeReq, outSizeReq, "sizeReq");
|
||||
auto inSizeReq = m_builder.CreateAdd(inOff, inSize, "inSizeReq");
|
||||
auto outSizeReq = m_builder.CreateAdd(outOff, outSize, "outSizeReq");
|
||||
auto cmp = m_builder.CreateICmpUGT(inSizeReq, outSizeReq);
|
||||
auto sizeReq = m_builder.CreateSelect(cmp, inSizeReq, outSizeReq, "sizeReq");
|
||||
memory.require(sizeReq);
|
||||
|
||||
auto receiveAddress = codeAddress;
|
||||
|
|
@ -803,7 +800,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
|
||||
memory.registerReturnData(index, size);
|
||||
|
||||
builder.CreateRet(Constant::get(ReturnCode::Return));
|
||||
m_builder.CreateRet(Constant::get(ReturnCode::Return));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -815,7 +812,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
}
|
||||
case Instruction::STOP:
|
||||
{
|
||||
builder.CreateRet(Constant::get(ReturnCode::Stop));
|
||||
m_builder.CreateRet(Constant::get(ReturnCode::Stop));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -824,12 +821,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
|
||||
gasMeter.commitCostBlock();
|
||||
|
||||
if (!builder.GetInsertBlock()->getTerminator()) // If block not terminated
|
||||
if (!m_builder.GetInsertBlock()->getTerminator()) // If block not terminated
|
||||
{
|
||||
if (basicBlock.end() == bytecode.size())
|
||||
{
|
||||
// Return STOP code
|
||||
builder.CreateRet(Constant::get(ReturnCode::Stop));
|
||||
m_builder.CreateRet(Constant::get(ReturnCode::Stop));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -837,7 +834,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
auto iterCopy = basicBlockPairIt;
|
||||
++iterCopy;
|
||||
auto& next = iterCopy->second;
|
||||
builder.CreateBr(next);
|
||||
m_builder.CreateBr(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -846,19 +843,19 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
// 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().
|
||||
builder.SetInsertPoint(m_stopBB);
|
||||
builder.CreateRet(Constant::get(ReturnCode::Stop));
|
||||
m_builder.SetInsertPoint(m_stopBB);
|
||||
m_builder.CreateRet(Constant::get(ReturnCode::Stop));
|
||||
|
||||
builder.SetInsertPoint(m_badJumpBlock->llvm());
|
||||
builder.CreateRet(Constant::get(ReturnCode::BadJumpDestination));
|
||||
m_builder.SetInsertPoint(m_badJumpBlock->llvm());
|
||||
m_builder.CreateRet(Constant::get(ReturnCode::BadJumpDestination));
|
||||
|
||||
builder.SetInsertPoint(m_jumpTableBlock->llvm());
|
||||
m_builder.SetInsertPoint(m_jumpTableBlock->llvm());
|
||||
if (m_indirectJumpTargets.size() > 0)
|
||||
{
|
||||
auto& stack = m_jumpTableBlock->getStack();
|
||||
|
||||
auto dest = stack.pop();
|
||||
auto switchInstr = builder.CreateSwitch(dest, m_badJumpBlock->llvm(),
|
||||
auto switchInstr = m_builder.CreateSwitch(dest, m_badJumpBlock->llvm(),
|
||||
m_indirectJumpTargets.size());
|
||||
for (auto it = m_indirectJumpTargets.cbegin(); it != m_indirectJumpTargets.cend(); ++it)
|
||||
{
|
||||
|
|
@ -869,7 +866,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
}
|
||||
else
|
||||
{
|
||||
builder.CreateBr(m_badJumpBlock->llvm());
|
||||
m_builder.CreateBr(m_badJumpBlock->llvm());
|
||||
}
|
||||
|
||||
linkBasicBlocks();
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <llvm/IR/Module.h>
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
|
||||
#include <libdevcore/Common.h>
|
||||
|
||||
|
|
@ -30,6 +30,8 @@ private:
|
|||
|
||||
void linkBasicBlocks();
|
||||
|
||||
llvm::IRBuilder<> m_builder;
|
||||
|
||||
/**
|
||||
* Maps a program counter pc to a basic block that starts at pc (if any).
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue