mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #4300 from nventuro/optimize-out-and
Add TruthyAnd Peephole optimization
This commit is contained in:
commit
ba7fbf11e7
@ -16,6 +16,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.
|
||||||
|
@ -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) ||
|
||||||
|
@ -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)
|
BOOST_AUTO_TEST_CASE(jumpdest_removal)
|
||||||
{
|
{
|
||||||
AssemblyItems items{
|
AssemblyItems items{
|
||||||
|
Loading…
Reference in New Issue
Block a user