mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Optimize RETURN x 0 to STOP.
This commit is contained in:
parent
a72e357c4e
commit
64a1e82b6c
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user