llir-opt  0.0.1
Low-Level Post-Link Optimiser for OCaml and C
dominator.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 <llvm/ADT/iterator.h>
8 #include <llvm/Analysis/DominanceFrontier.h>
9 #include <llvm/Analysis/DominanceFrontierImpl.h>
10 #include <llvm/Support/GenericDomTree.h>
11 #include <llvm/Support/GenericDomTreeConstruction.h>
12 
13 #include "core/cfg.h"
14 #include "core/block.h"
15 #include "core/func.h"
16 
17 
18 
22 class DominatorTree : public llvm::DominatorTreeBase<Block, false> {
23 public:
24  DominatorTree(Func &f) { recalculate(f); }
25 
26  bool Dominates(const Block *start, const Block *end, const Block *block)
27  {
28  if (!dominates(end, block)) {
29  return false;
30  }
31  if (end->pred_size() == 1) {
32  return true;
33  }
34 
35  bool isDuplicateEdge = false;
36  for (const Block *bb : end->predecessors()) {
37  if (bb == start) {
38  if (isDuplicateEdge) {
39  return false;
40  }
41  isDuplicateEdge = true;
42  } else {
43  if (!dominates(end, bb)) {
44  return false;
45  }
46  }
47  }
48  return true;
49  }
50 };
51 
55 class PostDominatorTree : public llvm::DominatorTreeBase<Block, true> {
56 public:
57  PostDominatorTree(Func &f) { recalculate(f); }
58 
59  bool Dominates(const Block *start, const Block *end, const Block *block)
60  {
61  if (!dominates(start, block)) {
62  return false;
63  }
64  if (start->succ_size() == 1) {
65  return true;
66  }
67 
68  bool isDuplicateEdge = false;
69  for (const Block *bb : start->successors()) {
70  if (bb == end) {
71  if (isDuplicateEdge) {
72  return false;
73  }
74  isDuplicateEdge = true;
75  } else {
76  if (!dominates(start, bb)) {
77  return false;
78  }
79  }
80  }
81  return true;
82  }
83 };
84 
85 
89 class DominanceFrontier : public llvm::ForwardDominanceFrontierBase<Block> {
90 public:
91  using iterator = llvm::DominanceFrontierBase<Block, false>::iterator;
92  using const_iterator = llvm::DominanceFrontierBase<Block, false>::const_iterator;
93 };
94 
98 class PostDominanceFrontier : public llvm::ReverseDominanceFrontierBase<Block> {
99 public:
100  using iterator = llvm::DominanceFrontierBase<Block, true>::iterator;
101  using const_iterator = llvm::DominanceFrontierBase<Block, true>::const_iterator;
102 };
103 
104 
105 
106 namespace llvm {
107 namespace DomTreeBuilder {
108 
109 using BlockDomTree = llvm::DominatorTreeBase<Block, false>;
110 extern template void Calculate<BlockDomTree>(BlockDomTree &DT);
111 
112 } // end namespace DomTreeBuilder
113 } // end namespace llvm
llvm
Graph traits for call graph nodes.
Definition: call_graph.h:129
Func
Definition: func.h:30
PostDominatorTree
Definition: dominator.h:55
PostDominanceFrontier
Definition: dominator.h:98
DominanceFrontier
Definition: dominator.h:89
Block
Definition: block.h:29
DominatorTree
Definition: dominator.h:22