Browse Source

Unpack runtime data at front. Not used one are removed by DCE pass.

cl-refactor
Paweł Bylica 10 years ago
parent
commit
854d088da9
  1. 1
      libevmjit/Optimizer.cpp
  2. 46
      libevmjit/RuntimeManager.cpp
  3. 2
      libevmjit/RuntimeManager.h

1
libevmjit/Optimizer.cpp

@ -79,6 +79,7 @@ bool LowerEVMPass::doFinalization(llvm::Module&)
bool prepare(llvm::Module& _module) bool prepare(llvm::Module& _module)
{ {
auto pm = llvm::legacy::PassManager{}; auto pm = llvm::legacy::PassManager{};
pm.add(llvm::createDeadCodeEliminationPass());
pm.add(new LowerEVMPass{}); pm.add(new LowerEVMPass{});
return pm.run(_module); return pm.run(_module);
} }

46
libevmjit/RuntimeManager.cpp

@ -64,22 +64,22 @@ llvm::Twine getName(RuntimeData::Index _index)
{ {
switch (_index) switch (_index)
{ {
default: return "data"; default: return "";
case RuntimeData::Address: return "address"; case RuntimeData::Gas: return "msg.gas";
case RuntimeData::Caller: return "caller"; case RuntimeData::GasPrice: return "tx.gasprice";
case RuntimeData::Origin: return "origin"; case RuntimeData::CallData: return "msg.data.ptr";
case RuntimeData::CallValue: return "callvalue"; case RuntimeData::CallDataSize: return "msg.data.size";
case RuntimeData::GasPrice: return "gasprice"; case RuntimeData::Address: return "this.address";
case RuntimeData::CoinBase: return "coinbase"; case RuntimeData::Caller: return "msg.caller";
case RuntimeData::Difficulty: return "difficulty"; case RuntimeData::Origin: return "tx.origin";
case RuntimeData::GasLimit: return "gaslimit"; case RuntimeData::CallValue: return "msg.value";
case RuntimeData::CallData: return "callData"; case RuntimeData::CoinBase: return "block.coinbase";
case RuntimeData::Code: return "code"; case RuntimeData::Difficulty: return "block.difficulty";
case RuntimeData::CodeSize: return "code"; case RuntimeData::GasLimit: return "block.gaslimit";
case RuntimeData::CallDataSize: return "callDataSize"; case RuntimeData::Number: return "block.number";
case RuntimeData::Gas: return "gas"; case RuntimeData::Timestamp: return "block.timestamp";
case RuntimeData::Number: return "number"; case RuntimeData::Code: return "code.ptr";
case RuntimeData::Timestamp: return "timestamp"; case RuntimeData::CodeSize: return "code.size";
} }
} }
} }
@ -93,9 +93,9 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
// Unpack data // Unpack data
auto rtPtr = getRuntimePtr(); auto rtPtr = getRuntimePtr();
m_dataPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 0), "data"); m_dataPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 0), "dataPtr");
assert(m_dataPtr->getType() == Type::RuntimeDataPtr); assert(m_dataPtr->getType() == Type::RuntimeDataPtr);
m_gasPtr = m_builder.CreateStructGEP(getRuntimeDataType(), m_dataPtr, 0, "gas"); m_gasPtr = m_builder.CreateStructGEP(getRuntimeDataType(), m_dataPtr, 0, "gasPtr");
assert(m_gasPtr->getType() == Type::Gas->getPointerTo()); assert(m_gasPtr->getType() == Type::Gas->getPointerTo());
m_memPtr = m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 2, "mem"); m_memPtr = m_builder.CreateStructGEP(getRuntimeType(), rtPtr, 2, "mem");
assert(m_memPtr->getType() == Array::getType()->getPointerTo()); assert(m_memPtr->getType() == Array::getType()->getPointerTo());
@ -105,6 +105,10 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder, code_iterator _codeB
m_stackSize = m_builder.CreateAlloca(Type::Size, nullptr, "stackSize"); m_stackSize = m_builder.CreateAlloca(Type::Size, nullptr, "stackSize");
m_builder.CreateStore(m_builder.getInt64(0), m_stackSize); m_builder.CreateStore(m_builder.getInt64(0), m_stackSize);
auto data = m_builder.CreateLoad(m_dataPtr, "data");
for (unsigned i = 0; i < m_dataElts.size(); ++i)
m_dataElts[i] = m_builder.CreateExtractValue(data, i, getName(RuntimeData::Index(i)));
llvm::Type* checkStackLimitArgs[] = {Type::Size->getPointerTo(), Type::Size, Type::Size, Type::BytePtr}; llvm::Type* checkStackLimitArgs[] = {Type::Size->getPointerTo(), Type::Size, Type::Size, Type::BytePtr};
m_checkStackLimit = llvm::Function::Create(llvm::FunctionType::get(Type::Void, checkStackLimitArgs, false), llvm::Function::PrivateLinkage, "stack.checkSize", getModule()); m_checkStackLimit = llvm::Function::Create(llvm::FunctionType::get(Type::Void, checkStackLimitArgs, false), llvm::Function::PrivateLinkage, "stack.checkSize", getModule());
m_checkStackLimit->setDoesNotThrow(); m_checkStackLimit->setDoesNotThrow();
@ -180,7 +184,7 @@ llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index)
llvm::Value* RuntimeManager::get(RuntimeData::Index _index) llvm::Value* RuntimeManager::get(RuntimeData::Index _index)
{ {
return getBuilder().CreateLoad(getPtr(_index), getName(_index)); return m_dataElts[_index];
} }
void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value) void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value)
@ -264,9 +268,7 @@ llvm::Value* RuntimeManager::getCallDataSize()
llvm::Value* RuntimeManager::getGas() llvm::Value* RuntimeManager::getGas()
{ {
auto gas = get(RuntimeData::Gas); return getBuilder().CreateLoad(getGasPtr(), "gas");
assert(gas->getType() == Type::Gas);
return gas;
} }
llvm::Value* RuntimeManager::getGasPtr() llvm::Value* RuntimeManager::getGasPtr()

2
libevmjit/RuntimeManager.h

@ -61,6 +61,8 @@ private:
llvm::Value* m_memPtr = nullptr; llvm::Value* m_memPtr = nullptr;
llvm::Value* m_envPtr = nullptr; llvm::Value* m_envPtr = nullptr;
std::array<llvm::Value*, static_cast<size_t>(RuntimeData::Index::CodeSize) + 1> m_dataElts;
llvm::Value* m_stackSize = nullptr; llvm::Value* m_stackSize = nullptr;
llvm::Function* m_checkStackLimit = nullptr; llvm::Function* m_checkStackLimit = nullptr;

Loading…
Cancel
Save