Merge pull request #4300 from nventuro/optimize-out-and

Add TruthyAnd Peephole optimization
This commit is contained in:
chriseth 2018-06-20 11:38:37 +02:00 committed by GitHub
commit ba7fbf11e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 1 deletions

View File

@ -16,6 +16,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,31 @@ BOOST_AUTO_TEST_CASE(peephole_swap_comparison)
}
}
BOOST_AUTO_TEST_CASE(peephole_truthy_and)
{
AssemblyItems items{
AssemblyItem(Tag, 1),
Instruction::BALANCE,
u256(0),
Instruction::NOT,
Instruction::AND,
AssemblyItem(PushTag, 1),
Instruction::JUMPI
};
AssemblyItems expectation{
AssemblyItem(Tag, 1),
Instruction::BALANCE,
AssemblyItem(PushTag, 1),
Instruction::JUMPI
};
PeepholeOptimiser peepOpt(items);
BOOST_REQUIRE(peepOpt.optimise());
BOOST_CHECK_EQUAL_COLLECTIONS(
items.begin(), items.end(),
expectation.begin(), expectation.end()
);
}
BOOST_AUTO_TEST_CASE(jumpdest_removal)
{
AssemblyItems items{