Browse Source

Merge pull request #2168 from chriseth/sol_optimizeZeroReturn

Optimize RETURN x 0 to STOP.
cl-refactor
Gav Wood 10 years ago
parent
commit
6cb2b74602
  1. 48
      libevmasm/CommonSubexpressionEliminator.cpp
  2. 5
      libsolidity/Compiler.cpp
  3. 8
      test/libsolidity/SolidityOptimizer.cpp

48
libevmasm/CommonSubexpressionEliminator.cpp

@ -79,31 +79,43 @@ void CommonSubexpressionEliminator::feedItem(AssemblyItem const& _item, bool _co
void CommonSubexpressionEliminator::optimizeBreakingItem()
{
if (!m_breakingItem || *m_breakingItem != AssemblyItem(Instruction::JUMPI))
if (!m_breakingItem)
return;
ExpressionClasses& classes = m_state.expressionClasses();
SourceLocation const& location = m_breakingItem->getLocation();
AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType();
Id condition = m_state.stackElement(m_state.stackHeight() - 1, location);
Id zero = m_state.expressionClasses().find(u256(0));
if (m_state.expressionClasses().knownToBeDifferent(condition, zero))
if (*m_breakingItem == AssemblyItem(Instruction::JUMPI))
{
feedItem(AssemblyItem(Instruction::SWAP1, location), true);
feedItem(AssemblyItem(Instruction::POP, location), true);
AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType();
AssemblyItem item(Instruction::JUMP, location);
item.setJumpType(jumpType);
m_breakingItem = m_state.expressionClasses().storeItem(item);
return;
Id condition = m_state.stackElement(m_state.stackHeight() - 1, location);
if (classes.knownNonZero(condition))
{
feedItem(AssemblyItem(Instruction::SWAP1, location), true);
feedItem(AssemblyItem(Instruction::POP, location), true);
AssemblyItem item(Instruction::JUMP, location);
item.setJumpType(jumpType);
m_breakingItem = classes.storeItem(item);
}
else if (classes.knownZero(condition))
{
AssemblyItem it(Instruction::POP, location);
feedItem(it, true);
feedItem(it, true);
m_breakingItem = nullptr;
}
}
Id negatedCondition = m_state.expressionClasses().find(Instruction::ISZERO, {condition});
if (m_state.expressionClasses().knownToBeDifferent(negatedCondition, zero))
else if (*m_breakingItem == AssemblyItem(Instruction::RETURN))
{
AssemblyItem it(Instruction::POP, location);
feedItem(it, true);
feedItem(it, true);
m_breakingItem = nullptr;
Id size = m_state.stackElement(m_state.stackHeight() - 1, location);
if (classes.knownZero(size))
{
feedItem(AssemblyItem(Instruction::POP, location), true);
feedItem(AssemblyItem(Instruction::POP, location), true);
AssemblyItem item(Instruction::STOP, location);
m_breakingItem = classes.storeItem(item);
}
}
}

5
libsolidity/Compiler.cpp

@ -298,7 +298,10 @@ void Compiler::appendReturnValuePacker(TypePointers const& _typeParameters)
stackDepth -= type->getSizeOnStack();
}
// note that the stack is not cleaned up here
m_context << u256(dataOffset) << u256(0) << eth::Instruction::RETURN;
if (dataOffset == 0)
m_context << eth::Instruction::STOP;
else
m_context << u256(dataOffset) << u256(0) << eth::Instruction::RETURN;
}
void Compiler::registerStateVariables(ContractDefinition const& _contract)

8
test/libsolidity/SolidityOptimizer.cpp

@ -944,6 +944,14 @@ BOOST_AUTO_TEST_CASE(cse_access_previous_sequence)
// 0, SLOAD, 1, ADD, SSTORE, 0 SLOAD
}
BOOST_AUTO_TEST_CASE(cse_optimise_return)
{
checkCSE(
AssemblyItems{u256(0), u256(7), Instruction::RETURN},
AssemblyItems{Instruction::STOP}
);
}
BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused)
{
// remove parts of the code that are unused

Loading…
Cancel
Save