Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: argotorg/solidity
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: develop
Choose a base ref
...
head repository: moh-eulith/solidity
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 28_e_push_two_swap_comop
Choose a head ref
  • 2 commits
  • 3 files changed
  • 1 contributor

Commits on Mar 3, 2025

  1. remove non-existant warning flags

    Mohammad Rezaei committed Mar 3, 2025
    Copy the full SHA
    1d375e4 View commit details
  2. push swap1 swapn comop optimization

    Mohammad Rezaei committed Mar 3, 2025
    Copy the full SHA
    def9f67 View commit details
Showing with 103 additions and 5 deletions.
  1. +0 −2 cmake/EthCompilerSettings.cmake
  2. +68 −3 libevmasm/PeepholeOptimiser.cpp
  3. +35 −0 test/libevmasm/Optimiser.cpp
2 changes: 0 additions & 2 deletions cmake/EthCompilerSettings.cmake
Original file line number Diff line number Diff line change
@@ -75,9 +75,7 @@ if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") OR ("${CMAKE_CXX_COMPILER_ID}" MA
eth_add_cxx_compiler_flag_if_supported(-Wfinal-dtor-non-final-class)
eth_add_cxx_compiler_flag_if_supported(-Wnewline-eof)
eth_add_cxx_compiler_flag_if_supported(-Wsuggest-destructor-override)
eth_add_cxx_compiler_flag_if_supported(-Wduplicated-cond)
eth_add_cxx_compiler_flag_if_supported(-Wduplicate-enum)
eth_add_cxx_compiler_flag_if_supported(-Wlogical-op)
eth_add_cxx_compiler_flag_if_supported(-Wno-unknown-attributes)
endif()

71 changes: 68 additions & 3 deletions libevmasm/PeepholeOptimiser.cpp
Original file line number Diff line number Diff line change
@@ -465,6 +465,53 @@ struct TruthyAnd: SimplePeepholeOptimizerMethod<TruthyAnd>
}
};

//push swap1 swapN ComOp -> swap[N-1] push ComOp
struct PushTwoSwapComop: SimplePeepholeOptimizerMethod<PushTwoSwapComop>
{
static bool applySimple(
AssemblyItem const& _push,
AssemblyItem const& _swap1,
AssemblyItem const& _swapN,
AssemblyItem const& _comop,
std::back_insert_iterator<AssemblyItems> _out
)
{
static std::map<Instruction, Instruction> const swapMinusOne{
{ Instruction::SWAP2, Instruction::SWAP1 },
{ Instruction::SWAP3, Instruction::SWAP2 },
{ Instruction::SWAP4, Instruction::SWAP3 },
{ Instruction::SWAP5, Instruction::SWAP4 },
{ Instruction::SWAP6, Instruction::SWAP5 },
{ Instruction::SWAP7, Instruction::SWAP6 },
{ Instruction::SWAP8, Instruction::SWAP7 },
{ Instruction::SWAP9, Instruction::SWAP8 },
{ Instruction::SWAP10, Instruction::SWAP9 },
{ Instruction::SWAP11, Instruction::SWAP10 },
{ Instruction::SWAP12, Instruction::SWAP11 },
};

auto t = _push.type();

if (SemanticInformation::isCommutativeOperation(_comop) &&
_swap1 == Instruction::SWAP1 &&
_swapN.type() == Operation &&
swapMinusOne.count(_swapN.instruction()) &&
(t == Push || t == PushTag || t == PushSub ||
t == PushSubSize || t == PushProgramSize || t == PushData || t == PushLibraryAddress)
)
{
*_out = AssemblyItem(swapMinusOne.at(_swapN.instruction()), _swapN.debugData());
*_out = _push;
*_out = _comop;
return true;
}
else
return false;
}
};



/// Removes everything after a JUMP (or similar) until the next JUMPDEST.
struct UnreachableCode
{
@@ -618,9 +665,27 @@ bool PeepholeOptimiser::optimise()
while (state.i < m_items.size())
applyMethods(
state,
PushPop(), OpPop(), OpStop(), OpReturnRevert(), DoublePush(), DoubleSwap(), CommutativeSwap(), SwapComparison(),
DupSwap(), IsZeroIsZeroJumpI(), EqIsZeroJumpI(), DoubleJump(), JumpToNext(), UnreachableCode(), DeduplicateNextTagSize3(),
DeduplicateNextTagSize2(), DeduplicateNextTagSize1(), TagConjunctions(), TruthyAnd(), Identity()
PushPop(),
OpPop(),
OpStop(),
OpReturnRevert(),
DoublePush(),
DoubleSwap(),
CommutativeSwap(),
SwapComparison(),
DupSwap(),
IsZeroIsZeroJumpI(),
EqIsZeroJumpI(),
DoubleJump(),
JumpToNext(),
UnreachableCode(),
PushTwoSwapComop(),
DeduplicateNextTagSize3(),
DeduplicateNextTagSize2(),
DeduplicateNextTagSize1(),
TagConjunctions(),
TruthyAnd(),
Identity()
);
if (m_optimisedItems.size() < m_items.size() || (
m_optimisedItems.size() == m_items.size() && (
35 changes: 35 additions & 0 deletions test/libevmasm/Optimiser.cpp
Original file line number Diff line number Diff line change
@@ -1269,6 +1269,41 @@ BOOST_AUTO_TEST_CASE(peephole_truthy_and)
);
}

BOOST_AUTO_TEST_CASE(peephole_push_swap1_swapN_comop)
{
std::vector<Instruction> ops{
Instruction::ADD,
Instruction::MUL,
Instruction::EQ,
Instruction::AND,
Instruction::OR,
Instruction::XOR
};
for (Instruction const op: ops)
{
AssemblyItems items{
u256(121),
Instruction::SWAP1,
Instruction::SWAP5,
op,
u256(4),
u256(5)
};
AssemblyItems expectation{
Instruction::SWAP4,
u256(121),
op,
u256(4),
u256(5)
};
PeepholeOptimiser peepOpt(items, solidity::test::CommonOptions::get().evmVersion());
BOOST_REQUIRE(peepOpt.optimise());
BOOST_CHECK_EQUAL_COLLECTIONS(
items.begin(), items.end(),
expectation.begin(), expectation.end()
);
}
}

BOOST_AUTO_TEST_CASE(peephole_iszero_iszero_jumpi)
{