mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 12:16:44 +00:00
Get IR module from IR builder
This commit is contained in:
parent
5e13d593be
commit
c83739e9dc
9 changed files with 35 additions and 30 deletions
|
|
@ -163,9 +163,9 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
||||||
createBasicBlocks(bytecode);
|
createBasicBlocks(bytecode);
|
||||||
|
|
||||||
// Init runtime structures.
|
// Init runtime structures.
|
||||||
GasMeter gasMeter(m_builder, module.get());
|
GasMeter gasMeter(m_builder);
|
||||||
Memory memory(m_builder, module.get(), gasMeter);
|
Memory memory(m_builder, gasMeter);
|
||||||
Ext ext(m_builder, module.get());
|
Ext ext(m_builder);
|
||||||
|
|
||||||
m_builder.CreateBr(basicBlocks.begin()->second);
|
m_builder.CreateBr(basicBlocks.begin()->second);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#include "CompilerHelper.h"
|
#include "CompilerHelper.h"
|
||||||
|
|
||||||
|
#include <llvm/IR/Function.h>
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
{
|
{
|
||||||
namespace eth
|
namespace eth
|
||||||
|
|
@ -8,6 +10,11 @@ namespace eth
|
||||||
namespace jit
|
namespace jit
|
||||||
{
|
{
|
||||||
|
|
||||||
|
CompilerHelper::CompilerHelper(llvm::IRBuilder<>& _builder) :
|
||||||
|
m_builder(_builder),
|
||||||
|
m_module(_builder.GetInsertBlock()->getParent()->getParent())
|
||||||
|
{}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,7 @@ namespace jit
|
||||||
class CompilerHelper
|
class CompilerHelper
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
CompilerHelper(llvm::IRBuilder<>& _builder, llvm::Module* _module):
|
CompilerHelper(llvm::IRBuilder<>& _builder);
|
||||||
m_builder(_builder),
|
|
||||||
m_module(_module)
|
|
||||||
{}
|
|
||||||
|
|
||||||
CompilerHelper(const CompilerHelper&) = delete;
|
CompilerHelper(const CompilerHelper&) = delete;
|
||||||
void operator=(CompilerHelper) = delete;
|
void operator=(CompilerHelper) = delete;
|
||||||
|
|
|
||||||
|
|
@ -43,10 +43,11 @@ struct ExtData
|
||||||
const byte* code;
|
const byte* code;
|
||||||
};
|
};
|
||||||
|
|
||||||
Ext::Ext(llvm::IRBuilder<>& _builder, llvm::Module* module):
|
Ext::Ext(llvm::IRBuilder<>& _builder):
|
||||||
CompilerHelper(_builder, module)
|
CompilerHelper(_builder)
|
||||||
{
|
{
|
||||||
auto&& ctx = _builder.getContext();
|
auto&& ctx = _builder.getContext();
|
||||||
|
auto module = m_module;
|
||||||
|
|
||||||
auto i256Ty = m_builder.getIntNTy(256);
|
auto i256Ty = m_builder.getIntNTy(256);
|
||||||
auto i256PtrTy = i256Ty->getPointerTo();
|
auto i256PtrTy = i256Ty->getPointerTo();
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ namespace jit
|
||||||
class Ext : public CompilerHelper
|
class Ext : public CompilerHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Ext(llvm::IRBuilder<>& _builder, llvm::Module* module);
|
Ext(llvm::IRBuilder<>& _builder);
|
||||||
|
|
||||||
llvm::Value* store(llvm::Value* _index);
|
llvm::Value* store(llvm::Value* _index);
|
||||||
void setStore(llvm::Value* _index, llvm::Value* _value);
|
void setStore(llvm::Value* _index, llvm::Value* _value);
|
||||||
|
|
|
||||||
|
|
@ -80,13 +80,13 @@ bool isCostBlockEnd(Instruction _inst)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module) :
|
GasMeter::GasMeter(llvm::IRBuilder<>& _builder) :
|
||||||
CompilerHelper(_builder, _module)
|
CompilerHelper(_builder)
|
||||||
{
|
{
|
||||||
m_gas = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas");
|
m_gas = new llvm::GlobalVariable(*m_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas");
|
||||||
m_gas->setUnnamedAddr(true); // Address is not important
|
m_gas->setUnnamedAddr(true); // Address is not important
|
||||||
|
|
||||||
m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", _module);
|
m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", m_module);
|
||||||
InsertPointGuard guard(m_builder);
|
InsertPointGuard guard(m_builder);
|
||||||
|
|
||||||
auto checkBB = llvm::BasicBlock::Create(_builder.getContext(), "Check", m_gasCheckFunc);
|
auto checkBB = llvm::BasicBlock::Create(_builder.getContext(), "Check", m_gasCheckFunc);
|
||||||
|
|
@ -103,9 +103,9 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module) :
|
||||||
m_builder.SetInsertPoint(outOfGasBB);
|
m_builder.SetInsertPoint(outOfGasBB);
|
||||||
|
|
||||||
//auto longjmpFunc = llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::eh_sjlj_longjmp);
|
//auto longjmpFunc = llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::eh_sjlj_longjmp);
|
||||||
auto extJmpBuf = new llvm::GlobalVariable(*_module, Type::BytePtr, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "rt_jmpBuf");
|
auto extJmpBuf = new llvm::GlobalVariable(*m_module, Type::BytePtr, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "rt_jmpBuf");
|
||||||
llvm::Type* args[] = {Type::BytePtr, m_builder.getInt32Ty()};
|
llvm::Type* args[] = {Type::BytePtr, m_builder.getInt32Ty()};
|
||||||
auto longjmpNative = llvm::Function::Create(llvm::FunctionType::get(Type::Void, args, false), llvm::Function::ExternalLinkage, "longjmp", _module);
|
auto longjmpNative = llvm::Function::Create(llvm::FunctionType::get(Type::Void, args, false), llvm::Function::ExternalLinkage, "longjmp", m_module);
|
||||||
m_builder.CreateCall2(longjmpNative, m_builder.CreateLoad(extJmpBuf), Constant::get(ReturnCode::OutOfGas));
|
m_builder.CreateCall2(longjmpNative, m_builder.CreateLoad(extJmpBuf), Constant::get(ReturnCode::OutOfGas));
|
||||||
m_builder.CreateUnreachable();
|
m_builder.CreateUnreachable();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ namespace jit
|
||||||
class GasMeter : public CompilerHelper
|
class GasMeter : public CompilerHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module);
|
GasMeter(llvm::IRBuilder<>& _builder);
|
||||||
|
|
||||||
/// Count step cost of instruction
|
/// Count step cost of instruction
|
||||||
void count(Instruction _inst);
|
void count(Instruction _inst);
|
||||||
|
|
|
||||||
|
|
@ -22,36 +22,36 @@ namespace eth
|
||||||
namespace jit
|
namespace jit
|
||||||
{
|
{
|
||||||
|
|
||||||
Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module, GasMeter& _gasMeter):
|
Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter):
|
||||||
CompilerHelper(_builder, _module)
|
CompilerHelper(_builder)
|
||||||
{
|
{
|
||||||
auto i64Ty = m_builder.getInt64Ty();
|
auto i64Ty = m_builder.getInt64Ty();
|
||||||
llvm::Type* argTypes[] = {i64Ty, i64Ty};
|
llvm::Type* argTypes[] = {i64Ty, i64Ty};
|
||||||
auto dumpTy = llvm::FunctionType::get(m_builder.getVoidTy(), llvm::ArrayRef<llvm::Type*>(argTypes), false);
|
auto dumpTy = llvm::FunctionType::get(m_builder.getVoidTy(), llvm::ArrayRef<llvm::Type*>(argTypes), false);
|
||||||
m_memDump = llvm::Function::Create(dumpTy, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
|
m_memDump = llvm::Function::Create(dumpTy, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
|
||||||
"evmccrt_memory_dump", _module);
|
"evmccrt_memory_dump", m_module);
|
||||||
|
|
||||||
m_data = new llvm::GlobalVariable(*_module, Type::BytePtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::BytePtr), "mem.data");
|
m_data = new llvm::GlobalVariable(*m_module, Type::BytePtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::BytePtr), "mem.data");
|
||||||
m_data->setUnnamedAddr(true); // Address is not important
|
m_data->setUnnamedAddr(true); // Address is not important
|
||||||
|
|
||||||
m_size = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, Constant::get(0), "mem.size");
|
m_size = new llvm::GlobalVariable(*m_module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, Constant::get(0), "mem.size");
|
||||||
m_size->setUnnamedAddr(true); // Address is not important
|
m_size->setUnnamedAddr(true); // Address is not important
|
||||||
|
|
||||||
m_returnDataOffset = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataOffset");
|
m_returnDataOffset = new llvm::GlobalVariable(*m_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataOffset");
|
||||||
m_returnDataOffset->setUnnamedAddr(true); // Address is not important
|
m_returnDataOffset->setUnnamedAddr(true); // Address is not important
|
||||||
|
|
||||||
m_returnDataSize = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataSize");
|
m_returnDataSize = new llvm::GlobalVariable(*m_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataSize");
|
||||||
m_returnDataSize->setUnnamedAddr(true); // Address is not important
|
m_returnDataSize->setUnnamedAddr(true); // Address is not important
|
||||||
|
|
||||||
m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, Type::WordPtr, false), llvm::Function::ExternalLinkage, "mem_resize", _module);
|
m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, Type::WordPtr, false), llvm::Function::ExternalLinkage, "mem_resize", m_module);
|
||||||
llvm::AttrBuilder attrBuilder;
|
llvm::AttrBuilder attrBuilder;
|
||||||
attrBuilder.addAttribute(llvm::Attribute::NoAlias).addAttribute(llvm::Attribute::NoCapture).addAttribute(llvm::Attribute::NonNull).addAttribute(llvm::Attribute::ReadOnly);
|
attrBuilder.addAttribute(llvm::Attribute::NoAlias).addAttribute(llvm::Attribute::NoCapture).addAttribute(llvm::Attribute::NonNull).addAttribute(llvm::Attribute::ReadOnly);
|
||||||
m_resize->setAttributes(llvm::AttributeSet::get(m_resize->getContext(), 1, attrBuilder));
|
m_resize->setAttributes(llvm::AttributeSet::get(m_resize->getContext(), 1, attrBuilder));
|
||||||
|
|
||||||
m_require = createRequireFunc(_module, _gasMeter);
|
m_require = createRequireFunc(m_module, _gasMeter);
|
||||||
m_loadWord = createFunc(false, Type::i256, _module, _gasMeter);
|
m_loadWord = createFunc(false, Type::i256, m_module, _gasMeter);
|
||||||
m_storeWord = createFunc(true, Type::i256, _module, _gasMeter);
|
m_storeWord = createFunc(true, Type::i256, m_module, _gasMeter);
|
||||||
m_storeByte = createFunc(true, Type::Byte, _module, _gasMeter);
|
m_storeByte = createFunc(true, Type::Byte, m_module, _gasMeter);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Function* Memory::createRequireFunc(llvm::Module* _module, GasMeter& _gasMeter)
|
llvm::Function* Memory::createRequireFunc(llvm::Module* _module, GasMeter& _gasMeter)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ namespace jit
|
||||||
class Memory : public CompilerHelper
|
class Memory : public CompilerHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module, class GasMeter& _gasMeter);
|
Memory(llvm::IRBuilder<>& _builder, class GasMeter& _gasMeter);
|
||||||
|
|
||||||
llvm::Value* loadWord(llvm::Value* _addr);
|
llvm::Value* loadWord(llvm::Value* _addr);
|
||||||
void storeWord(llvm::Value* _addr, llvm::Value* _word);
|
void storeWord(llvm::Value* _addr, llvm::Value* _word);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue