Add TruthyAnd Peephole optimization

This commit is contained in:
Nicolás Venturo 2018-06-14 14:29:42 -03:00
parent dc5cd3e1e7
commit 172e208c6a
3 changed files with 31 additions and 1 deletions

View File

@ -15,6 +15,7 @@ Breaking Changes:
``implements``, ``macro``, ``mutable``, ``override``, ``partial``, ``promise``, ``reference``, ``sealed``, ``implements``, ``macro``, ``mutable``, ``override``, ``partial``, ``promise``, ``reference``, ``sealed``,
``sizeof``, ``supports``, ``typedef`` and ``unchecked``. ``sizeof``, ``supports``, ``typedef`` and ``unchecked``.
* General: Remove assembly instruction aliases ``sha3`` and ``suicide`` * General: Remove assembly instruction aliases ``sha3`` and ``suicide``
* Optimizer: Remove the no-op ``PUSH1 0 NOT AND`` sequence.
* Parser: Disallow trailing dots that are not followed by a number. * Parser: Disallow trailing dots that are not followed by a number.
* Type Checker: Disallow arithmetic operations for boolean variables. * Type Checker: Disallow arithmetic operations for boolean variables.
* Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size. * Type Checker: Disallow conversions between ``bytesX`` and ``uintY`` of different size.

View File

@ -249,6 +249,23 @@ struct TagConjunctions: SimplePeepholeOptimizerMethod<TagConjunctions, 3>
} }
}; };
struct TruthyAnd: SimplePeepholeOptimizerMethod<TruthyAnd, 3>
{
static bool applySimple(
AssemblyItem const& _push,
AssemblyItem const& _not,
AssemblyItem const& _and,
std::back_insert_iterator<AssemblyItems>
)
{
return (
_push.type() == Push && _push.data() == 0 &&
_not == Instruction::NOT &&
_and == Instruction::AND
);
}
};
/// Removes everything after a JUMP (or similar) until the next JUMPDEST. /// Removes everything after a JUMP (or similar) until the next JUMPDEST.
struct UnreachableCode struct UnreachableCode
{ {
@ -305,7 +322,7 @@ bool PeepholeOptimiser::optimise()
{ {
OptimiserState state {m_items, 0, std::back_inserter(m_optimisedItems)}; OptimiserState state {m_items, 0, std::back_inserter(m_optimisedItems)};
while (state.i < m_items.size()) while (state.i < m_items.size())
applyMethods(state, PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(), JumpToNext(), UnreachableCode(), TagConjunctions(), Identity()); applyMethods(state, PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(), JumpToNext(), UnreachableCode(), TagConjunctions(), TruthyAnd(), Identity());
if (m_optimisedItems.size() < m_items.size() || ( if (m_optimisedItems.size() < m_items.size() || (
m_optimisedItems.size() == m_items.size() && ( m_optimisedItems.size() == m_items.size() && (
eth::bytesRequired(m_optimisedItems, 3) < eth::bytesRequired(m_items, 3) || eth::bytesRequired(m_optimisedItems, 3) < eth::bytesRequired(m_items, 3) ||

View File

@ -967,6 +967,18 @@ BOOST_AUTO_TEST_CASE(peephole_swap_comparison)
} }
} }
BOOST_AUTO_TEST_CASE(peephole_truthy_and)
{
AssemblyItems items{
u256(0),
Instruction::NOT,
Instruction::AND
};
PeepholeOptimiser peepOpt(items);
BOOST_REQUIRE(peepOpt.optimise());
BOOST_CHECK(items.empty());
}
BOOST_AUTO_TEST_CASE(jumpdest_removal) BOOST_AUTO_TEST_CASE(jumpdest_removal)
{ {
AssemblyItems items{ AssemblyItems items{