Browse Source

Optimize RETURN x 0 to STOP.

cl-refactor
chriseth 10 years ago
parent
commit
6c45ac6ab1
  1. 26
      libevmasm/CommonSubexpressionEliminator.cpp
  2. 3
      libsolidity/Compiler.cpp
  3. 8
      test/libsolidity/SolidityOptimizer.cpp

26
libevmasm/CommonSubexpressionEliminator.cpp

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

3
libsolidity/Compiler.cpp

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

8
test/libsolidity/SolidityOptimizer.cpp

@ -944,6 +944,14 @@ BOOST_AUTO_TEST_CASE(cse_access_previous_sequence)
// 0, SLOAD, 1, ADD, SSTORE, 0 SLOAD // 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) BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused)
{ {
// remove parts of the code that are unused // remove parts of the code that are unused

Loading…
Cancel
Save