Skip to content

Commit fa40814

Browse files
committed
SSA-CFG: Add pass to simplify negated condtions
When a jumo condition is a boolean negation (`iszero`), we can remove the negation and swap the zero and non-zero successors. This commit just adds the pass, but does not run it yet.
1 parent 6e2bd66 commit fa40814

3 files changed

Lines changed: 90 additions & 0 deletions

File tree

libyul/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ add_library(yul
110110
backends/evm/ssa/io/DotExporterBase.h
111111
backends/evm/ssa/io/JSONExporter.cpp
112112
backends/evm/ssa/io/JSONExporter.h
113+
backends/evm/ssa/transform/JumpConditionSimplifier.cpp
114+
backends/evm/ssa/transform/JumpConditionSimplifier.h
113115
backends/evm/ssa/transform/TrivialPhiEliminator.cpp
114116
backends/evm/ssa/transform/TrivialPhiEliminator.h
115117
backends/evm/ssa/transform/UnreachableBlockCleaner.cpp
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
This file is part of solidity.
3+
4+
solidity is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
solidity is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with solidity. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
// SPDX-License-Identifier: GPL-3.0
18+
19+
#include <libyul/backends/evm/ssa/transform/JumpConditionSimplifier.h>
20+
21+
#include <libyul/backends/evm/ssa/SSACFG.h>
22+
23+
namespace solidity::yul::ssa::transform
24+
{
25+
void simplifyNegatedJumpConditions(SSACFG& _cfg)
26+
{
27+
auto const maybeIsZero = _cfg.evmDialect.booleanNegationFunctionHandle();
28+
if (!maybeIsZero)
29+
return;
30+
auto const booleanNegationHandle = *maybeIsZero;
31+
for (SSACFG::BlockId blockId{0}; blockId.value < _cfg.numBlocks(); ++blockId.value)
32+
{
33+
auto & block = _cfg.block(blockId);
34+
if (!std::holds_alternative<SSACFG::BasicBlock::ConditionalJump>(block.exit))
35+
continue;
36+
auto & conditionalJump = std::get<SSACFG::BasicBlock::ConditionalJump>(block.exit);
37+
auto const condition = conditionalJump.condition;
38+
auto const & instruction = _cfg.inst(condition);
39+
if (instruction.opcode != InstOpcode::BuiltinCall)
40+
continue;
41+
42+
if (_cfg.builtinPayload(condition).builtin != booleanNegationHandle)
43+
continue;
44+
yulAssert(instruction.inputs.size() == 1);
45+
auto const arg = instruction.inputs.at(0);
46+
conditionalJump.condition = arg;
47+
std::swap(conditionalJump.zero, conditionalJump.nonZero);
48+
}
49+
}
50+
}
51+
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
This file is part of solidity.
3+
4+
solidity is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU General Public License as published by
6+
the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
solidity is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU General Public License for more details.
13+
14+
You should have received a copy of the GNU General Public License
15+
along with solidity. If not, see <http://www.gnu.org/licenses/>.
16+
*/
17+
// SPDX-License-Identifier: GPL-3.0
18+
/**
19+
* Removes trivial phis from an SSA CFG.
20+
*
21+
* A phi is trivial if all its upsilon operands provide the same value (modulo self-references).
22+
* Removal may cascade: eliminating one trivial phi can make others trivial.
23+
*/
24+
#pragma once
25+
26+
namespace solidity::yul::ssa
27+
{
28+
class SSACFG;
29+
namespace transform
30+
{
31+
32+
/// Removes unreachable blocks and cleans up references to them.
33+
void simplifyNegatedJumpConditions(SSACFG & _cfg);
34+
}
35+
}
36+
37+

0 commit comments

Comments
 (0)