Browse Source

Generate mem.store function and dependencies (currently unused)

[#80191662]
cl-refactor
Paweł Bylica 10 years ago
parent
commit
f825a6020f
  1. 60
      evmcc/Memory.cpp
  2. 8
      evmcc/Memory.h
  3. 6
      evmcc/Type.cpp
  4. 4
      evmcc/Type.h

60
evmcc/Memory.cpp

@ -6,10 +6,12 @@
#include <cstdint>
#include <cassert>
#include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/Function.h>
#include <libdevcore/Common.h>
#include "Type.h"
#include "Runtime.h"
#ifdef _MSC_VER
@ -21,7 +23,7 @@
namespace evmcc
{
Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module)
Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module)
: m_builder(_builder)
{
auto voidTy = m_builder.getVoidTy();
@ -30,17 +32,59 @@ Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module)
auto memRequireTy = llvm::FunctionType::get(m_builder.getInt8PtrTy(), i64Ty, false);
m_memRequire = llvm::Function::Create(memRequireTy,
llvm::GlobalValue::LinkageTypes::ExternalLinkage,
"evmccrt_memory_require", module);
"evmccrt_memory_require", _module);
auto memSizeTy = llvm::FunctionType::get(i64Ty, false);
m_memSize = llvm::Function::Create(memSizeTy,
llvm::GlobalValue::LinkageTypes::ExternalLinkage,
"evmccrt_memory_size", module);
"evmccrt_memory_size", _module);
std::vector<llvm::Type*> argTypes = {i64Ty, i64Ty};
auto dumpTy = llvm::FunctionType::get(m_builder.getVoidTy(), llvm::ArrayRef<llvm::Type*>(argTypes), false);
m_memDump = llvm::Function::Create(dumpTy, llvm::GlobalValue::LinkageTypes::ExternalLinkage,
"evmccrt_memory_dump", module);
"evmccrt_memory_dump", _module);
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_size = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, m_builder.getIntN(256, 0), "mem.size");
m_size->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);
llvm::Type* storeArgs[] = {Type::i256, Type::i256};
m_store = llvm::Function::Create(llvm::FunctionType::get(Type::Void, storeArgs, false), llvm::Function::PrivateLinkage, "mem.store", _module);
auto origBB = m_builder.GetInsertBlock();
auto origPt = m_builder.GetInsertPoint();
auto checkBB = llvm::BasicBlock::Create(m_store->getContext(), "check", m_store);
auto resizeBB = llvm::BasicBlock::Create(m_store->getContext(), "resize", m_store);
auto storeBB = llvm::BasicBlock::Create(m_store->getContext(), "store", m_store);
m_builder.SetInsertPoint(checkBB);
llvm::Value* index = m_store->arg_begin();
index->setName("index");
llvm::Value* value = ++m_store->arg_begin();
value->setName("value");
auto sizeRequired = m_builder.CreateAdd(index, m_builder.getIntN(256, 32), "sizeRequired");
auto size = m_builder.CreateLoad(m_size, "size");
auto resizeNeeded = m_builder.CreateICmpULE(sizeRequired, size, "resizeNeeded");
m_builder.CreateCondBr(resizeNeeded, resizeBB, storeBB); // OPT branch weights?
m_builder.SetInsertPoint(resizeBB);
m_builder.CreateStore(sizeRequired, m_size);
llvm::Value* data = m_builder.CreateCall(m_resize, m_size, "data");
m_builder.CreateStore(data, m_data);
m_builder.CreateBr(storeBB);
m_builder.SetInsertPoint(storeBB);
data = m_builder.CreateLoad(m_data, "data");
auto ptr = m_builder.CreateGEP(data, index, "ptr");
ptr = m_builder.CreateBitCast(ptr, Type::WordPtr, "wordPtr");
m_builder.CreateStore(value, ptr);
m_builder.CreateRetVoid();
m_builder.SetInsertPoint(origBB, origPt);
}
@ -114,6 +158,14 @@ extern "C"
{
using namespace evmcc;
EXPORT uint8_t* mem_resize(i256* _size)
{
auto size = _size->a; // Trunc to 64-bit
auto& memory = Runtime::getMemory();
memory.resize(size);
return memory.data();
}
// Resizes memory to contain at least _index + 1 bytes and returns the base address.
EXPORT uint8_t* evmccrt_memory_require(uint64_t _index)
{

8
evmcc/Memory.h

@ -10,7 +10,7 @@ namespace evmcc
class Memory
{
public:
Memory(llvm::IRBuilder<>& _builder, llvm::Module* module);
Memory(llvm::IRBuilder<>& _builder, llvm::Module* _module);
llvm::Value* loadWord(llvm::Value* _addr);
void storeWord(llvm::Value* _addr, llvm::Value* _word);
@ -22,6 +22,12 @@ public:
private:
llvm::IRBuilder<>& m_builder;
llvm::GlobalVariable* m_data;
llvm::GlobalVariable* m_size;
llvm::Function* m_store;
llvm::Function* m_resize;
llvm::Function* m_memRequire;
llvm::Function* m_memDump;
llvm::Function* m_memSize;

6
evmcc/Type.cpp

@ -7,13 +7,19 @@ namespace evmcc
{
llvm::IntegerType* Type::i256;
llvm::PointerType* Type::WordPtr;
llvm::IntegerType* Type::lowPrecision;
llvm::IntegerType* Type::Byte;
llvm::PointerType* Type::BytePtr;
llvm::Type* Type::Void;
void Type::init(llvm::LLVMContext& _context)
{
i256 = llvm::Type::getIntNTy(_context, 256);
WordPtr = i256->getPointerTo();
lowPrecision = llvm::Type::getInt64Ty(_context);
Byte = llvm::Type::getInt8Ty(_context);
BytePtr = Byte->getPointerTo();
Void = llvm::Type::getVoidTy(_context);
}

4
evmcc/Type.h

@ -9,11 +9,15 @@ namespace evmcc
struct Type
{
static llvm::IntegerType* i256;
static llvm::PointerType* WordPtr;
/// Type for doing low precision arithmetics where 256-bit precision is not supported by native target
/// @TODO: Use 64-bit for now. In 128-bit compiler-rt library functions are required
static llvm::IntegerType* lowPrecision;
static llvm::IntegerType* Byte;
static llvm::PointerType* BytePtr;
static llvm::Type* Void;
static void init(llvm::LLVMContext& _context);

Loading…
Cancel
Save