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``,
``sizeof``, ``supports``, ``typedef`` and ``unchecked``.
* 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.
* Type Checker: Disallow arithmetic operations for boolean variables.
* 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.
struct UnreachableCode
{
@ -305,7 +322,7 @@ bool PeepholeOptimiser::optimise()
{
OptimiserState state {m_items, 0, std::back_inserter(m_optimisedItems)};
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() || (
m_optimisedItems.size() == m_items.size() && (
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)
{
AssemblyItems items{