MimIR 0.1
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
looptree.h
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4
5#include <fe/cast.h>
6
7#include "mim/analyses/cfg.h"
8
9namespace mim {
10
11template<bool> class LoopTreeBuilder;
12
13/// Calculates a loop nesting forest rooted at LoopTree::root_.
14/// The implementation uses Steensgard's algorithm.
15/// Check out G. Ramalingam, "On Loops, Dominators, and Dominance Frontiers", 1999, for more information.
16template<bool forward> class LoopTree {
17public:
18 class Head;
19
20 /// Represents a node of a loop nesting forest.
21 /// A LoopTree::Base consists of a set of header CFNode%s.
22 /// The header CFNode%s are the set of CFNode%s not dominated by any other CFNode within the loop.
23 /// The root node is a LoopTree::Head without any CFNode%s but further children and `depth_ -1`.
24 /// Thus, the forest is pooled into a tree.
25 class Base : public fe::RuntimeCast<Base> {
26 public:
28 virtual ~Base() = default;
29
30 int depth() const { return depth_; }
31 const Head* parent() const { return parent_; }
32 auto cf_nodes() const { return cf_nodes_.view(); }
33 size_t num_cf_nodes() const { return cf_nodes().size(); }
34
35 protected:
38 int depth_;
39 };
40
41 /// A Head owns further nodes as children.
42 class Head : public Base {
43 private:
46
47 public:
48 auto children() const { return children_.view(); }
49 const Base* child(size_t i) const { return children_[i].get(); }
50 size_t num_children() const { return children().size(); }
51 bool is_root() const { return Base::parent_ == 0; }
52
53 private:
55
56 friend class Base;
57 friend class LoopTreeBuilder<forward>;
58 };
59
60 /// A Leaf only holds a single CFNode and does not have any children.
61 class Leaf : public Base {
62 private:
65 , index_(index) {
66 assert(Leaf::num_cf_nodes() == 1);
67 }
68
69 public:
70 const CFNode* cf_node() const { return Leaf::cf_nodes().front(); }
71 /// Index of a DFS of LoopTree::Leaf%s.
72 size_t index() const { return index_; }
73
74 private:
75 size_t index_;
76
77 friend class LoopTreeBuilder<forward>;
78 };
79
80 LoopTree(const LoopTree&) = delete;
82
83 explicit LoopTree(const CFG<forward>& cfg);
84 const CFG<forward>& cfg() const { return cfg_; }
85 const Head* root() const { return root_.get(); }
86 const Leaf* operator[](const CFNode* n) const { return find(leaves_, n); }
87
88private:
89 static void get_nodes(Vector<const Base*>& nodes, const Base* node) {
90 nodes.push_back(node);
91 if (auto head = node->template isa<Head>())
92 for (const auto& child : head->children()) get_nodes(nodes, child.get());
93 }
94
95 const CFG<forward>& cfg_;
96 typename CFG<forward>::template Map<Leaf*> leaves_;
97 std::unique_ptr<Head> root_;
98
99 template<bool f> friend std::ostream& operator<<(std::ostream&, const typename LoopTree<f>::Base*);
100 friend class LoopTreeBuilder<forward>;
101};
102
103} // namespace mim
A Control-Flow Graph.
Definition scope.h:8
A Control-Flow Node.
Definition cfg.h:27
Represents a node of a loop nesting forest.
Definition looptree.h:25
size_t num_cf_nodes() const
Definition looptree.h:33
Vector< const CFNode * > cf_nodes_
Definition looptree.h:37
const Head * parent() const
Definition looptree.h:31
virtual ~Base()=default
auto cf_nodes() const
Definition looptree.h:32
int depth() const
Definition looptree.h:30
Base(Head *parent, int depth, View< const CFNode * >)
Definition looptree.cpp:191
A Head owns further nodes as children.
Definition looptree.h:42
const Base * child(size_t i) const
Definition looptree.h:49
bool is_root() const
Definition looptree.h:51
friend class Base
Definition looptree.h:56
auto children() const
Definition looptree.h:48
size_t num_children() const
Definition looptree.h:50
A Leaf only holds a single CFNode and does not have any children.
Definition looptree.h:61
size_t index() const
Index of a DFS of LoopTree::Leafs.
Definition looptree.h:72
const CFNode * cf_node() const
Definition looptree.h:70
Calculates a loop nesting forest rooted at LoopTree::root_.
Definition looptree.h:16
friend std::ostream & operator<<(std::ostream &, const typename LoopTree< f >::Base *)
const CFG< forward > & cfg() const
Definition looptree.h:84
LoopTree & operator=(LoopTree)=delete
const Head * root() const
Definition looptree.h:85
const Leaf * operator[](const CFNode *n) const
Definition looptree.h:86
LoopTree(const LoopTree &)=delete
This is a thin wrapper for std::span<T, N> with the following additional features:
Definition span.h:28
This is a thin wrapper for absl::InlinedVector<T, N, / A> which in turn is a drop-in replacement for ...
Definition vector.h:16
Definition cfg.h:11
Value * find(IndexMap< Indexer, Key, Value * > &map, Key key)
Definition indexmap.h:67