Browse Source

Get IR module from IR builder on demand

cl-refactor
Paweł Bylica 11 years ago
parent
commit
8eea4752b2
  1. 10
      evmcc/CompilerHelper.cpp
  2. 6
      evmcc/CompilerHelper.h
  3. 2
      evmcc/Ext.cpp
  4. 9
      evmcc/GasMeter.cpp
  5. 29
      evmcc/Memory.cpp
  6. 4
      evmcc/Memory.h

10
evmcc/CompilerHelper.cpp

@ -11,10 +11,16 @@ namespace jit
{ {
CompilerHelper::CompilerHelper(llvm::IRBuilder<>& _builder) : CompilerHelper::CompilerHelper(llvm::IRBuilder<>& _builder) :
m_builder(_builder), m_builder(_builder)
m_module(_builder.GetInsertBlock()->getParent()->getParent())
{} {}
llvm::Module* CompilerHelper::getModule()
{
assert(m_builder.GetInsertBlock());
assert(m_builder.GetInsertBlock()->getParent()); // BB must be in a function
return m_builder.GetInsertBlock()->getParent()->getParent();
}
} }
} }
} }

6
evmcc/CompilerHelper.h

@ -19,11 +19,11 @@ protected:
CompilerHelper(const CompilerHelper&) = delete; CompilerHelper(const CompilerHelper&) = delete;
void operator=(CompilerHelper) = delete; void operator=(CompilerHelper) = delete;
/// Reference to the IR module being compiled
llvm::Module* getModule();
/// Reference to parent compiler IR builder /// Reference to parent compiler IR builder
llvm::IRBuilder<>& m_builder; llvm::IRBuilder<>& m_builder;
/// Reference to the IR module being compiled
llvm::Module* m_module;
}; };
} }

2
evmcc/Ext.cpp

@ -47,7 +47,7 @@ Ext::Ext(llvm::IRBuilder<>& _builder):
CompilerHelper(_builder) CompilerHelper(_builder)
{ {
auto&& ctx = _builder.getContext(); auto&& ctx = _builder.getContext();
auto module = m_module; auto module = getModule();
auto i256Ty = m_builder.getIntNTy(256); auto i256Ty = m_builder.getIntNTy(256);
auto i256PtrTy = i256Ty->getPointerTo(); auto i256PtrTy = i256Ty->getPointerTo();

9
evmcc/GasMeter.cpp

@ -83,10 +83,11 @@ bool isCostBlockEnd(Instruction _inst)
GasMeter::GasMeter(llvm::IRBuilder<>& _builder) : GasMeter::GasMeter(llvm::IRBuilder<>& _builder) :
CompilerHelper(_builder) CompilerHelper(_builder)
{ {
m_gas = new llvm::GlobalVariable(*m_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas"); auto module = getModule();
m_gas = new llvm::GlobalVariable(*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", m_module); m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "gas.check", 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 +104,9 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder) :
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(*m_module, Type::BytePtr, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "rt_jmpBuf"); auto extJmpBuf = new llvm::GlobalVariable(*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", m_module); auto longjmpNative = llvm::Function::Create(llvm::FunctionType::get(Type::Void, args, false), llvm::Function::ExternalLinkage, "longjmp", 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();

29
evmcc/Memory.cpp

@ -25,38 +25,39 @@ namespace jit
Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter): Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter):
CompilerHelper(_builder) CompilerHelper(_builder)
{ {
auto module = getModule();
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", m_module); "evmccrt_memory_dump", module);
m_data = new llvm::GlobalVariable(*m_module, Type::BytePtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::BytePtr), "mem.data"); m_data = new llvm::GlobalVariable(*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(*m_module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, Constant::get(0), "mem.size"); m_size = new llvm::GlobalVariable(*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(*m_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataOffset"); m_returnDataOffset = new llvm::GlobalVariable(*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(*m_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataSize"); m_returnDataSize = new llvm::GlobalVariable(*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", m_module); m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, Type::WordPtr, false), llvm::Function::ExternalLinkage, "mem_resize", 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(m_module, _gasMeter); m_require = createRequireFunc(_gasMeter);
m_loadWord = createFunc(false, Type::i256, m_module, _gasMeter); m_loadWord = createFunc(false, Type::i256, _gasMeter);
m_storeWord = createFunc(true, Type::i256, m_module, _gasMeter); m_storeWord = createFunc(true, Type::i256, _gasMeter);
m_storeByte = createFunc(true, Type::Byte, m_module, _gasMeter); m_storeByte = createFunc(true, Type::Byte, _gasMeter);
} }
llvm::Function* Memory::createRequireFunc(llvm::Module* _module, GasMeter& _gasMeter) llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter)
{ {
auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "mem.require", _module); auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "mem.require", getModule());
auto checkBB = llvm::BasicBlock::Create(func->getContext(), "check", func); auto checkBB = llvm::BasicBlock::Create(func->getContext(), "check", func);
auto resizeBB = llvm::BasicBlock::Create(func->getContext(), "resize", func); auto resizeBB = llvm::BasicBlock::Create(func->getContext(), "resize", func);
@ -91,14 +92,14 @@ llvm::Function* Memory::createRequireFunc(llvm::Module* _module, GasMeter& _gasM
return func; return func;
} }
llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, llvm::Module* _module, GasMeter& _gasMeter) llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMeter& _gasMeter)
{ {
auto isWord = _valueType == Type::i256; auto isWord = _valueType == Type::i256;
llvm::Type* storeArgs[] = {Type::i256, _valueType}; llvm::Type* storeArgs[] = {Type::i256, _valueType};
auto name = _isStore ? isWord ? "mstore" : "mstore8" : "mload"; auto name = _isStore ? isWord ? "mstore" : "mstore8" : "mload";
auto funcType = _isStore ? llvm::FunctionType::get(Type::Void, storeArgs, false) : llvm::FunctionType::get(Type::i256, Type::i256, false); auto funcType = _isStore ? llvm::FunctionType::get(Type::Void, storeArgs, false) : llvm::FunctionType::get(Type::i256, Type::i256, false);
auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, _module); auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, getModule());
InsertPointGuard guard(m_builder); // Restores insert point at function exit InsertPointGuard guard(m_builder); // Restores insert point at function exit

4
evmcc/Memory.h

@ -36,8 +36,8 @@ public:
void dump(uint64_t _begin, uint64_t _end = 0); void dump(uint64_t _begin, uint64_t _end = 0);
private: private:
llvm::Function* createFunc(bool _isStore, llvm::Type* _type, llvm::Module* _module, GasMeter& _gasMeter); llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter);
llvm::Function* createRequireFunc(llvm::Module* _module, GasMeter& _gasMeter); llvm::Function* createRequireFunc(GasMeter& _gasMeter);
private: private:
llvm::GlobalVariable* m_data; llvm::GlobalVariable* m_data;

Loading…
Cancel
Save