llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
loop_nesting.h
1 // This file if part of the llir-opt project.
2 // Licensing information can be found in the LICENSE file.
3 // (C) 2018 Nandor Licker. All rights reserved.
4 
5 #pragma once
6 
7 #include <memory>
8 #include <set>
9 #include <unordered_map>
10 #include <unordered_set>
11 #include <vector>
12 #include <llvm/ADT/iterator_range.h>
13 
14 #include "core/adt/hash.h"
15 #include "core/analysis/union_find.h"
16 
17 class Block;
18 class Func;
19 
20 
21 
28 class LoopNesting final {
29 public:
31  class Loop {
32  public:
34  const Block *GetHeader() const { return header_; }
35 
37  using LoopIter = std::vector<Loop *>::iterator;
38  LoopIter loop_begin() { return loops_.begin(); }
39  LoopIter loop_end() { return loops_.end(); }
40  llvm::iterator_range<LoopIter> loops()
41  {
42  return llvm::make_range(loop_begin(), loop_end());
43  }
44 
46  using BlockIter = std::vector<const Block *>::iterator;
47  BlockIter block_begin() { return blocks_.begin(); }
48  BlockIter block_end() { return blocks_.end(); }
49  llvm::iterator_range<BlockIter> blocks()
50  {
51  return llvm::make_range(block_begin(), block_end());
52  }
53 
54  private:
55  friend class LoopNesting;
57  Loop(const Block *header) : header_(header), blocks_({header}) {}
58 
59  public:
61  const Block *header_;
63  std::vector<Loop *> loops_;
65  std::vector<const Block *> blocks_;
66  };
67 
69  LoopNesting(const Func *func);
70 
72  bool IsLoopEdge(const Block *a, const Block *b);
73 
75  const Block *HighestAncestor(const Block *s, const Block *t);
76 
78  std::set<Loop *>::iterator begin() { return roots_.begin(); }
79  std::set<Loop *>::iterator end() { return roots_.end(); }
80 
82  void dump(llvm::raw_ostream &os = llvm::errs());
83 
84 private:
86  void FindLoop(unsigned header);
87 
89  bool IsCrossEdge(unsigned a, unsigned b);
91  bool IsTreeEdge(unsigned a, unsigned b);
93  bool IsForwardEdge(unsigned a, unsigned b);
95  bool IsBackEdge(unsigned a, unsigned b);
96 
98  unsigned DFS(const Block *block, unsigned parent);
100  void LCA(unsigned node);
101 
103  void MarkIrreducibleLoops(unsigned node);
104 
106  void HnCA(Loop *loop, std::set<const Block *> blocks);
107 
108 private:
110  using Edge = std::pair<unsigned, unsigned>;
111 
113  struct GraphNode {
115  unsigned Parent;
117  const Block *BlockPtr;
119  Loop *LoopPtr;
121  unsigned Start;
123  unsigned End;
124 
126  unsigned Link;
128  unsigned Rank;
130  unsigned Class;
131 
133  std::vector<unsigned> Pred;
135  std::vector<unsigned> Children;
137  std::vector<unsigned> CrossForwardCandidates;
139  std::vector<Edge> CrossForwardEdges;
140  };
141 
143  unsigned n_;
144 
146  std::vector<GraphNode> graph_;
148  std::unordered_map<const Block *, unsigned> blockToId_;
150  unsigned count_;
151 
153  UnionFind loopHeaders_;
155  UnionFind reducibleLoopHeaders_;
156 
158  UnionFind lcaParents_;
160  std::vector<bool> lcaVisited_;
162  std::vector<unsigned> lcaAncestor_;
163 
165  std::vector<bool> irreducibleLoopHeader_;
167  std::vector<std::optional<unsigned>> loopParent_;
168 
170  std::set<Loop *> roots_;
172  std::unordered_map<const Block *, std::unique_ptr<Loop>> blockToLoop_;
173 };
Func
Definition: func.h:30
LoopNesting::LoopNesting
LoopNesting(const Func *func)
Builds the loop nesting forest.
Definition: loop_nesting.cpp:16
LoopNesting
Definition: loop_nesting.h:28
LoopNesting::Loop::blocks_
std::vector< const Block * > blocks_
Nodes in the loop.
Definition: loop_nesting.h:65
LoopNesting::dump
void dump(llvm::raw_ostream &os=llvm::errs())
Prints the loop nesting information.
Definition: loop_nesting.cpp:245
LoopNesting::Loop::LoopIter
std::vector< Loop * >::iterator LoopIter
Iterator over loop children.
Definition: loop_nesting.h:37
LoopNesting::Loop::header_
const Block * header_
Header of the loop.
Definition: loop_nesting.h:61
LoopNesting::Loop::loops_
std::vector< Loop * > loops_
Loops in the loop.
Definition: loop_nesting.h:63
LoopNesting::Loop::BlockIter
std::vector< const Block * >::iterator BlockIter
Iterator over loop children.
Definition: loop_nesting.h:46
LoopNesting::Loop
Structure representing a loop.
Definition: loop_nesting.h:31
LoopNesting::IsLoopEdge
bool IsLoopEdge(const Block *a, const Block *b)
Checks if an edge is a loop edge.
Definition: loop_nesting.cpp:72
LoopNesting::HighestAncestor
const Block * HighestAncestor(const Block *s, const Block *t)
Returns the highest non-common ancestor of s and t.
Definition: loop_nesting.cpp:90
LoopNesting::begin
std::set< Loop * >::iterator begin()
Iterator over the loop nesting forest.
Definition: loop_nesting.h:78
Block
Definition: block.h:29
GraphNode
Definition: node.h:73
LoopNesting::Loop::GetHeader
const Block * GetHeader() const
Returns the loop header.
Definition: loop_nesting.h:34
UnionFind
Definition: union_find.h:18