Optimize RETURN x 0 to STOP.

This commit is contained in:
chriseth 2015-06-12 11:06:05 +02:00
parent a72e357c4e
commit 64a1e82b6c

View File

@ -79,31 +79,43 @@ 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();
AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType(); if (*m_breakingItem == AssemblyItem(Instruction::JUMPI))
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))
{ {
feedItem(AssemblyItem(Instruction::SWAP1, location), true); AssemblyItem::JumpType jumpType = m_breakingItem->getJumpType();
feedItem(AssemblyItem(Instruction::POP, location), true);
AssemblyItem item(Instruction::JUMP, location); Id condition = m_state.stackElement(m_state.stackHeight() - 1, location);
item.setJumpType(jumpType); if (classes.knownNonZero(condition))
m_breakingItem = m_state.expressionClasses().storeItem(item); {
return; 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}); else if (*m_breakingItem == AssemblyItem(Instruction::RETURN))
if (m_state.expressionClasses().knownToBeDifferent(negatedCondition, zero))
{ {
AssemblyItem it(Instruction::POP, location); Id size = m_state.stackElement(m_state.stackHeight() - 1, location);
feedItem(it, true); if (classes.knownZero(size))
feedItem(it, true); {
m_breakingItem = nullptr; feedItem(AssemblyItem(Instruction::POP, location), true);
feedItem(AssemblyItem(Instruction::POP, location), true);
AssemblyItem item(Instruction::STOP, location);
m_breakingItem = classes.storeItem(item);
}
} }
} }