diff options
author | chriseth <c@ethdev.com> | 2015-06-12 17:06:05 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-06-12 17:31:03 +0800 |
commit | 64a1e82b6cf6ef6483a159743827c68e7baa3a64 (patch) | |
tree | eef0aba4d4b3d4831dfdc67377ecad22efd0b20f /CommonSubexpressionEliminator.cpp | |
parent | a72e357c4eb5b8d4052fd3df6288f0b2f13b7a0e (diff) | |
download | dexon-solidity-64a1e82b6cf6ef6483a159743827c68e7baa3a64.tar.gz dexon-solidity-64a1e82b6cf6ef6483a159743827c68e7baa3a64.tar.zst dexon-solidity-64a1e82b6cf6ef6483a159743827c68e7baa3a64.zip |
Optimize RETURN x 0 to STOP.
Diffstat (limited to 'CommonSubexpressionEliminator.cpp')
-rw-r--r-- | CommonSubexpressionEliminator.cpp | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/CommonSubexpressionEliminator.cpp b/CommonSubexpressionEliminator.cpp index 2c4742d6..8fb4625a 100644 --- a/CommonSubexpressionEliminator.cpp +++ b/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); + } } } |