@@ -37,6 +37,29 @@ constexpr auto literalsFilter(SSACFG const& _cfg)
37
37
}
38
38
}
39
39
40
+ std::set<SSACFG::ValueId> SSACFGLiveness::blockExitValues (SSACFG::BlockId const & _blockId) const
41
+ {
42
+ std::set<SSACFG::ValueId> result;
43
+ util::GenericVisitor exitVisitor {
44
+ [](SSACFG::BasicBlock::MainExit const &) {},
45
+ [&](SSACFG::BasicBlock::FunctionReturn const & _functionReturn) {
46
+ result += _functionReturn.returnValues | ranges::views::filter (literalsFilter (m_cfg));
47
+ },
48
+ [&](SSACFG::BasicBlock::JumpTable const & _jt) {
49
+ if (literalsFilter (m_cfg)(_jt.value ))
50
+ result.emplace (_jt.value );
51
+ },
52
+ [](SSACFG::BasicBlock::Jump const &) {},
53
+ [&](SSACFG::BasicBlock::ConditionalJump const & _conditionalJump) {
54
+ if (literalsFilter (m_cfg)(_conditionalJump.condition ))
55
+ result.emplace (_conditionalJump.condition );
56
+ },
57
+ [](SSACFG::BasicBlock::Terminated const &) {}
58
+ };
59
+ std::visit (exitVisitor, m_cfg.block (_blockId).exit );
60
+ return result;
61
+ }
62
+
40
63
SSACFGLiveness::SSACFGLiveness (SSACFG const & _cfg):
41
64
m_cfg(_cfg),
42
65
m_topologicalSort(_cfg),
@@ -70,12 +93,7 @@ void SSACFGLiveness::runDagDfs()
70
93
{
71
94
auto const & info = m_cfg.valueInfo (phi);
72
95
yulAssert (std::holds_alternative<SSACFG::PhiValue>(info), " value info of phi wasn't PhiValue" );
73
- auto const & entries = m_cfg.block (std::get<SSACFG::PhiValue>(info).block ).entries ;
74
- // this is getting the argument index of the phi function corresponding to the path going
75
- // through "blockId", ie, the currently handled block
76
- auto const it = entries.find (blockId);
77
- yulAssert (it != entries.end ());
78
- auto const argIndex = static_cast <size_t >(std::distance (entries.begin (), it));
96
+ auto const argIndex = m_cfg.phiArgumentIndex (blockId, _successor);
79
97
yulAssert (argIndex < std::get<SSACFG::PhiValue>(info).arguments .size ());
80
98
auto const arg = std::get<SSACFG::PhiValue>(info).arguments .at (argIndex);
81
99
if (!std::holds_alternative<SSACFG::LiteralValue>(m_cfg.valueInfo (arg)))
@@ -103,23 +121,7 @@ void SSACFGLiveness::runDagDfs()
103
121
// for each program point p in B, backwards, do:
104
122
{
105
123
// add value ids to the live set that are used in exit blocks
106
- util::GenericVisitor exitVisitor {
107
- [](SSACFG::BasicBlock::MainExit const &) {},
108
- [&](SSACFG::BasicBlock::FunctionReturn const & _functionReturn) {
109
- live += _functionReturn.returnValues | ranges::views::filter (literalsFilter (m_cfg));
110
- },
111
- [&](SSACFG::BasicBlock::JumpTable const & _jt) {
112
- if (literalsFilter (m_cfg)(_jt.value ))
113
- live.emplace (_jt.value );
114
- },
115
- [](SSACFG::BasicBlock::Jump const &) {},
116
- [&](SSACFG::BasicBlock::ConditionalJump const & _conditionalJump) {
117
- if (literalsFilter (m_cfg)(_conditionalJump.condition ))
118
- live.emplace (_conditionalJump.condition );
119
- },
120
- [](SSACFG::BasicBlock::Terminated const &) {}
121
- };
122
- std::visit (exitVisitor, block.exit );
124
+ live += blockExitValues (blockId);
123
125
124
126
for (auto const & op: block.operations | ranges::views::reverse)
125
127
{
@@ -163,12 +165,13 @@ void SSACFGLiveness::fillOperationsLiveOut()
163
165
{
164
166
for (size_t blockIdValue = 0 ; blockIdValue < m_cfg.numBlocks (); ++blockIdValue)
165
167
{
166
- auto const & operations = m_cfg.block (SSACFG::BlockId{blockIdValue}).operations ;
168
+ SSACFG::BlockId const blockId{blockIdValue};
169
+ auto const & operations = m_cfg.block (blockId).operations ;
167
170
auto & liveOuts = m_operationLiveOuts[blockIdValue];
168
171
liveOuts.resize (operations.size ());
169
172
if (!operations.empty ())
170
173
{
171
- auto live = m_liveOuts[blockIdValue];
174
+ auto live = m_liveOuts[blockIdValue] + blockExitValues (blockId) ;
172
175
auto rit = liveOuts.rbegin ();
173
176
for (auto const & op: operations | ranges::views::reverse)
174
177
{
0 commit comments