mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Peephole optimizer for "iszero iszero <tag> jumpi".
This commit is contained in:
@@ -45,6 +45,14 @@ struct ApplyRule
|
||||
{
|
||||
};
|
||||
template <class Method>
|
||||
struct ApplyRule<Method, 4>
|
||||
{
|
||||
static bool applyRule(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out)
|
||||
{
|
||||
return Method::applySimple(_in[0], _in[1], _in[2], _in[3], _out);
|
||||
}
|
||||
};
|
||||
template <class Method>
|
||||
struct ApplyRule<Method, 3>
|
||||
{
|
||||
static bool applyRule(AssemblyItems::const_iterator _in, std::back_insert_iterator<AssemblyItems> _out)
|
||||
@@ -197,6 +205,32 @@ struct SwapComparison: SimplePeepholeOptimizerMethod<SwapComparison, 2>
|
||||
}
|
||||
};
|
||||
|
||||
struct IsZeroIsZeroJumpI: SimplePeepholeOptimizerMethod<IsZeroIsZeroJumpI, 4>
|
||||
{
|
||||
static size_t applySimple(
|
||||
AssemblyItem const& _iszero1,
|
||||
AssemblyItem const& _iszero2,
|
||||
AssemblyItem const& _pushTag,
|
||||
AssemblyItem const& _jumpi,
|
||||
std::back_insert_iterator<AssemblyItems> _out
|
||||
)
|
||||
{
|
||||
if (
|
||||
_iszero1 == Instruction::ISZERO &&
|
||||
_iszero2 == Instruction::ISZERO &&
|
||||
_pushTag.type() == PushTag &&
|
||||
_jumpi == Instruction::JUMPI
|
||||
)
|
||||
{
|
||||
*_out = _pushTag;
|
||||
*_out = _jumpi;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct JumpToNext: SimplePeepholeOptimizerMethod<JumpToNext, 3>
|
||||
{
|
||||
static size_t applySimple(
|
||||
@@ -320,7 +354,12 @@ 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(), TruthyAnd(), Identity());
|
||||
applyMethods(
|
||||
state,
|
||||
PushPop(), OpPop(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(),
|
||||
IsZeroIsZeroJumpI(), 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) ||
|
||||
|
||||
Reference in New Issue
Block a user