Skip to content

Commit d78bc8b

Browse files
committed
SSACFG backend: add stack abstraction
1 parent a5eb24d commit d78bc8b

File tree

3 files changed

+410
-1
lines changed

3 files changed

+410
-1
lines changed

libyul/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,10 @@ add_library(yul
8888
backends/evm/ssa/SSACFG.h
8989
backends/evm/ssa/SSACFGBuilder.cpp
9090
backends/evm/ssa/SSACFGBuilder.h
91-
backends/evm/ssa/SSACFGJsonExporter.h
9291
backends/evm/ssa/SSACFGJsonExporter.cpp
92+
backends/evm/ssa/SSACFGJsonExporter.h
93+
backends/evm/ssa/Stack.cpp
94+
backends/evm/ssa/Stack.h
9395
optimiser/ASTCopier.cpp
9496
optimiser/ASTCopier.h
9597
optimiser/ASTWalker.cpp

libyul/backends/evm/ssa/Stack.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
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/Stack.h>
20+
21+
#include <fmt/ranges.h>
22+
23+
#include <range/v3/view/drop.hpp>
24+
25+
namespace
26+
{
27+
size_t junkTailSize(solidity::yul::ssa::StackData const& _stackData)
28+
{
29+
std::size_t numJunk = 0;
30+
auto it = _stackData.begin();
31+
while (it != _stackData.end() && it->isJunk())
32+
{
33+
++numJunk;
34+
++it;
35+
}
36+
return numJunk;
37+
}
38+
}
39+
40+
namespace solidity::yul::ssa
41+
{
42+
43+
std::string slotToString(StackSlot const& _slot)
44+
{
45+
switch (_slot.kind())
46+
{
47+
case StackSlot::Kind::ValueID:
48+
if (_slot.isLiteralValueID())
49+
return fmt::format("lit{}", _slot.valueID().value());
50+
else
51+
return fmt::format("v{}", _slot.valueID().value());
52+
case StackSlot::Kind::Junk:
53+
return "JUNK";
54+
case StackSlot::Kind::FunctionCallReturnLabel:
55+
return fmt::format("FunctionCallReturnLabel[{}]", _slot.functionCallReturnLabel());
56+
case StackSlot::Kind::FunctionReturnLabel:
57+
return fmt::format("ReturnLabel[{}]", _slot.functionReturnLabel());
58+
}
59+
util::unreachable();
60+
}
61+
62+
std::string slotToString(StackSlot const& _slot, SSACFG const& _cfg)
63+
{
64+
if (_slot.kind() == StackSlot::Kind::ValueID)
65+
return _slot.valueID().str(_cfg);
66+
67+
return slotToString(_slot);
68+
}
69+
70+
std::string stackToString(StackData const& _stackData)
71+
{
72+
auto const numJunk = junkTailSize(_stackData);
73+
if (numJunk > 0)
74+
return fmt::format(
75+
"[JUNK x {}, {}]",
76+
numJunk,
77+
fmt::join(_stackData | ranges::views::drop(numJunk) | ranges::views::transform([&](auto const& _slot) { return slotToString(_slot); }), ", ")
78+
);
79+
80+
return fmt::format(
81+
"[{}]",
82+
fmt::join(_stackData | ranges::views::transform([&](auto const& _slot) { return slotToString(_slot); }), ", ")
83+
);
84+
}
85+
86+
std::string stackToString(StackData const& _stackData, SSACFG const& _cfg)
87+
{
88+
auto const numJunk = junkTailSize(_stackData);
89+
if (numJunk > 0)
90+
return fmt::format(
91+
"[JUNK x {}, {}]",
92+
numJunk,
93+
fmt::join(_stackData | ranges::views::drop(numJunk) | ranges::views::transform([&](auto const& _slot) { return slotToString(_slot, _cfg); }), ", ")
94+
);
95+
96+
return fmt::format(
97+
"[{}]",
98+
fmt::join(_stackData | ranges::views::transform([&](auto const& _slot) { return slotToString(_slot, _cfg); }), ", ")
99+
);
100+
}
101+
102+
}

0 commit comments

Comments
 (0)