Coverage Report

Created: 2025-09-08 08:10

/src/solidity/libyul/backends/evm/SSACFGLoopNestingForest.h
Line
Count
Source (jump to first uncovered line)
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
#pragma once
20
21
#include <libyul/backends/evm/SSACFGTopologicalSort.h>
22
#include <libyul/backends/evm/SSAControlFlowGraph.h>
23
24
#include <libsolutil/DisjointSet.h>
25
26
#include <cstddef>
27
#include <set>
28
#include <vector>
29
30
namespace solidity::yul
31
{
32
33
/// Constructs a loop nesting forest for an SSACFG using Tarjan's algorithm [1].
34
///
35
/// [1] Ramalingam, Ganesan. "Identifying loops in almost linear time."
36
///     ACM Transactions on Programming Languages and Systems (TOPLAS) 21.2 (1999): 175-188.
37
class SSACFGLoopNestingForest
38
{
39
public:
40
  explicit SSACFGLoopNestingForest(ForwardSSACFGTopologicalSort const& _sort);
41
42
  /// blocks which are not contained in a loop get assigned the loop parent numeric_limit<size_t>::max()
43
0
  std::vector<size_t> const& loopParents() const { return m_loopParents; }
44
  /// all loop nodes (entry blocks for loops), also nested ones
45
0
  std::set<size_t> const& loopNodes() const { return m_loopNodes; }
46
  /// root loop nodes in the forest for outer-most loops
47
0
  std::set<size_t> const& loopRootNodes() const { return m_loopRootNodes; }
48
private:
49
  void findLoop(size_t _potentialHeader);
50
  void collapse(std::set<size_t> const& _loopBody, size_t _loopHeader);
51
52
  ForwardSSACFGTopologicalSort const& m_sort;
53
  SSACFG const& m_cfg;
54
55
  util::ContiguousDisjointSet m_vertexPartition;
56
  std::vector<size_t> m_loopParents;
57
  std::set<size_t> m_loopNodes;
58
  std::set<size_t> m_loopRootNodes;
59
};
60
61
}