Browse Source

Merge branch 'develop-evmcc' of github.com:imapp-pl/ethereum into develop-evmcc

Conflicts:
	libevmjit/Compiler.cpp
cl-refactor
artur-zawlocki 10 years ago
parent
commit
b6b4f5f639
  1. 11
      libevmjit/Compiler.cpp
  2. 50
      libevmjit/Memory.cpp
  3. 4
      libevmjit/Memory.h
  4. 4
      libevmjit/Type.cpp
  5. 2
      libevmjit/Type.h

11
libevmjit/Compiler.cpp

@ -345,7 +345,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytesConstRef _bytecod
case Instruction::BNOT: case Instruction::BNOT:
{ {
auto value = stack.pop(); auto value = stack.pop();
auto ret = m_builder.CreateXor(value, llvm::APInt(256, -1, true), "bnot"); auto ret = m_builder.CreateXor(value, Constant::get(-1), "bnot");
stack.push(ret); stack.push(ret);
break; break;
} }
@ -760,12 +760,9 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytesConstRef _bytecod
_gasMeter.commitCostBlock(gas); _gasMeter.commitCostBlock(gas);
// Require _memory for the max of in and out buffers // Require memory for in and out buffers
auto inSizeReq = m_builder.CreateAdd(inOff, inSize, "inSizeReq"); memory.require(outOff, outSize); // Out buffer first as we guess it will be after the in one
auto outSizeReq = m_builder.CreateAdd(outOff, outSize, "outSizeReq"); memory.require(inOff, inSize);
auto cmp = m_builder.CreateICmpUGT(inSizeReq, outSizeReq);
auto sizeReq = m_builder.CreateSelect(cmp, inSizeReq, outSizeReq, "sizeReq");
_memory.require(sizeReq);
auto receiveAddress = codeAddress; auto receiveAddress = codeAddress;
if (inst == Instruction::CALLCODE) if (inst == Instruction::CALLCODE)

50
libevmjit/Memory.cpp

@ -8,6 +8,7 @@
#include <llvm/IR/GlobalVariable.h> #include <llvm/IR/GlobalVariable.h>
#include <llvm/IR/Function.h> #include <llvm/IR/Function.h>
#include <llvm/IR/IntrinsicInst.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
@ -28,8 +29,7 @@ Memory::Memory(RuntimeManager& _runtimeManager, GasMeter& _gasMeter):
RuntimeHelper(_runtimeManager) RuntimeHelper(_runtimeManager)
{ {
auto module = getModule(); auto module = getModule();
auto i64Ty = m_builder.getInt64Ty(); llvm::Type* argTypes[] = {Type::i256, Type::i256};
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", module);
@ -54,28 +54,41 @@ Memory::Memory(RuntimeManager& _runtimeManager, GasMeter& _gasMeter):
llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager) llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager)
{ {
auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "mem.require", getModule()); llvm::Type* argTypes[] = {Type::i256, Type::i256};
auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "mem.require", getModule());
auto offset = func->arg_begin();
offset->setName("offset");
auto size = offset->getNextNode();
size->setName("size");
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);
auto returnBB = llvm::BasicBlock::Create(func->getContext(), "return", func); auto returnBB = llvm::BasicBlock::Create(func->getContext(), "Return", func);
InsertPointGuard guard(m_builder); // Restores insert point at function exit InsertPointGuard guard(m_builder); // Restores insert point at function exit
// BB "check" // BB "check"
m_builder.SetInsertPoint(checkBB); m_builder.SetInsertPoint(checkBB);
llvm::Value* sizeRequired = func->arg_begin(); auto uaddWO = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::uadd_with_overflow, Type::i256);
sizeRequired->setName("sizeRequired"); auto uaddRes = m_builder.CreateCall2(uaddWO, offset, size, "res");
auto size = m_builder.CreateLoad(m_size, "size"); auto sizeRequired = m_builder.CreateExtractValue(uaddRes, 0, "sizeReq");
auto resizeNeeded = m_builder.CreateICmpULE(size, sizeRequired, "resizeNeeded"); auto overflow1 = m_builder.CreateExtractValue(uaddRes, 1, "overflow1");
auto currSize = m_builder.CreateLoad(m_size, "currSize");
auto tooSmall = m_builder.CreateICmpULE(size, sizeRequired, "tooSmall");
auto resizeNeeded = m_builder.CreateOr(tooSmall, overflow1, "resizeNeeded");
m_builder.CreateCondBr(resizeNeeded, resizeBB, returnBB); // OPT branch weights? m_builder.CreateCondBr(resizeNeeded, resizeBB, returnBB); // OPT branch weights?
// BB "resize" // BB "resize"
m_builder.SetInsertPoint(resizeBB); m_builder.SetInsertPoint(resizeBB);
// Check gas first // Check gas first
auto wordsRequired = m_builder.CreateUDiv(m_builder.CreateAdd(sizeRequired, Constant::get(31)), Constant::get(32), "wordsRequired"); uaddRes = m_builder.CreateCall2(uaddWO, sizeRequired, Constant::get(31), "res");
sizeRequired = m_builder.CreateMul(wordsRequired, Constant::get(32), "roundedSizeRequired"); auto wordsRequired = m_builder.CreateExtractValue(uaddRes, 0);
auto words = m_builder.CreateUDiv(size, Constant::get(32), "words"); // size is always 32*k auto overflow2 = m_builder.CreateExtractValue(uaddRes, 1, "overflow2");
auto overflow = m_builder.CreateOr(overflow1, overflow2, "overflow");
wordsRequired = m_builder.CreateSelect(overflow, Constant::get(-1), wordsRequired);
wordsRequired = m_builder.CreateUDiv(wordsRequired, Constant::get(32), "wordsReq");
sizeRequired = m_builder.CreateMul(wordsRequired, Constant::get(32), "roundedSizeReq");
auto words = m_builder.CreateUDiv(currSize, Constant::get(32), "words"); // size is always 32*k
auto newWords = m_builder.CreateSub(wordsRequired, words, "addtionalWords"); auto newWords = m_builder.CreateSub(wordsRequired, words, "addtionalWords");
_gasMeter.checkMemory(newWords, m_builder); _gasMeter.checkMemory(newWords, m_builder);
// Resize // Resize
@ -164,15 +177,9 @@ llvm::Value* Memory::getSize()
return m_builder.CreateLoad(m_size); return m_builder.CreateLoad(m_size);
} }
void Memory::require(llvm::Value* _size)
{
m_builder.CreateCall(m_require, _size);
}
void Memory::require(llvm::Value* _offset, llvm::Value* _size) void Memory::require(llvm::Value* _offset, llvm::Value* _size)
{ {
auto sizeRequired = m_builder.CreateAdd(_offset, _size, "sizeRequired"); m_builder.CreateCall2(m_require, _offset, _size);
require(sizeRequired);
} }
void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx, void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx,
@ -180,8 +187,7 @@ void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value*
{ {
auto zero256 = llvm::ConstantInt::get(Type::i256, 0); auto zero256 = llvm::ConstantInt::get(Type::i256, 0);
auto reqMemSize = m_builder.CreateAdd(_destMemIdx, _reqBytes, "req_mem_size"); require(_destMemIdx, _reqBytes);
require(reqMemSize);
auto srcPtr = m_builder.CreateGEP(_srcPtr, _srcIdx, "src_idx"); auto srcPtr = m_builder.CreateGEP(_srcPtr, _srcIdx, "src_idx");

4
libevmjit/Memory.h

@ -24,9 +24,6 @@ public:
void copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIndex, void copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIndex,
llvm::Value* _destMemIdx, llvm::Value* _byteCount); llvm::Value* _destMemIdx, llvm::Value* _byteCount);
/// Requires this amount of memory. And counts gas fee for that memory.
void require(llvm::Value* _size);
/// Requires the amount of memory to for data defined by offset and size. And counts gas fee for that memory. /// Requires the amount of memory to for data defined by offset and size. And counts gas fee for that memory.
void require(llvm::Value* _offset, llvm::Value* _size); void require(llvm::Value* _offset, llvm::Value* _size);
@ -36,7 +33,6 @@ private:
llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter); llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter);
llvm::Function* createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager); llvm::Function* createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager);
private:
llvm::GlobalVariable* m_data; llvm::GlobalVariable* m_data;
llvm::GlobalVariable* m_size; llvm::GlobalVariable* m_size;

4
libevmjit/Type.cpp

@ -36,9 +36,9 @@ void Type::init(llvm::LLVMContext& _context)
RuntimePtr = RuntimeData::getType()->getPointerTo(); RuntimePtr = RuntimeData::getType()->getPointerTo();
} }
llvm::ConstantInt* Constant::get(uint64_t _n) llvm::ConstantInt* Constant::get(int64_t _n)
{ {
return llvm::ConstantInt::get(Type::i256, _n); return llvm::ConstantInt::getSigned(Type::i256, _n);
} }
llvm::ConstantInt* Constant::get(u256 _n) llvm::ConstantInt* Constant::get(u256 _n)

2
libevmjit/Type.h

@ -51,7 +51,7 @@ enum class ReturnCode
struct Constant struct Constant
{ {
/// Returns word-size constant /// Returns word-size constant
static llvm::ConstantInt* get(uint64_t _n); static llvm::ConstantInt* get(int64_t _n);
static llvm::ConstantInt* get(u256 _n); static llvm::ConstantInt* get(u256 _n);
static llvm::ConstantInt* get(ReturnCode _returnCode); static llvm::ConstantInt* get(ReturnCode _returnCode);

Loading…
Cancel
Save