Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/include/llvm/Support/GenericDomTreeConstruction.h
Line
Count
Source (jump to first uncovered line)
1
//===- GenericDomTreeConstruction.h - Dominator Calculation ------*- C++ -*-==//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
/// \file
9
///
10
/// Generic dominator tree construction - This file provides routines to
11
/// construct immediate dominator information for a flow-graph based on the
12
/// Semi-NCA algorithm described in this dissertation:
13
///
14
///   Linear-Time Algorithms for Dominators and Related Problems
15
///   Loukas Georgiadis, Princeton University, November 2005, pp. 21-23:
16
///   ftp://ftp.cs.princeton.edu/reports/2005/737.pdf
17
///
18
/// Semi-NCA algorithm runs in O(n^2) worst-case time but usually slightly
19
/// faster than Simple Lengauer-Tarjan in practice.
20
///
21
/// O(n^2) worst cases happen when the computation of nearest common ancestors
22
/// requires O(n) average time, which is very unlikely in real world. If this
23
/// ever turns out to be an issue, consider implementing a hybrid algorithm.
24
///
25
/// The file uses the Depth Based Search algorithm to perform incremental
26
/// updates (insertion and deletions). The implemented algorithm is based on
27
/// this publication:
28
///
29
///   An Experimental Study of Dynamic Dominators
30
///   Loukas Georgiadis, et al., April 12 2016, pp. 5-7, 9-10:
31
///   https://arxiv.org/pdf/1604.02711.pdf
32
///
33
//===----------------------------------------------------------------------===//
34
35
#ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
36
#define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
37
38
#include <queue>
39
#include "llvm/ADT/ArrayRef.h"
40
#include "llvm/ADT/DenseSet.h"
41
#include "llvm/ADT/DepthFirstIterator.h"
42
#include "llvm/ADT/PointerIntPair.h"
43
#include "llvm/ADT/SmallPtrSet.h"
44
#include "llvm/Support/Debug.h"
45
#include "llvm/Support/GenericDomTree.h"
46
47
#define DEBUG_TYPE "dom-tree-builder"
48
49
namespace llvm {
50
namespace DomTreeBuilder {
51
52
template <typename DomTreeT>
53
struct SemiNCAInfo {
54
  using NodePtr = typename DomTreeT::NodePtr;
55
  using NodeT = typename DomTreeT::NodeType;
56
  using TreeNodePtr = DomTreeNodeBase<NodeT> *;
57
  using RootsT = decltype(DomTreeT::Roots);
58
  static constexpr bool IsPostDom = DomTreeT::IsPostDominator;
59
60
  // Information record used by Semi-NCA during tree construction.
61
  struct InfoRec {
62
    unsigned DFSNum = 0;
63
    unsigned Parent = 0;
64
    unsigned Semi = 0;
65
    NodePtr Label = nullptr;
66
    NodePtr IDom = nullptr;
67
    SmallVector<NodePtr, 2> ReverseChildren;
68
  };
69
70
  // Number to node mapping is 1-based. Initialize the mapping to start with
71
  // a dummy element.
72
  std::vector<NodePtr> NumToNode = {nullptr};
73
  DenseMap<NodePtr, InfoRec> NodeToInfo;
74
75
  using UpdateT = typename DomTreeT::UpdateType;
76
  using UpdateKind = typename DomTreeT::UpdateKind;
77
  struct BatchUpdateInfo {
78
    SmallVector<UpdateT, 4> Updates;
79
    using NodePtrAndKind = PointerIntPair<NodePtr, 1, UpdateKind>;
80
81
    // In order to be able to walk a CFG that is out of sync with the CFG
82
    // DominatorTree last knew about, use the list of updates to reconstruct
83
    // previous CFG versions of the current CFG. For each node, we store a set
84
    // of its virtually added/deleted future successors and predecessors.
85
    // Note that these children are from the future relative to what the
86
    // DominatorTree knows about -- using them to gets us some snapshot of the
87
    // CFG from the past (relative to the state of the CFG).
88
    DenseMap<NodePtr, SmallVector<NodePtrAndKind, 4>> FutureSuccessors;
89
    DenseMap<NodePtr, SmallVector<NodePtrAndKind, 4>> FuturePredecessors;
90
    // Remembers if the whole tree was recalculated at some point during the
91
    // current batch update.
92
    bool IsRecalculated = false;
93
  };
94
95
  BatchUpdateInfo *BatchUpdates;
96
  using BatchUpdatePtr = BatchUpdateInfo *;
97
98
  // If BUI is a nullptr, then there's no batch update in progress.
99
18.0M
  SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
99
2.61M
  SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
99
3.01M
  SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
99
11.2M
  SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
99
1.21M
  SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::BatchUpdateInfo*)
Line
Count
Source
99
28
  SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
99
8
  SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
99
214
  SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
100
101
34.7k
  void clear() {
102
34.7k
    NumToNode = {nullptr}; // Restore to initial state with a dummy start node.
103
34.7k
    NodeToInfo.clear();
104
34.7k
    // Don't reset the pointer to BatchUpdateInfo here -- if there's an update
105
34.7k
    // in progress, we need this information to continue it.
106
34.7k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::clear()
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::clear()
Line
Count
Source
101
1.38k
  void clear() {
102
1.38k
    NumToNode = {nullptr}; // Restore to initial state with a dummy start node.
103
1.38k
    NodeToInfo.clear();
104
1.38k
    // Don't reset the pointer to BatchUpdateInfo here -- if there's an update
105
1.38k
    // in progress, we need this information to continue it.
106
1.38k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::clear()
Line
Count
Source
101
4.71k
  void clear() {
102
4.71k
    NumToNode = {nullptr}; // Restore to initial state with a dummy start node.
103
4.71k
    NodeToInfo.clear();
104
4.71k
    // Don't reset the pointer to BatchUpdateInfo here -- if there's an update
105
4.71k
    // in progress, we need this information to continue it.
106
4.71k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::clear()
Line
Count
Source
101
28.6k
  void clear() {
102
28.6k
    NumToNode = {nullptr}; // Restore to initial state with a dummy start node.
103
28.6k
    NodeToInfo.clear();
104
28.6k
    // Don't reset the pointer to BatchUpdateInfo here -- if there's an update
105
28.6k
    // in progress, we need this information to continue it.
106
28.6k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::clear()
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::clear()
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::clear()
107
108
  template <bool Inverse>
109
  struct ChildrenGetter {
110
    using ResultTy = SmallVector<NodePtr, 8>;
111
112
111M
    static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) {
113
111M
      auto RChildren = reverse(children<NodePtr>(N));
114
111M
      return ResultTy(RChildren.begin(), RChildren.end());
115
111M
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ChildrenGetter<false>::Get(llvm::MachineBasicBlock*, std::__1::integral_constant<bool, false>)
Line
Count
Source
112
12.0M
    static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) {
113
12.0M
      auto RChildren = reverse(children<NodePtr>(N));
114
12.0M
      return ResultTy(RChildren.begin(), RChildren.end());
115
12.0M
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ChildrenGetter<false>::Get(llvm::MachineBasicBlock*, std::__1::integral_constant<bool, false>)
Line
Count
Source
112
8.53M
    static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) {
113
8.53M
      auto RChildren = reverse(children<NodePtr>(N));
114
8.53M
      return ResultTy(RChildren.begin(), RChildren.end());
115
8.53M
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ChildrenGetter<false>::Get(llvm::BasicBlock*, std::__1::integral_constant<bool, false>)
Line
Count
Source
112
87.7M
    static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) {
113
87.7M
      auto RChildren = reverse(children<NodePtr>(N));
114
87.7M
      return ResultTy(RChildren.begin(), RChildren.end());
115
87.7M
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ChildrenGetter<false>::Get(llvm::BasicBlock*, std::__1::integral_constant<bool, false>)
Line
Count
Source
112
3.07M
    static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) {
113
3.07M
      auto RChildren = reverse(children<NodePtr>(N));
114
3.07M
      return ResultTy(RChildren.begin(), RChildren.end());
115
3.07M
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::ChildrenGetter<false>::Get(llvm::VPBlockBase*, std::__1::integral_constant<bool, false>)
Line
Count
Source
112
135
    static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) {
113
135
      auto RChildren = reverse(children<NodePtr>(N));
114
135
      return ResultTy(RChildren.begin(), RChildren.end());
115
135
    }
116
117
23.6M
    static ResultTy Get(NodePtr N, std::integral_constant<bool, true>) {
118
23.6M
      auto IChildren = inverse_children<NodePtr>(N);
119
23.6M
      return ResultTy(IChildren.begin(), IChildren.end());
120
23.6M
    }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ChildrenGetter<true>::Get(llvm::MachineBasicBlock*, std::__1::integral_constant<bool, true>)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ChildrenGetter<true>::Get(llvm::MachineBasicBlock*, std::__1::integral_constant<bool, true>)
Line
Count
Source
117
17.0M
    static ResultTy Get(NodePtr N, std::integral_constant<bool, true>) {
118
17.0M
      auto IChildren = inverse_children<NodePtr>(N);
119
17.0M
      return ResultTy(IChildren.begin(), IChildren.end());
120
17.0M
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ChildrenGetter<true>::Get(llvm::BasicBlock*, std::__1::integral_constant<bool, true>)
Line
Count
Source
117
6.16M
    static ResultTy Get(NodePtr N, std::integral_constant<bool, true>) {
118
6.16M
      auto IChildren = inverse_children<NodePtr>(N);
119
6.16M
      return ResultTy(IChildren.begin(), IChildren.end());
120
6.16M
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ChildrenGetter<true>::Get(llvm::BasicBlock*, std::__1::integral_constant<bool, true>)
Line
Count
Source
117
414k
    static ResultTy Get(NodePtr N, std::integral_constant<bool, true>) {
118
414k
      auto IChildren = inverse_children<NodePtr>(N);
119
414k
      return ResultTy(IChildren.begin(), IChildren.end());
120
414k
    }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::ChildrenGetter<true>::Get(llvm::VPBlockBase*, std::__1::integral_constant<bool, true>)
121
122
    using Tag = std::integral_constant<bool, Inverse>;
123
124
    // The function below is the core part of the batch updater. It allows the
125
    // Depth Based Search algorithm to perform incremental updates in lockstep
126
    // with updates to the CFG. We emulated lockstep CFG updates by getting its
127
    // next snapshots by reverse-applying future updates.
128
134M
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
134M
      ResultTy Res = Get(N, Tag());
130
134M
      // If there's no batch update in progress, simply return node's children.
131
134M
      if (!BUI) 
return Res111M
;
132
23.8M
133
23.8M
      // CFG children are actually its *most current* children, and we have to
134
23.8M
      // reverse-apply the future updates to get the node's children at the
135
23.8M
      // point in time the update was performed.
136
23.8M
      auto &FutureChildren = (Inverse != IsPostDom) ? 
BUI->FuturePredecessors402k
137
23.8M
                                                    : 
BUI->FutureSuccessors23.4M
;
138
23.8M
      auto FCIt = FutureChildren.find(N);
139
23.8M
      if (FCIt == FutureChildren.end()) 
return Res23.0M
;
140
796k
141
1.09M
      
for (auto ChildAndKind : FCIt->second)796k
{
142
1.09M
        const NodePtr Child = ChildAndKind.getPointer();
143
1.09M
        const UpdateKind UK = ChildAndKind.getInt();
144
1.09M
145
1.09M
        // Reverse-apply the future update.
146
1.09M
        if (UK == UpdateKind::Insert) {
147
431k
          // If there's an insertion in the future, it means that the edge must
148
431k
          // exist in the current CFG, but was not present in it before.
149
431k
          assert(llvm::find(Res, Child) != Res.end()
150
431k
                 && "Expected child not found in the CFG");
151
431k
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
431k
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
431k
                            << BlockNamePrinter(Child) << "\n");
154
659k
        } else {
155
659k
          // If there's an deletion in the future, it means that the edge cannot
156
659k
          // exist in the current CFG, but existed in it before.
157
659k
          assert(llvm::find(Res, Child) == Res.end() &&
158
659k
                 "Unexpected child found in the CFG");
159
659k
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
659k
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
659k
          Res.push_back(Child);
162
659k
        }
163
1.09M
      }
164
796k
165
796k
      return Res;
166
796k
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ChildrenGetter<false>::Get(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
128
12.0M
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
12.0M
      ResultTy Res = Get(N, Tag());
130
12.0M
      // If there's no batch update in progress, simply return node's children.
131
12.0M
      if (!BUI) 
return Res12.0M
;
132
3
133
3
      // CFG children are actually its *most current* children, and we have to
134
3
      // reverse-apply the future updates to get the node's children at the
135
3
      // point in time the update was performed.
136
3
      auto &FutureChildren = (Inverse != IsPostDom) ? 
BUI->FuturePredecessors0
137
3
                                                    : BUI->FutureSuccessors;
138
3
      auto FCIt = FutureChildren.find(N);
139
3
      if (FCIt == FutureChildren.end()) 
return Res0
;
140
3
141
3
      for (auto ChildAndKind : FCIt->second) {
142
0
        const NodePtr Child = ChildAndKind.getPointer();
143
0
        const UpdateKind UK = ChildAndKind.getInt();
144
0
145
0
        // Reverse-apply the future update.
146
0
        if (UK == UpdateKind::Insert) {
147
0
          // If there's an insertion in the future, it means that the edge must
148
0
          // exist in the current CFG, but was not present in it before.
149
0
          assert(llvm::find(Res, Child) != Res.end()
150
0
                 && "Expected child not found in the CFG");
151
0
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
0
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
0
                            << BlockNamePrinter(Child) << "\n");
154
0
        } else {
155
0
          // If there's an deletion in the future, it means that the edge cannot
156
0
          // exist in the current CFG, but existed in it before.
157
0
          assert(llvm::find(Res, Child) == Res.end() &&
158
0
                 "Unexpected child found in the CFG");
159
0
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
0
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
0
          Res.push_back(Child);
162
0
        }
163
0
      }
164
3
165
3
      return Res;
166
3
    }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ChildrenGetter<true>::Get(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ChildrenGetter<false>::Get(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
128
8.53M
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
8.53M
      ResultTy Res = Get(N, Tag());
130
8.53M
      // If there's no batch update in progress, simply return node's children.
131
8.53M
      if (
!BUI8.53M
) return Res;
132
18.4E
133
18.4E
      // CFG children are actually its *most current* children, and we have to
134
18.4E
      // reverse-apply the future updates to get the node's children at the
135
18.4E
      // point in time the update was performed.
136
18.4E
      auto &FutureChildren = (Inverse != IsPostDom) ? 
BUI->FuturePredecessors0
137
18.4E
                                                    : BUI->FutureSuccessors;
138
18.4E
      auto FCIt = FutureChildren.find(N);
139
18.4E
      if (FCIt == FutureChildren.end()) 
return Res0
;
140
18.4E
141
18.4E
      for (auto ChildAndKind : FCIt->second) {
142
0
        const NodePtr Child = ChildAndKind.getPointer();
143
0
        const UpdateKind UK = ChildAndKind.getInt();
144
0
145
0
        // Reverse-apply the future update.
146
0
        if (UK == UpdateKind::Insert) {
147
0
          // If there's an insertion in the future, it means that the edge must
148
0
          // exist in the current CFG, but was not present in it before.
149
0
          assert(llvm::find(Res, Child) != Res.end()
150
0
                 && "Expected child not found in the CFG");
151
0
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
0
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
0
                            << BlockNamePrinter(Child) << "\n");
154
0
        } else {
155
0
          // If there's an deletion in the future, it means that the edge cannot
156
0
          // exist in the current CFG, but existed in it before.
157
0
          assert(llvm::find(Res, Child) == Res.end() &&
158
0
                 "Unexpected child found in the CFG");
159
0
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
0
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
0
          Res.push_back(Child);
162
0
        }
163
0
      }
164
18.4E
165
18.4E
      return Res;
166
18.4E
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ChildrenGetter<true>::Get(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
128
17.0M
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
17.0M
      ResultTy Res = Get(N, Tag());
130
17.0M
      // If there's no batch update in progress, simply return node's children.
131
17.0M
      if (!BUI) 
return Res17.0M
;
132
8
133
8
      // CFG children are actually its *most current* children, and we have to
134
8
      // reverse-apply the future updates to get the node's children at the
135
8
      // point in time the update was performed.
136
8
      auto &FutureChildren = (Inverse != IsPostDom) ? 
BUI->FuturePredecessors0
137
8
                                                    : BUI->FutureSuccessors;
138
8
      auto FCIt = FutureChildren.find(N);
139
8
      if (FCIt == FutureChildren.end()) 
return Res0
;
140
8
141
8
      for (auto ChildAndKind : FCIt->second) {
142
0
        const NodePtr Child = ChildAndKind.getPointer();
143
0
        const UpdateKind UK = ChildAndKind.getInt();
144
0
145
0
        // Reverse-apply the future update.
146
0
        if (UK == UpdateKind::Insert) {
147
0
          // If there's an insertion in the future, it means that the edge must
148
0
          // exist in the current CFG, but was not present in it before.
149
0
          assert(llvm::find(Res, Child) != Res.end()
150
0
                 && "Expected child not found in the CFG");
151
0
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
0
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
0
                            << BlockNamePrinter(Child) << "\n");
154
0
        } else {
155
0
          // If there's an deletion in the future, it means that the edge cannot
156
0
          // exist in the current CFG, but existed in it before.
157
0
          assert(llvm::find(Res, Child) == Res.end() &&
158
0
                 "Unexpected child found in the CFG");
159
0
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
0
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
0
          Res.push_back(Child);
162
0
        }
163
0
      }
164
8
165
8
      return Res;
166
8
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ChildrenGetter<false>::Get(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
128
87.7M
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
87.7M
      ResultTy Res = Get(N, Tag());
130
87.7M
      // If there's no batch update in progress, simply return node's children.
131
87.7M
      if (!BUI) 
return Res64.2M
;
132
23.4M
133
23.4M
      // CFG children are actually its *most current* children, and we have to
134
23.4M
      // reverse-apply the future updates to get the node's children at the
135
23.4M
      // point in time the update was performed.
136
23.4M
      auto &FutureChildren = (Inverse != IsPostDom) ? 
BUI->FuturePredecessors0
137
23.4M
                                                    : BUI->FutureSuccessors;
138
23.4M
      auto FCIt = FutureChildren.find(N);
139
23.4M
      if (FCIt == FutureChildren.end()) 
return Res22.7M
;
140
766k
141
1.04M
      
for (auto ChildAndKind : FCIt->second)766k
{
142
1.04M
        const NodePtr Child = ChildAndKind.getPointer();
143
1.04M
        const UpdateKind UK = ChildAndKind.getInt();
144
1.04M
145
1.04M
        // Reverse-apply the future update.
146
1.04M
        if (UK == UpdateKind::Insert) {
147
408k
          // If there's an insertion in the future, it means that the edge must
148
408k
          // exist in the current CFG, but was not present in it before.
149
408k
          assert(llvm::find(Res, Child) != Res.end()
150
408k
                 && "Expected child not found in the CFG");
151
408k
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
408k
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
408k
                            << BlockNamePrinter(Child) << "\n");
154
640k
        } else {
155
640k
          // If there's an deletion in the future, it means that the edge cannot
156
640k
          // exist in the current CFG, but existed in it before.
157
640k
          assert(llvm::find(Res, Child) == Res.end() &&
158
640k
                 "Unexpected child found in the CFG");
159
640k
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
640k
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
640k
          Res.push_back(Child);
162
640k
        }
163
1.04M
      }
164
766k
165
766k
      return Res;
166
766k
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ChildrenGetter<false>::Get(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
128
3.07M
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
3.07M
      ResultTy Res = Get(N, Tag());
130
3.07M
      // If there's no batch update in progress, simply return node's children.
131
3.07M
      if (!BUI) 
return Res3.06M
;
132
804
133
804
      // CFG children are actually its *most current* children, and we have to
134
804
      // reverse-apply the future updates to get the node's children at the
135
804
      // point in time the update was performed.
136
804
      auto &FutureChildren = (Inverse != IsPostDom) ? 
BUI->FuturePredecessors794
137
804
                                                    : 
BUI->FutureSuccessors10
;
138
804
      auto FCIt = FutureChildren.find(N);
139
804
      if (FCIt == FutureChildren.end()) 
return Res493
;
140
311
141
441
      
for (auto ChildAndKind : FCIt->second)311
{
142
441
        const NodePtr Child = ChildAndKind.getPointer();
143
441
        const UpdateKind UK = ChildAndKind.getInt();
144
441
145
441
        // Reverse-apply the future update.
146
441
        if (UK == UpdateKind::Insert) {
147
272
          // If there's an insertion in the future, it means that the edge must
148
272
          // exist in the current CFG, but was not present in it before.
149
272
          assert(llvm::find(Res, Child) != Res.end()
150
272
                 && "Expected child not found in the CFG");
151
272
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
272
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
272
                            << BlockNamePrinter(Child) << "\n");
154
272
        } else {
155
169
          // If there's an deletion in the future, it means that the edge cannot
156
169
          // exist in the current CFG, but existed in it before.
157
169
          assert(llvm::find(Res, Child) == Res.end() &&
158
169
                 "Unexpected child found in the CFG");
159
169
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
169
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
169
          Res.push_back(Child);
162
169
        }
163
441
      }
164
311
165
311
      return Res;
166
311
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ChildrenGetter<true>::Get(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
128
6.16M
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
6.16M
      ResultTy Res = Get(N, Tag());
130
6.16M
      // If there's no batch update in progress, simply return node's children.
131
6.16M
      if (!BUI) 
return Res6.16M
;
132
540
133
540
      // CFG children are actually its *most current* children, and we have to
134
540
      // reverse-apply the future updates to get the node's children at the
135
540
      // point in time the update was performed.
136
540
      auto &FutureChildren = (Inverse != IsPostDom) ? 
BUI->FuturePredecessors0
137
540
                                                    : BUI->FutureSuccessors;
138
540
      auto FCIt = FutureChildren.find(N);
139
540
      if (FCIt == FutureChildren.end()) 
return Res392
;
140
148
141
237
      
for (auto ChildAndKind : FCIt->second)148
{
142
237
        const NodePtr Child = ChildAndKind.getPointer();
143
237
        const UpdateKind UK = ChildAndKind.getInt();
144
237
145
237
        // Reverse-apply the future update.
146
237
        if (UK == UpdateKind::Insert) {
147
127
          // If there's an insertion in the future, it means that the edge must
148
127
          // exist in the current CFG, but was not present in it before.
149
127
          assert(llvm::find(Res, Child) != Res.end()
150
127
                 && "Expected child not found in the CFG");
151
127
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
127
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
127
                            << BlockNamePrinter(Child) << "\n");
154
127
        } else {
155
110
          // If there's an deletion in the future, it means that the edge cannot
156
110
          // exist in the current CFG, but existed in it before.
157
110
          assert(llvm::find(Res, Child) == Res.end() &&
158
110
                 "Unexpected child found in the CFG");
159
110
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
110
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
110
          Res.push_back(Child);
162
110
        }
163
237
      }
164
148
165
148
      return Res;
166
148
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ChildrenGetter<true>::Get(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
128
414k
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
414k
      ResultTy Res = Get(N, Tag());
130
414k
      // If there's no batch update in progress, simply return node's children.
131
414k
      if (!BUI) 
return Res12.2k
;
132
402k
133
402k
      // CFG children are actually its *most current* children, and we have to
134
402k
      // reverse-apply the future updates to get the node's children at the
135
402k
      // point in time the update was performed.
136
402k
      auto &FutureChildren = (Inverse != IsPostDom) ? BUI->FuturePredecessors
137
402k
                                                    : 
BUI->FutureSuccessors0
;
138
402k
      auto FCIt = FutureChildren.find(N);
139
402k
      if (FCIt == FutureChildren.end()) 
return Res372k
;
140
29.1k
141
42.2k
      
for (auto ChildAndKind : FCIt->second)29.1k
{
142
42.2k
        const NodePtr Child = ChildAndKind.getPointer();
143
42.2k
        const UpdateKind UK = ChildAndKind.getInt();
144
42.2k
145
42.2k
        // Reverse-apply the future update.
146
42.2k
        if (UK == UpdateKind::Insert) {
147
23.2k
          // If there's an insertion in the future, it means that the edge must
148
23.2k
          // exist in the current CFG, but was not present in it before.
149
23.2k
          assert(llvm::find(Res, Child) != Res.end()
150
23.2k
                 && "Expected child not found in the CFG");
151
23.2k
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
23.2k
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
23.2k
                            << BlockNamePrinter(Child) << "\n");
154
23.2k
        } else {
155
18.9k
          // If there's an deletion in the future, it means that the edge cannot
156
18.9k
          // exist in the current CFG, but existed in it before.
157
18.9k
          assert(llvm::find(Res, Child) == Res.end() &&
158
18.9k
                 "Unexpected child found in the CFG");
159
18.9k
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
18.9k
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
18.9k
          Res.push_back(Child);
162
18.9k
        }
163
42.2k
      }
164
29.1k
165
29.1k
      return Res;
166
29.1k
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::ChildrenGetter<false>::Get(llvm::VPBlockBase*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::BatchUpdateInfo*)
Line
Count
Source
128
135
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
135
      ResultTy Res = Get(N, Tag());
130
135
      // If there's no batch update in progress, simply return node's children.
131
135
      if (!BUI) return Res;
132
0
133
0
      // CFG children are actually its *most current* children, and we have to
134
0
      // reverse-apply the future updates to get the node's children at the
135
0
      // point in time the update was performed.
136
0
      auto &FutureChildren = (Inverse != IsPostDom) ? BUI->FuturePredecessors
137
0
                                                    : BUI->FutureSuccessors;
138
0
      auto FCIt = FutureChildren.find(N);
139
0
      if (FCIt == FutureChildren.end()) return Res;
140
0
141
0
      for (auto ChildAndKind : FCIt->second) {
142
0
        const NodePtr Child = ChildAndKind.getPointer();
143
0
        const UpdateKind UK = ChildAndKind.getInt();
144
0
145
0
        // Reverse-apply the future update.
146
0
        if (UK == UpdateKind::Insert) {
147
0
          // If there's an insertion in the future, it means that the edge must
148
0
          // exist in the current CFG, but was not present in it before.
149
0
          assert(llvm::find(Res, Child) != Res.end()
150
0
                 && "Expected child not found in the CFG");
151
0
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
0
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
0
                            << BlockNamePrinter(Child) << "\n");
154
0
        } else {
155
0
          // If there's an deletion in the future, it means that the edge cannot
156
0
          // exist in the current CFG, but existed in it before.
157
0
          assert(llvm::find(Res, Child) == Res.end() &&
158
0
                 "Unexpected child found in the CFG");
159
0
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
0
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
0
          Res.push_back(Child);
162
0
        }
163
0
      }
164
0
165
0
      return Res;
166
0
    }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::ChildrenGetter<true>::Get(llvm::VPBlockBase*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::BatchUpdateInfo*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::ChildrenGetter<false>::Get(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
128
66
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
66
      ResultTy Res = Get(N, Tag());
130
66
      // If there's no batch update in progress, simply return node's children.
131
66
      if (!BUI) return Res;
132
0
133
0
      // CFG children are actually its *most current* children, and we have to
134
0
      // reverse-apply the future updates to get the node's children at the
135
0
      // point in time the update was performed.
136
0
      auto &FutureChildren = (Inverse != IsPostDom) ? BUI->FuturePredecessors
137
0
                                                    : BUI->FutureSuccessors;
138
0
      auto FCIt = FutureChildren.find(N);
139
0
      if (FCIt == FutureChildren.end()) return Res;
140
0
141
0
      for (auto ChildAndKind : FCIt->second) {
142
0
        const NodePtr Child = ChildAndKind.getPointer();
143
0
        const UpdateKind UK = ChildAndKind.getInt();
144
0
145
0
        // Reverse-apply the future update.
146
0
        if (UK == UpdateKind::Insert) {
147
0
          // If there's an insertion in the future, it means that the edge must
148
0
          // exist in the current CFG, but was not present in it before.
149
0
          assert(llvm::find(Res, Child) != Res.end()
150
0
                 && "Expected child not found in the CFG");
151
0
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
0
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
0
                            << BlockNamePrinter(Child) << "\n");
154
0
        } else {
155
0
          // If there's an deletion in the future, it means that the edge cannot
156
0
          // exist in the current CFG, but existed in it before.
157
0
          assert(llvm::find(Res, Child) == Res.end() &&
158
0
                 "Unexpected child found in the CFG");
159
0
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
0
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
0
          Res.push_back(Child);
162
0
        }
163
0
      }
164
0
165
0
      return Res;
166
0
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::ChildrenGetter<false>::Get(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
128
549
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
549
      ResultTy Res = Get(N, Tag());
130
549
      // If there's no batch update in progress, simply return node's children.
131
549
      if (!BUI) return Res;
132
0
133
0
      // CFG children are actually its *most current* children, and we have to
134
0
      // reverse-apply the future updates to get the node's children at the
135
0
      // point in time the update was performed.
136
0
      auto &FutureChildren = (Inverse != IsPostDom) ? BUI->FuturePredecessors
137
0
                                                    : BUI->FutureSuccessors;
138
0
      auto FCIt = FutureChildren.find(N);
139
0
      if (FCIt == FutureChildren.end()) return Res;
140
0
141
0
      for (auto ChildAndKind : FCIt->second) {
142
0
        const NodePtr Child = ChildAndKind.getPointer();
143
0
        const UpdateKind UK = ChildAndKind.getInt();
144
0
145
0
        // Reverse-apply the future update.
146
0
        if (UK == UpdateKind::Insert) {
147
0
          // If there's an insertion in the future, it means that the edge must
148
0
          // exist in the current CFG, but was not present in it before.
149
0
          assert(llvm::find(Res, Child) != Res.end()
150
0
                 && "Expected child not found in the CFG");
151
0
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
0
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
0
                            << BlockNamePrinter(Child) << "\n");
154
0
        } else {
155
0
          // If there's an deletion in the future, it means that the edge cannot
156
0
          // exist in the current CFG, but existed in it before.
157
0
          assert(llvm::find(Res, Child) == Res.end() &&
158
0
                 "Unexpected child found in the CFG");
159
0
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
0
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
0
          Res.push_back(Child);
162
0
        }
163
0
      }
164
0
165
0
      return Res;
166
0
    }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::ChildrenGetter<true>::Get(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
128
1.09k
    static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) {
129
1.09k
      ResultTy Res = Get(N, Tag());
130
1.09k
      // If there's no batch update in progress, simply return node's children.
131
1.09k
      if (!BUI) return Res;
132
0
133
0
      // CFG children are actually its *most current* children, and we have to
134
0
      // reverse-apply the future updates to get the node's children at the
135
0
      // point in time the update was performed.
136
0
      auto &FutureChildren = (Inverse != IsPostDom) ? BUI->FuturePredecessors
137
0
                                                    : BUI->FutureSuccessors;
138
0
      auto FCIt = FutureChildren.find(N);
139
0
      if (FCIt == FutureChildren.end()) return Res;
140
0
141
0
      for (auto ChildAndKind : FCIt->second) {
142
0
        const NodePtr Child = ChildAndKind.getPointer();
143
0
        const UpdateKind UK = ChildAndKind.getInt();
144
0
145
0
        // Reverse-apply the future update.
146
0
        if (UK == UpdateKind::Insert) {
147
0
          // If there's an insertion in the future, it means that the edge must
148
0
          // exist in the current CFG, but was not present in it before.
149
0
          assert(llvm::find(Res, Child) != Res.end()
150
0
                 && "Expected child not found in the CFG");
151
0
          Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end());
152
0
          LLVM_DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> "
153
0
                            << BlockNamePrinter(Child) << "\n");
154
0
        } else {
155
0
          // If there's an deletion in the future, it means that the edge cannot
156
0
          // exist in the current CFG, but existed in it before.
157
0
          assert(llvm::find(Res, Child) == Res.end() &&
158
0
                 "Unexpected child found in the CFG");
159
0
          LLVM_DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N)
160
0
                            << " -> " << BlockNamePrinter(Child) << "\n");
161
0
          Res.push_back(Child);
162
0
        }
163
0
      }
164
0
165
0
      return Res;
166
0
    }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::ChildrenGetter<true>::Get(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*)
167
  };
168
169
74.8M
  NodePtr getIDom(NodePtr BB) const {
170
74.8M
    auto InfoIt = NodeToInfo.find(BB);
171
74.8M
    if (InfoIt == NodeToInfo.end()) 
return nullptr0
;
172
74.8M
173
74.8M
    return InfoIt->second.IDom;
174
74.8M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::getIDom(llvm::MachineBasicBlock*) const
Line
Count
Source
169
9.38M
  NodePtr getIDom(NodePtr BB) const {
170
9.38M
    auto InfoIt = NodeToInfo.find(BB);
171
9.38M
    if (InfoIt == NodeToInfo.end()) 
return nullptr0
;
172
9.38M
173
9.38M
    return InfoIt->second.IDom;
174
9.38M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::getIDom(llvm::MachineBasicBlock*) const
Line
Count
Source
169
8.52M
  NodePtr getIDom(NodePtr BB) const {
170
8.52M
    auto InfoIt = NodeToInfo.find(BB);
171
8.52M
    if (InfoIt == NodeToInfo.end()) 
return nullptr0
;
172
8.52M
173
8.52M
    return InfoIt->second.IDom;
174
8.52M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::getIDom(llvm::BasicBlock*) const
Line
Count
Source
169
53.8M
  NodePtr getIDom(NodePtr BB) const {
170
53.8M
    auto InfoIt = NodeToInfo.find(BB);
171
53.8M
    if (InfoIt == NodeToInfo.end()) 
return nullptr0
;
172
53.8M
173
53.8M
    return InfoIt->second.IDom;
174
53.8M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::getIDom(llvm::BasicBlock*) const
Line
Count
Source
169
3.06M
  NodePtr getIDom(NodePtr BB) const {
170
3.06M
    auto InfoIt = NodeToInfo.find(BB);
171
3.06M
    if (InfoIt == NodeToInfo.end()) 
return nullptr0
;
172
3.06M
173
3.06M
    return InfoIt->second.IDom;
174
3.06M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::getIDom(llvm::VPBlockBase*) const
Line
Count
Source
169
107
  NodePtr getIDom(NodePtr BB) const {
170
107
    auto InfoIt = NodeToInfo.find(BB);
171
107
    if (InfoIt == NodeToInfo.end()) 
return nullptr0
;
172
107
173
107
    return InfoIt->second.IDom;
174
107
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::getIDom(clang::CFGBlock*) const
Line
Count
Source
169
58
  NodePtr getIDom(NodePtr BB) const {
170
58
    auto InfoIt = NodeToInfo.find(BB);
171
58
    if (InfoIt == NodeToInfo.end()) 
return nullptr0
;
172
58
173
58
    return InfoIt->second.IDom;
174
58
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::getIDom(clang::CFGBlock*) const
Line
Count
Source
169
549
  NodePtr getIDom(NodePtr BB) const {
170
549
    auto InfoIt = NodeToInfo.find(BB);
171
549
    if (InfoIt == NodeToInfo.end()) 
return nullptr0
;
172
549
173
549
    return InfoIt->second.IDom;
174
549
  }
175
176
74.8M
  TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
177
74.8M
    if (TreeNodePtr Node = DT.getNode(BB)) 
return Node74.8M
;
178
1
179
1
    // Haven't calculated this node yet?  Get or calculate the node for the
180
1
    // immediate dominator.
181
1
    NodePtr IDom = getIDom(BB);
182
1
183
1
    assert(IDom || DT.DomTreeNodes[nullptr]);
184
1
    TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
185
1
186
1
    // Add a new tree node for this NodeT, and link it as a child of
187
1
    // IDomNode
188
1
    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
189
1
        llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
190
1
        .get();
191
1
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::getNodeForBlock(llvm::MachineBasicBlock*, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&)
Line
Count
Source
176
9.38M
  TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
177
9.38M
    if (TreeNodePtr Node = DT.getNode(BB)) return Node;
178
0
179
0
    // Haven't calculated this node yet?  Get or calculate the node for the
180
0
    // immediate dominator.
181
0
    NodePtr IDom = getIDom(BB);
182
0
183
0
    assert(IDom || DT.DomTreeNodes[nullptr]);
184
0
    TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
185
0
186
0
    // Add a new tree node for this NodeT, and link it as a child of
187
0
    // IDomNode
188
0
    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
189
0
        llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
190
0
        .get();
191
0
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::getNodeForBlock(llvm::MachineBasicBlock*, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&)
Line
Count
Source
176
8.52M
  TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
177
8.52M
    if (TreeNodePtr Node = DT.getNode(BB)) 
return Node8.52M
;
178
6
179
6
    // Haven't calculated this node yet?  Get or calculate the node for the
180
6
    // immediate dominator.
181
6
    NodePtr IDom = getIDom(BB);
182
6
183
6
    assert(IDom || DT.DomTreeNodes[nullptr]);
184
6
    TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
185
6
186
6
    // Add a new tree node for this NodeT, and link it as a child of
187
6
    // IDomNode
188
6
    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
189
6
        llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
190
6
        .get();
191
6
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::getNodeForBlock(llvm::BasicBlock*, llvm::DominatorTreeBase<llvm::BasicBlock, false>&)
Line
Count
Source
176
53.8M
  TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
177
53.8M
    if (TreeNodePtr Node = DT.getNode(BB)) return Node;
178
0
179
0
    // Haven't calculated this node yet?  Get or calculate the node for the
180
0
    // immediate dominator.
181
0
    NodePtr IDom = getIDom(BB);
182
0
183
0
    assert(IDom || DT.DomTreeNodes[nullptr]);
184
0
    TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
185
0
186
0
    // Add a new tree node for this NodeT, and link it as a child of
187
0
    // IDomNode
188
0
    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
189
0
        llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
190
0
        .get();
191
0
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::getNodeForBlock(llvm::BasicBlock*, llvm::DominatorTreeBase<llvm::BasicBlock, true>&)
Line
Count
Source
176
3.06M
  TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
177
3.06M
    if (TreeNodePtr 
Node3.06M
= DT.getNode(BB)) return Node;
178
18.4E
179
18.4E
    // Haven't calculated this node yet?  Get or calculate the node for the
180
18.4E
    // immediate dominator.
181
18.4E
    NodePtr IDom = getIDom(BB);
182
18.4E
183
18.4E
    assert(IDom || DT.DomTreeNodes[nullptr]);
184
18.4E
    TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
185
18.4E
186
18.4E
    // Add a new tree node for this NodeT, and link it as a child of
187
18.4E
    // IDomNode
188
18.4E
    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
189
18.4E
        llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
190
18.4E
        .get();
191
18.4E
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::getNodeForBlock(llvm::VPBlockBase*, llvm::DominatorTreeBase<llvm::VPBlockBase, false>&)
Line
Count
Source
176
107
  TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
177
107
    if (TreeNodePtr Node = DT.getNode(BB)) return Node;
178
0
179
0
    // Haven't calculated this node yet?  Get or calculate the node for the
180
0
    // immediate dominator.
181
0
    NodePtr IDom = getIDom(BB);
182
0
183
0
    assert(IDom || DT.DomTreeNodes[nullptr]);
184
0
    TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
185
0
186
0
    // Add a new tree node for this NodeT, and link it as a child of
187
0
    // IDomNode
188
0
    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
189
0
        llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
190
0
        .get();
191
0
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::getNodeForBlock(clang::CFGBlock*, llvm::DominatorTreeBase<clang::CFGBlock, false>&)
Line
Count
Source
176
58
  TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
177
58
    if (TreeNodePtr Node = DT.getNode(BB)) return Node;
178
0
179
0
    // Haven't calculated this node yet?  Get or calculate the node for the
180
0
    // immediate dominator.
181
0
    NodePtr IDom = getIDom(BB);
182
0
183
0
    assert(IDom || DT.DomTreeNodes[nullptr]);
184
0
    TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
185
0
186
0
    // Add a new tree node for this NodeT, and link it as a child of
187
0
    // IDomNode
188
0
    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
189
0
        llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
190
0
        .get();
191
0
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::getNodeForBlock(clang::CFGBlock*, llvm::DominatorTreeBase<clang::CFGBlock, true>&)
Line
Count
Source
176
549
  TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
177
549
    if (TreeNodePtr Node = DT.getNode(BB)) return Node;
178
0
179
0
    // Haven't calculated this node yet?  Get or calculate the node for the
180
0
    // immediate dominator.
181
0
    NodePtr IDom = getIDom(BB);
182
0
183
0
    assert(IDom || DT.DomTreeNodes[nullptr]);
184
0
    TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
185
0
186
0
    // Add a new tree node for this NodeT, and link it as a child of
187
0
    // IDomNode
188
0
    return (DT.DomTreeNodes[BB] = IDomNode->addChild(
189
0
        llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode)))
190
0
        .get();
191
0
  }
192
193
91.5M
  static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::AlwaysDescend(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)
Line
Count
Source
193
10.3M
  static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::AlwaysDescend(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)
Line
Count
Source
193
16.3M
  static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::AlwaysDescend(llvm::BasicBlock*, llvm::BasicBlock*)
Line
Count
Source
193
59.5M
  static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::AlwaysDescend(llvm::BasicBlock*, llvm::BasicBlock*)
Line
Count
Source
193
5.24M
  static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::AlwaysDescend(llvm::VPBlockBase*, llvm::VPBlockBase*)
Line
Count
Source
193
114
  static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::AlwaysDescend(clang::CFGBlock*, clang::CFGBlock*)
Line
Count
Source
193
61
  static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::AlwaysDescend(clang::CFGBlock*, clang::CFGBlock*)
Line
Count
Source
193
884
  static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
194
195
  struct BlockNamePrinter {
196
    NodePtr N;
197
198
0
    BlockNamePrinter(NodePtr Block) : N(Block) {}
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BlockNamePrinter::BlockNamePrinter(llvm::MachineBasicBlock*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BlockNamePrinter::BlockNamePrinter(llvm::MachineBasicBlock*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BlockNamePrinter::BlockNamePrinter(llvm::BasicBlock*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BlockNamePrinter::BlockNamePrinter(llvm::BasicBlock*)
199
0
    BlockNamePrinter(TreeNodePtr TN) : N(TN ? TN->getBlock() : nullptr) {}
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BlockNamePrinter::BlockNamePrinter(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BlockNamePrinter::BlockNamePrinter(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BlockNamePrinter::BlockNamePrinter(llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BlockNamePrinter::BlockNamePrinter(llvm::DomTreeNodeBase<llvm::BasicBlock>*)
200
201
0
    friend raw_ostream &operator<<(raw_ostream &O, const BlockNamePrinter &BP) {
202
0
      if (!BP.N)
203
0
        O << "nullptr";
204
0
      else
205
0
        BP.N->printAsOperand(O, false);
206
0
207
0
      return O;
208
0
    }
Unexecuted instantiation: llvm::DomTreeBuilder::operator<<(llvm::raw_ostream&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BlockNamePrinter const&)
Unexecuted instantiation: llvm::DomTreeBuilder::operator<<(llvm::raw_ostream&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BlockNamePrinter const&)
Unexecuted instantiation: llvm::DomTreeBuilder::operator<<(llvm::raw_ostream&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BlockNamePrinter const&)
Unexecuted instantiation: llvm::DomTreeBuilder::operator<<(llvm::raw_ostream&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BlockNamePrinter const&)
209
  };
210
211
  // Custom DFS implementation which can skip nodes based on a provided
212
  // predicate. It also collects ReverseChildren so that we don't have to spend
213
  // time getting predecessors in SemiNCA.
214
  //
215
  // If IsReverse is set to true, the DFS walk will be performed backwards
216
  // relative to IsPostDom -- using reverse edges for dominators and forward
217
  // edges for postdominators.
218
  template <bool IsReverse = false, typename DescendCondition>
219
  unsigned runDFS(NodePtr V, unsigned LastNum, DescendCondition Condition,
220
19.0M
                  unsigned AttachToNum) {
221
19.0M
    assert(V);
222
19.0M
    SmallVector<NodePtr, 64> WorkList = {V};
223
19.0M
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
19.0M
225
143M
    while (!WorkList.empty()) {
226
124M
      const NodePtr BB = WorkList.pop_back_val();
227
124M
      auto &BBInfo = NodeToInfo[BB];
228
124M
229
124M
      // Visited nodes always have positive DFS numbers.
230
124M
      if (BBInfo.DFSNum != 0) 
continue11.1M
;
231
113M
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
113M
      BBInfo.Label = BB;
233
113M
      NumToNode.push_back(BB);
234
113M
235
113M
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
113M
      for (const NodePtr Succ :
237
143M
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
143M
        const auto SIT = NodeToInfo.find(Succ);
239
143M
        // Don't visit nodes more than once but remember to collect
240
143M
        // ReverseChildren.
241
143M
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 048.4M
) {
242
37.2M
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)32.6M
;
243
37.2M
          continue;
244
37.2M
        }
245
106M
246
106M
        if (!Condition(BB, Succ)) 
continue778k
;
247
105M
248
105M
        // It's fine to add Succ to the map, because we know that it will be
249
105M
        // visited later.
250
105M
        auto &SuccInfo = NodeToInfo[Succ];
251
105M
        WorkList.push_back(Succ);
252
105M
        SuccInfo.Parent = LastNum;
253
105M
        SuccInfo.ReverseChildren.push_back(BB);
254
105M
      }
255
113M
    }
256
19.0M
257
19.0M
    return LastNum;
258
19.0M
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Line
Count
Source
220
2.61M
                  unsigned AttachToNum) {
221
2.61M
    assert(V);
222
2.61M
    SmallVector<NodePtr, 64> WorkList = {V};
223
2.61M
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
2.61M
225
15.6M
    while (!WorkList.empty()) {
226
13.0M
      const NodePtr BB = WorkList.pop_back_val();
227
13.0M
      auto &BBInfo = NodeToInfo[BB];
228
13.0M
229
13.0M
      // Visited nodes always have positive DFS numbers.
230
13.0M
      if (BBInfo.DFSNum != 0) 
continue1.00M
;
231
12.0M
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
12.0M
      BBInfo.Label = BB;
233
12.0M
      NumToNode.push_back(BB);
234
12.0M
235
12.0M
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
12.0M
      for (const NodePtr Succ :
237
14.2M
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
14.2M
        const auto SIT = NodeToInfo.find(Succ);
239
14.2M
        // Don't visit nodes more than once but remember to collect
240
14.2M
        // ReverseChildren.
241
14.2M
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 04.88M
) {
242
3.88M
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)3.38M
;
243
3.88M
          continue;
244
3.88M
        }
245
10.3M
246
10.3M
        if (!Condition(BB, Succ)) 
continue0
;
247
10.3M
248
10.3M
        // It's fine to add Succ to the map, because we know that it will be
249
10.3M
        // visited later.
250
10.3M
        auto &SuccInfo = NodeToInfo[Succ];
251
10.3M
        WorkList.push_back(Succ);
252
10.3M
        SuccInfo.Parent = LastNum;
253
10.3M
        SuccInfo.ReverseChildren.push_back(BB);
254
10.3M
      }
255
12.0M
    }
256
2.61M
257
2.61M
    return LastNum;
258
2.61M
  }
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<true, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Line
Count
Source
220
3.85M
                  unsigned AttachToNum) {
221
3.85M
    assert(V);
222
3.85M
    SmallVector<NodePtr, 64> WorkList = {V};
223
3.85M
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
3.85M
225
24.1M
    while (!WorkList.empty()) {
226
20.2M
      const NodePtr BB = WorkList.pop_back_val();
227
20.2M
      auto &BBInfo = NodeToInfo[BB];
228
20.2M
229
20.2M
      // Visited nodes always have positive DFS numbers.
230
20.2M
      if (BBInfo.DFSNum != 0) 
continue3.19M
;
231
17.0M
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
17.0M
      BBInfo.Label = BB;
233
17.0M
      NumToNode.push_back(BB);
234
17.0M
235
17.0M
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
17.0M
      for (const NodePtr Succ :
237
21.2M
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
21.2M
        const auto SIT = NodeToInfo.find(Succ);
239
21.2M
        // Don't visit nodes more than once but remember to collect
240
21.2M
        // ReverseChildren.
241
21.2M
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 08.08M
) {
242
4.88M
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)4.15M
;
243
4.88M
          continue;
244
4.88M
        }
245
16.3M
246
16.3M
        if (!Condition(BB, Succ)) 
continue0
;
247
16.3M
248
16.3M
        // It's fine to add Succ to the map, because we know that it will be
249
16.3M
        // visited later.
250
16.3M
        auto &SuccInfo = NodeToInfo[Succ];
251
16.3M
        WorkList.push_back(Succ);
252
16.3M
        SuccInfo.Parent = LastNum;
253
16.3M
        SuccInfo.ReverseChildren.push_back(BB);
254
16.3M
      }
255
17.0M
    }
256
3.85M
257
3.85M
    return LastNum;
258
3.85M
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<true, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Line
Count
Source
220
2.77k
                  unsigned AttachToNum) {
221
2.77k
    assert(V);
222
2.77k
    SmallVector<NodePtr, 64> WorkList = {V};
223
2.77k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
2.77k
225
11.6k
    while (!WorkList.empty()) {
226
8.91k
      const NodePtr BB = WorkList.pop_back_val();
227
8.91k
      auto &BBInfo = NodeToInfo[BB];
228
8.91k
229
8.91k
      // Visited nodes always have positive DFS numbers.
230
8.91k
      if (BBInfo.DFSNum != 0) 
continue1.50k
;
231
7.41k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
7.41k
      BBInfo.Label = BB;
233
7.41k
      NumToNode.push_back(BB);
234
7.41k
235
7.41k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
7.41k
      for (const NodePtr Succ :
237
12.2k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
12.2k
        const auto SIT = NodeToInfo.find(Succ);
239
12.2k
        // Don't visit nodes more than once but remember to collect
240
12.2k
        // ReverseChildren.
241
12.2k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 07.60k
) {
242
6.10k
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)3.45k
;
243
6.10k
          continue;
244
6.10k
        }
245
6.13k
246
6.13k
        if (!Condition(BB, Succ)) 
continue0
;
247
6.13k
248
6.13k
        // It's fine to add Succ to the map, because we know that it will be
249
6.13k
        // visited later.
250
6.13k
        auto &SuccInfo = NodeToInfo[Succ];
251
6.13k
        WorkList.push_back(Succ);
252
6.13k
        SuccInfo.Parent = LastNum;
253
6.13k
        SuccInfo.ReverseChildren.push_back(BB);
254
6.13k
      }
255
7.41k
    }
256
2.77k
257
2.77k
    return LastNum;
258
2.77k
  }
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int)
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
10.3M
                  unsigned AttachToNum) {
221
10.3M
    assert(V);
222
10.3M
    SmallVector<NodePtr, 64> WorkList = {V};
223
10.3M
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
10.3M
225
80.2M
    while (!WorkList.empty()) {
226
69.8M
      const NodePtr BB = WorkList.pop_back_val();
227
69.8M
      auto &BBInfo = NodeToInfo[BB];
228
69.8M
229
69.8M
      // Visited nodes always have positive DFS numbers.
230
69.8M
      if (BBInfo.DFSNum != 0) 
continue5.85M
;
231
64.0M
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
64.0M
      BBInfo.Label = BB;
233
64.0M
      NumToNode.push_back(BB);
234
64.0M
235
64.0M
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
64.0M
      for (const NodePtr Succ :
237
83.5M
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
83.5M
        const auto SIT = NodeToInfo.find(Succ);
239
83.5M
        // Don't visit nodes more than once but remember to collect
240
83.5M
        // ReverseChildren.
241
83.5M
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 029.9M
) {
242
24.0M
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)21.2M
;
243
24.0M
          continue;
244
24.0M
        }
245
59.5M
246
59.5M
        if (!Condition(BB, Succ)) 
continue0
;
247
59.5M
248
59.5M
        // It's fine to add Succ to the map, because we know that it will be
249
59.5M
        // visited later.
250
59.5M
        auto &SuccInfo = NodeToInfo[Succ];
251
59.5M
        WorkList.push_back(Succ);
252
59.5M
        SuccInfo.Parent = LastNum;
253
59.5M
        SuccInfo.ReverseChildren.push_back(BB);
254
59.5M
      }
255
64.0M
    }
256
10.3M
257
10.3M
    return LastNum;
258
10.3M
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
1.32M
                  unsigned AttachToNum) {
221
1.32M
    assert(V);
222
1.32M
    SmallVector<NodePtr, 64> WorkList = {V};
223
1.32M
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
1.32M
225
7.89M
    while (!WorkList.empty()) {
226
6.57M
      const NodePtr BB = WorkList.pop_back_val();
227
6.57M
      auto &BBInfo = NodeToInfo[BB];
228
6.57M
229
6.57M
      // Visited nodes always have positive DFS numbers.
230
6.57M
      if (BBInfo.DFSNum != 0) 
continue440k
;
231
6.13M
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
6.13M
      BBInfo.Label = BB;
233
6.13M
      NumToNode.push_back(BB);
234
6.13M
235
6.13M
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
6.13M
      for (const NodePtr Succ :
237
7.56M
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
7.56M
        const auto SIT = NodeToInfo.find(Succ);
239
7.56M
        // Don't visit nodes more than once but remember to collect
240
7.56M
        // ReverseChildren.
241
7.56M
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 02.75M
) {
242
2.31M
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)2.10M
;
243
2.31M
          continue;
244
2.31M
        }
245
5.24M
246
5.24M
        if (!Condition(BB, Succ)) 
continue0
;
247
5.24M
248
5.24M
        // It's fine to add Succ to the map, because we know that it will be
249
5.24M
        // visited later.
250
5.24M
        auto &SuccInfo = NodeToInfo[Succ];
251
5.24M
        WorkList.push_back(Succ);
252
5.24M
        SuccInfo.Parent = LastNum;
253
5.24M
        SuccInfo.ReverseChildren.push_back(BB);
254
5.24M
      }
255
6.13M
    }
256
1.32M
257
1.32M
    return LastNum;
258
1.32M
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<true, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
1.21k
                  unsigned AttachToNum) {
221
1.21k
    assert(V);
222
1.21k
    SmallVector<NodePtr, 64> WorkList = {V};
223
1.21k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
1.21k
225
4.15k
    while (!WorkList.empty()) {
226
2.94k
      const NodePtr BB = WorkList.pop_back_val();
227
2.94k
      auto &BBInfo = NodeToInfo[BB];
228
2.94k
229
2.94k
      // Visited nodes always have positive DFS numbers.
230
2.94k
      if (BBInfo.DFSNum != 0) 
continue105
;
231
2.83k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
2.83k
      BBInfo.Label = BB;
233
2.83k
      NumToNode.push_back(BB);
234
2.83k
235
2.83k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
2.83k
      for (const NodePtr Succ :
237
3.20k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
3.20k
        const auto SIT = NodeToInfo.find(Succ);
239
3.20k
        // Don't visit nodes more than once but remember to collect
240
3.20k
        // ReverseChildren.
241
3.20k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 01.58k
) {
242
1.47k
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)814
;
243
1.47k
          continue;
244
1.47k
        }
245
1.72k
246
1.72k
        if (!Condition(BB, Succ)) 
continue0
;
247
1.72k
248
1.72k
        // It's fine to add Succ to the map, because we know that it will be
249
1.72k
        // visited later.
250
1.72k
        auto &SuccInfo = NodeToInfo[Succ];
251
1.72k
        WorkList.push_back(Succ);
252
1.72k
        SuccInfo.Parent = LastNum;
253
1.72k
        SuccInfo.ReverseChildren.push_back(BB);
254
1.72k
      }
255
2.83k
    }
256
1.21k
257
1.21k
    return LastNum;
258
1.21k
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
114k
                  unsigned AttachToNum) {
221
114k
    assert(V);
222
114k
    SmallVector<NodePtr, 64> WorkList = {V};
223
114k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
114k
225
354k
    while (!WorkList.empty()) {
226
239k
      const NodePtr BB = WorkList.pop_back_val();
227
239k
      auto &BBInfo = NodeToInfo[BB];
228
239k
229
239k
      // Visited nodes always have positive DFS numbers.
230
239k
      if (BBInfo.DFSNum != 0) 
continue11.5k
;
231
228k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
228k
      BBInfo.Label = BB;
233
228k
      NumToNode.push_back(BB);
234
228k
235
228k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
228k
      for (const NodePtr Succ :
237
228k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
189k
        const auto SIT = NodeToInfo.find(Succ);
239
189k
        // Don't visit nodes more than once but remember to collect
240
189k
        // ReverseChildren.
241
189k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 049.8k
) {
242
38.2k
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)33.5k
;
243
38.2k
          continue;
244
38.2k
        }
245
150k
246
150k
        if (!Condition(BB, Succ)) 
continue25.4k
;
247
125k
248
125k
        // It's fine to add Succ to the map, because we know that it will be
249
125k
        // visited later.
250
125k
        auto &SuccInfo = NodeToInfo[Succ];
251
125k
        WorkList.push_back(Succ);
252
125k
        SuccInfo.Parent = LastNum;
253
125k
        SuccInfo.ReverseChildren.push_back(BB);
254
125k
      }
255
228k
    }
256
114k
257
114k
    return LastNum;
258
114k
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
3
                  unsigned AttachToNum) {
221
3
    assert(V);
222
3
    SmallVector<NodePtr, 64> WorkList = {V};
223
3
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
3
225
6
    while (!WorkList.empty()) {
226
3
      const NodePtr BB = WorkList.pop_back_val();
227
3
      auto &BBInfo = NodeToInfo[BB];
228
3
229
3
      // Visited nodes always have positive DFS numbers.
230
3
      if (BBInfo.DFSNum != 0) 
continue0
;
231
3
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
3
      BBInfo.Label = BB;
233
3
      NumToNode.push_back(BB);
234
3
235
3
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
3
      for (const NodePtr Succ :
237
3
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
0
        const auto SIT = NodeToInfo.find(Succ);
239
0
        // Don't visit nodes more than once but remember to collect
240
0
        // ReverseChildren.
241
0
        if (SIT != NodeToInfo.end() && SIT->second.DFSNum != 0) {
242
0
          if (Succ != BB) SIT->second.ReverseChildren.push_back(BB);
243
0
          continue;
244
0
        }
245
0
246
0
        if (!Condition(BB, Succ)) continue;
247
0
248
0
        // It's fine to add Succ to the map, because we know that it will be
249
0
        // visited later.
250
0
        auto &SuccInfo = NodeToInfo[Succ];
251
0
        WorkList.push_back(Succ);
252
0
        SuccInfo.Parent = LastNum;
253
0
        SuccInfo.ReverseChildren.push_back(BB);
254
0
      }
255
3
    }
256
3
257
3
    return LastNum;
258
3
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
399k
                  unsigned AttachToNum) {
221
399k
    assert(V);
222
399k
    SmallVector<NodePtr, 64> WorkList = {V};
223
399k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
399k
225
14.3M
    while (!WorkList.empty()) {
226
13.9M
      const NodePtr BB = WorkList.pop_back_val();
227
13.9M
      auto &BBInfo = NodeToInfo[BB];
228
13.9M
229
13.9M
      // Visited nodes always have positive DFS numbers.
230
13.9M
      if (BBInfo.DFSNum != 0) 
continue651k
;
231
13.2M
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
13.2M
      BBInfo.Label = BB;
233
13.2M
      NumToNode.push_back(BB);
234
13.2M
235
13.2M
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
13.2M
      for (const NodePtr Succ :
237
16.1M
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
16.1M
        const auto SIT = NodeToInfo.find(Succ);
239
16.1M
        // Don't visit nodes more than once but remember to collect
240
16.1M
        // ReverseChildren.
241
16.1M
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 02.60M
) {
242
1.95M
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)1.66M
;
243
1.95M
          continue;
244
1.95M
        }
245
14.1M
246
14.1M
        if (!Condition(BB, Succ)) 
continue660k
;
247
13.5M
248
13.5M
        // It's fine to add Succ to the map, because we know that it will be
249
13.5M
        // visited later.
250
13.5M
        auto &SuccInfo = NodeToInfo[Succ];
251
13.5M
        WorkList.push_back(Succ);
252
13.5M
        SuccInfo.Parent = LastNum;
253
13.5M
        SuccInfo.ReverseChildren.push_back(BB);
254
13.5M
      }
255
13.2M
    }
256
399k
257
399k
    return LastNum;
258
399k
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
303k
                  unsigned AttachToNum) {
221
303k
    assert(V);
222
303k
    SmallVector<NodePtr, 64> WorkList = {V};
223
303k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
303k
225
737k
    while (!WorkList.empty()) {
226
433k
      const NodePtr BB = WorkList.pop_back_val();
227
433k
      auto &BBInfo = NodeToInfo[BB];
228
433k
229
433k
      // Visited nodes always have positive DFS numbers.
230
433k
      if (BBInfo.DFSNum != 0) 
continue10.1k
;
231
423k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
423k
      BBInfo.Label = BB;
233
423k
      NumToNode.push_back(BB);
234
423k
235
423k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
423k
      for (const NodePtr Succ :
237
423k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
225k
        const auto SIT = NodeToInfo.find(Succ);
239
225k
        // Don't visit nodes more than once but remember to collect
240
225k
        // ReverseChildren.
241
225k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 060.7k
) {
242
50.5k
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)32.7k
;
243
50.5k
          continue;
244
50.5k
        }
245
174k
246
174k
        if (!Condition(BB, Succ)) 
continue44.3k
;
247
130k
248
130k
        // It's fine to add Succ to the map, because we know that it will be
249
130k
        // visited later.
250
130k
        auto &SuccInfo = NodeToInfo[Succ];
251
130k
        WorkList.push_back(Succ);
252
130k
        SuccInfo.Parent = LastNum;
253
130k
        SuccInfo.ReverseChildren.push_back(BB);
254
130k
      }
255
423k
    }
256
303k
257
303k
    return LastNum;
258
303k
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
24.0k
                  unsigned AttachToNum) {
221
24.0k
    assert(V);
222
24.0k
    SmallVector<NodePtr, 64> WorkList = {V};
223
24.0k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
24.0k
225
358k
    while (!WorkList.empty()) {
226
334k
      const NodePtr BB = WorkList.pop_back_val();
227
334k
      auto &BBInfo = NodeToInfo[BB];
228
334k
229
334k
      // Visited nodes always have positive DFS numbers.
230
334k
      if (BBInfo.DFSNum != 0) 
continue17.9k
;
231
316k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
316k
      BBInfo.Label = BB;
233
316k
      NumToNode.push_back(BB);
234
316k
235
316k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
316k
      for (const NodePtr Succ :
237
439k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
439k
        const auto SIT = NodeToInfo.find(Succ);
239
439k
        // Don't visit nodes more than once but remember to collect
240
439k
        // ReverseChildren.
241
439k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 0107k
) {
242
89.5k
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)75.9k
;
243
89.5k
          continue;
244
89.5k
        }
245
349k
246
349k
        if (!Condition(BB, Succ)) 
continue39.2k
;
247
310k
248
310k
        // It's fine to add Succ to the map, because we know that it will be
249
310k
        // visited later.
250
310k
        auto &SuccInfo = NodeToInfo[Succ];
251
310k
        WorkList.push_back(Succ);
252
310k
        SuccInfo.Parent = LastNum;
253
310k
        SuccInfo.ReverseChildren.push_back(BB);
254
310k
      }
255
316k
    }
256
24.0k
257
24.0k
    return LastNum;
258
24.0k
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
93
                  unsigned AttachToNum) {
221
93
    assert(V);
222
93
    SmallVector<NodePtr, 64> WorkList = {V};
223
93
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
93
225
478
    while (!WorkList.empty()) {
226
385
      const NodePtr BB = WorkList.pop_back_val();
227
385
      auto &BBInfo = NodeToInfo[BB];
228
385
229
385
      // Visited nodes always have positive DFS numbers.
230
385
      if (BBInfo.DFSNum != 0) 
continue13
;
231
372
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
372
      BBInfo.Label = BB;
233
372
      NumToNode.push_back(BB);
234
372
235
372
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
372
      for (const NodePtr Succ :
237
392
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
392
        const auto SIT = NodeToInfo.find(Succ);
239
392
        // Don't visit nodes more than once but remember to collect
240
392
        // ReverseChildren.
241
392
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 044
) {
242
31
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)28
;
243
31
          continue;
244
31
        }
245
361
246
361
        if (!Condition(BB, Succ)) 
continue69
;
247
292
248
292
        // It's fine to add Succ to the map, because we know that it will be
249
292
        // visited later.
250
292
        auto &SuccInfo = NodeToInfo[Succ];
251
292
        WorkList.push_back(Succ);
252
292
        SuccInfo.Parent = LastNum;
253
292
        SuccInfo.ReverseChildren.push_back(BB);
254
292
      }
255
372
    }
256
93
257
93
    return LastNum;
258
93
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
1.73k
                  unsigned AttachToNum) {
221
1.73k
    assert(V);
222
1.73k
    SmallVector<NodePtr, 64> WorkList = {V};
223
1.73k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
1.73k
225
9.69k
    while (!WorkList.empty()) {
226
7.95k
      const NodePtr BB = WorkList.pop_back_val();
227
7.95k
      auto &BBInfo = NodeToInfo[BB];
228
7.95k
229
7.95k
      // Visited nodes always have positive DFS numbers.
230
7.95k
      if (BBInfo.DFSNum != 0) 
continue141
;
231
7.81k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
7.81k
      BBInfo.Label = BB;
233
7.81k
      NumToNode.push_back(BB);
234
7.81k
235
7.81k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
7.81k
      for (const NodePtr Succ :
237
8.68k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
8.68k
        const auto SIT = NodeToInfo.find(Succ);
239
8.68k
        // Don't visit nodes more than once but remember to collect
240
8.68k
        // ReverseChildren.
241
8.68k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 0768
) {
242
627
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)450
;
243
627
          continue;
244
627
        }
245
8.06k
246
8.06k
        if (!Condition(BB, Succ)) 
continue1.84k
;
247
6.21k
248
6.21k
        // It's fine to add Succ to the map, because we know that it will be
249
6.21k
        // visited later.
250
6.21k
        auto &SuccInfo = NodeToInfo[Succ];
251
6.21k
        WorkList.push_back(Succ);
252
6.21k
        SuccInfo.Parent = LastNum;
253
6.21k
        SuccInfo.ReverseChildren.push_back(BB);
254
6.21k
      }
255
7.81k
    }
256
1.73k
257
1.73k
    return LastNum;
258
1.73k
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
2.46k
                  unsigned AttachToNum) {
221
2.46k
    assert(V);
222
2.46k
    SmallVector<NodePtr, 64> WorkList = {V};
223
2.46k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
2.46k
225
19.2k
    while (!WorkList.empty()) {
226
16.7k
      const NodePtr BB = WorkList.pop_back_val();
227
16.7k
      auto &BBInfo = NodeToInfo[BB];
228
16.7k
229
16.7k
      // Visited nodes always have positive DFS numbers.
230
16.7k
      if (BBInfo.DFSNum != 0) 
continue351
;
231
16.4k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
16.4k
      BBInfo.Label = BB;
233
16.4k
      NumToNode.push_back(BB);
234
16.4k
235
16.4k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
16.4k
      for (const NodePtr Succ :
237
18.5k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
18.5k
        const auto SIT = NodeToInfo.find(Succ);
239
18.5k
        // Don't visit nodes more than once but remember to collect
240
18.5k
        // ReverseChildren.
241
18.5k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 01.88k
) {
242
1.53k
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)1.28k
;
243
1.53k
          continue;
244
1.53k
        }
245
17.0k
246
17.0k
        if (!Condition(BB, Succ)) 
continue2.74k
;
247
14.3k
248
14.3k
        // It's fine to add Succ to the map, because we know that it will be
249
14.3k
        // visited later.
250
14.3k
        auto &SuccInfo = NodeToInfo[Succ];
251
14.3k
        WorkList.push_back(Succ);
252
14.3k
        SuccInfo.Parent = LastNum;
253
14.3k
        SuccInfo.ReverseChildren.push_back(BB);
254
14.3k
      }
255
16.4k
    }
256
2.46k
257
2.46k
    return LastNum;
258
2.46k
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
5.13k
                  unsigned AttachToNum) {
221
5.13k
    assert(V);
222
5.13k
    SmallVector<NodePtr, 64> WorkList = {V};
223
5.13k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
5.13k
225
20.3k
    while (!WorkList.empty()) {
226
15.1k
      const NodePtr BB = WorkList.pop_back_val();
227
15.1k
      auto &BBInfo = NodeToInfo[BB];
228
15.1k
229
15.1k
      // Visited nodes always have positive DFS numbers.
230
15.1k
      if (BBInfo.DFSNum != 0) 
continue435
;
231
14.7k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
14.7k
      BBInfo.Label = BB;
233
14.7k
      NumToNode.push_back(BB);
234
14.7k
235
14.7k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
14.7k
      for (const NodePtr Succ :
237
15.3k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
15.3k
        const auto SIT = NodeToInfo.find(Succ);
239
15.3k
        // Don't visit nodes more than once but remember to collect
240
15.3k
        // ReverseChildren.
241
15.3k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 03.23k
) {
242
2.80k
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)2.79k
;
243
2.80k
          continue;
244
2.80k
        }
245
12.5k
246
12.5k
        if (!Condition(BB, Succ)) 
continue2.49k
;
247
10.0k
248
10.0k
        // It's fine to add Succ to the map, because we know that it will be
249
10.0k
        // visited later.
250
10.0k
        auto &SuccInfo = NodeToInfo[Succ];
251
10.0k
        WorkList.push_back(Succ);
252
10.0k
        SuccInfo.Parent = LastNum;
253
10.0k
        SuccInfo.ReverseChildren.push_back(BB);
254
10.0k
      }
255
14.7k
    }
256
5.13k
257
5.13k
    return LastNum;
258
5.13k
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Line
Count
Source
220
6.04k
                  unsigned AttachToNum) {
221
6.04k
    assert(V);
222
6.04k
    SmallVector<NodePtr, 64> WorkList = {V};
223
6.04k
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
6.04k
225
26.7k
    while (!WorkList.empty()) {
226
20.7k
      const NodePtr BB = WorkList.pop_back_val();
227
20.7k
      auto &BBInfo = NodeToInfo[BB];
228
20.7k
229
20.7k
      // Visited nodes always have positive DFS numbers.
230
20.7k
      if (BBInfo.DFSNum != 0) 
continue807
;
231
19.9k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
19.9k
      BBInfo.Label = BB;
233
19.9k
      NumToNode.push_back(BB);
234
19.9k
235
19.9k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
19.9k
      for (const NodePtr Succ :
237
21.3k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
21.3k
        const auto SIT = NodeToInfo.find(Succ);
239
21.3k
        // Don't visit nodes more than once but remember to collect
240
21.3k
        // ReverseChildren.
241
21.3k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 05.14k
) {
242
4.33k
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)4.32k
;
243
4.33k
          continue;
244
4.33k
        }
245
17.0k
246
17.0k
        if (!Condition(BB, Succ)) 
continue2.35k
;
247
14.6k
248
14.6k
        // It's fine to add Succ to the map, because we know that it will be
249
14.6k
        // visited later.
250
14.6k
        auto &SuccInfo = NodeToInfo[Succ];
251
14.6k
        WorkList.push_back(Succ);
252
14.6k
        SuccInfo.Parent = LastNum;
253
14.6k
        SuccInfo.ReverseChildren.push_back(BB);
254
14.6k
      }
255
19.9k
    }
256
6.04k
257
6.04k
    return LastNum;
258
6.04k
  }
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<true, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int)
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::runDFS<false, bool (*)(llvm::VPBlockBase*, llvm::VPBlockBase*)>(llvm::VPBlockBase*, unsigned int, bool (*)(llvm::VPBlockBase*, llvm::VPBlockBase*), unsigned int)
Line
Count
Source
220
28
                  unsigned AttachToNum) {
221
28
    assert(V);
222
28
    SmallVector<NodePtr, 64> WorkList = {V};
223
28
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
28
225
170
    while (!WorkList.empty()) {
226
142
      const NodePtr BB = WorkList.pop_back_val();
227
142
      auto &BBInfo = NodeToInfo[BB];
228
142
229
142
      // Visited nodes always have positive DFS numbers.
230
142
      if (BBInfo.DFSNum != 0) 
continue7
;
231
135
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
135
      BBInfo.Label = BB;
233
135
      NumToNode.push_back(BB);
234
135
235
135
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
135
      for (const NodePtr Succ :
237
158
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
158
        const auto SIT = NodeToInfo.find(Succ);
239
158
        // Don't visit nodes more than once but remember to collect
240
158
        // ReverseChildren.
241
158
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 051
) {
242
44
          if (Succ != BB) 
SIT->second.ReverseChildren.push_back(BB)25
;
243
44
          continue;
244
44
        }
245
114
246
114
        if (!Condition(BB, Succ)) 
continue0
;
247
114
248
114
        // It's fine to add Succ to the map, because we know that it will be
249
114
        // visited later.
250
114
        auto &SuccInfo = NodeToInfo[Succ];
251
114
        WorkList.push_back(Succ);
252
114
        SuccInfo.Parent = LastNum;
253
114
        SuccInfo.ReverseChildren.push_back(BB);
254
114
      }
255
135
    }
256
28
257
28
    return LastNum;
258
28
  }
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::runDFS<true, bool (*)(llvm::VPBlockBase*, llvm::VPBlockBase*)>(llvm::VPBlockBase*, unsigned int, bool (*)(llvm::VPBlockBase*, llvm::VPBlockBase*), unsigned int)
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::runDFS<false, bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(clang::CFGBlock*, unsigned int, bool (*)(clang::CFGBlock*, clang::CFGBlock*), unsigned int)
Line
Count
Source
220
8
                  unsigned AttachToNum) {
221
8
    assert(V);
222
8
    SmallVector<NodePtr, 64> WorkList = {V};
223
8
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
8
225
77
    while (!WorkList.empty()) {
226
69
      const NodePtr BB = WorkList.pop_back_val();
227
69
      auto &BBInfo = NodeToInfo[BB];
228
69
229
69
      // Visited nodes always have positive DFS numbers.
230
69
      if (BBInfo.DFSNum != 0) 
continue3
;
231
66
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
66
      BBInfo.Label = BB;
233
66
      NumToNode.push_back(BB);
234
66
235
66
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
66
      for (const NodePtr Succ :
237
74
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
74
        const auto SIT = NodeToInfo.find(Succ);
239
74
        // Don't visit nodes more than once but remember to collect
240
74
        // ReverseChildren.
241
74
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 016
) {
242
13
          if (Succ != BB) SIT->second.ReverseChildren.push_back(BB);
243
13
          continue;
244
13
        }
245
61
246
61
        if (!Condition(BB, Succ)) 
continue0
;
247
61
248
61
        // It's fine to add Succ to the map, because we know that it will be
249
61
        // visited later.
250
61
        auto &SuccInfo = NodeToInfo[Succ];
251
61
        WorkList.push_back(Succ);
252
61
        SuccInfo.Parent = LastNum;
253
61
        SuccInfo.ReverseChildren.push_back(BB);
254
61
      }
255
66
    }
256
8
257
8
    return LastNum;
258
8
  }
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::runDFS<false, bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(clang::CFGBlock*, unsigned int, bool (*)(clang::CFGBlock*, clang::CFGBlock*), unsigned int)
Line
Count
Source
220
214
                  unsigned AttachToNum) {
221
214
    assert(V);
222
214
    SmallVector<NodePtr, 64> WorkList = {V};
223
214
    if (NodeToInfo.count(V) != 0) 
NodeToInfo[V].Parent = AttachToNum0
;
224
214
225
1.31k
    while (!WorkList.empty()) {
226
1.09k
      const NodePtr BB = WorkList.pop_back_val();
227
1.09k
      auto &BBInfo = NodeToInfo[BB];
228
1.09k
229
1.09k
      // Visited nodes always have positive DFS numbers.
230
1.09k
      if (BBInfo.DFSNum != 0) 
continue0
;
231
1.09k
      BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
232
1.09k
      BBInfo.Label = BB;
233
1.09k
      NumToNode.push_back(BB);
234
1.09k
235
1.09k
      constexpr bool Direction = IsReverse != IsPostDom;  // XOR.
236
1.09k
      for (const NodePtr Succ :
237
1.17k
           ChildrenGetter<Direction>::Get(BB, BatchUpdates)) {
238
1.17k
        const auto SIT = NodeToInfo.find(Succ);
239
1.17k
        // Don't visit nodes more than once but remember to collect
240
1.17k
        // ReverseChildren.
241
1.17k
        if (SIT != NodeToInfo.end() && 
SIT->second.DFSNum != 0294
) {
242
294
          if (Succ != BB) SIT->second.ReverseChildren.push_back(BB);
243
294
          continue;
244
294
        }
245
884
246
884
        if (!Condition(BB, Succ)) 
continue0
;
247
884
248
884
        // It's fine to add Succ to the map, because we know that it will be
249
884
        // visited later.
250
884
        auto &SuccInfo = NodeToInfo[Succ];
251
884
        WorkList.push_back(Succ);
252
884
        SuccInfo.Parent = LastNum;
253
884
        SuccInfo.ReverseChildren.push_back(BB);
254
884
      }
255
1.09k
    }
256
214
257
214
    return LastNum;
258
214
  }
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::runDFS<true, bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(clang::CFGBlock*, unsigned int, bool (*)(clang::CFGBlock*, clang::CFGBlock*), unsigned int)
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::runDFS<true, bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(clang::CFGBlock*, unsigned int, bool (*)(clang::CFGBlock*, clang::CFGBlock*), unsigned int)
259
260
  // V is a predecessor of W. eval() returns V if V < W, otherwise the minimum
261
  // of sdom(U), where U > W and there is a virtual forest path from U to V. The
262
  // virtual forest consists of linked edges of processed vertices.
263
  //
264
  // We can follow Parent pointers (virtual forest edges) to determine the
265
  // ancestor U with minimum sdom(U). But it is slow and thus we employ the path
266
  // compression technique to speed up to O(m*log(n)). Theoretically the virtual
267
  // forest can be organized as balanced trees to achieve almost linear
268
  // O(m*alpha(m,n)) running time. But it requires two auxiliary arrays (Size
269
  // and Child) and is unlikely to be faster than the simple implementation.
270
  //
271
  // For each vertex V, its Label points to the vertex with the minimal sdom(U)
272
  // (Semi) in its path from V (included) to NodeToInfo[V].Parent (excluded).
273
  NodePtr eval(NodePtr V, unsigned LastLinked,
274
124M
               SmallVectorImpl<InfoRec *> &Stack) {
275
124M
    InfoRec *VInfo = &NodeToInfo[V];
276
124M
    if (VInfo->Parent < LastLinked)
277
106M
      return VInfo->Label;
278
17.3M
279
17.3M
    // Store ancestors except the last (root of a virtual tree) into a stack.
280
17.3M
    assert(Stack.empty());
281
42.5M
    do {
282
42.5M
      Stack.push_back(VInfo);
283
42.5M
      VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
284
42.5M
    } while (VInfo->Parent >= LastLinked);
285
17.3M
286
17.3M
    // Path compression. Point each vertex's Parent to the root and update its
287
17.3M
    // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
288
17.3M
    const InfoRec *PInfo = VInfo;
289
17.3M
    const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
290
42.5M
    do {
291
42.5M
      VInfo = Stack.pop_back_val();
292
42.5M
      VInfo->Parent = PInfo->Parent;
293
42.5M
      const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
294
42.5M
      if (PLabelInfo->Semi < VLabelInfo->Semi)
295
40.2M
        VInfo->Label = PInfo->Label;
296
2.34M
      else
297
2.34M
        PLabelInfo = VLabelInfo;
298
42.5M
      PInfo = VInfo;
299
42.5M
    } while (!Stack.empty());
300
17.3M
    return VInfo->Label;
301
17.3M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::eval(llvm::MachineBasicBlock*, unsigned int, llvm::SmallVectorImpl<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InfoRec*>&)
Line
Count
Source
274
13.7M
               SmallVectorImpl<InfoRec *> &Stack) {
275
13.7M
    InfoRec *VInfo = &NodeToInfo[V];
276
13.7M
    if (VInfo->Parent < LastLinked)
277
11.7M
      return VInfo->Label;
278
2.01M
279
2.01M
    // Store ancestors except the last (root of a virtual tree) into a stack.
280
2.01M
    assert(Stack.empty());
281
4.95M
    do {
282
4.95M
      Stack.push_back(VInfo);
283
4.95M
      VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
284
4.95M
    } while (VInfo->Parent >= LastLinked);
285
2.01M
286
2.01M
    // Path compression. Point each vertex's Parent to the root and update its
287
2.01M
    // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
288
2.01M
    const InfoRec *PInfo = VInfo;
289
2.01M
    const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
290
4.95M
    do {
291
4.95M
      VInfo = Stack.pop_back_val();
292
4.95M
      VInfo->Parent = PInfo->Parent;
293
4.95M
      const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
294
4.95M
      if (PLabelInfo->Semi < VLabelInfo->Semi)
295
4.79M
        VInfo->Label = PInfo->Label;
296
157k
      else
297
157k
        PLabelInfo = VLabelInfo;
298
4.95M
      PInfo = VInfo;
299
4.95M
    } while (!Stack.empty());
300
2.01M
    return VInfo->Label;
301
2.01M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::eval(llvm::MachineBasicBlock*, unsigned int, llvm::SmallVectorImpl<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InfoRec*>&)
Line
Count
Source
274
10.2M
               SmallVectorImpl<InfoRec *> &Stack) {
275
10.2M
    InfoRec *VInfo = &NodeToInfo[V];
276
10.2M
    if (VInfo->Parent < LastLinked)
277
9.33M
      return VInfo->Label;
278
940k
279
940k
    // Store ancestors except the last (root of a virtual tree) into a stack.
280
940k
    assert(Stack.empty());
281
3.01M
    do {
282
3.01M
      Stack.push_back(VInfo);
283
3.01M
      VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
284
3.01M
    } while (VInfo->Parent >= LastLinked);
285
940k
286
940k
    // Path compression. Point each vertex's Parent to the root and update its
287
940k
    // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
288
940k
    const InfoRec *PInfo = VInfo;
289
940k
    const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
290
3.01M
    do {
291
3.01M
      VInfo = Stack.pop_back_val();
292
3.01M
      VInfo->Parent = PInfo->Parent;
293
3.01M
      const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
294
3.01M
      if (PLabelInfo->Semi < VLabelInfo->Semi)
295
2.05M
        VInfo->Label = PInfo->Label;
296
966k
      else
297
966k
        PLabelInfo = VLabelInfo;
298
3.01M
      PInfo = VInfo;
299
3.01M
    } while (!Stack.empty());
300
940k
    return VInfo->Label;
301
940k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::eval(llvm::BasicBlock*, unsigned int, llvm::SmallVectorImpl<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InfoRec*>&)
Line
Count
Source
274
96.4M
               SmallVectorImpl<InfoRec *> &Stack) {
275
96.4M
    InfoRec *VInfo = &NodeToInfo[V];
276
96.4M
    if (VInfo->Parent < LastLinked)
277
82.5M
      return VInfo->Label;
278
13.9M
279
13.9M
    // Store ancestors except the last (root of a virtual tree) into a stack.
280
13.9M
    assert(Stack.empty());
281
33.4M
    do {
282
33.4M
      Stack.push_back(VInfo);
283
33.4M
      VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
284
33.4M
    } while (VInfo->Parent >= LastLinked);
285
13.9M
286
13.9M
    // Path compression. Point each vertex's Parent to the root and update its
287
13.9M
    // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
288
13.9M
    const InfoRec *PInfo = VInfo;
289
13.9M
    const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
290
33.4M
    do {
291
33.4M
      VInfo = Stack.pop_back_val();
292
33.4M
      VInfo->Parent = PInfo->Parent;
293
33.4M
      const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
294
33.4M
      if (PLabelInfo->Semi < VLabelInfo->Semi)
295
32.6M
        VInfo->Label = PInfo->Label;
296
850k
      else
297
850k
        PLabelInfo = VLabelInfo;
298
33.4M
      PInfo = VInfo;
299
33.4M
    } while (!Stack.empty());
300
13.9M
    return VInfo->Label;
301
13.9M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::eval(llvm::BasicBlock*, unsigned int, llvm::SmallVectorImpl<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InfoRec*>&)
Line
Count
Source
274
3.67M
               SmallVectorImpl<InfoRec *> &Stack) {
275
3.67M
    InfoRec *VInfo = &NodeToInfo[V];
276
3.67M
    if (VInfo->Parent < LastLinked)
277
3.17M
      return VInfo->Label;
278
493k
279
493k
    // Store ancestors except the last (root of a virtual tree) into a stack.
280
493k
    assert(Stack.empty());
281
1.07M
    do {
282
1.07M
      Stack.push_back(VInfo);
283
1.07M
      VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
284
1.07M
    } while (VInfo->Parent >= LastLinked);
285
493k
286
493k
    // Path compression. Point each vertex's Parent to the root and update its
287
493k
    // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
288
493k
    const InfoRec *PInfo = VInfo;
289
493k
    const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
290
1.07M
    do {
291
1.07M
      VInfo = Stack.pop_back_val();
292
1.07M
      VInfo->Parent = PInfo->Parent;
293
1.07M
      const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
294
1.07M
      if (PLabelInfo->Semi < VLabelInfo->Semi)
295
713k
        VInfo->Label = PInfo->Label;
296
366k
      else
297
366k
        PLabelInfo = VLabelInfo;
298
1.07M
      PInfo = VInfo;
299
1.07M
    } while (!Stack.empty());
300
493k
    return VInfo->Label;
301
493k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::eval(llvm::VPBlockBase*, unsigned int, llvm::SmallVectorImpl<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::InfoRec*>&)
Line
Count
Source
274
139
               SmallVectorImpl<InfoRec *> &Stack) {
275
139
    InfoRec *VInfo = &NodeToInfo[V];
276
139
    if (VInfo->Parent < LastLinked)
277
121
      return VInfo->Label;
278
18
279
18
    // Store ancestors except the last (root of a virtual tree) into a stack.
280
18
    assert(Stack.empty());
281
30
    do {
282
30
      Stack.push_back(VInfo);
283
30
      VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
284
30
    } while (VInfo->Parent >= LastLinked);
285
18
286
18
    // Path compression. Point each vertex's Parent to the root and update its
287
18
    // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
288
18
    const InfoRec *PInfo = VInfo;
289
18
    const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
290
30
    do {
291
30
      VInfo = Stack.pop_back_val();
292
30
      VInfo->Parent = PInfo->Parent;
293
30
      const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
294
30
      if (PLabelInfo->Semi < VLabelInfo->Semi)
295
22
        VInfo->Label = PInfo->Label;
296
8
      else
297
8
        PLabelInfo = VLabelInfo;
298
30
      PInfo = VInfo;
299
30
    } while (!Stack.empty());
300
18
    return VInfo->Label;
301
18
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::eval(clang::CFGBlock*, unsigned int, llvm::SmallVectorImpl<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::InfoRec*>&)
Line
Count
Source
274
74
               SmallVectorImpl<InfoRec *> &Stack) {
275
74
    InfoRec *VInfo = &NodeToInfo[V];
276
74
    if (VInfo->Parent < LastLinked)
277
67
      return VInfo->Label;
278
7
279
7
    // Store ancestors except the last (root of a virtual tree) into a stack.
280
7
    assert(Stack.empty());
281
10
    do {
282
10
      Stack.push_back(VInfo);
283
10
      VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
284
10
    } while (VInfo->Parent >= LastLinked);
285
7
286
7
    // Path compression. Point each vertex's Parent to the root and update its
287
7
    // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
288
7
    const InfoRec *PInfo = VInfo;
289
7
    const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
290
10
    do {
291
10
      VInfo = Stack.pop_back_val();
292
10
      VInfo->Parent = PInfo->Parent;
293
10
      const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
294
10
      if (PLabelInfo->Semi < VLabelInfo->Semi)
295
10
        VInfo->Label = PInfo->Label;
296
0
      else
297
0
        PLabelInfo = VLabelInfo;
298
10
      PInfo = VInfo;
299
10
    } while (!Stack.empty());
300
7
    return VInfo->Label;
301
7
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::eval(clang::CFGBlock*, unsigned int, llvm::SmallVectorImpl<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::InfoRec*>&)
Line
Count
Source
274
589
               SmallVectorImpl<InfoRec *> &Stack) {
275
589
    InfoRec *VInfo = &NodeToInfo[V];
276
589
    if (VInfo->Parent < LastLinked)
277
570
      return VInfo->Label;
278
19
279
19
    // Store ancestors except the last (root of a virtual tree) into a stack.
280
19
    assert(Stack.empty());
281
25
    do {
282
25
      Stack.push_back(VInfo);
283
25
      VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
284
25
    } while (VInfo->Parent >= LastLinked);
285
19
286
19
    // Path compression. Point each vertex's Parent to the root and update its
287
19
    // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
288
19
    const InfoRec *PInfo = VInfo;
289
19
    const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
290
25
    do {
291
25
      VInfo = Stack.pop_back_val();
292
25
      VInfo->Parent = PInfo->Parent;
293
25
      const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
294
25
      if (PLabelInfo->Semi < VLabelInfo->Semi)
295
25
        VInfo->Label = PInfo->Label;
296
0
      else
297
0
        PLabelInfo = VLabelInfo;
298
25
      PInfo = VInfo;
299
25
    } while (!Stack.empty());
300
19
    return VInfo->Label;
301
19
  }
302
303
  // This function requires DFS to be run before calling it.
304
15.6M
  void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
305
15.6M
    const unsigned NextDFSNum(NumToNode.size());
306
15.6M
    // Initialize IDoms to spanning tree parents.
307
119M
    for (unsigned i = 1; i < NextDFSNum; 
++i103M
) {
308
103M
      const NodePtr V = NumToNode[i];
309
103M
      auto &VInfo = NodeToInfo[V];
310
103M
      VInfo.IDom = NumToNode[VInfo.Parent];
311
103M
    }
312
15.6M
313
15.6M
    // Step #1: Calculate the semidominators of all vertices.
314
15.6M
    SmallVector<InfoRec *, 32> EvalStack;
315
103M
    for (unsigned i = NextDFSNum - 1; i >= 2; 
--i87.9M
) {
316
87.9M
      NodePtr W = NumToNode[i];
317
87.9M
      auto &WInfo = NodeToInfo[W];
318
87.9M
319
87.9M
      // Initialize the semi dominator to point to the parent node.
320
87.9M
      WInfo.Semi = WInfo.Parent;
321
124M
      for (const auto &N : WInfo.ReverseChildren) {
322
124M
        if (NodeToInfo.count(N) == 0)  // Skip unreachable predecessors.
323
0
          continue;
324
124M
325
124M
        const TreeNodePtr TN = DT.getNode(N);
326
124M
        // Skip predecessors whose level is above the subtree we are processing.
327
124M
        if (TN && 
TN->getLevel() < MinLevel15.5M
)
328
0
          continue;
329
124M
330
124M
        unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
331
124M
        if (SemiU < WInfo.Semi) 
WInfo.Semi = SemiU14.9M
;
332
124M
      }
333
87.9M
    }
334
15.6M
335
15.6M
    // Step #2: Explicitly define the immediate dominator of each vertex.
336
15.6M
    //          IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
337
15.6M
    // Note that the parents were stored in IDoms and later got invalidated
338
15.6M
    // during path compression in Eval.
339
103M
    for (unsigned i = 2; i < NextDFSNum; 
++i87.9M
) {
340
87.9M
      const NodePtr W = NumToNode[i];
341
87.9M
      auto &WInfo = NodeToInfo[W];
342
87.9M
      const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
343
87.9M
      NodePtr WIDomCandidate = WInfo.IDom;
344
114M
      while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
345
26.3M
        WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
346
87.9M
347
87.9M
      WInfo.IDom = WIDomCandidate;
348
87.9M
    }
349
15.6M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runSemiNCA(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, unsigned int)
Line
Count
Source
304
2.61M
  void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
305
2.61M
    const unsigned NextDFSNum(NumToNode.size());
306
2.61M
    // Initialize IDoms to spanning tree parents.
307
14.6M
    for (unsigned i = 1; i < NextDFSNum; 
++i12.0M
) {
308
12.0M
      const NodePtr V = NumToNode[i];
309
12.0M
      auto &VInfo = NodeToInfo[V];
310
12.0M
      VInfo.IDom = NumToNode[VInfo.Parent];
311
12.0M
    }
312
2.61M
313
2.61M
    // Step #1: Calculate the semidominators of all vertices.
314
2.61M
    SmallVector<InfoRec *, 32> EvalStack;
315
12.0M
    for (unsigned i = NextDFSNum - 1; i >= 2; 
--i9.38M
) {
316
9.38M
      NodePtr W = NumToNode[i];
317
9.38M
      auto &WInfo = NodeToInfo[W];
318
9.38M
319
9.38M
      // Initialize the semi dominator to point to the parent node.
320
9.38M
      WInfo.Semi = WInfo.Parent;
321
13.7M
      for (const auto &N : WInfo.ReverseChildren) {
322
13.7M
        if (NodeToInfo.count(N) == 0)  // Skip unreachable predecessors.
323
0
          continue;
324
13.7M
325
13.7M
        const TreeNodePtr TN = DT.getNode(N);
326
13.7M
        // Skip predecessors whose level is above the subtree we are processing.
327
13.7M
        if (TN && 
TN->getLevel() < MinLevel0
)
328
0
          continue;
329
13.7M
330
13.7M
        unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
331
13.7M
        if (SemiU < WInfo.Semi) 
WInfo.Semi = SemiU1.60M
;
332
13.7M
      }
333
9.38M
    }
334
2.61M
335
2.61M
    // Step #2: Explicitly define the immediate dominator of each vertex.
336
2.61M
    //          IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
337
2.61M
    // Note that the parents were stored in IDoms and later got invalidated
338
2.61M
    // during path compression in Eval.
339
12.0M
    for (unsigned i = 2; i < NextDFSNum; 
++i9.38M
) {
340
9.38M
      const NodePtr W = NumToNode[i];
341
9.38M
      auto &WInfo = NodeToInfo[W];
342
9.38M
      const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
343
9.38M
      NodePtr WIDomCandidate = WInfo.IDom;
344
12.2M
      while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
345
2.84M
        WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
346
9.38M
347
9.38M
      WInfo.IDom = WIDomCandidate;
348
9.38M
    }
349
2.61M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runSemiNCA(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, unsigned int)
Line
Count
Source
304
1.50M
  void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
305
1.50M
    const unsigned NextDFSNum(NumToNode.size());
306
1.50M
    // Initialize IDoms to spanning tree parents.
307
11.5M
    for (unsigned i = 1; i < NextDFSNum; 
++i10.0M
) {
308
10.0M
      const NodePtr V = NumToNode[i];
309
10.0M
      auto &VInfo = NodeToInfo[V];
310
10.0M
      VInfo.IDom = NumToNode[VInfo.Parent];
311
10.0M
    }
312
1.50M
313
1.50M
    // Step #1: Calculate the semidominators of all vertices.
314
1.50M
    SmallVector<InfoRec *, 32> EvalStack;
315
10.0M
    for (unsigned i = NextDFSNum - 1; i >= 2; 
--i8.52M
) {
316
8.52M
      NodePtr W = NumToNode[i];
317
8.52M
      auto &WInfo = NodeToInfo[W];
318
8.52M
319
8.52M
      // Initialize the semi dominator to point to the parent node.
320
8.52M
      WInfo.Semi = WInfo.Parent;
321
10.2M
      for (const auto &N : WInfo.ReverseChildren) {
322
10.2M
        if (NodeToInfo.count(N) == 0)  // Skip unreachable predecessors.
323
0
          continue;
324
10.2M
325
10.2M
        const TreeNodePtr TN = DT.getNode(N);
326
10.2M
        // Skip predecessors whose level is above the subtree we are processing.
327
10.2M
        if (TN && 
TN->getLevel() < MinLevel0
)
328
0
          continue;
329
10.2M
330
10.2M
        unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
331
10.2M
        if (SemiU < WInfo.Semi) 
WInfo.Semi = SemiU3.37M
;
332
10.2M
      }
333
8.52M
    }
334
1.50M
335
1.50M
    // Step #2: Explicitly define the immediate dominator of each vertex.
336
1.50M
    //          IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
337
1.50M
    // Note that the parents were stored in IDoms and later got invalidated
338
1.50M
    // during path compression in Eval.
339
10.0M
    for (unsigned i = 2; i < NextDFSNum; 
++i8.52M
) {
340
8.52M
      const NodePtr W = NumToNode[i];
341
8.52M
      auto &WInfo = NodeToInfo[W];
342
8.52M
      const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
343
8.52M
      NodePtr WIDomCandidate = WInfo.IDom;
344
13.2M
      while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
345
4.70M
        WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
346
8.52M
347
8.52M
      WInfo.IDom = WIDomCandidate;
348
8.52M
    }
349
1.50M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runSemiNCA(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, unsigned int)
Line
Count
Source
304
10.9M
  void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
305
10.9M
    const unsigned NextDFSNum(NumToNode.size());
306
10.9M
    // Initialize IDoms to spanning tree parents.
307
88.7M
    for (unsigned i = 1; i < NextDFSNum; 
++i77.8M
) {
308
77.8M
      const NodePtr V = NumToNode[i];
309
77.8M
      auto &VInfo = NodeToInfo[V];
310
77.8M
      VInfo.IDom = NumToNode[VInfo.Parent];
311
77.8M
    }
312
10.9M
313
10.9M
    // Step #1: Calculate the semidominators of all vertices.
314
10.9M
    SmallVector<InfoRec *, 32> EvalStack;
315
77.8M
    for (unsigned i = NextDFSNum - 1; i >= 2; 
--i66.9M
) {
316
66.9M
      NodePtr W = NumToNode[i];
317
66.9M
      auto &WInfo = NodeToInfo[W];
318
66.9M
319
66.9M
      // Initialize the semi dominator to point to the parent node.
320
66.9M
      WInfo.Semi = WInfo.Parent;
321
96.4M
      for (const auto &N : WInfo.ReverseChildren) {
322
96.4M
        if (NodeToInfo.count(N) == 0)  // Skip unreachable predecessors.
323
0
          continue;
324
96.4M
325
96.4M
        const TreeNodePtr TN = DT.getNode(N);
326
96.4M
        // Skip predecessors whose level is above the subtree we are processing.
327
96.4M
        if (TN && 
TN->getLevel() < MinLevel15.5M
)
328
0
          continue;
329
96.4M
330
96.4M
        unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
331
96.4M
        if (SemiU < WInfo.Semi) 
WInfo.Semi = SemiU9.19M
;
332
96.4M
      }
333
66.9M
    }
334
10.9M
335
10.9M
    // Step #2: Explicitly define the immediate dominator of each vertex.
336
10.9M
    //          IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
337
10.9M
    // Note that the parents were stored in IDoms and later got invalidated
338
10.9M
    // during path compression in Eval.
339
77.8M
    for (unsigned i = 2; i < NextDFSNum; 
++i66.9M
) {
340
66.9M
      const NodePtr W = NumToNode[i];
341
66.9M
      auto &WInfo = NodeToInfo[W];
342
66.9M
      const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
343
66.9M
      NodePtr WIDomCandidate = WInfo.IDom;
344
84.7M
      while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
345
17.8M
        WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
346
66.9M
347
66.9M
      WInfo.IDom = WIDomCandidate;
348
66.9M
    }
349
10.9M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runSemiNCA(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, unsigned int)
Line
Count
Source
304
605k
  void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
305
605k
    const unsigned NextDFSNum(NumToNode.size());
306
605k
    // Initialize IDoms to spanning tree parents.
307
4.27M
    for (unsigned i = 1; i < NextDFSNum; 
++i3.66M
) {
308
3.66M
      const NodePtr V = NumToNode[i];
309
3.66M
      auto &VInfo = NodeToInfo[V];
310
3.66M
      VInfo.IDom = NumToNode[VInfo.Parent];
311
3.66M
    }
312
605k
313
605k
    // Step #1: Calculate the semidominators of all vertices.
314
605k
    SmallVector<InfoRec *, 32> EvalStack;
315
3.66M
    for (unsigned i = NextDFSNum - 1; i >= 2; 
--i3.06M
) {
316
3.06M
      NodePtr W = NumToNode[i];
317
3.06M
      auto &WInfo = NodeToInfo[W];
318
3.06M
319
3.06M
      // Initialize the semi dominator to point to the parent node.
320
3.06M
      WInfo.Semi = WInfo.Parent;
321
3.67M
      for (const auto &N : WInfo.ReverseChildren) {
322
3.67M
        if (NodeToInfo.count(N) == 0)  // Skip unreachable predecessors.
323
0
          continue;
324
3.67M
325
3.67M
        const TreeNodePtr TN = DT.getNode(N);
326
3.67M
        // Skip predecessors whose level is above the subtree we are processing.
327
3.67M
        if (TN && 
TN->getLevel() < MinLevel308
)
328
0
          continue;
329
3.67M
330
3.67M
        unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
331
3.67M
        if (SemiU < WInfo.Semi) 
WInfo.Semi = SemiU792k
;
332
3.67M
      }
333
3.06M
    }
334
605k
335
605k
    // Step #2: Explicitly define the immediate dominator of each vertex.
336
605k
    //          IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
337
605k
    // Note that the parents were stored in IDoms and later got invalidated
338
605k
    // during path compression in Eval.
339
3.66M
    for (unsigned i = 2; i < NextDFSNum; 
++i3.06M
) {
340
3.06M
      const NodePtr W = NumToNode[i];
341
3.06M
      auto &WInfo = NodeToInfo[W];
342
3.06M
      const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
343
3.06M
      NodePtr WIDomCandidate = WInfo.IDom;
344
4.05M
      while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
345
992k
        WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
346
3.06M
347
3.06M
      WInfo.IDom = WIDomCandidate;
348
3.06M
    }
349
605k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::runSemiNCA(llvm::DominatorTreeBase<llvm::VPBlockBase, false>&, unsigned int)
Line
Count
Source
304
28
  void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
305
28
    const unsigned NextDFSNum(NumToNode.size());
306
28
    // Initialize IDoms to spanning tree parents.
307
163
    for (unsigned i = 1; i < NextDFSNum; 
++i135
) {
308
135
      const NodePtr V = NumToNode[i];
309
135
      auto &VInfo = NodeToInfo[V];
310
135
      VInfo.IDom = NumToNode[VInfo.Parent];
311
135
    }
312
28
313
28
    // Step #1: Calculate the semidominators of all vertices.
314
28
    SmallVector<InfoRec *, 32> EvalStack;
315
135
    for (unsigned i = NextDFSNum - 1; i >= 2; 
--i107
) {
316
107
      NodePtr W = NumToNode[i];
317
107
      auto &WInfo = NodeToInfo[W];
318
107
319
107
      // Initialize the semi dominator to point to the parent node.
320
107
      WInfo.Semi = WInfo.Parent;
321
139
      for (const auto &N : WInfo.ReverseChildren) {
322
139
        if (NodeToInfo.count(N) == 0)  // Skip unreachable predecessors.
323
0
          continue;
324
139
325
139
        const TreeNodePtr TN = DT.getNode(N);
326
139
        // Skip predecessors whose level is above the subtree we are processing.
327
139
        if (TN && 
TN->getLevel() < MinLevel0
)
328
0
          continue;
329
139
330
139
        unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
331
139
        if (SemiU < WInfo.Semi) 
WInfo.Semi = SemiU10
;
332
139
      }
333
107
    }
334
28
335
28
    // Step #2: Explicitly define the immediate dominator of each vertex.
336
28
    //          IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
337
28
    // Note that the parents were stored in IDoms and later got invalidated
338
28
    // during path compression in Eval.
339
135
    for (unsigned i = 2; i < NextDFSNum; 
++i107
) {
340
107
      const NodePtr W = NumToNode[i];
341
107
      auto &WInfo = NodeToInfo[W];
342
107
      const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
343
107
      NodePtr WIDomCandidate = WInfo.IDom;
344
123
      while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
345
16
        WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
346
107
347
107
      WInfo.IDom = WIDomCandidate;
348
107
    }
349
28
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::runSemiNCA(llvm::DominatorTreeBase<clang::CFGBlock, false>&, unsigned int)
Line
Count
Source
304
8
  void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
305
8
    const unsigned NextDFSNum(NumToNode.size());
306
8
    // Initialize IDoms to spanning tree parents.
307
74
    for (unsigned i = 1; i < NextDFSNum; 
++i66
) {
308
66
      const NodePtr V = NumToNode[i];
309
66
      auto &VInfo = NodeToInfo[V];
310
66
      VInfo.IDom = NumToNode[VInfo.Parent];
311
66
    }
312
8
313
8
    // Step #1: Calculate the semidominators of all vertices.
314
8
    SmallVector<InfoRec *, 32> EvalStack;
315
66
    for (unsigned i = NextDFSNum - 1; i >= 2; 
--i58
) {
316
58
      NodePtr W = NumToNode[i];
317
58
      auto &WInfo = NodeToInfo[W];
318
58
319
58
      // Initialize the semi dominator to point to the parent node.
320
58
      WInfo.Semi = WInfo.Parent;
321
74
      for (const auto &N : WInfo.ReverseChildren) {
322
74
        if (NodeToInfo.count(N) == 0)  // Skip unreachable predecessors.
323
0
          continue;
324
74
325
74
        const TreeNodePtr TN = DT.getNode(N);
326
74
        // Skip predecessors whose level is above the subtree we are processing.
327
74
        if (TN && 
TN->getLevel() < MinLevel0
)
328
0
          continue;
329
74
330
74
        unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
331
74
        if (SemiU < WInfo.Semi) 
WInfo.Semi = SemiU9
;
332
74
      }
333
58
    }
334
8
335
8
    // Step #2: Explicitly define the immediate dominator of each vertex.
336
8
    //          IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
337
8
    // Note that the parents were stored in IDoms and later got invalidated
338
8
    // during path compression in Eval.
339
66
    for (unsigned i = 2; i < NextDFSNum; 
++i58
) {
340
58
      const NodePtr W = NumToNode[i];
341
58
      auto &WInfo = NodeToInfo[W];
342
58
      const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
343
58
      NodePtr WIDomCandidate = WInfo.IDom;
344
70
      while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
345
12
        WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
346
58
347
58
      WInfo.IDom = WIDomCandidate;
348
58
    }
349
8
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::runSemiNCA(llvm::DominatorTreeBase<clang::CFGBlock, true>&, unsigned int)
Line
Count
Source
304
107
  void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
305
107
    const unsigned NextDFSNum(NumToNode.size());
306
107
    // Initialize IDoms to spanning tree parents.
307
763
    for (unsigned i = 1; i < NextDFSNum; 
++i656
) {
308
656
      const NodePtr V = NumToNode[i];
309
656
      auto &VInfo = NodeToInfo[V];
310
656
      VInfo.IDom = NumToNode[VInfo.Parent];
311
656
    }
312
107
313
107
    // Step #1: Calculate the semidominators of all vertices.
314
107
    SmallVector<InfoRec *, 32> EvalStack;
315
656
    for (unsigned i = NextDFSNum - 1; i >= 2; 
--i549
) {
316
549
      NodePtr W = NumToNode[i];
317
549
      auto &WInfo = NodeToInfo[W];
318
549
319
549
      // Initialize the semi dominator to point to the parent node.
320
549
      WInfo.Semi = WInfo.Parent;
321
589
      for (const auto &N : WInfo.ReverseChildren) {
322
589
        if (NodeToInfo.count(N) == 0)  // Skip unreachable predecessors.
323
0
          continue;
324
589
325
589
        const TreeNodePtr TN = DT.getNode(N);
326
589
        // Skip predecessors whose level is above the subtree we are processing.
327
589
        if (TN && 
TN->getLevel() < MinLevel0
)
328
0
          continue;
329
589
330
589
        unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
331
589
        if (SemiU < WInfo.Semi) 
WInfo.Semi = SemiU16
;
332
589
      }
333
549
    }
334
107
335
107
    // Step #2: Explicitly define the immediate dominator of each vertex.
336
107
    //          IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
337
107
    // Note that the parents were stored in IDoms and later got invalidated
338
107
    // during path compression in Eval.
339
656
    for (unsigned i = 2; i < NextDFSNum; 
++i549
) {
340
549
      const NodePtr W = NumToNode[i];
341
549
      auto &WInfo = NodeToInfo[W];
342
549
      const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
343
549
      NodePtr WIDomCandidate = WInfo.IDom;
344
569
      while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
345
20
        WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
346
549
347
549
      WInfo.IDom = WIDomCandidate;
348
549
    }
349
107
  }
350
351
  // PostDominatorTree always has a virtual root that represents a virtual CFG
352
  // node that serves as a single exit from the function. All the other exits
353
  // (CFG nodes with terminators and nodes in infinite loops are logically
354
  // connected to this virtual CFG exit node).
355
  // This functions maps a nullptr CFG node to the virtual root tree node.
356
4.22M
  void addVirtualRoot() {
357
4.22M
    assert(IsPostDom && "Only postdominators have a virtual root");
358
4.22M
    assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed");
359
4.22M
360
4.22M
    auto &BBInfo = NodeToInfo[nullptr];
361
4.22M
    BBInfo.DFSNum = BBInfo.Semi = 1;
362
4.22M
    BBInfo.Label = nullptr;
363
4.22M
364
4.22M
    NumToNode.push_back(nullptr);  // NumToNode[1] = nullptr;
365
4.22M
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::addVirtualRoot()
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::addVirtualRoot()
Line
Count
Source
356
3.01M
  void addVirtualRoot() {
357
3.01M
    assert(IsPostDom && "Only postdominators have a virtual root");
358
3.01M
    assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed");
359
3.01M
360
3.01M
    auto &BBInfo = NodeToInfo[nullptr];
361
3.01M
    BBInfo.DFSNum = BBInfo.Semi = 1;
362
3.01M
    BBInfo.Label = nullptr;
363
3.01M
364
3.01M
    NumToNode.push_back(nullptr);  // NumToNode[1] = nullptr;
365
3.01M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::addVirtualRoot()
Line
Count
Source
356
1.21M
  void addVirtualRoot() {
357
1.21M
    assert(IsPostDom && "Only postdominators have a virtual root");
358
1.21M
    assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed");
359
1.21M
360
1.21M
    auto &BBInfo = NodeToInfo[nullptr];
361
1.21M
    BBInfo.DFSNum = BBInfo.Semi = 1;
362
1.21M
    BBInfo.Label = nullptr;
363
1.21M
364
1.21M
    NumToNode.push_back(nullptr);  // NumToNode[1] = nullptr;
365
1.21M
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::addVirtualRoot()
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::addVirtualRoot()
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::addVirtualRoot()
Line
Count
Source
356
214
  void addVirtualRoot() {
357
214
    assert(IsPostDom && "Only postdominators have a virtual root");
358
214
    assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed");
359
214
360
214
    auto &BBInfo = NodeToInfo[nullptr];
361
214
    BBInfo.DFSNum = BBInfo.Semi = 1;
362
214
    BBInfo.Label = nullptr;
363
214
364
214
    NumToNode.push_back(nullptr);  // NumToNode[1] = nullptr;
365
214
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::addVirtualRoot()
366
367
  // For postdominators, nodes with no forward successors are trivial roots that
368
  // are always selected as tree roots. Roots with forward successors correspond
369
  // to CFG nodes within infinite loops.
370
11.5M
  static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) {
371
11.5M
    assert(N && "N must be a valid node");
372
11.5M
    return !ChildrenGetter<false>::Get(N, BUI).empty();
373
11.5M
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::HasForwardSuccessors(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::HasForwardSuccessors(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
370
8.52M
  static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) {
371
8.52M
    assert(N && "N must be a valid node");
372
8.52M
    return !ChildrenGetter<false>::Get(N, BUI).empty();
373
8.52M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::HasForwardSuccessors(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
370
3.06M
  static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) {
371
3.06M
    assert(N && "N must be a valid node");
372
3.06M
    return !ChildrenGetter<false>::Get(N, BUI).empty();
373
3.06M
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::HasForwardSuccessors(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::HasForwardSuccessors(llvm::VPBlockBase*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::BatchUpdateInfo*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::HasForwardSuccessors(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
370
549
  static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) {
371
549
    assert(N && "N must be a valid node");
372
549
    return !ChildrenGetter<false>::Get(N, BUI).empty();
373
549
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::HasForwardSuccessors(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*)
374
375
13.0M
  static NodePtr GetEntryNode(const DomTreeT &DT) {
376
13.0M
    assert(DT.Parent && "Parent not set");
377
13.0M
    return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent);
378
13.0M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::GetEntryNode(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)
Line
Count
Source
375
2.61M
  static NodePtr GetEntryNode(const DomTreeT &DT) {
376
2.61M
    assert(DT.Parent && "Parent not set");
377
2.61M
    return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent);
378
2.61M
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::GetEntryNode(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::GetEntryNode(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)
Line
Count
Source
375
10.3M
  static NodePtr GetEntryNode(const DomTreeT &DT) {
376
10.3M
    assert(DT.Parent && "Parent not set");
377
10.3M
    return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent);
378
10.3M
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::GetEntryNode(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::GetEntryNode(llvm::DominatorTreeBase<llvm::VPBlockBase, false> const&)
Line
Count
Source
375
28
  static NodePtr GetEntryNode(const DomTreeT &DT) {
376
28
    assert(DT.Parent && "Parent not set");
377
28
    return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent);
378
28
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::GetEntryNode(llvm::DominatorTreeBase<clang::CFGBlock, false> const&)
Line
Count
Source
375
8
  static NodePtr GetEntryNode(const DomTreeT &DT) {
376
8
    assert(DT.Parent && "Parent not set");
377
8
    return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent);
378
8
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::GetEntryNode(llvm::DominatorTreeBase<clang::CFGBlock, true> const&)
379
380
  // Finds all roots without relaying on the set of roots already stored in the
381
  // tree.
382
  // We define roots to be some non-redundant set of the CFG nodes
383
15.1M
  static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
384
15.1M
    assert(DT.Parent && "Parent pointer is not set");
385
15.1M
    RootsT Roots;
386
15.1M
387
15.1M
    // For dominators, function entry CFG node is always a tree root node.
388
15.1M
    if (!IsPostDom) {
389
13.0M
      Roots.push_back(GetEntryNode(DT));
390
13.0M
      return Roots;
391
13.0M
    }
392
2.11M
393
2.11M
    SemiNCAInfo SNCA(BUI);
394
2.11M
395
2.11M
    // PostDominatorTree always has a virtual root.
396
2.11M
    SNCA.addVirtualRoot();
397
2.11M
    unsigned Num = 1;
398
2.11M
399
2.11M
    LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
400
2.11M
401
2.11M
    // Step #1: Find all the trivial roots that are going to will definitely
402
2.11M
    // remain tree roots.
403
2.11M
    unsigned Total = 0;
404
2.11M
    // It may happen that there are some new nodes in the CFG that are result of
405
2.11M
    // the ongoing batch update, but we cannot really pretend that they don't
406
2.11M
    // exist -- we won't see any outgoing or incoming edges to them, so it's
407
2.11M
    // fine to discover them here, as they would end up appearing in the CFG at
408
2.11M
    // some point anyway.
409
11.5M
    for (const NodePtr N : nodes(DT.Parent)) {
410
11.5M
      ++Total;
411
11.5M
      // If it has no *successors*, it is definitely a root.
412
11.5M
      if (!HasForwardSuccessors(N, BUI)) {
413
2.59M
        Roots.push_back(N);
414
2.59M
        // Run DFS not to walk this part of CFG later.
415
2.59M
        Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
416
2.59M
        LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
417
2.59M
                          << "\n");
418
2.59M
        LLVM_DEBUG(dbgs() << "Last visited node: "
419
2.59M
                          << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
420
2.59M
      }
421
11.5M
    }
422
2.11M
423
2.11M
    LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
424
2.11M
425
2.11M
    // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
426
2.11M
    // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
427
2.11M
    // nodes in infinite loops).
428
2.11M
    bool HasNonTrivialRoots = false;
429
2.11M
    // Accounting for the virtual exit, see if we had any reverse-unreachable
430
2.11M
    // nodes.
431
2.11M
    if (Total + 1 != Num) {
432
1.80k
      HasNonTrivialRoots = true;
433
1.80k
      // Make another DFS pass over all other nodes to find the
434
1.80k
      // reverse-unreachable blocks, and find the furthest paths we'll be able
435
1.80k
      // to make.
436
1.80k
      // Note that this looks N^2, but it's really 2N worst case, if every node
437
1.80k
      // is unreachable. This is because we are still going to only visit each
438
1.80k
      // unreachable node once, we may just visit it in two directions,
439
1.80k
      // depending on how lucky we get.
440
1.80k
      SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
441
18.2k
      for (const NodePtr I : nodes(DT.Parent)) {
442
18.2k
        if (SNCA.NodeToInfo.count(I) == 0) {
443
1.99k
          LLVM_DEBUG(dbgs()
444
1.99k
                     << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
445
1.99k
          // Find the furthest away we can get by following successors, then
446
1.99k
          // follow them in reverse.  This gives us some reasonable answer about
447
1.99k
          // the post-dom tree inside any infinite loop. In particular, it
448
1.99k
          // guarantees we get to the farthest away point along *some*
449
1.99k
          // path. This also matches the GCC's behavior.
450
1.99k
          // If we really wanted a totally complete picture of dominance inside
451
1.99k
          // this infinite loop, we could do it with SCC-like algorithms to find
452
1.99k
          // the lowest and highest points in the infinite loop.  In theory, it
453
1.99k
          // would be nice to give the canonical backedge for the loop, but it's
454
1.99k
          // expensive and does not always lead to a minimal set of roots.
455
1.99k
          LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
456
1.99k
457
1.99k
          const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num);
458
1.99k
          const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
459
1.99k
          LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
460
1.99k
                            << "(non-trivial root): "
461
1.99k
                            << BlockNamePrinter(FurthestAway) << "\n");
462
1.99k
          ConnectToExitBlock.insert(FurthestAway);
463
1.99k
          Roots.push_back(FurthestAway);
464
1.99k
          LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
465
1.99k
                            << NewNum << "\n\t\t\tRemoving DFS info\n");
466
8.11k
          for (unsigned i = NewNum; i > Num; 
--i6.12k
) {
467
6.12k
            const NodePtr N = SNCA.NumToNode[i];
468
6.12k
            LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
469
6.12k
                              << BlockNamePrinter(N) << "\n");
470
6.12k
            SNCA.NodeToInfo.erase(N);
471
6.12k
            SNCA.NumToNode.pop_back();
472
6.12k
          }
473
1.99k
          const unsigned PrevNum = Num;
474
1.99k
          LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
475
1.99k
          Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
476
7.89k
          for (unsigned i = PrevNum + 1; i <= Num; 
++i5.90k
)
477
1.99k
            LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
478
1.99k
                              << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
479
1.99k
        }
480
18.2k
      }
481
1.80k
    }
482
2.11M
483
2.11M
    LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
484
2.11M
    LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
485
2.11M
    LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
486
2.11M
               << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
487
2.11M
488
2.11M
    assert((Total + 1 == Num) && "Everything should have been visited");
489
2.11M
490
2.11M
    // Step #3: If we found some non-trivial roots, make them non-redundant.
491
2.11M
    if (HasNonTrivialRoots) 
RemoveRedundantRoots(DT, BUI, Roots)1.80k
;
492
2.11M
493
2.11M
    LLVM_DEBUG(dbgs() << "Found roots: ");
494
2.11M
    LLVM_DEBUG(for (auto *Root
495
2.11M
                    : Roots) dbgs()
496
2.11M
               << BlockNamePrinter(Root) << " ");
497
2.11M
    LLVM_DEBUG(dbgs() << "\n");
498
2.11M
499
2.11M
    return Roots;
500
2.11M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::FindRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
383
2.61M
  static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
384
2.61M
    assert(DT.Parent && "Parent pointer is not set");
385
2.61M
    RootsT Roots;
386
2.61M
387
2.61M
    // For dominators, function entry CFG node is always a tree root node.
388
2.61M
    if (!IsPostDom) {
389
2.61M
      Roots.push_back(GetEntryNode(DT));
390
2.61M
      return Roots;
391
2.61M
    }
392
0
393
0
    SemiNCAInfo SNCA(BUI);
394
0
395
0
    // PostDominatorTree always has a virtual root.
396
0
    SNCA.addVirtualRoot();
397
0
    unsigned Num = 1;
398
0
399
0
    LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
400
0
401
0
    // Step #1: Find all the trivial roots that are going to will definitely
402
0
    // remain tree roots.
403
0
    unsigned Total = 0;
404
0
    // It may happen that there are some new nodes in the CFG that are result of
405
0
    // the ongoing batch update, but we cannot really pretend that they don't
406
0
    // exist -- we won't see any outgoing or incoming edges to them, so it's
407
0
    // fine to discover them here, as they would end up appearing in the CFG at
408
0
    // some point anyway.
409
0
    for (const NodePtr N : nodes(DT.Parent)) {
410
0
      ++Total;
411
0
      // If it has no *successors*, it is definitely a root.
412
0
      if (!HasForwardSuccessors(N, BUI)) {
413
0
        Roots.push_back(N);
414
0
        // Run DFS not to walk this part of CFG later.
415
0
        Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
416
0
        LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
417
0
                          << "\n");
418
0
        LLVM_DEBUG(dbgs() << "Last visited node: "
419
0
                          << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
420
0
      }
421
0
    }
422
0
423
0
    LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
424
0
425
0
    // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
426
0
    // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
427
0
    // nodes in infinite loops).
428
0
    bool HasNonTrivialRoots = false;
429
0
    // Accounting for the virtual exit, see if we had any reverse-unreachable
430
0
    // nodes.
431
0
    if (Total + 1 != Num) {
432
0
      HasNonTrivialRoots = true;
433
0
      // Make another DFS pass over all other nodes to find the
434
0
      // reverse-unreachable blocks, and find the furthest paths we'll be able
435
0
      // to make.
436
0
      // Note that this looks N^2, but it's really 2N worst case, if every node
437
0
      // is unreachable. This is because we are still going to only visit each
438
0
      // unreachable node once, we may just visit it in two directions,
439
0
      // depending on how lucky we get.
440
0
      SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
441
0
      for (const NodePtr I : nodes(DT.Parent)) {
442
0
        if (SNCA.NodeToInfo.count(I) == 0) {
443
0
          LLVM_DEBUG(dbgs()
444
0
                     << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
445
0
          // Find the furthest away we can get by following successors, then
446
0
          // follow them in reverse.  This gives us some reasonable answer about
447
0
          // the post-dom tree inside any infinite loop. In particular, it
448
0
          // guarantees we get to the farthest away point along *some*
449
0
          // path. This also matches the GCC's behavior.
450
0
          // If we really wanted a totally complete picture of dominance inside
451
0
          // this infinite loop, we could do it with SCC-like algorithms to find
452
0
          // the lowest and highest points in the infinite loop.  In theory, it
453
0
          // would be nice to give the canonical backedge for the loop, but it's
454
0
          // expensive and does not always lead to a minimal set of roots.
455
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
456
0
457
0
          const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num);
458
0
          const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
459
0
          LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
460
0
                            << "(non-trivial root): "
461
0
                            << BlockNamePrinter(FurthestAway) << "\n");
462
0
          ConnectToExitBlock.insert(FurthestAway);
463
0
          Roots.push_back(FurthestAway);
464
0
          LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
465
0
                            << NewNum << "\n\t\t\tRemoving DFS info\n");
466
0
          for (unsigned i = NewNum; i > Num; --i) {
467
0
            const NodePtr N = SNCA.NumToNode[i];
468
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
469
0
                              << BlockNamePrinter(N) << "\n");
470
0
            SNCA.NodeToInfo.erase(N);
471
0
            SNCA.NumToNode.pop_back();
472
0
          }
473
0
          const unsigned PrevNum = Num;
474
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
475
0
          Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
476
0
          for (unsigned i = PrevNum + 1; i <= Num; ++i)
477
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
478
0
                              << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
479
0
        }
480
0
      }
481
0
    }
482
0
483
0
    LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
484
0
    LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
485
0
    LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
486
0
               << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
487
0
488
0
    assert((Total + 1 == Num) && "Everything should have been visited");
489
0
490
0
    // Step #3: If we found some non-trivial roots, make them non-redundant.
491
0
    if (HasNonTrivialRoots) RemoveRedundantRoots(DT, BUI, Roots);
492
0
493
0
    LLVM_DEBUG(dbgs() << "Found roots: ");
494
0
    LLVM_DEBUG(for (auto *Root
495
0
                    : Roots) dbgs()
496
0
               << BlockNamePrinter(Root) << " ");
497
0
    LLVM_DEBUG(dbgs() << "\n");
498
0
499
0
    return Roots;
500
0
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::FindRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
383
1.50M
  static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
384
1.50M
    assert(DT.Parent && "Parent pointer is not set");
385
1.50M
    RootsT Roots;
386
1.50M
387
1.50M
    // For dominators, function entry CFG node is always a tree root node.
388
1.50M
    if (!IsPostDom) {
389
0
      Roots.push_back(GetEntryNode(DT));
390
0
      return Roots;
391
0
    }
392
1.50M
393
1.50M
    SemiNCAInfo SNCA(BUI);
394
1.50M
395
1.50M
    // PostDominatorTree always has a virtual root.
396
1.50M
    SNCA.addVirtualRoot();
397
1.50M
    unsigned Num = 1;
398
1.50M
399
1.50M
    LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
400
1.50M
401
1.50M
    // Step #1: Find all the trivial roots that are going to will definitely
402
1.50M
    // remain tree roots.
403
1.50M
    unsigned Total = 0;
404
1.50M
    // It may happen that there are some new nodes in the CFG that are result of
405
1.50M
    // the ongoing batch update, but we cannot really pretend that they don't
406
1.50M
    // exist -- we won't see any outgoing or incoming edges to them, so it's
407
1.50M
    // fine to discover them here, as they would end up appearing in the CFG at
408
1.50M
    // some point anyway.
409
8.52M
    for (const NodePtr N : nodes(DT.Parent)) {
410
8.52M
      ++Total;
411
8.52M
      // If it has no *successors*, it is definitely a root.
412
8.52M
      if (!HasForwardSuccessors(N, BUI)) {
413
1.92M
        Roots.push_back(N);
414
1.92M
        // Run DFS not to walk this part of CFG later.
415
1.92M
        Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
416
1.92M
        LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
417
1.92M
                          << "\n");
418
1.92M
        LLVM_DEBUG(dbgs() << "Last visited node: "
419
1.92M
                          << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
420
1.92M
      }
421
8.52M
    }
422
1.50M
423
1.50M
    LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
424
1.50M
425
1.50M
    // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
426
1.50M
    // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
427
1.50M
    // nodes in infinite loops).
428
1.50M
    bool HasNonTrivialRoots = false;
429
1.50M
    // Accounting for the virtual exit, see if we had any reverse-unreachable
430
1.50M
    // nodes.
431
1.50M
    if (Total + 1 != Num) {
432
1.29k
      HasNonTrivialRoots = true;
433
1.29k
      // Make another DFS pass over all other nodes to find the
434
1.29k
      // reverse-unreachable blocks, and find the furthest paths we'll be able
435
1.29k
      // to make.
436
1.29k
      // Note that this looks N^2, but it's really 2N worst case, if every node
437
1.29k
      // is unreachable. This is because we are still going to only visit each
438
1.29k
      // unreachable node once, we may just visit it in two directions,
439
1.29k
      // depending on how lucky we get.
440
1.29k
      SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
441
9.47k
      for (const NodePtr I : nodes(DT.Parent)) {
442
9.47k
        if (SNCA.NodeToInfo.count(I) == 0) {
443
1.38k
          LLVM_DEBUG(dbgs()
444
1.38k
                     << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
445
1.38k
          // Find the furthest away we can get by following successors, then
446
1.38k
          // follow them in reverse.  This gives us some reasonable answer about
447
1.38k
          // the post-dom tree inside any infinite loop. In particular, it
448
1.38k
          // guarantees we get to the farthest away point along *some*
449
1.38k
          // path. This also matches the GCC's behavior.
450
1.38k
          // If we really wanted a totally complete picture of dominance inside
451
1.38k
          // this infinite loop, we could do it with SCC-like algorithms to find
452
1.38k
          // the lowest and highest points in the infinite loop.  In theory, it
453
1.38k
          // would be nice to give the canonical backedge for the loop, but it's
454
1.38k
          // expensive and does not always lead to a minimal set of roots.
455
1.38k
          LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
456
1.38k
457
1.38k
          const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num);
458
1.38k
          const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
459
1.38k
          LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
460
1.38k
                            << "(non-trivial root): "
461
1.38k
                            << BlockNamePrinter(FurthestAway) << "\n");
462
1.38k
          ConnectToExitBlock.insert(FurthestAway);
463
1.38k
          Roots.push_back(FurthestAway);
464
1.38k
          LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
465
1.38k
                            << NewNum << "\n\t\t\tRemoving DFS info\n");
466
5.85k
          for (unsigned i = NewNum; i > Num; 
--i4.46k
) {
467
4.46k
            const NodePtr N = SNCA.NumToNode[i];
468
4.46k
            LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
469
4.46k
                              << BlockNamePrinter(N) << "\n");
470
4.46k
            SNCA.NodeToInfo.erase(N);
471
4.46k
            SNCA.NumToNode.pop_back();
472
4.46k
          }
473
1.38k
          const unsigned PrevNum = Num;
474
1.38k
          LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
475
1.38k
          Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
476
5.69k
          for (unsigned i = PrevNum + 1; i <= Num; 
++i4.30k
)
477
1.38k
            LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
478
1.38k
                              << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
479
1.38k
        }
480
9.47k
      }
481
1.29k
    }
482
1.50M
483
1.50M
    LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
484
1.50M
    LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
485
1.50M
    LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
486
1.50M
               << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
487
1.50M
488
1.50M
    assert((Total + 1 == Num) && "Everything should have been visited");
489
1.50M
490
1.50M
    // Step #3: If we found some non-trivial roots, make them non-redundant.
491
1.50M
    if (HasNonTrivialRoots) 
RemoveRedundantRoots(DT, BUI, Roots)1.29k
;
492
1.50M
493
1.50M
    LLVM_DEBUG(dbgs() << "Found roots: ");
494
1.50M
    LLVM_DEBUG(for (auto *Root
495
1.50M
                    : Roots) dbgs()
496
1.50M
               << BlockNamePrinter(Root) << " ");
497
1.50M
    LLVM_DEBUG(dbgs() << "\n");
498
1.50M
499
1.50M
    return Roots;
500
1.50M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::FindRoots(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
383
10.3M
  static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
384
10.3M
    assert(DT.Parent && "Parent pointer is not set");
385
10.3M
    RootsT Roots;
386
10.3M
387
10.3M
    // For dominators, function entry CFG node is always a tree root node.
388
10.3M
    if (!IsPostDom) {
389
10.3M
      Roots.push_back(GetEntryNode(DT));
390
10.3M
      return Roots;
391
10.3M
    }
392
0
393
0
    SemiNCAInfo SNCA(BUI);
394
0
395
0
    // PostDominatorTree always has a virtual root.
396
0
    SNCA.addVirtualRoot();
397
0
    unsigned Num = 1;
398
0
399
0
    LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
400
0
401
0
    // Step #1: Find all the trivial roots that are going to will definitely
402
0
    // remain tree roots.
403
0
    unsigned Total = 0;
404
0
    // It may happen that there are some new nodes in the CFG that are result of
405
0
    // the ongoing batch update, but we cannot really pretend that they don't
406
0
    // exist -- we won't see any outgoing or incoming edges to them, so it's
407
0
    // fine to discover them here, as they would end up appearing in the CFG at
408
0
    // some point anyway.
409
0
    for (const NodePtr N : nodes(DT.Parent)) {
410
0
      ++Total;
411
0
      // If it has no *successors*, it is definitely a root.
412
0
      if (!HasForwardSuccessors(N, BUI)) {
413
0
        Roots.push_back(N);
414
0
        // Run DFS not to walk this part of CFG later.
415
0
        Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
416
0
        LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
417
0
                          << "\n");
418
0
        LLVM_DEBUG(dbgs() << "Last visited node: "
419
0
                          << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
420
0
      }
421
0
    }
422
0
423
0
    LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
424
0
425
0
    // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
426
0
    // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
427
0
    // nodes in infinite loops).
428
0
    bool HasNonTrivialRoots = false;
429
0
    // Accounting for the virtual exit, see if we had any reverse-unreachable
430
0
    // nodes.
431
0
    if (Total + 1 != Num) {
432
0
      HasNonTrivialRoots = true;
433
0
      // Make another DFS pass over all other nodes to find the
434
0
      // reverse-unreachable blocks, and find the furthest paths we'll be able
435
0
      // to make.
436
0
      // Note that this looks N^2, but it's really 2N worst case, if every node
437
0
      // is unreachable. This is because we are still going to only visit each
438
0
      // unreachable node once, we may just visit it in two directions,
439
0
      // depending on how lucky we get.
440
0
      SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
441
0
      for (const NodePtr I : nodes(DT.Parent)) {
442
0
        if (SNCA.NodeToInfo.count(I) == 0) {
443
0
          LLVM_DEBUG(dbgs()
444
0
                     << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
445
0
          // Find the furthest away we can get by following successors, then
446
0
          // follow them in reverse.  This gives us some reasonable answer about
447
0
          // the post-dom tree inside any infinite loop. In particular, it
448
0
          // guarantees we get to the farthest away point along *some*
449
0
          // path. This also matches the GCC's behavior.
450
0
          // If we really wanted a totally complete picture of dominance inside
451
0
          // this infinite loop, we could do it with SCC-like algorithms to find
452
0
          // the lowest and highest points in the infinite loop.  In theory, it
453
0
          // would be nice to give the canonical backedge for the loop, but it's
454
0
          // expensive and does not always lead to a minimal set of roots.
455
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
456
0
457
0
          const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num);
458
0
          const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
459
0
          LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
460
0
                            << "(non-trivial root): "
461
0
                            << BlockNamePrinter(FurthestAway) << "\n");
462
0
          ConnectToExitBlock.insert(FurthestAway);
463
0
          Roots.push_back(FurthestAway);
464
0
          LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
465
0
                            << NewNum << "\n\t\t\tRemoving DFS info\n");
466
0
          for (unsigned i = NewNum; i > Num; --i) {
467
0
            const NodePtr N = SNCA.NumToNode[i];
468
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
469
0
                              << BlockNamePrinter(N) << "\n");
470
0
            SNCA.NodeToInfo.erase(N);
471
0
            SNCA.NumToNode.pop_back();
472
0
          }
473
0
          const unsigned PrevNum = Num;
474
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
475
0
          Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
476
0
          for (unsigned i = PrevNum + 1; i <= Num; ++i)
477
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
478
0
                              << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
479
0
        }
480
0
      }
481
0
    }
482
0
483
0
    LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
484
0
    LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
485
0
    LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
486
0
               << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
487
0
488
0
    assert((Total + 1 == Num) && "Everything should have been visited");
489
0
490
0
    // Step #3: If we found some non-trivial roots, make them non-redundant.
491
0
    if (HasNonTrivialRoots) RemoveRedundantRoots(DT, BUI, Roots);
492
0
493
0
    LLVM_DEBUG(dbgs() << "Found roots: ");
494
0
    LLVM_DEBUG(for (auto *Root
495
0
                    : Roots) dbgs()
496
0
               << BlockNamePrinter(Root) << " ");
497
0
    LLVM_DEBUG(dbgs() << "\n");
498
0
499
0
    return Roots;
500
0
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::FindRoots(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
383
605k
  static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
384
605k
    assert(DT.Parent && "Parent pointer is not set");
385
605k
    RootsT Roots;
386
605k
387
605k
    // For dominators, function entry CFG node is always a tree root node.
388
605k
    if (!IsPostDom) {
389
0
      Roots.push_back(GetEntryNode(DT));
390
0
      return Roots;
391
0
    }
392
605k
393
605k
    SemiNCAInfo SNCA(BUI);
394
605k
395
605k
    // PostDominatorTree always has a virtual root.
396
605k
    SNCA.addVirtualRoot();
397
605k
    unsigned Num = 1;
398
605k
399
605k
    LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
400
605k
401
605k
    // Step #1: Find all the trivial roots that are going to will definitely
402
605k
    // remain tree roots.
403
605k
    unsigned Total = 0;
404
605k
    // It may happen that there are some new nodes in the CFG that are result of
405
605k
    // the ongoing batch update, but we cannot really pretend that they don't
406
605k
    // exist -- we won't see any outgoing or incoming edges to them, so it's
407
605k
    // fine to discover them here, as they would end up appearing in the CFG at
408
605k
    // some point anyway.
409
3.06M
    for (const NodePtr N : nodes(DT.Parent)) {
410
3.06M
      ++Total;
411
3.06M
      // If it has no *successors*, it is definitely a root.
412
3.06M
      if (!HasForwardSuccessors(N, BUI)) {
413
663k
        Roots.push_back(N);
414
663k
        // Run DFS not to walk this part of CFG later.
415
663k
        Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
416
663k
        LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
417
663k
                          << "\n");
418
663k
        LLVM_DEBUG(dbgs() << "Last visited node: "
419
663k
                          << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
420
663k
      }
421
3.06M
    }
422
605k
423
605k
    LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
424
605k
425
605k
    // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
426
605k
    // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
427
605k
    // nodes in infinite loops).
428
605k
    bool HasNonTrivialRoots = false;
429
605k
    // Accounting for the virtual exit, see if we had any reverse-unreachable
430
605k
    // nodes.
431
605k
    if (Total + 1 != Num) {
432
509
      HasNonTrivialRoots = true;
433
509
      // Make another DFS pass over all other nodes to find the
434
509
      // reverse-unreachable blocks, and find the furthest paths we'll be able
435
509
      // to make.
436
509
      // Note that this looks N^2, but it's really 2N worst case, if every node
437
509
      // is unreachable. This is because we are still going to only visit each
438
509
      // unreachable node once, we may just visit it in two directions,
439
509
      // depending on how lucky we get.
440
509
      SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
441
8.76k
      for (const NodePtr I : nodes(DT.Parent)) {
442
8.76k
        if (SNCA.NodeToInfo.count(I) == 0) {
443
606
          LLVM_DEBUG(dbgs()
444
606
                     << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
445
606
          // Find the furthest away we can get by following successors, then
446
606
          // follow them in reverse.  This gives us some reasonable answer about
447
606
          // the post-dom tree inside any infinite loop. In particular, it
448
606
          // guarantees we get to the farthest away point along *some*
449
606
          // path. This also matches the GCC's behavior.
450
606
          // If we really wanted a totally complete picture of dominance inside
451
606
          // this infinite loop, we could do it with SCC-like algorithms to find
452
606
          // the lowest and highest points in the infinite loop.  In theory, it
453
606
          // would be nice to give the canonical backedge for the loop, but it's
454
606
          // expensive and does not always lead to a minimal set of roots.
455
606
          LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
456
606
457
606
          const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num);
458
606
          const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
459
606
          LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
460
606
                            << "(non-trivial root): "
461
606
                            << BlockNamePrinter(FurthestAway) << "\n");
462
606
          ConnectToExitBlock.insert(FurthestAway);
463
606
          Roots.push_back(FurthestAway);
464
606
          LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
465
606
                            << NewNum << "\n\t\t\tRemoving DFS info\n");
466
2.26k
          for (unsigned i = NewNum; i > Num; 
--i1.65k
) {
467
1.65k
            const NodePtr N = SNCA.NumToNode[i];
468
1.65k
            LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
469
1.65k
                              << BlockNamePrinter(N) << "\n");
470
1.65k
            SNCA.NodeToInfo.erase(N);
471
1.65k
            SNCA.NumToNode.pop_back();
472
1.65k
          }
473
606
          const unsigned PrevNum = Num;
474
606
          LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
475
606
          Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
476
2.20k
          for (unsigned i = PrevNum + 1; i <= Num; 
++i1.59k
)
477
606
            LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
478
606
                              << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
479
606
        }
480
8.76k
      }
481
509
    }
482
605k
483
605k
    LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
484
605k
    LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
485
605k
    LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
486
605k
               << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
487
605k
488
605k
    assert((Total + 1 == Num) && "Everything should have been visited");
489
605k
490
605k
    // Step #3: If we found some non-trivial roots, make them non-redundant.
491
605k
    if (HasNonTrivialRoots) 
RemoveRedundantRoots(DT, BUI, Roots)509
;
492
605k
493
605k
    LLVM_DEBUG(dbgs() << "Found roots: ");
494
605k
    LLVM_DEBUG(for (auto *Root
495
605k
                    : Roots) dbgs()
496
605k
               << BlockNamePrinter(Root) << " ");
497
605k
    LLVM_DEBUG(dbgs() << "\n");
498
605k
499
605k
    return Roots;
500
605k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::FindRoots(llvm::DominatorTreeBase<llvm::VPBlockBase, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::BatchUpdateInfo*)
Line
Count
Source
383
28
  static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
384
28
    assert(DT.Parent && "Parent pointer is not set");
385
28
    RootsT Roots;
386
28
387
28
    // For dominators, function entry CFG node is always a tree root node.
388
28
    if (!IsPostDom) {
389
28
      Roots.push_back(GetEntryNode(DT));
390
28
      return Roots;
391
28
    }
392
0
393
0
    SemiNCAInfo SNCA(BUI);
394
0
395
0
    // PostDominatorTree always has a virtual root.
396
0
    SNCA.addVirtualRoot();
397
0
    unsigned Num = 1;
398
0
399
0
    LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
400
0
401
0
    // Step #1: Find all the trivial roots that are going to will definitely
402
0
    // remain tree roots.
403
0
    unsigned Total = 0;
404
0
    // It may happen that there are some new nodes in the CFG that are result of
405
0
    // the ongoing batch update, but we cannot really pretend that they don't
406
0
    // exist -- we won't see any outgoing or incoming edges to them, so it's
407
0
    // fine to discover them here, as they would end up appearing in the CFG at
408
0
    // some point anyway.
409
0
    for (const NodePtr N : nodes(DT.Parent)) {
410
0
      ++Total;
411
0
      // If it has no *successors*, it is definitely a root.
412
0
      if (!HasForwardSuccessors(N, BUI)) {
413
0
        Roots.push_back(N);
414
0
        // Run DFS not to walk this part of CFG later.
415
0
        Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
416
0
        LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
417
0
                          << "\n");
418
0
        LLVM_DEBUG(dbgs() << "Last visited node: "
419
0
                          << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
420
0
      }
421
0
    }
422
0
423
0
    LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
424
0
425
0
    // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
426
0
    // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
427
0
    // nodes in infinite loops).
428
0
    bool HasNonTrivialRoots = false;
429
0
    // Accounting for the virtual exit, see if we had any reverse-unreachable
430
0
    // nodes.
431
0
    if (Total + 1 != Num) {
432
0
      HasNonTrivialRoots = true;
433
0
      // Make another DFS pass over all other nodes to find the
434
0
      // reverse-unreachable blocks, and find the furthest paths we'll be able
435
0
      // to make.
436
0
      // Note that this looks N^2, but it's really 2N worst case, if every node
437
0
      // is unreachable. This is because we are still going to only visit each
438
0
      // unreachable node once, we may just visit it in two directions,
439
0
      // depending on how lucky we get.
440
0
      SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
441
0
      for (const NodePtr I : nodes(DT.Parent)) {
442
0
        if (SNCA.NodeToInfo.count(I) == 0) {
443
0
          LLVM_DEBUG(dbgs()
444
0
                     << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
445
0
          // Find the furthest away we can get by following successors, then
446
0
          // follow them in reverse.  This gives us some reasonable answer about
447
0
          // the post-dom tree inside any infinite loop. In particular, it
448
0
          // guarantees we get to the farthest away point along *some*
449
0
          // path. This also matches the GCC's behavior.
450
0
          // If we really wanted a totally complete picture of dominance inside
451
0
          // this infinite loop, we could do it with SCC-like algorithms to find
452
0
          // the lowest and highest points in the infinite loop.  In theory, it
453
0
          // would be nice to give the canonical backedge for the loop, but it's
454
0
          // expensive and does not always lead to a minimal set of roots.
455
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
456
0
457
0
          const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num);
458
0
          const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
459
0
          LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
460
0
                            << "(non-trivial root): "
461
0
                            << BlockNamePrinter(FurthestAway) << "\n");
462
0
          ConnectToExitBlock.insert(FurthestAway);
463
0
          Roots.push_back(FurthestAway);
464
0
          LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
465
0
                            << NewNum << "\n\t\t\tRemoving DFS info\n");
466
0
          for (unsigned i = NewNum; i > Num; --i) {
467
0
            const NodePtr N = SNCA.NumToNode[i];
468
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
469
0
                              << BlockNamePrinter(N) << "\n");
470
0
            SNCA.NodeToInfo.erase(N);
471
0
            SNCA.NumToNode.pop_back();
472
0
          }
473
0
          const unsigned PrevNum = Num;
474
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
475
0
          Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
476
0
          for (unsigned i = PrevNum + 1; i <= Num; ++i)
477
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
478
0
                              << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
479
0
        }
480
0
      }
481
0
    }
482
0
483
0
    LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
484
0
    LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
485
0
    LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
486
0
               << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
487
0
488
0
    assert((Total + 1 == Num) && "Everything should have been visited");
489
0
490
0
    // Step #3: If we found some non-trivial roots, make them non-redundant.
491
0
    if (HasNonTrivialRoots) RemoveRedundantRoots(DT, BUI, Roots);
492
0
493
0
    LLVM_DEBUG(dbgs() << "Found roots: ");
494
0
    LLVM_DEBUG(for (auto *Root
495
0
                    : Roots) dbgs()
496
0
               << BlockNamePrinter(Root) << " ");
497
0
    LLVM_DEBUG(dbgs() << "\n");
498
0
499
0
    return Roots;
500
0
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::FindRoots(llvm::DominatorTreeBase<clang::CFGBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
383
8
  static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
384
8
    assert(DT.Parent && "Parent pointer is not set");
385
8
    RootsT Roots;
386
8
387
8
    // For dominators, function entry CFG node is always a tree root node.
388
8
    if (!IsPostDom) {
389
8
      Roots.push_back(GetEntryNode(DT));
390
8
      return Roots;
391
8
    }
392
0
393
0
    SemiNCAInfo SNCA(BUI);
394
0
395
0
    // PostDominatorTree always has a virtual root.
396
0
    SNCA.addVirtualRoot();
397
0
    unsigned Num = 1;
398
0
399
0
    LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
400
0
401
0
    // Step #1: Find all the trivial roots that are going to will definitely
402
0
    // remain tree roots.
403
0
    unsigned Total = 0;
404
0
    // It may happen that there are some new nodes in the CFG that are result of
405
0
    // the ongoing batch update, but we cannot really pretend that they don't
406
0
    // exist -- we won't see any outgoing or incoming edges to them, so it's
407
0
    // fine to discover them here, as they would end up appearing in the CFG at
408
0
    // some point anyway.
409
0
    for (const NodePtr N : nodes(DT.Parent)) {
410
0
      ++Total;
411
0
      // If it has no *successors*, it is definitely a root.
412
0
      if (!HasForwardSuccessors(N, BUI)) {
413
0
        Roots.push_back(N);
414
0
        // Run DFS not to walk this part of CFG later.
415
0
        Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
416
0
        LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
417
0
                          << "\n");
418
0
        LLVM_DEBUG(dbgs() << "Last visited node: "
419
0
                          << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
420
0
      }
421
0
    }
422
0
423
0
    LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
424
0
425
0
    // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
426
0
    // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
427
0
    // nodes in infinite loops).
428
0
    bool HasNonTrivialRoots = false;
429
0
    // Accounting for the virtual exit, see if we had any reverse-unreachable
430
0
    // nodes.
431
0
    if (Total + 1 != Num) {
432
0
      HasNonTrivialRoots = true;
433
0
      // Make another DFS pass over all other nodes to find the
434
0
      // reverse-unreachable blocks, and find the furthest paths we'll be able
435
0
      // to make.
436
0
      // Note that this looks N^2, but it's really 2N worst case, if every node
437
0
      // is unreachable. This is because we are still going to only visit each
438
0
      // unreachable node once, we may just visit it in two directions,
439
0
      // depending on how lucky we get.
440
0
      SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
441
0
      for (const NodePtr I : nodes(DT.Parent)) {
442
0
        if (SNCA.NodeToInfo.count(I) == 0) {
443
0
          LLVM_DEBUG(dbgs()
444
0
                     << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
445
0
          // Find the furthest away we can get by following successors, then
446
0
          // follow them in reverse.  This gives us some reasonable answer about
447
0
          // the post-dom tree inside any infinite loop. In particular, it
448
0
          // guarantees we get to the farthest away point along *some*
449
0
          // path. This also matches the GCC's behavior.
450
0
          // If we really wanted a totally complete picture of dominance inside
451
0
          // this infinite loop, we could do it with SCC-like algorithms to find
452
0
          // the lowest and highest points in the infinite loop.  In theory, it
453
0
          // would be nice to give the canonical backedge for the loop, but it's
454
0
          // expensive and does not always lead to a minimal set of roots.
455
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
456
0
457
0
          const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num);
458
0
          const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
459
0
          LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
460
0
                            << "(non-trivial root): "
461
0
                            << BlockNamePrinter(FurthestAway) << "\n");
462
0
          ConnectToExitBlock.insert(FurthestAway);
463
0
          Roots.push_back(FurthestAway);
464
0
          LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
465
0
                            << NewNum << "\n\t\t\tRemoving DFS info\n");
466
0
          for (unsigned i = NewNum; i > Num; --i) {
467
0
            const NodePtr N = SNCA.NumToNode[i];
468
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
469
0
                              << BlockNamePrinter(N) << "\n");
470
0
            SNCA.NodeToInfo.erase(N);
471
0
            SNCA.NumToNode.pop_back();
472
0
          }
473
0
          const unsigned PrevNum = Num;
474
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
475
0
          Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
476
0
          for (unsigned i = PrevNum + 1; i <= Num; ++i)
477
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
478
0
                              << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
479
0
        }
480
0
      }
481
0
    }
482
0
483
0
    LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
484
0
    LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
485
0
    LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
486
0
               << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
487
0
488
0
    assert((Total + 1 == Num) && "Everything should have been visited");
489
0
490
0
    // Step #3: If we found some non-trivial roots, make them non-redundant.
491
0
    if (HasNonTrivialRoots) RemoveRedundantRoots(DT, BUI, Roots);
492
0
493
0
    LLVM_DEBUG(dbgs() << "Found roots: ");
494
0
    LLVM_DEBUG(for (auto *Root
495
0
                    : Roots) dbgs()
496
0
               << BlockNamePrinter(Root) << " ");
497
0
    LLVM_DEBUG(dbgs() << "\n");
498
0
499
0
    return Roots;
500
0
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::FindRoots(llvm::DominatorTreeBase<clang::CFGBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
383
107
  static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
384
107
    assert(DT.Parent && "Parent pointer is not set");
385
107
    RootsT Roots;
386
107
387
107
    // For dominators, function entry CFG node is always a tree root node.
388
107
    if (!IsPostDom) {
389
0
      Roots.push_back(GetEntryNode(DT));
390
0
      return Roots;
391
0
    }
392
107
393
107
    SemiNCAInfo SNCA(BUI);
394
107
395
107
    // PostDominatorTree always has a virtual root.
396
107
    SNCA.addVirtualRoot();
397
107
    unsigned Num = 1;
398
107
399
107
    LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
400
107
401
107
    // Step #1: Find all the trivial roots that are going to will definitely
402
107
    // remain tree roots.
403
107
    unsigned Total = 0;
404
107
    // It may happen that there are some new nodes in the CFG that are result of
405
107
    // the ongoing batch update, but we cannot really pretend that they don't
406
107
    // exist -- we won't see any outgoing or incoming edges to them, so it's
407
107
    // fine to discover them here, as they would end up appearing in the CFG at
408
107
    // some point anyway.
409
549
    for (const NodePtr N : nodes(DT.Parent)) {
410
549
      ++Total;
411
549
      // If it has no *successors*, it is definitely a root.
412
549
      if (!HasForwardSuccessors(N, BUI)) {
413
107
        Roots.push_back(N);
414
107
        // Run DFS not to walk this part of CFG later.
415
107
        Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
416
107
        LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
417
107
                          << "\n");
418
107
        LLVM_DEBUG(dbgs() << "Last visited node: "
419
107
                          << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
420
107
      }
421
549
    }
422
107
423
107
    LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
424
107
425
107
    // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
426
107
    // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
427
107
    // nodes in infinite loops).
428
107
    bool HasNonTrivialRoots = false;
429
107
    // Accounting for the virtual exit, see if we had any reverse-unreachable
430
107
    // nodes.
431
107
    if (Total + 1 != Num) {
432
0
      HasNonTrivialRoots = true;
433
0
      // Make another DFS pass over all other nodes to find the
434
0
      // reverse-unreachable blocks, and find the furthest paths we'll be able
435
0
      // to make.
436
0
      // Note that this looks N^2, but it's really 2N worst case, if every node
437
0
      // is unreachable. This is because we are still going to only visit each
438
0
      // unreachable node once, we may just visit it in two directions,
439
0
      // depending on how lucky we get.
440
0
      SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
441
0
      for (const NodePtr I : nodes(DT.Parent)) {
442
0
        if (SNCA.NodeToInfo.count(I) == 0) {
443
0
          LLVM_DEBUG(dbgs()
444
0
                     << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
445
0
          // Find the furthest away we can get by following successors, then
446
0
          // follow them in reverse.  This gives us some reasonable answer about
447
0
          // the post-dom tree inside any infinite loop. In particular, it
448
0
          // guarantees we get to the farthest away point along *some*
449
0
          // path. This also matches the GCC's behavior.
450
0
          // If we really wanted a totally complete picture of dominance inside
451
0
          // this infinite loop, we could do it with SCC-like algorithms to find
452
0
          // the lowest and highest points in the infinite loop.  In theory, it
453
0
          // would be nice to give the canonical backedge for the loop, but it's
454
0
          // expensive and does not always lead to a minimal set of roots.
455
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
456
0
457
0
          const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num);
458
0
          const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
459
0
          LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
460
0
                            << "(non-trivial root): "
461
0
                            << BlockNamePrinter(FurthestAway) << "\n");
462
0
          ConnectToExitBlock.insert(FurthestAway);
463
0
          Roots.push_back(FurthestAway);
464
0
          LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
465
0
                            << NewNum << "\n\t\t\tRemoving DFS info\n");
466
0
          for (unsigned i = NewNum; i > Num; --i) {
467
0
            const NodePtr N = SNCA.NumToNode[i];
468
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
469
0
                              << BlockNamePrinter(N) << "\n");
470
0
            SNCA.NodeToInfo.erase(N);
471
0
            SNCA.NumToNode.pop_back();
472
0
          }
473
0
          const unsigned PrevNum = Num;
474
0
          LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
475
0
          Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
476
0
          for (unsigned i = PrevNum + 1; i <= Num; ++i)
477
0
            LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
478
0
                              << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
479
0
        }
480
0
      }
481
0
    }
482
107
483
107
    LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
484
107
    LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
485
107
    LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
486
107
               << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
487
107
488
107
    assert((Total + 1 == Num) && "Everything should have been visited");
489
107
490
107
    // Step #3: If we found some non-trivial roots, make them non-redundant.
491
107
    if (HasNonTrivialRoots) 
RemoveRedundantRoots(DT, BUI, Roots)0
;
492
107
493
107
    LLVM_DEBUG(dbgs() << "Found roots: ");
494
107
    LLVM_DEBUG(for (auto *Root
495
107
                    : Roots) dbgs()
496
107
               << BlockNamePrinter(Root) << " ");
497
107
    LLVM_DEBUG(dbgs() << "\n");
498
107
499
107
    return Roots;
500
107
  }
501
502
  // This function only makes sense for postdominators.
503
  // We define roots to be some set of CFG nodes where (reverse) DFS walks have
504
  // to start in order to visit all the CFG nodes (including the
505
  // reverse-unreachable ones).
506
  // When the search for non-trivial roots is done it may happen that some of
507
  // the non-trivial roots are reverse-reachable from other non-trivial roots,
508
  // which makes them redundant. This function removes them from the set of
509
  // input roots.
510
  static void RemoveRedundantRoots(const DomTreeT &DT, BatchUpdatePtr BUI,
511
1.80k
                                   RootsT &Roots) {
512
1.80k
    assert(IsPostDom && "This function is for postdominators only");
513
1.80k
    LLVM_DEBUG(dbgs() << "Removing redundant roots\n");
514
1.80k
515
1.80k
    SemiNCAInfo SNCA(BUI);
516
1.80k
517
5.08k
    for (unsigned i = 0; i < Roots.size(); 
++i3.28k
) {
518
3.28k
      auto &Root = Roots[i];
519
3.28k
      // Trivial roots are always non-redundant.
520
3.28k
      if (!HasForwardSuccessors(Root, BUI)) 
continue1.29k
;
521
1.99k
      LLVM_DEBUG(dbgs() << "\tChecking if " << BlockNamePrinter(Root)
522
1.99k
                        << " remains a root\n");
523
1.99k
      SNCA.clear();
524
1.99k
      // Do a forward walk looking for the other roots.
525
1.99k
      const unsigned Num = SNCA.runDFS<true>(Root, 0, AlwaysDescend, 0);
526
1.99k
      // Skip the start node and begin from the second one (note that DFS uses
527
1.99k
      // 1-based indexing).
528
3.95k
      for (unsigned x = 2; x <= Num; 
++x1.96k
) {
529
2.04k
        const NodePtr N = SNCA.NumToNode[x];
530
2.04k
        // If we wound another root in a (forward) DFS walk, remove the current
531
2.04k
        // root from the set of roots, as it is reverse-reachable from the other
532
2.04k
        // one.
533
2.04k
        if (llvm::find(Roots, N) != Roots.end()) {
534
79
          LLVM_DEBUG(dbgs() << "\tForward DFS walk found another root "
535
79
                            << BlockNamePrinter(N) << "\n\tRemoving root "
536
79
                            << BlockNamePrinter(Root) << "\n");
537
79
          std::swap(Root, Roots.back());
538
79
          Roots.pop_back();
539
79
540
79
          // Root at the back takes the current root's place.
541
79
          // Start the next loop iteration with the same index.
542
79
          --i;
543
79
          break;
544
79
        }
545
2.04k
      }
546
1.99k
    }
547
1.80k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::SmallVector<llvm::MachineBasicBlock*, 1u>&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::SmallVector<llvm::MachineBasicBlock*, 4u>&)
Line
Count
Source
511
1.29k
                                   RootsT &Roots) {
512
1.29k
    assert(IsPostDom && "This function is for postdominators only");
513
1.29k
    LLVM_DEBUG(dbgs() << "Removing redundant roots\n");
514
1.29k
515
1.29k
    SemiNCAInfo SNCA(BUI);
516
1.29k
517
3.42k
    for (unsigned i = 0; i < Roots.size(); 
++i2.13k
) {
518
2.13k
      auto &Root = Roots[i];
519
2.13k
      // Trivial roots are always non-redundant.
520
2.13k
      if (!HasForwardSuccessors(Root, BUI)) 
continue744
;
521
1.38k
      LLVM_DEBUG(dbgs() << "\tChecking if " << BlockNamePrinter(Root)
522
1.38k
                        << " remains a root\n");
523
1.38k
      SNCA.clear();
524
1.38k
      // Do a forward walk looking for the other roots.
525
1.38k
      const unsigned Num = SNCA.runDFS<true>(Root, 0, AlwaysDescend, 0);
526
1.38k
      // Skip the start node and begin from the second one (note that DFS uses
527
1.38k
      // 1-based indexing).
528
2.85k
      for (unsigned x = 2; x <= Num; 
++x1.47k
) {
529
1.51k
        const NodePtr N = SNCA.NumToNode[x];
530
1.51k
        // If we wound another root in a (forward) DFS walk, remove the current
531
1.51k
        // root from the set of roots, as it is reverse-reachable from the other
532
1.51k
        // one.
533
1.51k
        if (llvm::find(Roots, N) != Roots.end()) {
534
39
          LLVM_DEBUG(dbgs() << "\tForward DFS walk found another root "
535
39
                            << BlockNamePrinter(N) << "\n\tRemoving root "
536
39
                            << BlockNamePrinter(Root) << "\n");
537
39
          std::swap(Root, Roots.back());
538
39
          Roots.pop_back();
539
39
540
39
          // Root at the back takes the current root's place.
541
39
          // Start the next loop iteration with the same index.
542
39
          --i;
543
39
          break;
544
39
        }
545
1.51k
      }
546
1.38k
    }
547
1.29k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::SmallVector<llvm::BasicBlock*, 4u>&)
Line
Count
Source
511
509
                                   RootsT &Roots) {
512
509
    assert(IsPostDom && "This function is for postdominators only");
513
509
    LLVM_DEBUG(dbgs() << "Removing redundant roots\n");
514
509
515
509
    SemiNCAInfo SNCA(BUI);
516
509
517
1.66k
    for (unsigned i = 0; i < Roots.size(); 
++i1.15k
) {
518
1.15k
      auto &Root = Roots[i];
519
1.15k
      // Trivial roots are always non-redundant.
520
1.15k
      if (!HasForwardSuccessors(Root, BUI)) 
continue547
;
521
606
      LLVM_DEBUG(dbgs() << "\tChecking if " << BlockNamePrinter(Root)
522
606
                        << " remains a root\n");
523
606
      SNCA.clear();
524
606
      // Do a forward walk looking for the other roots.
525
606
      const unsigned Num = SNCA.runDFS<true>(Root, 0, AlwaysDescend, 0);
526
606
      // Skip the start node and begin from the second one (note that DFS uses
527
606
      // 1-based indexing).
528
1.10k
      for (unsigned x = 2; x <= Num; 
++x495
) {
529
535
        const NodePtr N = SNCA.NumToNode[x];
530
535
        // If we wound another root in a (forward) DFS walk, remove the current
531
535
        // root from the set of roots, as it is reverse-reachable from the other
532
535
        // one.
533
535
        if (llvm::find(Roots, N) != Roots.end()) {
534
40
          LLVM_DEBUG(dbgs() << "\tForward DFS walk found another root "
535
40
                            << BlockNamePrinter(N) << "\n\tRemoving root "
536
40
                            << BlockNamePrinter(Root) << "\n");
537
40
          std::swap(Root, Roots.back());
538
40
          Roots.pop_back();
539
40
540
40
          // Root at the back takes the current root's place.
541
40
          // Start the next loop iteration with the same index.
542
40
          --i;
543
40
          break;
544
40
        }
545
535
      }
546
606
    }
547
509
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::SmallVector<llvm::BasicBlock*, 1u>&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::VPBlockBase, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::BatchUpdateInfo*, llvm::SmallVector<llvm::VPBlockBase*, 1u>&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::RemoveRedundantRoots(llvm::DominatorTreeBase<clang::CFGBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::BatchUpdateInfo*, llvm::SmallVector<clang::CFGBlock*, 4u>&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::RemoveRedundantRoots(llvm::DominatorTreeBase<clang::CFGBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*, llvm::SmallVector<clang::CFGBlock*, 1u>&)
548
549
  template <typename DescendCondition>
550
15.1M
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
15.1M
    if (!IsPostDom) {
552
13.0M
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
13.0M
      runDFS(DT.Roots[0], 0, DC, 0);
554
13.0M
      return;
555
13.0M
    }
556
2.11M
557
2.11M
    addVirtualRoot();
558
2.11M
    unsigned Num = 1;
559
2.60M
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
2.11M
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::doFullDFSWalk<bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*))
Line
Count
Source
550
2.61M
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
2.61M
    if (!IsPostDom) {
552
2.61M
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
2.61M
      runDFS(DT.Roots[0], 0, DC, 0);
554
2.61M
      return;
555
2.61M
    }
556
0
557
0
    addVirtualRoot();
558
0
    unsigned Num = 1;
559
0
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
0
  }
Unexecuted instantiation: void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*))
Unexecuted instantiation: void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*))
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::doFullDFSWalk<bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*))
Line
Count
Source
550
1.50M
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
1.50M
    if (!IsPostDom) {
552
0
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
0
      runDFS(DT.Roots[0], 0, DC, 0);
554
0
      return;
555
0
    }
556
1.50M
557
1.50M
    addVirtualRoot();
558
1.50M
    unsigned Num = 1;
559
1.92M
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
1.50M
  }
Unexecuted instantiation: void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*))
Unexecuted instantiation: void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*))
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::doFullDFSWalk<bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*))
Line
Count
Source
550
10.3M
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
10.3M
    if (!IsPostDom) {
552
10.3M
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
10.3M
      runDFS(DT.Roots[0], 0, DC, 0);
554
10.3M
      return;
555
10.3M
    }
556
0
557
0
    addVirtualRoot();
558
0
    unsigned Num = 1;
559
0
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
0
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::doFullDFSWalk<bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*))
Line
Count
Source
550
605k
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
605k
    if (!IsPostDom) {
552
0
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
0
      runDFS(DT.Roots[0], 0, DC, 0);
554
0
      return;
555
0
    }
556
605k
557
605k
    addVirtualRoot();
558
605k
    unsigned Num = 1;
559
663k
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
605k
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*))
Line
Count
Source
550
1.73k
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
1.73k
    if (!IsPostDom) {
552
1.73k
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
1.73k
      runDFS(DT.Roots[0], 0, DC, 0);
554
1.73k
      return;
555
1.73k
    }
556
0
557
0
    addVirtualRoot();
558
0
    unsigned Num = 1;
559
0
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
0
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*))
Line
Count
Source
550
2.46k
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
2.46k
    if (!IsPostDom) {
552
2.46k
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
2.46k
      runDFS(DT.Roots[0], 0, DC, 0);
554
2.46k
      return;
555
2.46k
    }
556
0
557
0
    addVirtualRoot();
558
0
    unsigned Num = 1;
559
0
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
0
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*))
Line
Count
Source
550
1.70k
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
1.70k
    if (!IsPostDom) {
552
0
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
0
      runDFS(DT.Roots[0], 0, DC, 0);
554
0
      return;
555
0
    }
556
1.70k
557
1.70k
    addVirtualRoot();
558
1.70k
    unsigned Num = 1;
559
5.13k
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
1.70k
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*))
Line
Count
Source
550
2.05k
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
2.05k
    if (!IsPostDom) {
552
0
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
0
      runDFS(DT.Roots[0], 0, DC, 0);
554
0
      return;
555
0
    }
556
2.05k
557
2.05k
    addVirtualRoot();
558
2.05k
    unsigned Num = 1;
559
6.04k
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
2.05k
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::doFullDFSWalk<bool (*)(llvm::VPBlockBase*, llvm::VPBlockBase*)>(llvm::DominatorTreeBase<llvm::VPBlockBase, false> const&, bool (*)(llvm::VPBlockBase*, llvm::VPBlockBase*))
Line
Count
Source
550
28
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
28
    if (!IsPostDom) {
552
28
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
28
      runDFS(DT.Roots[0], 0, DC, 0);
554
28
      return;
555
28
    }
556
0
557
0
    addVirtualRoot();
558
0
    unsigned Num = 1;
559
0
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
0
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::doFullDFSWalk<bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(llvm::DominatorTreeBase<clang::CFGBlock, false> const&, bool (*)(clang::CFGBlock*, clang::CFGBlock*))
Line
Count
Source
550
8
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
8
    if (!IsPostDom) {
552
8
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
8
      runDFS(DT.Roots[0], 0, DC, 0);
554
8
      return;
555
8
    }
556
0
557
0
    addVirtualRoot();
558
0
    unsigned Num = 1;
559
0
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
0
  }
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::doFullDFSWalk<bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(llvm::DominatorTreeBase<clang::CFGBlock, true> const&, bool (*)(clang::CFGBlock*, clang::CFGBlock*))
Line
Count
Source
550
107
  void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
551
107
    if (!IsPostDom) {
552
0
      assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
553
0
      runDFS(DT.Roots[0], 0, DC, 0);
554
0
      return;
555
0
    }
556
107
557
107
    addVirtualRoot();
558
107
    unsigned Num = 1;
559
107
    for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
560
107
  }
561
562
15.1M
  static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
563
15.1M
    auto *Parent = DT.Parent;
564
15.1M
    DT.reset();
565
15.1M
    DT.Parent = Parent;
566
15.1M
    SemiNCAInfo SNCA(nullptr);  // Since we are rebuilding the whole tree,
567
15.1M
                                // there's no point doing it incrementally.
568
15.1M
569
15.1M
    // Step #0: Number blocks in depth-first order and initialize variables used
570
15.1M
    // in later stages of the algorithm.
571
15.1M
    DT.Roots = FindRoots(DT, nullptr);
572
15.1M
    SNCA.doFullDFSWalk(DT, AlwaysDescend);
573
15.1M
574
15.1M
    SNCA.runSemiNCA(DT);
575
15.1M
    if (BUI) {
576
165k
      BUI->IsRecalculated = true;
577
165k
      LLVM_DEBUG(
578
165k
          dbgs() << "DomTree recalculated, skipping future batch updates\n");
579
165k
    }
580
15.1M
581
15.1M
    if (DT.Roots.empty()) 
return0
;
582
15.1M
583
15.1M
    // Add a node for the root. If the tree is a PostDominatorTree it will be
584
15.1M
    // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
585
15.1M
    // all real exits (including multiple exit blocks, infinite loops).
586
15.1M
    NodePtr Root = IsPostDom ? 
nullptr2.11M
:
DT.Roots[0]13.0M
;
587
15.1M
588
15.1M
    DT.RootNode = (DT.DomTreeNodes[Root] =
589
15.1M
                       llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
590
15.1M
        .get();
591
15.1M
    SNCA.attachNewSubtree(DT, DT.RootNode);
592
15.1M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
562
2.61M
  static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
563
2.61M
    auto *Parent = DT.Parent;
564
2.61M
    DT.reset();
565
2.61M
    DT.Parent = Parent;
566
2.61M
    SemiNCAInfo SNCA(nullptr);  // Since we are rebuilding the whole tree,
567
2.61M
                                // there's no point doing it incrementally.
568
2.61M
569
2.61M
    // Step #0: Number blocks in depth-first order and initialize variables used
570
2.61M
    // in later stages of the algorithm.
571
2.61M
    DT.Roots = FindRoots(DT, nullptr);
572
2.61M
    SNCA.doFullDFSWalk(DT, AlwaysDescend);
573
2.61M
574
2.61M
    SNCA.runSemiNCA(DT);
575
2.61M
    if (BUI) {
576
0
      BUI->IsRecalculated = true;
577
0
      LLVM_DEBUG(
578
0
          dbgs() << "DomTree recalculated, skipping future batch updates\n");
579
0
    }
580
2.61M
581
2.61M
    if (DT.Roots.empty()) 
return0
;
582
2.61M
583
2.61M
    // Add a node for the root. If the tree is a PostDominatorTree it will be
584
2.61M
    // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
585
2.61M
    // all real exits (including multiple exit blocks, infinite loops).
586
2.61M
    NodePtr Root = IsPostDom ? 
nullptr0
: DT.Roots[0];
587
2.61M
588
2.61M
    DT.RootNode = (DT.DomTreeNodes[Root] =
589
2.61M
                       llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
590
2.61M
        .get();
591
2.61M
    SNCA.attachNewSubtree(DT, DT.RootNode);
592
2.61M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
562
1.50M
  static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
563
1.50M
    auto *Parent = DT.Parent;
564
1.50M
    DT.reset();
565
1.50M
    DT.Parent = Parent;
566
1.50M
    SemiNCAInfo SNCA(nullptr);  // Since we are rebuilding the whole tree,
567
1.50M
                                // there's no point doing it incrementally.
568
1.50M
569
1.50M
    // Step #0: Number blocks in depth-first order and initialize variables used
570
1.50M
    // in later stages of the algorithm.
571
1.50M
    DT.Roots = FindRoots(DT, nullptr);
572
1.50M
    SNCA.doFullDFSWalk(DT, AlwaysDescend);
573
1.50M
574
1.50M
    SNCA.runSemiNCA(DT);
575
1.50M
    if (BUI) {
576
0
      BUI->IsRecalculated = true;
577
0
      LLVM_DEBUG(
578
0
          dbgs() << "DomTree recalculated, skipping future batch updates\n");
579
0
    }
580
1.50M
581
1.50M
    if (DT.Roots.empty()) 
return0
;
582
1.50M
583
1.50M
    // Add a node for the root. If the tree is a PostDominatorTree it will be
584
1.50M
    // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
585
1.50M
    // all real exits (including multiple exit blocks, infinite loops).
586
18.4E
    
NodePtr Root = IsPostDom 1.50M
?
nullptr1.50M
: DT.Roots[0];
587
1.50M
588
1.50M
    DT.RootNode = (DT.DomTreeNodes[Root] =
589
1.50M
                       llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
590
1.50M
        .get();
591
1.50M
    SNCA.attachNewSubtree(DT, DT.RootNode);
592
1.50M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
562
10.3M
  static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
563
10.3M
    auto *Parent = DT.Parent;
564
10.3M
    DT.reset();
565
10.3M
    DT.Parent = Parent;
566
10.3M
    SemiNCAInfo SNCA(nullptr);  // Since we are rebuilding the whole tree,
567
10.3M
                                // there's no point doing it incrementally.
568
10.3M
569
10.3M
    // Step #0: Number blocks in depth-first order and initialize variables used
570
10.3M
    // in later stages of the algorithm.
571
10.3M
    DT.Roots = FindRoots(DT, nullptr);
572
10.3M
    SNCA.doFullDFSWalk(DT, AlwaysDescend);
573
10.3M
574
10.3M
    SNCA.runSemiNCA(DT);
575
10.3M
    if (BUI) {
576
165k
      BUI->IsRecalculated = true;
577
165k
      LLVM_DEBUG(
578
165k
          dbgs() << "DomTree recalculated, skipping future batch updates\n");
579
165k
    }
580
10.3M
581
10.3M
    if (DT.Roots.empty()) 
return0
;
582
10.3M
583
10.3M
    // Add a node for the root. If the tree is a PostDominatorTree it will be
584
10.3M
    // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
585
10.3M
    // all real exits (including multiple exit blocks, infinite loops).
586
10.3M
    NodePtr Root = IsPostDom ? 
nullptr0
: DT.Roots[0];
587
10.3M
588
10.3M
    DT.RootNode = (DT.DomTreeNodes[Root] =
589
10.3M
                       llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
590
10.3M
        .get();
591
10.3M
    SNCA.attachNewSubtree(DT, DT.RootNode);
592
10.3M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
562
605k
  static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
563
605k
    auto *Parent = DT.Parent;
564
605k
    DT.reset();
565
605k
    DT.Parent = Parent;
566
605k
    SemiNCAInfo SNCA(nullptr);  // Since we are rebuilding the whole tree,
567
605k
                                // there's no point doing it incrementally.
568
605k
569
605k
    // Step #0: Number blocks in depth-first order and initialize variables used
570
605k
    // in later stages of the algorithm.
571
605k
    DT.Roots = FindRoots(DT, nullptr);
572
605k
    SNCA.doFullDFSWalk(DT, AlwaysDescend);
573
605k
574
605k
    SNCA.runSemiNCA(DT);
575
605k
    if (BUI) {
576
56
      BUI->IsRecalculated = true;
577
56
      LLVM_DEBUG(
578
56
          dbgs() << "DomTree recalculated, skipping future batch updates\n");
579
56
    }
580
605k
581
605k
    if (DT.Roots.empty()) 
return0
;
582
605k
583
605k
    // Add a node for the root. If the tree is a PostDominatorTree it will be
584
605k
    // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
585
605k
    // all real exits (including multiple exit blocks, infinite loops).
586
605k
    NodePtr Root = IsPostDom ? 
nullptr605k
:
DT.Roots[0]3
;
587
605k
588
605k
    DT.RootNode = (DT.DomTreeNodes[Root] =
589
605k
                       llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
590
605k
        .get();
591
605k
    SNCA.attachNewSubtree(DT, DT.RootNode);
592
605k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::VPBlockBase, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::BatchUpdateInfo*)
Line
Count
Source
562
28
  static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
563
28
    auto *Parent = DT.Parent;
564
28
    DT.reset();
565
28
    DT.Parent = Parent;
566
28
    SemiNCAInfo SNCA(nullptr);  // Since we are rebuilding the whole tree,
567
28
                                // there's no point doing it incrementally.
568
28
569
28
    // Step #0: Number blocks in depth-first order and initialize variables used
570
28
    // in later stages of the algorithm.
571
28
    DT.Roots = FindRoots(DT, nullptr);
572
28
    SNCA.doFullDFSWalk(DT, AlwaysDescend);
573
28
574
28
    SNCA.runSemiNCA(DT);
575
28
    if (BUI) {
576
0
      BUI->IsRecalculated = true;
577
0
      LLVM_DEBUG(
578
0
          dbgs() << "DomTree recalculated, skipping future batch updates\n");
579
0
    }
580
28
581
28
    if (DT.Roots.empty()) 
return0
;
582
28
583
28
    // Add a node for the root. If the tree is a PostDominatorTree it will be
584
28
    // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
585
28
    // all real exits (including multiple exit blocks, infinite loops).
586
28
    NodePtr Root = IsPostDom ? 
nullptr0
: DT.Roots[0];
587
28
588
28
    DT.RootNode = (DT.DomTreeNodes[Root] =
589
28
                       llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
590
28
        .get();
591
28
    SNCA.attachNewSubtree(DT, DT.RootNode);
592
28
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::CalculateFromScratch(llvm::DominatorTreeBase<clang::CFGBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*)
Line
Count
Source
562
8
  static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
563
8
    auto *Parent = DT.Parent;
564
8
    DT.reset();
565
8
    DT.Parent = Parent;
566
8
    SemiNCAInfo SNCA(nullptr);  // Since we are rebuilding the whole tree,
567
8
                                // there's no point doing it incrementally.
568
8
569
8
    // Step #0: Number blocks in depth-first order and initialize variables used
570
8
    // in later stages of the algorithm.
571
8
    DT.Roots = FindRoots(DT, nullptr);
572
8
    SNCA.doFullDFSWalk(DT, AlwaysDescend);
573
8
574
8
    SNCA.runSemiNCA(DT);
575
8
    if (BUI) {
576
0
      BUI->IsRecalculated = true;
577
0
      LLVM_DEBUG(
578
0
          dbgs() << "DomTree recalculated, skipping future batch updates\n");
579
0
    }
580
8
581
8
    if (DT.Roots.empty()) 
return0
;
582
8
583
8
    // Add a node for the root. If the tree is a PostDominatorTree it will be
584
8
    // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
585
8
    // all real exits (including multiple exit blocks, infinite loops).
586
8
    NodePtr Root = IsPostDom ? 
nullptr0
: DT.Roots[0];
587
8
588
8
    DT.RootNode = (DT.DomTreeNodes[Root] =
589
8
                       llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
590
8
        .get();
591
8
    SNCA.attachNewSubtree(DT, DT.RootNode);
592
8
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::CalculateFromScratch(llvm::DominatorTreeBase<clang::CFGBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
562
107
  static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
563
107
    auto *Parent = DT.Parent;
564
107
    DT.reset();
565
107
    DT.Parent = Parent;
566
107
    SemiNCAInfo SNCA(nullptr);  // Since we are rebuilding the whole tree,
567
107
                                // there's no point doing it incrementally.
568
107
569
107
    // Step #0: Number blocks in depth-first order and initialize variables used
570
107
    // in later stages of the algorithm.
571
107
    DT.Roots = FindRoots(DT, nullptr);
572
107
    SNCA.doFullDFSWalk(DT, AlwaysDescend);
573
107
574
107
    SNCA.runSemiNCA(DT);
575
107
    if (BUI) {
576
0
      BUI->IsRecalculated = true;
577
0
      LLVM_DEBUG(
578
0
          dbgs() << "DomTree recalculated, skipping future batch updates\n");
579
0
    }
580
107
581
107
    if (DT.Roots.empty()) 
return0
;
582
107
583
107
    // Add a node for the root. If the tree is a PostDominatorTree it will be
584
107
    // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
585
107
    // all real exits (including multiple exit blocks, infinite loops).
586
107
    NodePtr Root = IsPostDom ? nullptr : 
DT.Roots[0]0
;
587
107
588
107
    DT.RootNode = (DT.DomTreeNodes[Root] =
589
107
                       llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr))
590
107
        .get();
591
107
    SNCA.attachNewSubtree(DT, DT.RootNode);
592
107
  }
593
594
15.2M
  void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
595
15.2M
    // Attach the first unreachable block to AttachTo.
596
15.2M
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
597
15.2M
    // Loop over all of the discovered blocks in the function...
598
105M
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i89.9M
) {
599
89.9M
      NodePtr W = NumToNode[i];
600
89.9M
      LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
601
89.9M
                        << BlockNamePrinter(W) << "\n");
602
89.9M
603
89.9M
      // Don't replace this with 'count', the insertion side effect is important
604
89.9M
      if (DT.DomTreeNodes[W]) 
continue15.1M
; // Haven't calculated this node yet?
605
74.8M
606
74.8M
      NodePtr ImmDom = getIDom(W);
607
74.8M
608
74.8M
      // Get or calculate the node for the immediate dominator.
609
74.8M
      TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
610
74.8M
611
74.8M
      // Add a new tree node for this BasicBlock, and link it as a child of
612
74.8M
      // IDomNode.
613
74.8M
      DT.DomTreeNodes[W] = IDomNode->addChild(
614
74.8M
          llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
615
74.8M
    }
616
15.2M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Line
Count
Source
594
2.61M
  void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
595
2.61M
    // Attach the first unreachable block to AttachTo.
596
2.61M
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
597
2.61M
    // Loop over all of the discovered blocks in the function...
598
14.6M
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i12.0M
) {
599
12.0M
      NodePtr W = NumToNode[i];
600
12.0M
      LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
601
12.0M
                        << BlockNamePrinter(W) << "\n");
602
12.0M
603
12.0M
      // Don't replace this with 'count', the insertion side effect is important
604
12.0M
      if (DT.DomTreeNodes[W]) 
continue2.61M
; // Haven't calculated this node yet?
605
9.38M
606
9.38M
      NodePtr ImmDom = getIDom(W);
607
9.38M
608
9.38M
      // Get or calculate the node for the immediate dominator.
609
9.38M
      TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
610
9.38M
611
9.38M
      // Add a new tree node for this BasicBlock, and link it as a child of
612
9.38M
      // IDomNode.
613
9.38M
      DT.DomTreeNodes[W] = IDomNode->addChild(
614
9.38M
          llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
615
9.38M
    }
616
2.61M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Line
Count
Source
594
1.50M
  void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
595
1.50M
    // Attach the first unreachable block to AttachTo.
596
1.50M
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
597
1.50M
    // Loop over all of the discovered blocks in the function...
598
11.5M
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i10.0M
) {
599
10.0M
      NodePtr W = NumToNode[i];
600
10.0M
      LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
601
10.0M
                        << BlockNamePrinter(W) << "\n");
602
10.0M
603
10.0M
      // Don't replace this with 'count', the insertion side effect is important
604
10.0M
      if (DT.DomTreeNodes[W]) 
continue1.50M
; // Haven't calculated this node yet?
605
8.52M
606
8.52M
      NodePtr ImmDom = getIDom(W);
607
8.52M
608
8.52M
      // Get or calculate the node for the immediate dominator.
609
8.52M
      TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
610
8.52M
611
8.52M
      // Add a new tree node for this BasicBlock, and link it as a child of
612
8.52M
      // IDomNode.
613
8.52M
      DT.DomTreeNodes[W] = IDomNode->addChild(
614
8.52M
          llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
615
8.52M
    }
616
1.50M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
594
10.5M
  void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
595
10.5M
    // Attach the first unreachable block to AttachTo.
596
10.5M
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
597
10.5M
    // Loop over all of the discovered blocks in the function...
598
74.7M
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i64.2M
) {
599
64.2M
      NodePtr W = NumToNode[i];
600
64.2M
      LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
601
64.2M
                        << BlockNamePrinter(W) << "\n");
602
64.2M
603
64.2M
      // Don't replace this with 'count', the insertion side effect is important
604
64.2M
      if (DT.DomTreeNodes[W]) 
continue10.3M
; // Haven't calculated this node yet?
605
53.8M
606
53.8M
      NodePtr ImmDom = getIDom(W);
607
53.8M
608
53.8M
      // Get or calculate the node for the immediate dominator.
609
53.8M
      TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
610
53.8M
611
53.8M
      // Add a new tree node for this BasicBlock, and link it as a child of
612
53.8M
      // IDomNode.
613
53.8M
      DT.DomTreeNodes[W] = IDomNode->addChild(
614
53.8M
          llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
615
53.8M
    }
616
10.5M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
594
605k
  void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
595
605k
    // Attach the first unreachable block to AttachTo.
596
605k
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
597
605k
    // Loop over all of the discovered blocks in the function...
598
4.27M
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i3.66M
) {
599
3.66M
      NodePtr W = NumToNode[i];
600
3.66M
      LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
601
3.66M
                        << BlockNamePrinter(W) << "\n");
602
3.66M
603
3.66M
      // Don't replace this with 'count', the insertion side effect is important
604
3.66M
      if (DT.DomTreeNodes[W]) 
continue605k
; // Haven't calculated this node yet?
605
3.06M
606
3.06M
      NodePtr ImmDom = getIDom(W);
607
3.06M
608
3.06M
      // Get or calculate the node for the immediate dominator.
609
3.06M
      TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
610
3.06M
611
3.06M
      // Add a new tree node for this BasicBlock, and link it as a child of
612
3.06M
      // IDomNode.
613
3.06M
      DT.DomTreeNodes[W] = IDomNode->addChild(
614
3.06M
          llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
615
3.06M
    }
616
605k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::VPBlockBase, false>&, llvm::DomTreeNodeBase<llvm::VPBlockBase>*)
Line
Count
Source
594
28
  void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
595
28
    // Attach the first unreachable block to AttachTo.
596
28
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
597
28
    // Loop over all of the discovered blocks in the function...
598
163
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i135
) {
599
135
      NodePtr W = NumToNode[i];
600
135
      LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
601
135
                        << BlockNamePrinter(W) << "\n");
602
135
603
135
      // Don't replace this with 'count', the insertion side effect is important
604
135
      if (DT.DomTreeNodes[W]) 
continue28
; // Haven't calculated this node yet?
605
107
606
107
      NodePtr ImmDom = getIDom(W);
607
107
608
107
      // Get or calculate the node for the immediate dominator.
609
107
      TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
610
107
611
107
      // Add a new tree node for this BasicBlock, and link it as a child of
612
107
      // IDomNode.
613
107
      DT.DomTreeNodes[W] = IDomNode->addChild(
614
107
          llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
615
107
    }
616
28
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::attachNewSubtree(llvm::DominatorTreeBase<clang::CFGBlock, false>&, llvm::DomTreeNodeBase<clang::CFGBlock>*)
Line
Count
Source
594
8
  void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
595
8
    // Attach the first unreachable block to AttachTo.
596
8
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
597
8
    // Loop over all of the discovered blocks in the function...
598
74
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i66
) {
599
66
      NodePtr W = NumToNode[i];
600
66
      LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
601
66
                        << BlockNamePrinter(W) << "\n");
602
66
603
66
      // Don't replace this with 'count', the insertion side effect is important
604
66
      if (DT.DomTreeNodes[W]) 
continue8
; // Haven't calculated this node yet?
605
58
606
58
      NodePtr ImmDom = getIDom(W);
607
58
608
58
      // Get or calculate the node for the immediate dominator.
609
58
      TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
610
58
611
58
      // Add a new tree node for this BasicBlock, and link it as a child of
612
58
      // IDomNode.
613
58
      DT.DomTreeNodes[W] = IDomNode->addChild(
614
58
          llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
615
58
    }
616
8
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, true> >::attachNewSubtree(llvm::DominatorTreeBase<clang::CFGBlock, true>&, llvm::DomTreeNodeBase<clang::CFGBlock>*)
Line
Count
Source
594
107
  void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
595
107
    // Attach the first unreachable block to AttachTo.
596
107
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
597
107
    // Loop over all of the discovered blocks in the function...
598
763
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i656
) {
599
656
      NodePtr W = NumToNode[i];
600
656
      LLVM_DEBUG(dbgs() << "\tdiscovered a new reachable node "
601
656
                        << BlockNamePrinter(W) << "\n");
602
656
603
656
      // Don't replace this with 'count', the insertion side effect is important
604
656
      if (DT.DomTreeNodes[W]) 
continue107
; // Haven't calculated this node yet?
605
549
606
549
      NodePtr ImmDom = getIDom(W);
607
549
608
549
      // Get or calculate the node for the immediate dominator.
609
549
      TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
610
549
611
549
      // Add a new tree node for this BasicBlock, and link it as a child of
612
549
      // IDomNode.
613
549
      DT.DomTreeNodes[W] = IDomNode->addChild(
614
549
          llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode));
615
549
    }
616
107
  }
617
618
423k
  void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) {
619
423k
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
620
14.0M
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i13.5M
) {
621
13.5M
      const NodePtr N = NumToNode[i];
622
13.5M
      const TreeNodePtr TN = DT.getNode(N);
623
13.5M
      assert(TN);
624
13.5M
      const TreeNodePtr NewIDom = DT.getNode(NodeToInfo[N].IDom);
625
13.5M
      TN->setIDom(NewIDom);
626
13.5M
    }
627
423k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::reattachExistingSubtree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::reattachExistingSubtree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::reattachExistingSubtree(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
618
423k
  void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) {
619
423k
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
620
14.0M
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i13.5M
) {
621
13.5M
      const NodePtr N = NumToNode[i];
622
13.5M
      const TreeNodePtr TN = DT.getNode(N);
623
13.5M
      assert(TN);
624
13.5M
      const TreeNodePtr NewIDom = DT.getNode(NodeToInfo[N].IDom);
625
13.5M
      TN->setIDom(NewIDom);
626
13.5M
    }
627
423k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::reattachExistingSubtree(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
618
93
  void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) {
619
93
    NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
620
465
    for (size_t i = 1, e = NumToNode.size(); i != e; 
++i372
) {
621
372
      const NodePtr N = NumToNode[i];
622
372
      const TreeNodePtr TN = DT.getNode(N);
623
372
      assert(TN);
624
372
      const TreeNodePtr NewIDom = DT.getNode(NodeToInfo[N].IDom);
625
372
      TN->setIDom(NewIDom);
626
372
    }
627
93
  }
628
629
  // Helper struct used during edge insertions.
630
  struct InsertionInfo {
631
    struct Compare {
632
855
      bool operator()(TreeNodePtr LHS, TreeNodePtr RHS) const {
633
855
        return LHS->getLevel() < RHS->getLevel();
634
855
      }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertionInfo::Compare::operator()(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertionInfo::Compare::operator()(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertionInfo::Compare::operator()(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) const
Line
Count
Source
632
854
      bool operator()(TreeNodePtr LHS, TreeNodePtr RHS) const {
633
854
        return LHS->getLevel() < RHS->getLevel();
634
854
      }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertionInfo::Compare::operator()(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) const
Line
Count
Source
632
1
      bool operator()(TreeNodePtr LHS, TreeNodePtr RHS) const {
633
1
        return LHS->getLevel() < RHS->getLevel();
634
1
      }
635
    };
636
637
    // Bucket queue of tree nodes ordered by descending level. For simplicity,
638
    // we use a priority_queue here.
639
    std::priority_queue<TreeNodePtr, SmallVector<TreeNodePtr, 8>,
640
                        Compare>
641
        Bucket;
642
    SmallDenseSet<TreeNodePtr, 8> Visited;
643
    SmallVector<TreeNodePtr, 8> Affected;
644
#ifndef NDEBUG
645
    SmallVector<TreeNodePtr, 8> VisitedUnaffected;
646
#endif
647
  };
648
649
  static void InsertEdge(DomTreeT &DT, const BatchUpdatePtr BUI,
650
619k
                         const NodePtr From, const NodePtr To) {
651
619k
    assert((From || IsPostDom) &&
652
619k
           "From has to be a valid CFG node or a virtual root");
653
619k
    assert(To && "Cannot be a nullptr");
654
619k
    LLVM_DEBUG(dbgs() << "Inserting edge " << BlockNamePrinter(From) << " -> "
655
619k
                      << BlockNamePrinter(To) << "\n");
656
619k
    TreeNodePtr FromTN = DT.getNode(From);
657
619k
658
619k
    if (!FromTN) {
659
11.3k
      // Ignore edges from unreachable nodes for (forward) dominators.
660
11.3k
      if (!IsPostDom) 
return11.3k
;
661
3
662
3
      // The unreachable node becomes a new root -- a tree node for it.
663
3
      TreeNodePtr VirtualRoot = DT.getNode(nullptr);
664
3
      FromTN =
665
3
          (DT.DomTreeNodes[From] = VirtualRoot->addChild(
666
3
               llvm::make_unique<DomTreeNodeBase<NodeT>>(From, VirtualRoot)))
667
3
              .get();
668
3
      DT.Roots.push_back(From);
669
3
    }
670
619k
671
619k
    DT.DFSInfoValid = false;
672
608k
673
608k
    const TreeNodePtr ToTN = DT.getNode(To);
674
608k
    if (!ToTN)
675
114k
      InsertUnreachable(DT, BUI, FromTN, To);
676
493k
    else
677
493k
      InsertReachable(DT, BUI, FromTN, ToTN);
678
608k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertEdge(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertEdge(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertEdge(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::BasicBlock*)
Line
Count
Source
650
619k
                         const NodePtr From, const NodePtr To) {
651
619k
    assert((From || IsPostDom) &&
652
619k
           "From has to be a valid CFG node or a virtual root");
653
619k
    assert(To && "Cannot be a nullptr");
654
619k
    LLVM_DEBUG(dbgs() << "Inserting edge " << BlockNamePrinter(From) << " -> "
655
619k
                      << BlockNamePrinter(To) << "\n");
656
619k
    TreeNodePtr FromTN = DT.getNode(From);
657
619k
658
619k
    if (!FromTN) {
659
11.3k
      // Ignore edges from unreachable nodes for (forward) dominators.
660
11.3k
      if (!IsPostDom) return;
661
0
662
0
      // The unreachable node becomes a new root -- a tree node for it.
663
0
      TreeNodePtr VirtualRoot = DT.getNode(nullptr);
664
0
      FromTN =
665
0
          (DT.DomTreeNodes[From] = VirtualRoot->addChild(
666
0
               llvm::make_unique<DomTreeNodeBase<NodeT>>(From, VirtualRoot)))
667
0
              .get();
668
0
      DT.Roots.push_back(From);
669
0
    }
670
619k
671
619k
    DT.DFSInfoValid = false;
672
608k
673
608k
    const TreeNodePtr ToTN = DT.getNode(To);
674
608k
    if (!ToTN)
675
114k
      InsertUnreachable(DT, BUI, FromTN, To);
676
493k
    else
677
493k
      InsertReachable(DT, BUI, FromTN, ToTN);
678
608k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertEdge(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::BasicBlock*)
Line
Count
Source
650
162
                         const NodePtr From, const NodePtr To) {
651
162
    assert((From || IsPostDom) &&
652
162
           "From has to be a valid CFG node or a virtual root");
653
162
    assert(To && "Cannot be a nullptr");
654
162
    LLVM_DEBUG(dbgs() << "Inserting edge " << BlockNamePrinter(From) << " -> "
655
162
                      << BlockNamePrinter(To) << "\n");
656
162
    TreeNodePtr FromTN = DT.getNode(From);
657
162
658
162
    if (!FromTN) {
659
3
      // Ignore edges from unreachable nodes for (forward) dominators.
660
3
      if (!IsPostDom) 
return0
;
661
3
662
3
      // The unreachable node becomes a new root -- a tree node for it.
663
3
      TreeNodePtr VirtualRoot = DT.getNode(nullptr);
664
3
      FromTN =
665
3
          (DT.DomTreeNodes[From] = VirtualRoot->addChild(
666
3
               llvm::make_unique<DomTreeNodeBase<NodeT>>(From, VirtualRoot)))
667
3
              .get();
668
3
      DT.Roots.push_back(From);
669
3
    }
670
162
671
162
    DT.DFSInfoValid = false;
672
162
673
162
    const TreeNodePtr ToTN = DT.getNode(To);
674
162
    if (!ToTN)
675
3
      InsertUnreachable(DT, BUI, FromTN, To);
676
159
    else
677
159
      InsertReachable(DT, BUI, FromTN, ToTN);
678
162
  }
679
680
  // Determines if some existing root becomes reverse-reachable after the
681
  // insertion. Rebuilds the whole tree if that situation happens.
682
  static bool UpdateRootsBeforeInsertion(DomTreeT &DT, const BatchUpdatePtr BUI,
683
                                         const TreeNodePtr From,
684
230
                                         const TreeNodePtr To) {
685
230
    assert(IsPostDom && "This function is only for postdominators");
686
230
    // Destination node is not attached to the virtual root, so it cannot be a
687
230
    // root.
688
230
    if (!DT.isVirtualRoot(To->getIDom())) 
return false130
;
689
100
690
100
    auto RIt = llvm::find(DT.Roots, To->getBlock());
691
100
    if (RIt == DT.Roots.end())
692
15
      return false;  // To is not a root, nothing to update.
693
85
694
85
    LLVM_DEBUG(dbgs() << "\t\tAfter the insertion, " << BlockNamePrinter(To)
695
85
                      << " is no longer a root\n\t\tRebuilding the tree!!!\n");
696
85
697
85
    CalculateFromScratch(DT, BUI);
698
85
    return true;
699
85
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::UpdateRootsBeforeInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateRootsBeforeInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateRootsBeforeInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
684
230
                                         const TreeNodePtr To) {
685
230
    assert(IsPostDom && "This function is only for postdominators");
686
230
    // Destination node is not attached to the virtual root, so it cannot be a
687
230
    // root.
688
230
    if (!DT.isVirtualRoot(To->getIDom())) 
return false130
;
689
100
690
100
    auto RIt = llvm::find(DT.Roots, To->getBlock());
691
100
    if (RIt == DT.Roots.end())
692
15
      return false;  // To is not a root, nothing to update.
693
85
694
85
    LLVM_DEBUG(dbgs() << "\t\tAfter the insertion, " << BlockNamePrinter(To)
695
85
                      << " is no longer a root\n\t\tRebuilding the tree!!!\n");
696
85
697
85
    CalculateFromScratch(DT, BUI);
698
85
    return true;
699
85
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::UpdateRootsBeforeInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
700
701
  static bool isPermutation(const SmallVectorImpl<NodePtr> &A,
702
782
                            const SmallVectorImpl<NodePtr> &B) {
703
782
    if (A.size() != B.size())
704
11
      return false;
705
771
    SmallPtrSet<NodePtr, 4> Set(A.begin(), A.end());
706
771
    for (NodePtr N : B)
707
1.50k
      if (Set.count(N) == 0)
708
26
        return false;
709
771
    
return true745
;
710
771
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::isPermutation(llvm::SmallVectorImpl<llvm::MachineBasicBlock*> const&, llvm::SmallVectorImpl<llvm::MachineBasicBlock*> const&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::isPermutation(llvm::SmallVectorImpl<llvm::MachineBasicBlock*> const&, llvm::SmallVectorImpl<llvm::MachineBasicBlock*> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::isPermutation(llvm::SmallVectorImpl<llvm::BasicBlock*> const&, llvm::SmallVectorImpl<llvm::BasicBlock*> const&)
Line
Count
Source
702
415
                            const SmallVectorImpl<NodePtr> &B) {
703
415
    if (A.size() != B.size())
704
11
      return false;
705
404
    SmallPtrSet<NodePtr, 4> Set(A.begin(), A.end());
706
404
    for (NodePtr N : B)
707
1.13k
      if (Set.count(N) == 0)
708
26
        return false;
709
404
    
return true378
;
710
404
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::isPermutation(llvm::SmallVectorImpl<llvm::BasicBlock*> const&, llvm::SmallVectorImpl<llvm::BasicBlock*> const&)
Line
Count
Source
702
367
                            const SmallVectorImpl<NodePtr> &B) {
703
367
    if (A.size() != B.size())
704
0
      return false;
705
367
    SmallPtrSet<NodePtr, 4> Set(A.begin(), A.end());
706
367
    for (NodePtr N : B)
707
367
      if (Set.count(N) == 0)
708
0
        return false;
709
367
    return true;
710
367
  }
711
712
  // Updates the set of roots after insertion or deletion. This ensures that
713
  // roots are the same when after a series of updates and when the tree would
714
  // be built from scratch.
715
330
  static void UpdateRootsAfterUpdate(DomTreeT &DT, const BatchUpdatePtr BUI) {
716
330
    assert(IsPostDom && "This function is only for postdominators");
717
330
718
330
    // The tree has only trivial roots -- nothing to update.
719
763
    if (
std::none_of(DT.Roots.begin(), DT.Roots.end(), [BUI](const NodePtr N) 330
{
720
763
          return HasForwardSuccessors(N, BUI);
721
763
        }))
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)::'lambda'(llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)::'lambda'(llvm::BasicBlock*)::operator()(llvm::BasicBlock*) const
Line
Count
Source
719
763
    if (std::none_of(DT.Roots.begin(), DT.Roots.end(), [BUI](const NodePtr N) {
720
763
          return HasForwardSuccessors(N, BUI);
721
763
        }))
722
263
      return;
723
67
724
67
    // Recalculate the set of roots.
725
67
    RootsT Roots = FindRoots(DT, BUI);
726
67
    if (!isPermutation(DT.Roots, Roots)) {
727
37
      // The roots chosen in the CFG have changed. This is because the
728
37
      // incremental algorithm does not really know or use the set of roots and
729
37
      // can make a different (implicit) decision about which node within an
730
37
      // infinite loop becomes a root.
731
37
732
37
      LLVM_DEBUG(dbgs() << "Roots are different in updated trees\n"
733
37
                        << "The entire tree needs to be rebuilt\n");
734
37
      // It may be possible to update the tree without recalculating it, but
735
37
      // we do not know yet how to do it, and it happens rarely in practise.
736
37
      CalculateFromScratch(DT, BUI);
737
37
    }
738
67
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)
Line
Count
Source
715
330
  static void UpdateRootsAfterUpdate(DomTreeT &DT, const BatchUpdatePtr BUI) {
716
330
    assert(IsPostDom && "This function is only for postdominators");
717
330
718
330
    // The tree has only trivial roots -- nothing to update.
719
330
    if (std::none_of(DT.Roots.begin(), DT.Roots.end(), [BUI](const NodePtr N) {
720
330
          return HasForwardSuccessors(N, BUI);
721
330
        }))
722
263
      return;
723
67
724
67
    // Recalculate the set of roots.
725
67
    RootsT Roots = FindRoots(DT, BUI);
726
67
    if (!isPermutation(DT.Roots, Roots)) {
727
37
      // The roots chosen in the CFG have changed. This is because the
728
37
      // incremental algorithm does not really know or use the set of roots and
729
37
      // can make a different (implicit) decision about which node within an
730
37
      // infinite loop becomes a root.
731
37
732
37
      LLVM_DEBUG(dbgs() << "Roots are different in updated trees\n"
733
37
                        << "The entire tree needs to be rebuilt\n");
734
37
      // It may be possible to update the tree without recalculating it, but
735
37
      // we do not know yet how to do it, and it happens rarely in practise.
736
37
      CalculateFromScratch(DT, BUI);
737
37
    }
738
67
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*)
739
740
  // Handles insertion to a node already in the dominator tree.
741
  static void InsertReachable(DomTreeT &DT, const BatchUpdatePtr BUI,
742
519k
                              const TreeNodePtr From, const TreeNodePtr To) {
743
519k
    LLVM_DEBUG(dbgs() << "\tReachable " << BlockNamePrinter(From->getBlock())
744
519k
                      << " -> " << BlockNamePrinter(To->getBlock()) << "\n");
745
519k
    if (IsPostDom && 
UpdateRootsBeforeInsertion(DT, BUI, From, To)230
)
return85
;
746
519k
    // DT.findNCD expects both pointers to be valid. When From is a virtual
747
519k
    // root, then its CFG block pointer is a nullptr, so we have to 'compute'
748
519k
    // the NCD manually.
749
519k
    const NodePtr NCDBlock =
750
519k
        (From->getBlock() && 
To->getBlock()519k
)
751
519k
            ? 
DT.findNearestCommonDominator(From->getBlock(), To->getBlock())519k
752
519k
            : 
nullptr71
;
753
519k
    assert(NCDBlock || DT.isPostDominator());
754
519k
    const TreeNodePtr NCD = DT.getNode(NCDBlock);
755
519k
    assert(NCD);
756
519k
757
519k
    LLVM_DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n");
758
519k
    const unsigned NCDLevel = NCD->getLevel();
759
519k
760
519k
    // Based on Lemma 2.5 from the second paper, after insertion of (From,To), v
761
519k
    // is affected iff depth(NCD)+1 < depth(v) && a path P from To to v exists
762
519k
    // where every w on P s.t. depth(v) <= depth(w)
763
519k
    //
764
519k
    // This reduces to a widest path problem (maximizing the depth of the
765
519k
    // minimum vertex in the path) which can be solved by a modified version of
766
519k
    // Dijkstra with a bucket queue (named depth-based search in the paper).
767
519k
768
519k
    // To is in the path, so depth(NCD)+1 < depth(v) <= depth(To). Nothing
769
519k
    // affected if this does not hold.
770
519k
    if (NCDLevel + 1 >= To->getLevel())
771
189k
      return;
772
329k
773
329k
    InsertionInfo II;
774
329k
    SmallVector<TreeNodePtr, 8> UnaffectedOnCurrentLevel;
775
329k
    II.Bucket.push(To);
776
329k
    II.Visited.insert(To);
777
329k
778
671k
    while (!II.Bucket.empty()) {
779
341k
      TreeNodePtr TN = II.Bucket.top();
780
341k
      II.Bucket.pop();
781
341k
      II.Affected.push_back(TN);
782
341k
783
341k
      const unsigned CurrentLevel = TN->getLevel();
784
341k
      LLVM_DEBUG(dbgs() << "Mark " << BlockNamePrinter(TN) <<
785
341k
                 "as affected, CurrentLevel " << CurrentLevel << "\n");
786
341k
787
341k
      assert(TN->getBlock() && II.Visited.count(TN) && "Preconditions!");
788
341k
789
9.43M
      while (true) {
790
9.43M
        // Unlike regular Dijkstra, we have an inner loop to expand more
791
9.43M
        // vertices. The first iteration is for the (affected) vertex popped
792
9.43M
        // from II.Bucket and the rest are for vertices in
793
9.43M
        // UnaffectedOnCurrentLevel, which may eventually expand to affected
794
9.43M
        // vertices.
795
9.43M
        //
796
9.43M
        // Invariant: there is an optimal path from `To` to TN with the minimum
797
9.43M
        // depth being CurrentLevel.
798
9.43M
        for (const NodePtr Succ :
799
10.4M
             ChildrenGetter<IsPostDom>::Get(TN->getBlock(), BUI)) {
800
10.4M
          const TreeNodePtr SuccTN = DT.getNode(Succ);
801
10.4M
          assert(SuccTN &&
802
10.4M
                 "Unreachable successor found at reachable insertion");
803
10.4M
          const unsigned SuccLevel = SuccTN->getLevel();
804
10.4M
805
10.4M
          LLVM_DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ)
806
10.4M
                            << ", level = " << SuccLevel << "\n");
807
10.4M
808
10.4M
          // There is an optimal path from `To` to Succ with the minimum depth
809
10.4M
          // being min(CurrentLevel, SuccLevel).
810
10.4M
          //
811
10.4M
          // If depth(NCD)+1 < depth(Succ) is not satisfied, Succ is unaffected
812
10.4M
          // and no affected vertex may be reached by a path passing through it.
813
10.4M
          // Stop here. Also, Succ may be visited by other predecessors but the
814
10.4M
          // first visit has the optimal path. Stop if Succ has been visited.
815
10.4M
          if (SuccLevel <= NCDLevel + 1 || 
!II.Visited.insert(SuccTN).second9.99M
)
816
1.34M
            continue;
817
9.10M
818
9.10M
          if (SuccLevel > CurrentLevel) {
819
9.09M
            // Succ is unaffected but it may (transitively) expand to affected
820
9.09M
            // vertices. Store it in UnaffectedOnCurrentLevel.
821
9.09M
            LLVM_DEBUG(dbgs() << "\t\tMarking visited not affected "
822
9.09M
                              << BlockNamePrinter(Succ) << "\n");
823
9.09M
            UnaffectedOnCurrentLevel.push_back(SuccTN);
824
#ifndef NDEBUG
825
            II.VisitedUnaffected.push_back(SuccTN);
826
#endif
827
11.5k
          } else {
828
11.5k
            // The condition is satisfied (Succ is affected). Add Succ to the
829
11.5k
            // bucket queue.
830
11.5k
            LLVM_DEBUG(dbgs() << "\t\tAdd " << BlockNamePrinter(Succ)
831
11.5k
                              << " to a Bucket\n");
832
11.5k
            II.Bucket.push(SuccTN);
833
11.5k
          }
834
9.10M
        }
835
9.43M
836
9.43M
        if (UnaffectedOnCurrentLevel.empty())
837
341k
          break;
838
9.09M
        TN = UnaffectedOnCurrentLevel.pop_back_val();
839
9.09M
        LLVM_DEBUG(dbgs() << " Next: " << BlockNamePrinter(TN) << "\n");
840
9.09M
      }
841
341k
    }
842
329k
843
329k
    // Finish by updating immediate dominators and levels.
844
329k
    UpdateInsertion(DT, BUI, NCD, II);
845
329k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
742
519k
                              const TreeNodePtr From, const TreeNodePtr To) {
743
519k
    LLVM_DEBUG(dbgs() << "\tReachable " << BlockNamePrinter(From->getBlock())
744
519k
                      << " -> " << BlockNamePrinter(To->getBlock()) << "\n");
745
519k
    if (IsPostDom && 
UpdateRootsBeforeInsertion(DT, BUI, From, To)0
)
return0
;
746
519k
    // DT.findNCD expects both pointers to be valid. When From is a virtual
747
519k
    // root, then its CFG block pointer is a nullptr, so we have to 'compute'
748
519k
    // the NCD manually.
749
519k
    const NodePtr NCDBlock =
750
519k
        (From->getBlock() && To->getBlock())
751
519k
            ? DT.findNearestCommonDominator(From->getBlock(), To->getBlock())
752
519k
            : 
nullptr0
;
753
519k
    assert(NCDBlock || DT.isPostDominator());
754
519k
    const TreeNodePtr NCD = DT.getNode(NCDBlock);
755
519k
    assert(NCD);
756
519k
757
519k
    LLVM_DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n");
758
519k
    const unsigned NCDLevel = NCD->getLevel();
759
519k
760
519k
    // Based on Lemma 2.5 from the second paper, after insertion of (From,To), v
761
519k
    // is affected iff depth(NCD)+1 < depth(v) && a path P from To to v exists
762
519k
    // where every w on P s.t. depth(v) <= depth(w)
763
519k
    //
764
519k
    // This reduces to a widest path problem (maximizing the depth of the
765
519k
    // minimum vertex in the path) which can be solved by a modified version of
766
519k
    // Dijkstra with a bucket queue (named depth-based search in the paper).
767
519k
768
519k
    // To is in the path, so depth(NCD)+1 < depth(v) <= depth(To). Nothing
769
519k
    // affected if this does not hold.
770
519k
    if (NCDLevel + 1 >= To->getLevel())
771
189k
      return;
772
329k
773
329k
    InsertionInfo II;
774
329k
    SmallVector<TreeNodePtr, 8> UnaffectedOnCurrentLevel;
775
329k
    II.Bucket.push(To);
776
329k
    II.Visited.insert(To);
777
329k
778
671k
    while (!II.Bucket.empty()) {
779
341k
      TreeNodePtr TN = II.Bucket.top();
780
341k
      II.Bucket.pop();
781
341k
      II.Affected.push_back(TN);
782
341k
783
341k
      const unsigned CurrentLevel = TN->getLevel();
784
341k
      LLVM_DEBUG(dbgs() << "Mark " << BlockNamePrinter(TN) <<
785
341k
                 "as affected, CurrentLevel " << CurrentLevel << "\n");
786
341k
787
341k
      assert(TN->getBlock() && II.Visited.count(TN) && "Preconditions!");
788
341k
789
9.43M
      while (true) {
790
9.43M
        // Unlike regular Dijkstra, we have an inner loop to expand more
791
9.43M
        // vertices. The first iteration is for the (affected) vertex popped
792
9.43M
        // from II.Bucket and the rest are for vertices in
793
9.43M
        // UnaffectedOnCurrentLevel, which may eventually expand to affected
794
9.43M
        // vertices.
795
9.43M
        //
796
9.43M
        // Invariant: there is an optimal path from `To` to TN with the minimum
797
9.43M
        // depth being CurrentLevel.
798
9.43M
        for (const NodePtr Succ :
799
10.4M
             ChildrenGetter<IsPostDom>::Get(TN->getBlock(), BUI)) {
800
10.4M
          const TreeNodePtr SuccTN = DT.getNode(Succ);
801
10.4M
          assert(SuccTN &&
802
10.4M
                 "Unreachable successor found at reachable insertion");
803
10.4M
          const unsigned SuccLevel = SuccTN->getLevel();
804
10.4M
805
10.4M
          LLVM_DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ)
806
10.4M
                            << ", level = " << SuccLevel << "\n");
807
10.4M
808
10.4M
          // There is an optimal path from `To` to Succ with the minimum depth
809
10.4M
          // being min(CurrentLevel, SuccLevel).
810
10.4M
          //
811
10.4M
          // If depth(NCD)+1 < depth(Succ) is not satisfied, Succ is unaffected
812
10.4M
          // and no affected vertex may be reached by a path passing through it.
813
10.4M
          // Stop here. Also, Succ may be visited by other predecessors but the
814
10.4M
          // first visit has the optimal path. Stop if Succ has been visited.
815
10.4M
          if (SuccLevel <= NCDLevel + 1 || 
!II.Visited.insert(SuccTN).second9.99M
)
816
1.34M
            continue;
817
9.10M
818
9.10M
          if (SuccLevel > CurrentLevel) {
819
9.09M
            // Succ is unaffected but it may (transitively) expand to affected
820
9.09M
            // vertices. Store it in UnaffectedOnCurrentLevel.
821
9.09M
            LLVM_DEBUG(dbgs() << "\t\tMarking visited not affected "
822
9.09M
                              << BlockNamePrinter(Succ) << "\n");
823
9.09M
            UnaffectedOnCurrentLevel.push_back(SuccTN);
824
#ifndef NDEBUG
825
            II.VisitedUnaffected.push_back(SuccTN);
826
#endif
827
11.5k
          } else {
828
11.5k
            // The condition is satisfied (Succ is affected). Add Succ to the
829
11.5k
            // bucket queue.
830
11.5k
            LLVM_DEBUG(dbgs() << "\t\tAdd " << BlockNamePrinter(Succ)
831
11.5k
                              << " to a Bucket\n");
832
11.5k
            II.Bucket.push(SuccTN);
833
11.5k
          }
834
9.10M
        }
835
9.43M
836
9.43M
        if (UnaffectedOnCurrentLevel.empty())
837
341k
          break;
838
9.09M
        TN = UnaffectedOnCurrentLevel.pop_back_val();
839
9.09M
        LLVM_DEBUG(dbgs() << " Next: " << BlockNamePrinter(TN) << "\n");
840
9.09M
      }
841
341k
    }
842
329k
843
329k
    // Finish by updating immediate dominators and levels.
844
329k
    UpdateInsertion(DT, BUI, NCD, II);
845
329k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
742
230
                              const TreeNodePtr From, const TreeNodePtr To) {
743
230
    LLVM_DEBUG(dbgs() << "\tReachable " << BlockNamePrinter(From->getBlock())
744
230
                      << " -> " << BlockNamePrinter(To->getBlock()) << "\n");
745
230
    if (IsPostDom && UpdateRootsBeforeInsertion(DT, BUI, From, To)) 
return85
;
746
145
    // DT.findNCD expects both pointers to be valid. When From is a virtual
747
145
    // root, then its CFG block pointer is a nullptr, so we have to 'compute'
748
145
    // the NCD manually.
749
145
    const NodePtr NCDBlock =
750
145
        (From->getBlock() && 
To->getBlock()74
)
751
145
            ? 
DT.findNearestCommonDominator(From->getBlock(), To->getBlock())74
752
145
            : 
nullptr71
;
753
145
    assert(NCDBlock || DT.isPostDominator());
754
145
    const TreeNodePtr NCD = DT.getNode(NCDBlock);
755
145
    assert(NCD);
756
145
757
145
    LLVM_DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n");
758
145
    const unsigned NCDLevel = NCD->getLevel();
759
145
760
145
    // Based on Lemma 2.5 from the second paper, after insertion of (From,To), v
761
145
    // is affected iff depth(NCD)+1 < depth(v) && a path P from To to v exists
762
145
    // where every w on P s.t. depth(v) <= depth(w)
763
145
    //
764
145
    // This reduces to a widest path problem (maximizing the depth of the
765
145
    // minimum vertex in the path) which can be solved by a modified version of
766
145
    // Dijkstra with a bucket queue (named depth-based search in the paper).
767
145
768
145
    // To is in the path, so depth(NCD)+1 < depth(v) <= depth(To). Nothing
769
145
    // affected if this does not hold.
770
145
    if (NCDLevel + 1 >= To->getLevel())
771
38
      return;
772
107
773
107
    InsertionInfo II;
774
107
    SmallVector<TreeNodePtr, 8> UnaffectedOnCurrentLevel;
775
107
    II.Bucket.push(To);
776
107
    II.Visited.insert(To);
777
107
778
228
    while (!II.Bucket.empty()) {
779
121
      TreeNodePtr TN = II.Bucket.top();
780
121
      II.Bucket.pop();
781
121
      II.Affected.push_back(TN);
782
121
783
121
      const unsigned CurrentLevel = TN->getLevel();
784
121
      LLVM_DEBUG(dbgs() << "Mark " << BlockNamePrinter(TN) <<
785
121
                 "as affected, CurrentLevel " << CurrentLevel << "\n");
786
121
787
121
      assert(TN->getBlock() && II.Visited.count(TN) && "Preconditions!");
788
121
789
263
      while (true) {
790
263
        // Unlike regular Dijkstra, we have an inner loop to expand more
791
263
        // vertices. The first iteration is for the (affected) vertex popped
792
263
        // from II.Bucket and the rest are for vertices in
793
263
        // UnaffectedOnCurrentLevel, which may eventually expand to affected
794
263
        // vertices.
795
263
        //
796
263
        // Invariant: there is an optimal path from `To` to TN with the minimum
797
263
        // depth being CurrentLevel.
798
263
        for (const NodePtr Succ :
799
263
             ChildrenGetter<IsPostDom>::Get(TN->getBlock(), BUI)) {
800
227
          const TreeNodePtr SuccTN = DT.getNode(Succ);
801
227
          assert(SuccTN &&
802
227
                 "Unreachable successor found at reachable insertion");
803
227
          const unsigned SuccLevel = SuccTN->getLevel();
804
227
805
227
          LLVM_DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ)
806
227
                            << ", level = " << SuccLevel << "\n");
807
227
808
227
          // There is an optimal path from `To` to Succ with the minimum depth
809
227
          // being min(CurrentLevel, SuccLevel).
810
227
          //
811
227
          // If depth(NCD)+1 < depth(Succ) is not satisfied, Succ is unaffected
812
227
          // and no affected vertex may be reached by a path passing through it.
813
227
          // Stop here. Also, Succ may be visited by other predecessors but the
814
227
          // first visit has the optimal path. Stop if Succ has been visited.
815
227
          if (SuccLevel <= NCDLevel + 1 || 
!II.Visited.insert(SuccTN).second184
)
816
71
            continue;
817
156
818
156
          if (SuccLevel > CurrentLevel) {
819
142
            // Succ is unaffected but it may (transitively) expand to affected
820
142
            // vertices. Store it in UnaffectedOnCurrentLevel.
821
142
            LLVM_DEBUG(dbgs() << "\t\tMarking visited not affected "
822
142
                              << BlockNamePrinter(Succ) << "\n");
823
142
            UnaffectedOnCurrentLevel.push_back(SuccTN);
824
#ifndef NDEBUG
825
            II.VisitedUnaffected.push_back(SuccTN);
826
#endif
827
14
          } else {
828
14
            // The condition is satisfied (Succ is affected). Add Succ to the
829
14
            // bucket queue.
830
14
            LLVM_DEBUG(dbgs() << "\t\tAdd " << BlockNamePrinter(Succ)
831
14
                              << " to a Bucket\n");
832
14
            II.Bucket.push(SuccTN);
833
14
          }
834
156
        }
835
263
836
263
        if (UnaffectedOnCurrentLevel.empty())
837
121
          break;
838
142
        TN = UnaffectedOnCurrentLevel.pop_back_val();
839
142
        LLVM_DEBUG(dbgs() << " Next: " << BlockNamePrinter(TN) << "\n");
840
142
      }
841
121
    }
842
107
843
107
    // Finish by updating immediate dominators and levels.
844
107
    UpdateInsertion(DT, BUI, NCD, II);
845
107
  }
846
847
  // Updates immediate dominators and levels after insertion.
848
  static void UpdateInsertion(DomTreeT &DT, const BatchUpdatePtr BUI,
849
329k
                              const TreeNodePtr NCD, InsertionInfo &II) {
850
329k
    LLVM_DEBUG(dbgs() << "Updating NCD = " << BlockNamePrinter(NCD) << "\n");
851
329k
852
341k
    for (const TreeNodePtr TN : II.Affected) {
853
341k
      LLVM_DEBUG(dbgs() << "\tIDom(" << BlockNamePrinter(TN)
854
341k
                        << ") = " << BlockNamePrinter(NCD) << "\n");
855
341k
      TN->setIDom(NCD);
856
341k
    }
857
329k
858
#ifndef NDEBUG
859
    for (const TreeNodePtr TN : II.VisitedUnaffected)
860
      assert(TN->getLevel() == TN->getIDom()->getLevel() + 1 &&
861
             "TN should have been updated by an affected ancestor");
862
#endif
863
864
329k
    if (IsPostDom) 
UpdateRootsAfterUpdate(DT, BUI)107
;
865
329k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::UpdateInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertionInfo&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertionInfo&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::UpdateInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertionInfo&)
Line
Count
Source
849
329k
                              const TreeNodePtr NCD, InsertionInfo &II) {
850
329k
    LLVM_DEBUG(dbgs() << "Updating NCD = " << BlockNamePrinter(NCD) << "\n");
851
329k
852
341k
    for (const TreeNodePtr TN : II.Affected) {
853
341k
      LLVM_DEBUG(dbgs() << "\tIDom(" << BlockNamePrinter(TN)
854
341k
                        << ") = " << BlockNamePrinter(NCD) << "\n");
855
341k
      TN->setIDom(NCD);
856
341k
    }
857
329k
858
#ifndef NDEBUG
859
    for (const TreeNodePtr TN : II.VisitedUnaffected)
860
      assert(TN->getLevel() == TN->getIDom()->getLevel() + 1 &&
861
             "TN should have been updated by an affected ancestor");
862
#endif
863
864
329k
    if (IsPostDom) 
UpdateRootsAfterUpdate(DT, BUI)0
;
865
329k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertionInfo&)
Line
Count
Source
849
107
                              const TreeNodePtr NCD, InsertionInfo &II) {
850
107
    LLVM_DEBUG(dbgs() << "Updating NCD = " << BlockNamePrinter(NCD) << "\n");
851
107
852
121
    for (const TreeNodePtr TN : II.Affected) {
853
121
      LLVM_DEBUG(dbgs() << "\tIDom(" << BlockNamePrinter(TN)
854
121
                        << ") = " << BlockNamePrinter(NCD) << "\n");
855
121
      TN->setIDom(NCD);
856
121
    }
857
107
858
#ifndef NDEBUG
859
    for (const TreeNodePtr TN : II.VisitedUnaffected)
860
      assert(TN->getLevel() == TN->getIDom()->getLevel() + 1 &&
861
             "TN should have been updated by an affected ancestor");
862
#endif
863
864
107
    if (IsPostDom) UpdateRootsAfterUpdate(DT, BUI);
865
107
  }
866
867
  // Handles insertion to previously unreachable nodes.
868
  static void InsertUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI,
869
114k
                                const TreeNodePtr From, const NodePtr To) {
870
114k
    LLVM_DEBUG(dbgs() << "Inserting " << BlockNamePrinter(From)
871
114k
                      << " -> (unreachable) " << BlockNamePrinter(To) << "\n");
872
114k
873
114k
    // Collect discovered edges to already reachable nodes.
874
114k
    SmallVector<std::pair<NodePtr, TreeNodePtr>, 8> DiscoveredEdgesToReachable;
875
114k
    // Discover and connect nodes that became reachable with the insertion.
876
114k
    ComputeUnreachableDominators(DT, BUI, To, From, DiscoveredEdgesToReachable);
877
114k
878
114k
    LLVM_DEBUG(dbgs() << "Inserted " << BlockNamePrinter(From)
879
114k
                      << " -> (prev unreachable) " << BlockNamePrinter(To)
880
114k
                      << "\n");
881
114k
882
114k
    // Used the discovered edges and inset discovered connecting (incoming)
883
114k
    // edges.
884
114k
    for (const auto &Edge : DiscoveredEdgesToReachable) {
885
25.4k
      LLVM_DEBUG(dbgs() << "\tInserting discovered connecting edge "
886
25.4k
                        << BlockNamePrinter(Edge.first) << " -> "
887
25.4k
                        << BlockNamePrinter(Edge.second) << "\n");
888
25.4k
      InsertReachable(DT, BUI, DT.getNode(Edge.first), Edge.second);
889
25.4k
    }
890
114k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::MachineBasicBlock*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::MachineBasicBlock*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::BasicBlock*)
Line
Count
Source
869
114k
                                const TreeNodePtr From, const NodePtr To) {
870
114k
    LLVM_DEBUG(dbgs() << "Inserting " << BlockNamePrinter(From)
871
114k
                      << " -> (unreachable) " << BlockNamePrinter(To) << "\n");
872
114k
873
114k
    // Collect discovered edges to already reachable nodes.
874
114k
    SmallVector<std::pair<NodePtr, TreeNodePtr>, 8> DiscoveredEdgesToReachable;
875
114k
    // Discover and connect nodes that became reachable with the insertion.
876
114k
    ComputeUnreachableDominators(DT, BUI, To, From, DiscoveredEdgesToReachable);
877
114k
878
114k
    LLVM_DEBUG(dbgs() << "Inserted " << BlockNamePrinter(From)
879
114k
                      << " -> (prev unreachable) " << BlockNamePrinter(To)
880
114k
                      << "\n");
881
114k
882
114k
    // Used the discovered edges and inset discovered connecting (incoming)
883
114k
    // edges.
884
114k
    for (const auto &Edge : DiscoveredEdgesToReachable) {
885
25.4k
      LLVM_DEBUG(dbgs() << "\tInserting discovered connecting edge "
886
25.4k
                        << BlockNamePrinter(Edge.first) << " -> "
887
25.4k
                        << BlockNamePrinter(Edge.second) << "\n");
888
25.4k
      InsertReachable(DT, BUI, DT.getNode(Edge.first), Edge.second);
889
25.4k
    }
890
114k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::BasicBlock*)
Line
Count
Source
869
3
                                const TreeNodePtr From, const NodePtr To) {
870
3
    LLVM_DEBUG(dbgs() << "Inserting " << BlockNamePrinter(From)
871
3
                      << " -> (unreachable) " << BlockNamePrinter(To) << "\n");
872
3
873
3
    // Collect discovered edges to already reachable nodes.
874
3
    SmallVector<std::pair<NodePtr, TreeNodePtr>, 8> DiscoveredEdgesToReachable;
875
3
    // Discover and connect nodes that became reachable with the insertion.
876
3
    ComputeUnreachableDominators(DT, BUI, To, From, DiscoveredEdgesToReachable);
877
3
878
3
    LLVM_DEBUG(dbgs() << "Inserted " << BlockNamePrinter(From)
879
3
                      << " -> (prev unreachable) " << BlockNamePrinter(To)
880
3
                      << "\n");
881
3
882
3
    // Used the discovered edges and inset discovered connecting (incoming)
883
3
    // edges.
884
3
    for (const auto &Edge : DiscoveredEdgesToReachable) {
885
0
      LLVM_DEBUG(dbgs() << "\tInserting discovered connecting edge "
886
0
                        << BlockNamePrinter(Edge.first) << " -> "
887
0
                        << BlockNamePrinter(Edge.second) << "\n");
888
0
      InsertReachable(DT, BUI, DT.getNode(Edge.first), Edge.second);
889
0
    }
890
3
  }
891
892
  // Connects nodes that become reachable with an insertion.
893
  static void ComputeUnreachableDominators(
894
      DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr Root,
895
      const TreeNodePtr Incoming,
896
      SmallVectorImpl<std::pair<NodePtr, TreeNodePtr>>
897
114k
          &DiscoveredConnectingEdges) {
898
114k
    assert(!DT.getNode(Root) && "Root must not be reachable");
899
114k
900
114k
    // Visit only previously unreachable nodes.
901
114k
    auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](NodePtr From,
902
150k
                                                                  NodePtr To) {
903
150k
      const TreeNodePtr ToTN = DT.getNode(To);
904
150k
      if (!ToTN) 
return true125k
;
905
25.4k
906
25.4k
      DiscoveredConnectingEdges.push_back({From, ToTN});
907
25.4k
      return false;
908
25.4k
    };
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
902
150k
                                                                  NodePtr To) {
903
150k
      const TreeNodePtr ToTN = DT.getNode(To);
904
150k
      if (!ToTN) 
return true125k
;
905
25.4k
906
25.4k
      DiscoveredConnectingEdges.push_back({From, ToTN});
907
25.4k
      return false;
908
25.4k
    };
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
909
114k
910
114k
    SemiNCAInfo SNCA(BUI);
911
114k
    SNCA.runDFS(Root, 0, UnreachableDescender, 0);
912
114k
    SNCA.runSemiNCA(DT);
913
114k
    SNCA.attachNewSubtree(DT, Incoming);
914
114k
915
114k
    LLVM_DEBUG(dbgs() << "After adding unreachable nodes\n");
916
114k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)
Line
Count
Source
897
114k
          &DiscoveredConnectingEdges) {
898
114k
    assert(!DT.getNode(Root) && "Root must not be reachable");
899
114k
900
114k
    // Visit only previously unreachable nodes.
901
114k
    auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](NodePtr From,
902
114k
                                                                  NodePtr To) {
903
114k
      const TreeNodePtr ToTN = DT.getNode(To);
904
114k
      if (!ToTN) return true;
905
114k
906
114k
      DiscoveredConnectingEdges.push_back({From, ToTN});
907
114k
      return false;
908
114k
    };
909
114k
910
114k
    SemiNCAInfo SNCA(BUI);
911
114k
    SNCA.runDFS(Root, 0, UnreachableDescender, 0);
912
114k
    SNCA.runSemiNCA(DT);
913
114k
    SNCA.attachNewSubtree(DT, Incoming);
914
114k
915
114k
    LLVM_DEBUG(dbgs() << "After adding unreachable nodes\n");
916
114k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)
Line
Count
Source
897
3
          &DiscoveredConnectingEdges) {
898
3
    assert(!DT.getNode(Root) && "Root must not be reachable");
899
3
900
3
    // Visit only previously unreachable nodes.
901
3
    auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](NodePtr From,
902
3
                                                                  NodePtr To) {
903
3
      const TreeNodePtr ToTN = DT.getNode(To);
904
3
      if (!ToTN) return true;
905
3
906
3
      DiscoveredConnectingEdges.push_back({From, ToTN});
907
3
      return false;
908
3
    };
909
3
910
3
    SemiNCAInfo SNCA(BUI);
911
3
    SNCA.runDFS(Root, 0, UnreachableDescender, 0);
912
3
    SNCA.runSemiNCA(DT);
913
3
    SNCA.attachNewSubtree(DT, Incoming);
914
3
915
3
    LLVM_DEBUG(dbgs() << "After adding unreachable nodes\n");
916
3
  }
917
918
  static void DeleteEdge(DomTreeT &DT, const BatchUpdatePtr BUI,
919
841k
                         const NodePtr From, const NodePtr To) {
920
841k
    assert(From && To && "Cannot disconnect nullptrs");
921
841k
    LLVM_DEBUG(dbgs() << "Deleting edge " << BlockNamePrinter(From) << " -> "
922
841k
                      << BlockNamePrinter(To) << "\n");
923
841k
924
#ifndef NDEBUG
925
    // Ensure that the edge was in fact deleted from the CFG before informing
926
    // the DomTree about it.
927
    // The check is O(N), so run it only in debug configuration.
928
    auto IsSuccessor = [BUI](const NodePtr SuccCandidate, const NodePtr Of) {
929
      auto Successors = ChildrenGetter<IsPostDom>::Get(Of, BUI);
930
      return llvm::find(Successors, SuccCandidate) != Successors.end();
931
    };
932
    (void)IsSuccessor;
933
    assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!");
934
#endif
935
936
841k
    const TreeNodePtr FromTN = DT.getNode(From);
937
841k
    // Deletion in an unreachable subtree -- nothing to do.
938
841k
    if (!FromTN) 
return8.22k
;
939
833k
940
833k
    const TreeNodePtr ToTN = DT.getNode(To);
941
833k
    if (!ToTN) {
942
0
      LLVM_DEBUG(
943
0
          dbgs() << "\tTo (" << BlockNamePrinter(To)
944
0
                 << ") already unreachable -- there is no edge to delete\n");
945
0
      return;
946
0
    }
947
833k
948
833k
    const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To);
949
833k
    const TreeNodePtr NCD = DT.getNode(NCDBlock);
950
833k
951
833k
    // If To dominates From -- nothing to do.
952
833k
    if (ToTN != NCD) {
953
790k
      DT.DFSInfoValid = false;
954
790k
955
790k
      const TreeNodePtr ToIDom = ToTN->getIDom();
956
790k
      LLVM_DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom "
957
790k
                        << BlockNamePrinter(ToIDom) << "\n");
958
790k
959
790k
      // To remains reachable after deletion.
960
790k
      // (Based on the caption under Figure 4. from the second paper.)
961
790k
      if (FromTN != ToIDom || 
HasProperSupport(DT, BUI, ToTN)414k
)
962
487k
        DeleteReachable(DT, BUI, FromTN, ToTN);
963
303k
      else
964
303k
        DeleteUnreachable(DT, BUI, ToTN);
965
790k
    }
966
833k
967
833k
    if (IsPostDom) 
UpdateRootsAfterUpdate(DT, BUI)223
;
968
833k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteEdge(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteEdge(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteEdge(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::BasicBlock*)
Line
Count
Source
919
841k
                         const NodePtr From, const NodePtr To) {
920
841k
    assert(From && To && "Cannot disconnect nullptrs");
921
841k
    LLVM_DEBUG(dbgs() << "Deleting edge " << BlockNamePrinter(From) << " -> "
922
841k
                      << BlockNamePrinter(To) << "\n");
923
841k
924
#ifndef NDEBUG
925
    // Ensure that the edge was in fact deleted from the CFG before informing
926
    // the DomTree about it.
927
    // The check is O(N), so run it only in debug configuration.
928
    auto IsSuccessor = [BUI](const NodePtr SuccCandidate, const NodePtr Of) {
929
      auto Successors = ChildrenGetter<IsPostDom>::Get(Of, BUI);
930
      return llvm::find(Successors, SuccCandidate) != Successors.end();
931
    };
932
    (void)IsSuccessor;
933
    assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!");
934
#endif
935
936
841k
    const TreeNodePtr FromTN = DT.getNode(From);
937
841k
    // Deletion in an unreachable subtree -- nothing to do.
938
841k
    if (!FromTN) 
return8.22k
;
939
832k
940
832k
    const TreeNodePtr ToTN = DT.getNode(To);
941
832k
    if (!ToTN) {
942
0
      LLVM_DEBUG(
943
0
          dbgs() << "\tTo (" << BlockNamePrinter(To)
944
0
                 << ") already unreachable -- there is no edge to delete\n");
945
0
      return;
946
0
    }
947
832k
948
832k
    const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To);
949
832k
    const TreeNodePtr NCD = DT.getNode(NCDBlock);
950
832k
951
832k
    // If To dominates From -- nothing to do.
952
832k
    if (ToTN != NCD) {
953
790k
      DT.DFSInfoValid = false;
954
790k
955
790k
      const TreeNodePtr ToIDom = ToTN->getIDom();
956
790k
      LLVM_DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom "
957
790k
                        << BlockNamePrinter(ToIDom) << "\n");
958
790k
959
790k
      // To remains reachable after deletion.
960
790k
      // (Based on the caption under Figure 4. from the second paper.)
961
790k
      if (FromTN != ToIDom || 
HasProperSupport(DT, BUI, ToTN)414k
)
962
487k
        DeleteReachable(DT, BUI, FromTN, ToTN);
963
303k
      else
964
303k
        DeleteUnreachable(DT, BUI, ToTN);
965
790k
    }
966
832k
967
832k
    if (IsPostDom) 
UpdateRootsAfterUpdate(DT, BUI)0
;
968
832k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteEdge(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::BasicBlock*)
Line
Count
Source
919
223
                         const NodePtr From, const NodePtr To) {
920
223
    assert(From && To && "Cannot disconnect nullptrs");
921
223
    LLVM_DEBUG(dbgs() << "Deleting edge " << BlockNamePrinter(From) << " -> "
922
223
                      << BlockNamePrinter(To) << "\n");
923
223
924
#ifndef NDEBUG
925
    // Ensure that the edge was in fact deleted from the CFG before informing
926
    // the DomTree about it.
927
    // The check is O(N), so run it only in debug configuration.
928
    auto IsSuccessor = [BUI](const NodePtr SuccCandidate, const NodePtr Of) {
929
      auto Successors = ChildrenGetter<IsPostDom>::Get(Of, BUI);
930
      return llvm::find(Successors, SuccCandidate) != Successors.end();
931
    };
932
    (void)IsSuccessor;
933
    assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!");
934
#endif
935
936
223
    const TreeNodePtr FromTN = DT.getNode(From);
937
223
    // Deletion in an unreachable subtree -- nothing to do.
938
223
    if (!FromTN) 
return0
;
939
223
940
223
    const TreeNodePtr ToTN = DT.getNode(To);
941
223
    if (!ToTN) {
942
0
      LLVM_DEBUG(
943
0
          dbgs() << "\tTo (" << BlockNamePrinter(To)
944
0
                 << ") already unreachable -- there is no edge to delete\n");
945
0
      return;
946
0
    }
947
223
948
223
    const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To);
949
223
    const TreeNodePtr NCD = DT.getNode(NCDBlock);
950
223
951
223
    // If To dominates From -- nothing to do.
952
223
    if (ToTN != NCD) {
953
215
      DT.DFSInfoValid = false;
954
215
955
215
      const TreeNodePtr ToIDom = ToTN->getIDom();
956
215
      LLVM_DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom "
957
215
                        << BlockNamePrinter(ToIDom) << "\n");
958
215
959
215
      // To remains reachable after deletion.
960
215
      // (Based on the caption under Figure 4. from the second paper.)
961
215
      if (FromTN != ToIDom || 
HasProperSupport(DT, BUI, ToTN)74
)
962
144
        DeleteReachable(DT, BUI, FromTN, ToTN);
963
71
      else
964
71
        DeleteUnreachable(DT, BUI, ToTN);
965
215
    }
966
223
967
223
    if (IsPostDom) UpdateRootsAfterUpdate(DT, BUI);
968
223
  }
969
970
  // Handles deletions that leave destination nodes reachable.
971
  static void DeleteReachable(DomTreeT &DT, const BatchUpdatePtr BUI,
972
                              const TreeNodePtr FromTN,
973
487k
                              const TreeNodePtr ToTN) {
974
487k
    LLVM_DEBUG(dbgs() << "Deleting reachable " << BlockNamePrinter(FromTN)
975
487k
                      << " -> " << BlockNamePrinter(ToTN) << "\n");
976
487k
    LLVM_DEBUG(dbgs() << "\tRebuilding subtree\n");
977
487k
978
487k
    // Find the top of the subtree that needs to be rebuilt.
979
487k
    // (Based on the lemma 2.6 from the second paper.)
980
487k
    const NodePtr ToIDom =
981
487k
        DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock());
982
487k
    assert(ToIDom || DT.isPostDominator());
983
487k
    const TreeNodePtr ToIDomTN = DT.getNode(ToIDom);
984
487k
    assert(ToIDomTN);
985
487k
    const TreeNodePtr PrevIDomSubTree = ToIDomTN->getIDom();
986
487k
    // Top of the subtree to rebuild is the root node. Rebuild the tree from
987
487k
    // scratch.
988
487k
    if (!PrevIDomSubTree) {
989
87.7k
      LLVM_DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
990
87.7k
      CalculateFromScratch(DT, BUI);
991
87.7k
      return;
992
87.7k
    }
993
399k
994
399k
    // Only visit nodes in the subtree starting at To.
995
399k
    const unsigned Level = ToIDomTN->getLevel();
996
14.1M
    auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) {
997
14.1M
      return DT.getNode(To)->getLevel() > Level;
998
14.1M
    };
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
996
14.1M
    auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) {
997
14.1M
      return DT.getNode(To)->getLevel() > Level;
998
14.1M
    };
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
996
361
    auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) {
997
361
      return DT.getNode(To)->getLevel() > Level;
998
361
    };
999
399k
1000
399k
    LLVM_DEBUG(dbgs() << "\tTop of subtree: " << BlockNamePrinter(ToIDomTN)
1001
399k
                      << "\n");
1002
399k
1003
399k
    SemiNCAInfo SNCA(BUI);
1004
399k
    SNCA.runDFS(ToIDom, 0, DescendBelow, 0);
1005
399k
    LLVM_DEBUG(dbgs() << "\tRunning Semi-NCA\n");
1006
399k
    SNCA.runSemiNCA(DT, Level);
1007
399k
    SNCA.reattachExistingSubtree(DT, PrevIDomSubTree);
1008
399k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
973
487k
                              const TreeNodePtr ToTN) {
974
487k
    LLVM_DEBUG(dbgs() << "Deleting reachable " << BlockNamePrinter(FromTN)
975
487k
                      << " -> " << BlockNamePrinter(ToTN) << "\n");
976
487k
    LLVM_DEBUG(dbgs() << "\tRebuilding subtree\n");
977
487k
978
487k
    // Find the top of the subtree that needs to be rebuilt.
979
487k
    // (Based on the lemma 2.6 from the second paper.)
980
487k
    const NodePtr ToIDom =
981
487k
        DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock());
982
487k
    assert(ToIDom || DT.isPostDominator());
983
487k
    const TreeNodePtr ToIDomTN = DT.getNode(ToIDom);
984
487k
    assert(ToIDomTN);
985
487k
    const TreeNodePtr PrevIDomSubTree = ToIDomTN->getIDom();
986
487k
    // Top of the subtree to rebuild is the root node. Rebuild the tree from
987
487k
    // scratch.
988
487k
    if (!PrevIDomSubTree) {
989
87.7k
      LLVM_DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
990
87.7k
      CalculateFromScratch(DT, BUI);
991
87.7k
      return;
992
87.7k
    }
993
399k
994
399k
    // Only visit nodes in the subtree starting at To.
995
399k
    const unsigned Level = ToIDomTN->getLevel();
996
399k
    auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) {
997
399k
      return DT.getNode(To)->getLevel() > Level;
998
399k
    };
999
399k
1000
399k
    LLVM_DEBUG(dbgs() << "\tTop of subtree: " << BlockNamePrinter(ToIDomTN)
1001
399k
                      << "\n");
1002
399k
1003
399k
    SemiNCAInfo SNCA(BUI);
1004
399k
    SNCA.runDFS(ToIDom, 0, DescendBelow, 0);
1005
399k
    LLVM_DEBUG(dbgs() << "\tRunning Semi-NCA\n");
1006
399k
    SNCA.runSemiNCA(DT, Level);
1007
399k
    SNCA.reattachExistingSubtree(DT, PrevIDomSubTree);
1008
399k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
973
144
                              const TreeNodePtr ToTN) {
974
144
    LLVM_DEBUG(dbgs() << "Deleting reachable " << BlockNamePrinter(FromTN)
975
144
                      << " -> " << BlockNamePrinter(ToTN) << "\n");
976
144
    LLVM_DEBUG(dbgs() << "\tRebuilding subtree\n");
977
144
978
144
    // Find the top of the subtree that needs to be rebuilt.
979
144
    // (Based on the lemma 2.6 from the second paper.)
980
144
    const NodePtr ToIDom =
981
144
        DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock());
982
144
    assert(ToIDom || DT.isPostDominator());
983
144
    const TreeNodePtr ToIDomTN = DT.getNode(ToIDom);
984
144
    assert(ToIDomTN);
985
144
    const TreeNodePtr PrevIDomSubTree = ToIDomTN->getIDom();
986
144
    // Top of the subtree to rebuild is the root node. Rebuild the tree from
987
144
    // scratch.
988
144
    if (!PrevIDomSubTree) {
989
51
      LLVM_DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
990
51
      CalculateFromScratch(DT, BUI);
991
51
      return;
992
51
    }
993
93
994
93
    // Only visit nodes in the subtree starting at To.
995
93
    const unsigned Level = ToIDomTN->getLevel();
996
93
    auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) {
997
93
      return DT.getNode(To)->getLevel() > Level;
998
93
    };
999
93
1000
93
    LLVM_DEBUG(dbgs() << "\tTop of subtree: " << BlockNamePrinter(ToIDomTN)
1001
93
                      << "\n");
1002
93
1003
93
    SemiNCAInfo SNCA(BUI);
1004
93
    SNCA.runDFS(ToIDom, 0, DescendBelow, 0);
1005
93
    LLVM_DEBUG(dbgs() << "\tRunning Semi-NCA\n");
1006
93
    SNCA.runSemiNCA(DT, Level);
1007
93
    SNCA.reattachExistingSubtree(DT, PrevIDomSubTree);
1008
93
  }
1009
1010
  // Checks if a node has proper support, as defined on the page 3 and later
1011
  // explained on the page 7 of the second paper.
1012
  static bool HasProperSupport(DomTreeT &DT, const BatchUpdatePtr BUI,
1013
414k
                               const TreeNodePtr TN) {
1014
414k
    LLVM_DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN)
1015
414k
                      << "\n");
1016
414k
    for (const NodePtr Pred :
1017
414k
         ChildrenGetter<!IsPostDom>::Get(TN->getBlock(), BUI)) {
1018
127k
      LLVM_DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n");
1019
127k
      if (!DT.getNode(Pred)) 
continue1.64k
;
1020
125k
1021
125k
      const NodePtr Support =
1022
125k
          DT.findNearestCommonDominator(TN->getBlock(), Pred);
1023
125k
      LLVM_DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n");
1024
125k
      if (Support != TN->getBlock()) {
1025
110k
        LLVM_DEBUG(dbgs() << "\t" << BlockNamePrinter(TN)
1026
110k
                          << " is reachable from support "
1027
110k
                          << BlockNamePrinter(Support) << "\n");
1028
110k
        return true;
1029
110k
      }
1030
125k
    }
1031
414k
1032
414k
    
return false303k
;
1033
414k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::HasProperSupport(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::HasProperSupport(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::HasProperSupport(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
1013
414k
                               const TreeNodePtr TN) {
1014
414k
    LLVM_DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN)
1015
414k
                      << "\n");
1016
414k
    for (const NodePtr Pred :
1017
414k
         ChildrenGetter<!IsPostDom>::Get(TN->getBlock(), BUI)) {
1018
127k
      LLVM_DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n");
1019
127k
      if (!DT.getNode(Pred)) 
continue1.64k
;
1020
125k
1021
125k
      const NodePtr Support =
1022
125k
          DT.findNearestCommonDominator(TN->getBlock(), Pred);
1023
125k
      LLVM_DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n");
1024
125k
      if (Support != TN->getBlock()) {
1025
110k
        LLVM_DEBUG(dbgs() << "\t" << BlockNamePrinter(TN)
1026
110k
                          << " is reachable from support "
1027
110k
                          << BlockNamePrinter(Support) << "\n");
1028
110k
        return true;
1029
110k
      }
1030
125k
    }
1031
414k
1032
414k
    
return false303k
;
1033
414k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::HasProperSupport(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
1013
74
                               const TreeNodePtr TN) {
1014
74
    LLVM_DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN)
1015
74
                      << "\n");
1016
74
    for (const NodePtr Pred :
1017
74
         ChildrenGetter<!IsPostDom>::Get(TN->getBlock(), BUI)) {
1018
17
      LLVM_DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n");
1019
17
      if (!DT.getNode(Pred)) 
continue0
;
1020
17
1021
17
      const NodePtr Support =
1022
17
          DT.findNearestCommonDominator(TN->getBlock(), Pred);
1023
17
      LLVM_DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n");
1024
17
      if (Support != TN->getBlock()) {
1025
3
        LLVM_DEBUG(dbgs() << "\t" << BlockNamePrinter(TN)
1026
3
                          << " is reachable from support "
1027
3
                          << BlockNamePrinter(Support) << "\n");
1028
3
        return true;
1029
3
      }
1030
17
    }
1031
74
1032
74
    
return false71
;
1033
74
  }
1034
1035
  // Handle deletions that make destination node unreachable.
1036
  // (Based on the lemma 2.7 from the second paper.)
1037
  static void DeleteUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI,
1038
303k
                                const TreeNodePtr ToTN) {
1039
303k
    LLVM_DEBUG(dbgs() << "Deleting unreachable subtree "
1040
303k
                      << BlockNamePrinter(ToTN) << "\n");
1041
303k
    assert(ToTN);
1042
303k
    assert(ToTN->getBlock());
1043
303k
1044
303k
    if (IsPostDom) {
1045
71
      // Deletion makes a region reverse-unreachable and creates a new root.
1046
71
      // Simulate that by inserting an edge from the virtual root to ToTN and
1047
71
      // adding it as a new root.
1048
71
      LLVM_DEBUG(dbgs() << "\tDeletion made a region reverse-unreachable\n");
1049
71
      LLVM_DEBUG(dbgs() << "\tAdding new root " << BlockNamePrinter(ToTN)
1050
71
                        << "\n");
1051
71
      DT.Roots.push_back(ToTN->getBlock());
1052
71
      InsertReachable(DT, BUI, DT.getNode(nullptr), ToTN);
1053
71
      return;
1054
71
    }
1055
303k
1056
303k
    SmallVector<NodePtr, 16> AffectedQueue;
1057
303k
    const unsigned Level = ToTN->getLevel();
1058
303k
1059
303k
    // Traverse destination node's descendants with greater level in the tree
1060
303k
    // and collect visited nodes.
1061
303k
    auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) {
1062
174k
      const TreeNodePtr TN = DT.getNode(To);
1063
174k
      assert(TN);
1064
174k
      if (TN->getLevel() > Level) 
return true130k
;
1065
44.3k
      if (llvm::find(AffectedQueue, To) == AffectedQueue.end())
1066
34.7k
        AffectedQueue.push_back(To);
1067
44.3k
1068
44.3k
      return false;
1069
44.3k
    };
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
1061
174k
    auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) {
1062
174k
      const TreeNodePtr TN = DT.getNode(To);
1063
174k
      assert(TN);
1064
174k
      if (TN->getLevel() > Level) 
return true130k
;
1065
44.3k
      if (llvm::find(AffectedQueue, To) == AffectedQueue.end())
1066
34.7k
        AffectedQueue.push_back(To);
1067
44.3k
1068
44.3k
      return false;
1069
44.3k
    };
1070
303k
1071
303k
    SemiNCAInfo SNCA(BUI);
1072
303k
    unsigned LastDFSNum =
1073
303k
        SNCA.runDFS(ToTN->getBlock(), 0, DescendAndCollect, 0);
1074
303k
1075
303k
    TreeNodePtr MinNode = ToTN;
1076
303k
1077
303k
    // Identify the top of the subtree to rebuild by finding the NCD of all
1078
303k
    // the affected nodes.
1079
303k
    for (const NodePtr N : AffectedQueue) {
1080
34.7k
      const TreeNodePtr TN = DT.getNode(N);
1081
34.7k
      const NodePtr NCDBlock =
1082
34.7k
          DT.findNearestCommonDominator(TN->getBlock(), ToTN->getBlock());
1083
34.7k
      assert(NCDBlock || DT.isPostDominator());
1084
34.7k
      const TreeNodePtr NCD = DT.getNode(NCDBlock);
1085
34.7k
      assert(NCD);
1086
34.7k
1087
34.7k
      LLVM_DEBUG(dbgs() << "Processing affected node " << BlockNamePrinter(TN)
1088
34.7k
                        << " with NCD = " << BlockNamePrinter(NCD)
1089
34.7k
                        << ", MinNode =" << BlockNamePrinter(MinNode) << "\n");
1090
34.7k
      if (NCD != TN && 
NCD->getLevel() < MinNode->getLevel()31.7k
)
MinNode = NCD30.1k
;
1091
34.7k
    }
1092
303k
1093
303k
    // Root reached, rebuild the whole tree from scratch.
1094
303k
    if (!MinNode->getIDom()) {
1095
5.51k
      LLVM_DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
1096
5.51k
      CalculateFromScratch(DT, BUI);
1097
5.51k
      return;
1098
5.51k
    }
1099
298k
1100
298k
    // Erase the unreachable subtree in reverse preorder to process all children
1101
298k
    // before deleting their parent.
1102
672k
    
for (unsigned i = LastDFSNum; 298k
i > 0;
--i374k
) {
1103
374k
      const NodePtr N = SNCA.NumToNode[i];
1104
374k
      const TreeNodePtr TN = DT.getNode(N);
1105
374k
      LLVM_DEBUG(dbgs() << "Erasing node " << BlockNamePrinter(TN) << "\n");
1106
374k
1107
374k
      EraseNode(DT, TN);
1108
374k
    }
1109
298k
1110
298k
    // The affected subtree start at the To node -- there's no extra work to do.
1111
298k
    if (MinNode == ToTN) 
return274k
;
1112
24.0k
1113
24.0k
    LLVM_DEBUG(dbgs() << "DeleteUnreachable: running DFS with MinNode = "
1114
24.0k
                      << BlockNamePrinter(MinNode) << "\n");
1115
24.0k
    const unsigned MinLevel = MinNode->getLevel();
1116
24.0k
    const TreeNodePtr PrevIDom = MinNode->getIDom();
1117
24.0k
    assert(PrevIDom);
1118
24.0k
    SNCA.clear();
1119
24.0k
1120
24.0k
    // Identify nodes that remain in the affected subtree.
1121
349k
    auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) {
1122
349k
      const TreeNodePtr ToTN = DT.getNode(To);
1123
349k
      return ToTN && ToTN->getLevel() > MinLevel;
1124
349k
    };
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
1121
349k
    auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) {
1122
349k
      const TreeNodePtr ToTN = DT.getNode(To);
1123
349k
      return ToTN && ToTN->getLevel() > MinLevel;
1124
349k
    };
1125
24.0k
    SNCA.runDFS(MinNode->getBlock(), 0, DescendBelow, 0);
1126
24.0k
1127
24.0k
    LLVM_DEBUG(dbgs() << "Previous IDom(MinNode) = "
1128
24.0k
                      << BlockNamePrinter(PrevIDom) << "\nRunning Semi-NCA\n");
1129
24.0k
1130
24.0k
    // Rebuild the remaining part of affected subtree.
1131
24.0k
    SNCA.runSemiNCA(DT, MinLevel);
1132
24.0k
    SNCA.reattachExistingSubtree(DT, PrevIDom);
1133
24.0k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
1038
303k
                                const TreeNodePtr ToTN) {
1039
303k
    LLVM_DEBUG(dbgs() << "Deleting unreachable subtree "
1040
303k
                      << BlockNamePrinter(ToTN) << "\n");
1041
303k
    assert(ToTN);
1042
303k
    assert(ToTN->getBlock());
1043
303k
1044
303k
    if (IsPostDom) {
1045
0
      // Deletion makes a region reverse-unreachable and creates a new root.
1046
0
      // Simulate that by inserting an edge from the virtual root to ToTN and
1047
0
      // adding it as a new root.
1048
0
      LLVM_DEBUG(dbgs() << "\tDeletion made a region reverse-unreachable\n");
1049
0
      LLVM_DEBUG(dbgs() << "\tAdding new root " << BlockNamePrinter(ToTN)
1050
0
                        << "\n");
1051
0
      DT.Roots.push_back(ToTN->getBlock());
1052
0
      InsertReachable(DT, BUI, DT.getNode(nullptr), ToTN);
1053
0
      return;
1054
0
    }
1055
303k
1056
303k
    SmallVector<NodePtr, 16> AffectedQueue;
1057
303k
    const unsigned Level = ToTN->getLevel();
1058
303k
1059
303k
    // Traverse destination node's descendants with greater level in the tree
1060
303k
    // and collect visited nodes.
1061
303k
    auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) {
1062
303k
      const TreeNodePtr TN = DT.getNode(To);
1063
303k
      assert(TN);
1064
303k
      if (TN->getLevel() > Level) return true;
1065
303k
      if (llvm::find(AffectedQueue, To) == AffectedQueue.end())
1066
303k
        AffectedQueue.push_back(To);
1067
303k
1068
303k
      return false;
1069
303k
    };
1070
303k
1071
303k
    SemiNCAInfo SNCA(BUI);
1072
303k
    unsigned LastDFSNum =
1073
303k
        SNCA.runDFS(ToTN->getBlock(), 0, DescendAndCollect, 0);
1074
303k
1075
303k
    TreeNodePtr MinNode = ToTN;
1076
303k
1077
303k
    // Identify the top of the subtree to rebuild by finding the NCD of all
1078
303k
    // the affected nodes.
1079
303k
    for (const NodePtr N : AffectedQueue) {
1080
34.7k
      const TreeNodePtr TN = DT.getNode(N);
1081
34.7k
      const NodePtr NCDBlock =
1082
34.7k
          DT.findNearestCommonDominator(TN->getBlock(), ToTN->getBlock());
1083
34.7k
      assert(NCDBlock || DT.isPostDominator());
1084
34.7k
      const TreeNodePtr NCD = DT.getNode(NCDBlock);
1085
34.7k
      assert(NCD);
1086
34.7k
1087
34.7k
      LLVM_DEBUG(dbgs() << "Processing affected node " << BlockNamePrinter(TN)
1088
34.7k
                        << " with NCD = " << BlockNamePrinter(NCD)
1089
34.7k
                        << ", MinNode =" << BlockNamePrinter(MinNode) << "\n");
1090
34.7k
      if (NCD != TN && 
NCD->getLevel() < MinNode->getLevel()31.7k
)
MinNode = NCD30.1k
;
1091
34.7k
    }
1092
303k
1093
303k
    // Root reached, rebuild the whole tree from scratch.
1094
303k
    if (!MinNode->getIDom()) {
1095
5.51k
      LLVM_DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
1096
5.51k
      CalculateFromScratch(DT, BUI);
1097
5.51k
      return;
1098
5.51k
    }
1099
298k
1100
298k
    // Erase the unreachable subtree in reverse preorder to process all children
1101
298k
    // before deleting their parent.
1102
672k
    
for (unsigned i = LastDFSNum; 298k
i > 0;
--i374k
) {
1103
374k
      const NodePtr N = SNCA.NumToNode[i];
1104
374k
      const TreeNodePtr TN = DT.getNode(N);
1105
374k
      LLVM_DEBUG(dbgs() << "Erasing node " << BlockNamePrinter(TN) << "\n");
1106
374k
1107
374k
      EraseNode(DT, TN);
1108
374k
    }
1109
298k
1110
298k
    // The affected subtree start at the To node -- there's no extra work to do.
1111
298k
    if (MinNode == ToTN) 
return274k
;
1112
24.0k
1113
24.0k
    LLVM_DEBUG(dbgs() << "DeleteUnreachable: running DFS with MinNode = "
1114
24.0k
                      << BlockNamePrinter(MinNode) << "\n");
1115
24.0k
    const unsigned MinLevel = MinNode->getLevel();
1116
24.0k
    const TreeNodePtr PrevIDom = MinNode->getIDom();
1117
24.0k
    assert(PrevIDom);
1118
24.0k
    SNCA.clear();
1119
24.0k
1120
24.0k
    // Identify nodes that remain in the affected subtree.
1121
24.0k
    auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) {
1122
24.0k
      const TreeNodePtr ToTN = DT.getNode(To);
1123
24.0k
      return ToTN && ToTN->getLevel() > MinLevel;
1124
24.0k
    };
1125
24.0k
    SNCA.runDFS(MinNode->getBlock(), 0, DescendBelow, 0);
1126
24.0k
1127
24.0k
    LLVM_DEBUG(dbgs() << "Previous IDom(MinNode) = "
1128
24.0k
                      << BlockNamePrinter(PrevIDom) << "\nRunning Semi-NCA\n");
1129
24.0k
1130
24.0k
    // Rebuild the remaining part of affected subtree.
1131
24.0k
    SNCA.runSemiNCA(DT, MinLevel);
1132
24.0k
    SNCA.reattachExistingSubtree(DT, PrevIDom);
1133
24.0k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
1038
71
                                const TreeNodePtr ToTN) {
1039
71
    LLVM_DEBUG(dbgs() << "Deleting unreachable subtree "
1040
71
                      << BlockNamePrinter(ToTN) << "\n");
1041
71
    assert(ToTN);
1042
71
    assert(ToTN->getBlock());
1043
71
1044
71
    if (IsPostDom) {
1045
71
      // Deletion makes a region reverse-unreachable and creates a new root.
1046
71
      // Simulate that by inserting an edge from the virtual root to ToTN and
1047
71
      // adding it as a new root.
1048
71
      LLVM_DEBUG(dbgs() << "\tDeletion made a region reverse-unreachable\n");
1049
71
      LLVM_DEBUG(dbgs() << "\tAdding new root " << BlockNamePrinter(ToTN)
1050
71
                        << "\n");
1051
71
      DT.Roots.push_back(ToTN->getBlock());
1052
71
      InsertReachable(DT, BUI, DT.getNode(nullptr), ToTN);
1053
71
      return;
1054
71
    }
1055
0
1056
0
    SmallVector<NodePtr, 16> AffectedQueue;
1057
0
    const unsigned Level = ToTN->getLevel();
1058
0
1059
0
    // Traverse destination node's descendants with greater level in the tree
1060
0
    // and collect visited nodes.
1061
0
    auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) {
1062
0
      const TreeNodePtr TN = DT.getNode(To);
1063
0
      assert(TN);
1064
0
      if (TN->getLevel() > Level) return true;
1065
0
      if (llvm::find(AffectedQueue, To) == AffectedQueue.end())
1066
0
        AffectedQueue.push_back(To);
1067
0
1068
0
      return false;
1069
0
    };
1070
0
1071
0
    SemiNCAInfo SNCA(BUI);
1072
0
    unsigned LastDFSNum =
1073
0
        SNCA.runDFS(ToTN->getBlock(), 0, DescendAndCollect, 0);
1074
0
1075
0
    TreeNodePtr MinNode = ToTN;
1076
0
1077
0
    // Identify the top of the subtree to rebuild by finding the NCD of all
1078
0
    // the affected nodes.
1079
0
    for (const NodePtr N : AffectedQueue) {
1080
0
      const TreeNodePtr TN = DT.getNode(N);
1081
0
      const NodePtr NCDBlock =
1082
0
          DT.findNearestCommonDominator(TN->getBlock(), ToTN->getBlock());
1083
0
      assert(NCDBlock || DT.isPostDominator());
1084
0
      const TreeNodePtr NCD = DT.getNode(NCDBlock);
1085
0
      assert(NCD);
1086
0
1087
0
      LLVM_DEBUG(dbgs() << "Processing affected node " << BlockNamePrinter(TN)
1088
0
                        << " with NCD = " << BlockNamePrinter(NCD)
1089
0
                        << ", MinNode =" << BlockNamePrinter(MinNode) << "\n");
1090
0
      if (NCD != TN && NCD->getLevel() < MinNode->getLevel()) MinNode = NCD;
1091
0
    }
1092
0
1093
0
    // Root reached, rebuild the whole tree from scratch.
1094
0
    if (!MinNode->getIDom()) {
1095
0
      LLVM_DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
1096
0
      CalculateFromScratch(DT, BUI);
1097
0
      return;
1098
0
    }
1099
0
1100
0
    // Erase the unreachable subtree in reverse preorder to process all children
1101
0
    // before deleting their parent.
1102
0
    for (unsigned i = LastDFSNum; i > 0; --i) {
1103
0
      const NodePtr N = SNCA.NumToNode[i];
1104
0
      const TreeNodePtr TN = DT.getNode(N);
1105
0
      LLVM_DEBUG(dbgs() << "Erasing node " << BlockNamePrinter(TN) << "\n");
1106
0
1107
0
      EraseNode(DT, TN);
1108
0
    }
1109
0
1110
0
    // The affected subtree start at the To node -- there's no extra work to do.
1111
0
    if (MinNode == ToTN) return;
1112
0
1113
0
    LLVM_DEBUG(dbgs() << "DeleteUnreachable: running DFS with MinNode = "
1114
0
                      << BlockNamePrinter(MinNode) << "\n");
1115
0
    const unsigned MinLevel = MinNode->getLevel();
1116
0
    const TreeNodePtr PrevIDom = MinNode->getIDom();
1117
0
    assert(PrevIDom);
1118
0
    SNCA.clear();
1119
0
1120
0
    // Identify nodes that remain in the affected subtree.
1121
0
    auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) {
1122
0
      const TreeNodePtr ToTN = DT.getNode(To);
1123
0
      return ToTN && ToTN->getLevel() > MinLevel;
1124
0
    };
1125
0
    SNCA.runDFS(MinNode->getBlock(), 0, DescendBelow, 0);
1126
0
1127
0
    LLVM_DEBUG(dbgs() << "Previous IDom(MinNode) = "
1128
0
                      << BlockNamePrinter(PrevIDom) << "\nRunning Semi-NCA\n");
1129
0
1130
0
    // Rebuild the remaining part of affected subtree.
1131
0
    SNCA.runSemiNCA(DT, MinLevel);
1132
0
    SNCA.reattachExistingSubtree(DT, PrevIDom);
1133
0
  }
1134
1135
  // Removes leaf tree nodes from the dominator tree.
1136
374k
  static void EraseNode(DomTreeT &DT, const TreeNodePtr TN) {
1137
374k
    assert(TN);
1138
374k
    assert(TN->getNumChildren() == 0 && "Not a tree leaf");
1139
374k
1140
374k
    const TreeNodePtr IDom = TN->getIDom();
1141
374k
    assert(IDom);
1142
374k
1143
374k
    auto ChIt = llvm::find(IDom->Children, TN);
1144
374k
    assert(ChIt != IDom->Children.end());
1145
374k
    std::swap(*ChIt, IDom->Children.back());
1146
374k
    IDom->Children.pop_back();
1147
374k
1148
374k
    DT.DomTreeNodes.erase(TN->getBlock());
1149
374k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::EraseNode(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::EraseNode(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::EraseNode(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
Line
Count
Source
1136
374k
  static void EraseNode(DomTreeT &DT, const TreeNodePtr TN) {
1137
374k
    assert(TN);
1138
374k
    assert(TN->getNumChildren() == 0 && "Not a tree leaf");
1139
374k
1140
374k
    const TreeNodePtr IDom = TN->getIDom();
1141
374k
    assert(IDom);
1142
374k
1143
374k
    auto ChIt = llvm::find(IDom->Children, TN);
1144
374k
    assert(ChIt != IDom->Children.end());
1145
374k
    std::swap(*ChIt, IDom->Children.back());
1146
374k
    IDom->Children.pop_back();
1147
374k
1148
374k
    DT.DomTreeNodes.erase(TN->getBlock());
1149
374k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::EraseNode(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*)
1150
1151
  //~~
1152
  //===--------------------- DomTree Batch Updater --------------------------===
1153
  //~~
1154
1155
521k
  static void ApplyUpdates(DomTreeT &DT, ArrayRef<UpdateT> Updates) {
1156
521k
    const size_t NumUpdates = Updates.size();
1157
521k
    if (NumUpdates == 0)
1158
192
      return;
1159
521k
1160
521k
    // Take the fast path for a single update and avoid running the batch update
1161
521k
    // machinery.
1162
521k
    if (NumUpdates == 1) {
1163
7.77k
      const auto &Update = Updates.front();
1164
7.77k
      if (Update.getKind() == UpdateKind::Insert)
1165
4.19k
        DT.insertEdge(Update.getFrom(), Update.getTo());
1166
3.58k
      else
1167
3.58k
        DT.deleteEdge(Update.getFrom(), Update.getTo());
1168
7.77k
1169
7.77k
      return;
1170
7.77k
    }
1171
513k
1172
513k
    BatchUpdateInfo BUI;
1173
513k
    LLVM_DEBUG(dbgs() << "Legalizing " << BUI.Updates.size() << " updates\n");
1174
513k
    cfg::LegalizeUpdates<NodePtr>(Updates, BUI.Updates, IsPostDom);
1175
513k
1176
513k
    const size_t NumLegalized = BUI.Updates.size();
1177
513k
    BUI.FutureSuccessors.reserve(NumLegalized);
1178
513k
    BUI.FuturePredecessors.reserve(NumLegalized);
1179
513k
1180
513k
    // Use the legalized future updates to initialize future successors and
1181
513k
    // predecessors. Note that these sets will only decrease size over time, as
1182
513k
    // the next CFG snapshots slowly approach the actual (current) CFG.
1183
2.49M
    for (UpdateT &U : BUI.Updates) {
1184
2.49M
      BUI.FutureSuccessors[U.getFrom()].push_back({U.getTo(), U.getKind()});
1185
2.49M
      BUI.FuturePredecessors[U.getTo()].push_back({U.getFrom(), U.getKind()});
1186
2.49M
    }
1187
513k
1188
#if 0
1189
    // FIXME: The LLVM_DEBUG macro only plays well with a modular
1190
    // build of LLVM when the header is marked as textual, but doing
1191
    // so causes redefinition errors.
1192
    LLVM_DEBUG(dbgs() << "About to apply " << NumLegalized << " updates\n");
1193
    LLVM_DEBUG(if (NumLegalized < 32) for (const auto &U
1194
                                           : reverse(BUI.Updates)) {
1195
      dbgs() << "\t";
1196
      U.dump();
1197
      dbgs() << "\n";
1198
    });
1199
    LLVM_DEBUG(dbgs() << "\n");
1200
#endif
1201
1202
513k
    // Recalculate the DominatorTree when the number of updates
1203
513k
    // exceeds a threshold, which usually makes direct updating slower than
1204
513k
    // recalculation. We select this threshold proportional to the
1205
513k
    // size of the DominatorTree. The constant is selected
1206
513k
    // by choosing the one with an acceptable performance on some real-world
1207
513k
    // inputs.
1208
513k
1209
513k
    // Make unittests of the incremental algorithm work
1210
513k
    if (DT.DomTreeNodes.size() <= 100) {
1211
339k
      if (NumLegalized > DT.DomTreeNodes.size())
1212
5.25k
        CalculateFromScratch(DT, &BUI);
1213
339k
    } else 
if (174k
NumLegalized > DT.DomTreeNodes.size() / 40174k
)
1214
69.9k
      CalculateFromScratch(DT, &BUI);
1215
513k
1216
513k
    // If the DominatorTree was recalculated at some point, stop the batch
1217
513k
    // updates. Full recalculations ignore batch updates and look at the actual
1218
513k
    // CFG.
1219
1.95M
    for (size_t i = 0; i < NumLegalized && 
!BUI.IsRecalculated1.57M
;
++i1.44M
)
1220
1.44M
      ApplyNextUpdate(DT, BUI);
1221
513k
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ApplyUpdates(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::ArrayRef<llvm::cfg::Update<llvm::MachineBasicBlock*> >)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ApplyUpdates(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::ArrayRef<llvm::cfg::Update<llvm::MachineBasicBlock*> >)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ApplyUpdates(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::ArrayRef<llvm::cfg::Update<llvm::BasicBlock*> >)
Line
Count
Source
1155
521k
  static void ApplyUpdates(DomTreeT &DT, ArrayRef<UpdateT> Updates) {
1156
521k
    const size_t NumUpdates = Updates.size();
1157
521k
    if (NumUpdates == 0)
1158
15
      return;
1159
521k
1160
521k
    // Take the fast path for a single update and avoid running the batch update
1161
521k
    // machinery.
1162
521k
    if (NumUpdates == 1) {
1163
7.67k
      const auto &Update = Updates.front();
1164
7.67k
      if (Update.getKind() == UpdateKind::Insert)
1165
4.19k
        DT.insertEdge(Update.getFrom(), Update.getTo());
1166
3.48k
      else
1167
3.48k
        DT.deleteEdge(Update.getFrom(), Update.getTo());
1168
7.67k
1169
7.67k
      return;
1170
7.67k
    }
1171
513k
1172
513k
    BatchUpdateInfo BUI;
1173
513k
    LLVM_DEBUG(dbgs() << "Legalizing " << BUI.Updates.size() << " updates\n");
1174
513k
    cfg::LegalizeUpdates<NodePtr>(Updates, BUI.Updates, IsPostDom);
1175
513k
1176
513k
    const size_t NumLegalized = BUI.Updates.size();
1177
513k
    BUI.FutureSuccessors.reserve(NumLegalized);
1178
513k
    BUI.FuturePredecessors.reserve(NumLegalized);
1179
513k
1180
513k
    // Use the legalized future updates to initialize future successors and
1181
513k
    // predecessors. Note that these sets will only decrease size over time, as
1182
513k
    // the next CFG snapshots slowly approach the actual (current) CFG.
1183
2.49M
    for (UpdateT &U : BUI.Updates) {
1184
2.49M
      BUI.FutureSuccessors[U.getFrom()].push_back({U.getTo(), U.getKind()});
1185
2.49M
      BUI.FuturePredecessors[U.getTo()].push_back({U.getFrom(), U.getKind()});
1186
2.49M
    }
1187
513k
1188
#if 0
1189
    // FIXME: The LLVM_DEBUG macro only plays well with a modular
1190
    // build of LLVM when the header is marked as textual, but doing
1191
    // so causes redefinition errors.
1192
    LLVM_DEBUG(dbgs() << "About to apply " << NumLegalized << " updates\n");
1193
    LLVM_DEBUG(if (NumLegalized < 32) for (const auto &U
1194
                                           : reverse(BUI.Updates)) {
1195
      dbgs() << "\t";
1196
      U.dump();
1197
      dbgs() << "\n";
1198
    });
1199
    LLVM_DEBUG(dbgs() << "\n");
1200
#endif
1201
1202
513k
    // Recalculate the DominatorTree when the number of updates
1203
513k
    // exceeds a threshold, which usually makes direct updating slower than
1204
513k
    // recalculation. We select this threshold proportional to the
1205
513k
    // size of the DominatorTree. The constant is selected
1206
513k
    // by choosing the one with an acceptable performance on some real-world
1207
513k
    // inputs.
1208
513k
1209
513k
    // Make unittests of the incremental algorithm work
1210
513k
    if (DT.DomTreeNodes.size() <= 100) {
1211
339k
      if (NumLegalized > DT.DomTreeNodes.size())
1212
5.25k
        CalculateFromScratch(DT, &BUI);
1213
339k
    } else 
if (174k
NumLegalized > DT.DomTreeNodes.size() / 40174k
)
1214
69.9k
      CalculateFromScratch(DT, &BUI);
1215
513k
1216
513k
    // If the DominatorTree was recalculated at some point, stop the batch
1217
513k
    // updates. Full recalculations ignore batch updates and look at the actual
1218
513k
    // CFG.
1219
1.95M
    for (size_t i = 0; i < NumLegalized && 
!BUI.IsRecalculated1.57M
;
++i1.44M
)
1220
1.44M
      ApplyNextUpdate(DT, BUI);
1221
513k
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ApplyUpdates(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::ArrayRef<llvm::cfg::Update<llvm::BasicBlock*> >)
Line
Count
Source
1155
326
  static void ApplyUpdates(DomTreeT &DT, ArrayRef<UpdateT> Updates) {
1156
326
    const size_t NumUpdates = Updates.size();
1157
326
    if (NumUpdates == 0)
1158
177
      return;
1159
149
1160
149
    // Take the fast path for a single update and avoid running the batch update
1161
149
    // machinery.
1162
149
    if (NumUpdates == 1) {
1163
107
      const auto &Update = Updates.front();
1164
107
      if (Update.getKind() == UpdateKind::Insert)
1165
2
        DT.insertEdge(Update.getFrom(), Update.getTo());
1166
105
      else
1167
105
        DT.deleteEdge(Update.getFrom(), Update.getTo());
1168
107
1169
107
      return;
1170
107
    }
1171
42
1172
42
    BatchUpdateInfo BUI;
1173
42
    LLVM_DEBUG(dbgs() << "Legalizing " << BUI.Updates.size() << " updates\n");
1174
42
    cfg::LegalizeUpdates<NodePtr>(Updates, BUI.Updates, IsPostDom);
1175
42
1176
42
    const size_t NumLegalized = BUI.Updates.size();
1177
42
    BUI.FutureSuccessors.reserve(NumLegalized);
1178
42
    BUI.FuturePredecessors.reserve(NumLegalized);
1179
42
1180
42
    // Use the legalized future updates to initialize future successors and
1181
42
    // predecessors. Note that these sets will only decrease size over time, as
1182
42
    // the next CFG snapshots slowly approach the actual (current) CFG.
1183
300
    for (UpdateT &U : BUI.Updates) {
1184
300
      BUI.FutureSuccessors[U.getFrom()].push_back({U.getTo(), U.getKind()});
1185
300
      BUI.FuturePredecessors[U.getTo()].push_back({U.getFrom(), U.getKind()});
1186
300
    }
1187
42
1188
#if 0
1189
    // FIXME: The LLVM_DEBUG macro only plays well with a modular
1190
    // build of LLVM when the header is marked as textual, but doing
1191
    // so causes redefinition errors.
1192
    LLVM_DEBUG(dbgs() << "About to apply " << NumLegalized << " updates\n");
1193
    LLVM_DEBUG(if (NumLegalized < 32) for (const auto &U
1194
                                           : reverse(BUI.Updates)) {
1195
      dbgs() << "\t";
1196
      U.dump();
1197
      dbgs() << "\n";
1198
    });
1199
    LLVM_DEBUG(dbgs() << "\n");
1200
#endif
1201
1202
42
    // Recalculate the DominatorTree when the number of updates
1203
42
    // exceeds a threshold, which usually makes direct updating slower than
1204
42
    // recalculation. We select this threshold proportional to the
1205
42
    // size of the DominatorTree. The constant is selected
1206
42
    // by choosing the one with an acceptable performance on some real-world
1207
42
    // inputs.
1208
42
1209
42
    // Make unittests of the incremental algorithm work
1210
42
    if (DT.DomTreeNodes.size() <= 100) {
1211
42
      if (NumLegalized > DT.DomTreeNodes.size())
1212
1
        CalculateFromScratch(DT, &BUI);
1213
42
    } else 
if (0
NumLegalized > DT.DomTreeNodes.size() / 400
)
1214
0
      CalculateFromScratch(DT, &BUI);
1215
42
1216
42
    // If the DominatorTree was recalculated at some point, stop the batch
1217
42
    // updates. Full recalculations ignore batch updates and look at the actual
1218
42
    // CFG.
1219
103
    for (size_t i = 0; i < NumLegalized && 
!BUI.IsRecalculated94
;
++i61
)
1220
61
      ApplyNextUpdate(DT, BUI);
1221
42
  }
1222
1223
1.44M
  static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) {
1224
1.44M
    assert(!BUI.Updates.empty() && "No updates to apply!");
1225
1.44M
    UpdateT CurrentUpdate = BUI.Updates.pop_back_val();
1226
#if 0
1227
    // FIXME: The LLVM_DEBUG macro only plays well with a modular
1228
    // build of LLVM when the header is marked as textual, but doing
1229
    // so causes redefinition errors.
1230
    LLVM_DEBUG(dbgs() << "Applying update: ");
1231
    LLVM_DEBUG(CurrentUpdate.dump(); dbgs() << "\n");
1232
#endif
1233
1234
1.44M
    // Move to the next snapshot of the CFG by removing the reverse-applied
1235
1.44M
    // current update. Since updates are performed in the same order they are
1236
1.44M
    // legalized it's sufficient to pop the last item here.
1237
1.44M
    auto &FS = BUI.FutureSuccessors[CurrentUpdate.getFrom()];
1238
1.44M
    assert(FS.back().getPointer() == CurrentUpdate.getTo() &&
1239
1.44M
           FS.back().getInt() == CurrentUpdate.getKind());
1240
1.44M
    FS.pop_back();
1241
1.44M
    if (FS.empty()) 
BUI.FutureSuccessors.erase(CurrentUpdate.getFrom())857k
;
1242
1.44M
1243
1.44M
    auto &FP = BUI.FuturePredecessors[CurrentUpdate.getTo()];
1244
1.44M
    assert(FP.back().getPointer() == CurrentUpdate.getFrom() &&
1245
1.44M
           FP.back().getInt() == CurrentUpdate.getKind());
1246
1.44M
    FP.pop_back();
1247
1.44M
    if (FP.empty()) 
BUI.FuturePredecessors.erase(CurrentUpdate.getTo())955k
;
1248
1.44M
1249
1.44M
    if (CurrentUpdate.getKind() == UpdateKind::Insert)
1250
615k
      InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1251
828k
    else
1252
828k
      DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1253
1.44M
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ApplyNextUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ApplyNextUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ApplyNextUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo&)
Line
Count
Source
1223
1.44M
  static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) {
1224
1.44M
    assert(!BUI.Updates.empty() && "No updates to apply!");
1225
1.44M
    UpdateT CurrentUpdate = BUI.Updates.pop_back_val();
1226
#if 0
1227
    // FIXME: The LLVM_DEBUG macro only plays well with a modular
1228
    // build of LLVM when the header is marked as textual, but doing
1229
    // so causes redefinition errors.
1230
    LLVM_DEBUG(dbgs() << "Applying update: ");
1231
    LLVM_DEBUG(CurrentUpdate.dump(); dbgs() << "\n");
1232
#endif
1233
1234
1.44M
    // Move to the next snapshot of the CFG by removing the reverse-applied
1235
1.44M
    // current update. Since updates are performed in the same order they are
1236
1.44M
    // legalized it's sufficient to pop the last item here.
1237
1.44M
    auto &FS = BUI.FutureSuccessors[CurrentUpdate.getFrom()];
1238
1.44M
    assert(FS.back().getPointer() == CurrentUpdate.getTo() &&
1239
1.44M
           FS.back().getInt() == CurrentUpdate.getKind());
1240
1.44M
    FS.pop_back();
1241
1.44M
    if (FS.empty()) 
BUI.FutureSuccessors.erase(CurrentUpdate.getFrom())857k
;
1242
1.44M
1243
1.44M
    auto &FP = BUI.FuturePredecessors[CurrentUpdate.getTo()];
1244
1.44M
    assert(FP.back().getPointer() == CurrentUpdate.getFrom() &&
1245
1.44M
           FP.back().getInt() == CurrentUpdate.getKind());
1246
1.44M
    FP.pop_back();
1247
1.44M
    if (FP.empty()) 
BUI.FuturePredecessors.erase(CurrentUpdate.getTo())955k
;
1248
1.44M
1249
1.44M
    if (CurrentUpdate.getKind() == UpdateKind::Insert)
1250
615k
      InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1251
828k
    else
1252
828k
      DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1253
1.44M
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ApplyNextUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo&)
Line
Count
Source
1223
61
  static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) {
1224
61
    assert(!BUI.Updates.empty() && "No updates to apply!");
1225
61
    UpdateT CurrentUpdate = BUI.Updates.pop_back_val();
1226
#if 0
1227
    // FIXME: The LLVM_DEBUG macro only plays well with a modular
1228
    // build of LLVM when the header is marked as textual, but doing
1229
    // so causes redefinition errors.
1230
    LLVM_DEBUG(dbgs() << "Applying update: ");
1231
    LLVM_DEBUG(CurrentUpdate.dump(); dbgs() << "\n");
1232
#endif
1233
1234
61
    // Move to the next snapshot of the CFG by removing the reverse-applied
1235
61
    // current update. Since updates are performed in the same order they are
1236
61
    // legalized it's sufficient to pop the last item here.
1237
61
    auto &FS = BUI.FutureSuccessors[CurrentUpdate.getFrom()];
1238
61
    assert(FS.back().getPointer() == CurrentUpdate.getTo() &&
1239
61
           FS.back().getInt() == CurrentUpdate.getKind());
1240
61
    FS.pop_back();
1241
61
    if (FS.empty()) 
BUI.FutureSuccessors.erase(CurrentUpdate.getFrom())44
;
1242
61
1243
61
    auto &FP = BUI.FuturePredecessors[CurrentUpdate.getTo()];
1244
61
    assert(FP.back().getPointer() == CurrentUpdate.getFrom() &&
1245
61
           FP.back().getInt() == CurrentUpdate.getKind());
1246
61
    FP.pop_back();
1247
61
    if (FP.empty()) 
BUI.FuturePredecessors.erase(CurrentUpdate.getTo())21
;
1248
61
1249
61
    if (CurrentUpdate.getKind() == UpdateKind::Insert)
1250
20
      InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1251
41
    else
1252
41
      DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1253
61
  }
1254
1255
  //~~
1256
  //===--------------- DomTree correctness verification ---------------------===
1257
  //~~
1258
1259
  // Check if the tree has correct roots. A DominatorTree always has a single
1260
  // root which is the function's entry node. A PostDominatorTree can have
1261
  // multiple roots - one for each node with no successors and for infinite
1262
  // loops.
1263
  // Running time: O(N).
1264
715
  bool verifyRoots(const DomTreeT &DT) {
1265
715
    if (!DT.Parent && 
!DT.Roots.empty()0
) {
1266
0
      errs() << "Tree has no parent but has roots!\n";
1267
0
      errs().flush();
1268
0
      return false;
1269
0
    }
1270
715
1271
715
    if (!IsPostDom) {
1272
367
      if (DT.Roots.empty()) {
1273
0
        errs() << "Tree doesn't have a root!\n";
1274
0
        errs().flush();
1275
0
        return false;
1276
0
      }
1277
367
1278
367
      if (DT.getRoot() != GetEntryNode(DT)) {
1279
0
        errs() << "Tree's root is not its parent's entry node!\n";
1280
0
        errs().flush();
1281
0
        return false;
1282
0
      }
1283
715
    }
1284
715
1285
715
    RootsT ComputedRoots = FindRoots(DT, nullptr);
1286
715
    if (!isPermutation(DT.Roots, ComputedRoots)) {
1287
0
      errs() << "Tree has different roots than freshly computed ones!\n";
1288
0
      errs() << "\tPDT roots: ";
1289
0
      for (const NodePtr N : DT.Roots) errs() << BlockNamePrinter(N) << ", ";
1290
0
      errs() << "\n\tComputed roots: ";
1291
0
      for (const NodePtr N : ComputedRoots)
1292
0
        errs() << BlockNamePrinter(N) << ", ";
1293
0
      errs() << "\n";
1294
0
      errs().flush();
1295
0
      return false;
1296
0
    }
1297
715
1298
715
    return true;
1299
715
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyRoots(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)
Line
Count
Source
1264
367
  bool verifyRoots(const DomTreeT &DT) {
1265
367
    if (!DT.Parent && 
!DT.Roots.empty()0
) {
1266
0
      errs() << "Tree has no parent but has roots!\n";
1267
0
      errs().flush();
1268
0
      return false;
1269
0
    }
1270
367
1271
367
    if (!IsPostDom) {
1272
367
      if (DT.Roots.empty()) {
1273
0
        errs() << "Tree doesn't have a root!\n";
1274
0
        errs().flush();
1275
0
        return false;
1276
0
      }
1277
367
1278
367
      if (DT.getRoot() != GetEntryNode(DT)) {
1279
0
        errs() << "Tree's root is not its parent's entry node!\n";
1280
0
        errs().flush();
1281
0
        return false;
1282
0
      }
1283
367
    }
1284
367
1285
367
    RootsT ComputedRoots = FindRoots(DT, nullptr);
1286
367
    if (!isPermutation(DT.Roots, ComputedRoots)) {
1287
0
      errs() << "Tree has different roots than freshly computed ones!\n";
1288
0
      errs() << "\tPDT roots: ";
1289
0
      for (const NodePtr N : DT.Roots) errs() << BlockNamePrinter(N) << ", ";
1290
0
      errs() << "\n\tComputed roots: ";
1291
0
      for (const NodePtr N : ComputedRoots)
1292
0
        errs() << BlockNamePrinter(N) << ", ";
1293
0
      errs() << "\n";
1294
0
      errs().flush();
1295
0
      return false;
1296
0
    }
1297
367
1298
367
    return true;
1299
367
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyRoots(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)
Line
Count
Source
1264
348
  bool verifyRoots(const DomTreeT &DT) {
1265
348
    if (!DT.Parent && 
!DT.Roots.empty()0
) {
1266
0
      errs() << "Tree has no parent but has roots!\n";
1267
0
      errs().flush();
1268
0
      return false;
1269
0
    }
1270
348
1271
348
    if (!IsPostDom) {
1272
0
      if (DT.Roots.empty()) {
1273
0
        errs() << "Tree doesn't have a root!\n";
1274
0
        errs().flush();
1275
0
        return false;
1276
0
      }
1277
0
1278
0
      if (DT.getRoot() != GetEntryNode(DT)) {
1279
0
        errs() << "Tree's root is not its parent's entry node!\n";
1280
0
        errs().flush();
1281
0
        return false;
1282
0
      }
1283
348
    }
1284
348
1285
348
    RootsT ComputedRoots = FindRoots(DT, nullptr);
1286
348
    if (!isPermutation(DT.Roots, ComputedRoots)) {
1287
0
      errs() << "Tree has different roots than freshly computed ones!\n";
1288
0
      errs() << "\tPDT roots: ";
1289
0
      for (const NodePtr N : DT.Roots) errs() << BlockNamePrinter(N) << ", ";
1290
0
      errs() << "\n\tComputed roots: ";
1291
0
      for (const NodePtr N : ComputedRoots)
1292
0
        errs() << BlockNamePrinter(N) << ", ";
1293
0
      errs() << "\n";
1294
0
      errs().flush();
1295
0
      return false;
1296
0
    }
1297
348
1298
348
    return true;
1299
348
  }
1300
1301
  // Checks if the tree contains all reachable nodes in the input graph.
1302
  // Running time: O(N).
1303
715
  bool verifyReachability(const DomTreeT &DT) {
1304
715
    clear();
1305
715
    doFullDFSWalk(DT, AlwaysDescend);
1306
715
1307
6.68k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1308
6.68k
      const TreeNodePtr TN = NodeToTN.second.get();
1309
6.68k
      const NodePtr BB = TN->getBlock();
1310
6.68k
1311
6.68k
      // Virtual root has a corresponding virtual CFG node.
1312
6.68k
      if (DT.isVirtualRoot(TN)) 
continue348
;
1313
6.33k
1314
6.33k
      if (NodeToInfo.count(BB) == 0) {
1315
0
        errs() << "DomTree node " << BlockNamePrinter(BB)
1316
0
               << " not found by DFS walk!\n";
1317
0
        errs().flush();
1318
0
1319
0
        return false;
1320
0
      }
1321
6.33k
    }
1322
715
1323
7.39k
    
for (const NodePtr N : NumToNode)715
{
1324
7.39k
      if (N && 
!DT.getNode(N)6.33k
) {
1325
0
        errs() << "CFG node " << BlockNamePrinter(N)
1326
0
               << " not found in the DomTree!\n";
1327
0
        errs().flush();
1328
0
1329
0
        return false;
1330
0
      }
1331
7.39k
    }
1332
715
1333
715
    return true;
1334
715
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyReachability(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyReachability(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyReachability(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)
Line
Count
Source
1303
367
  bool verifyReachability(const DomTreeT &DT) {
1304
367
    clear();
1305
367
    doFullDFSWalk(DT, AlwaysDescend);
1306
367
1307
2.83k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1308
2.83k
      const TreeNodePtr TN = NodeToTN.second.get();
1309
2.83k
      const NodePtr BB = TN->getBlock();
1310
2.83k
1311
2.83k
      // Virtual root has a corresponding virtual CFG node.
1312
2.83k
      if (DT.isVirtualRoot(TN)) 
continue0
;
1313
2.83k
1314
2.83k
      if (NodeToInfo.count(BB) == 0) {
1315
0
        errs() << "DomTree node " << BlockNamePrinter(BB)
1316
0
               << " not found by DFS walk!\n";
1317
0
        errs().flush();
1318
0
1319
0
        return false;
1320
0
      }
1321
2.83k
    }
1322
367
1323
3.20k
    
for (const NodePtr N : NumToNode)367
{
1324
3.20k
      if (N && 
!DT.getNode(N)2.83k
) {
1325
0
        errs() << "CFG node " << BlockNamePrinter(N)
1326
0
               << " not found in the DomTree!\n";
1327
0
        errs().flush();
1328
0
1329
0
        return false;
1330
0
      }
1331
3.20k
    }
1332
367
1333
367
    return true;
1334
367
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyReachability(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)
Line
Count
Source
1303
348
  bool verifyReachability(const DomTreeT &DT) {
1304
348
    clear();
1305
348
    doFullDFSWalk(DT, AlwaysDescend);
1306
348
1307
3.85k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1308
3.85k
      const TreeNodePtr TN = NodeToTN.second.get();
1309
3.85k
      const NodePtr BB = TN->getBlock();
1310
3.85k
1311
3.85k
      // Virtual root has a corresponding virtual CFG node.
1312
3.85k
      if (DT.isVirtualRoot(TN)) 
continue348
;
1313
3.50k
1314
3.50k
      if (NodeToInfo.count(BB) == 0) {
1315
0
        errs() << "DomTree node " << BlockNamePrinter(BB)
1316
0
               << " not found by DFS walk!\n";
1317
0
        errs().flush();
1318
0
1319
0
        return false;
1320
0
      }
1321
3.50k
    }
1322
348
1323
4.19k
    
for (const NodePtr N : NumToNode)348
{
1324
4.19k
      if (N && 
!DT.getNode(N)3.50k
) {
1325
0
        errs() << "CFG node " << BlockNamePrinter(N)
1326
0
               << " not found in the DomTree!\n";
1327
0
        errs().flush();
1328
0
1329
0
        return false;
1330
0
      }
1331
4.19k
    }
1332
348
1333
348
    return true;
1334
348
  }
1335
1336
  // Check if for every parent with a level L in the tree all of its children
1337
  // have level L + 1.
1338
  // Running time: O(N).
1339
715
  static bool VerifyLevels(const DomTreeT &DT) {
1340
6.68k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1341
6.68k
      const TreeNodePtr TN = NodeToTN.second.get();
1342
6.68k
      const NodePtr BB = TN->getBlock();
1343
6.68k
      if (!BB) 
continue348
;
1344
6.33k
1345
6.33k
      const TreeNodePtr IDom = TN->getIDom();
1346
6.33k
      if (!IDom && 
TN->getLevel() != 0367
) {
1347
0
        errs() << "Node without an IDom " << BlockNamePrinter(BB)
1348
0
               << " has a nonzero level " << TN->getLevel() << "!\n";
1349
0
        errs().flush();
1350
0
1351
0
        return false;
1352
0
      }
1353
6.33k
1354
6.33k
      if (IDom && 
TN->getLevel() != IDom->getLevel() + 15.96k
) {
1355
0
        errs() << "Node " << BlockNamePrinter(BB) << " has level "
1356
0
               << TN->getLevel() << " while its IDom "
1357
0
               << BlockNamePrinter(IDom->getBlock()) << " has level "
1358
0
               << IDom->getLevel() << "!\n";
1359
0
        errs().flush();
1360
0
1361
0
        return false;
1362
0
      }
1363
6.33k
    }
1364
715
1365
715
    return true;
1366
715
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::VerifyLevels(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::VerifyLevels(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::VerifyLevels(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)
Line
Count
Source
1339
367
  static bool VerifyLevels(const DomTreeT &DT) {
1340
2.83k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1341
2.83k
      const TreeNodePtr TN = NodeToTN.second.get();
1342
2.83k
      const NodePtr BB = TN->getBlock();
1343
2.83k
      if (!BB) 
continue0
;
1344
2.83k
1345
2.83k
      const TreeNodePtr IDom = TN->getIDom();
1346
2.83k
      if (!IDom && 
TN->getLevel() != 0367
) {
1347
0
        errs() << "Node without an IDom " << BlockNamePrinter(BB)
1348
0
               << " has a nonzero level " << TN->getLevel() << "!\n";
1349
0
        errs().flush();
1350
0
1351
0
        return false;
1352
0
      }
1353
2.83k
1354
2.83k
      if (IDom && 
TN->getLevel() != IDom->getLevel() + 12.46k
) {
1355
0
        errs() << "Node " << BlockNamePrinter(BB) << " has level "
1356
0
               << TN->getLevel() << " while its IDom "
1357
0
               << BlockNamePrinter(IDom->getBlock()) << " has level "
1358
0
               << IDom->getLevel() << "!\n";
1359
0
        errs().flush();
1360
0
1361
0
        return false;
1362
0
      }
1363
2.83k
    }
1364
367
1365
367
    return true;
1366
367
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::VerifyLevels(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)
Line
Count
Source
1339
348
  static bool VerifyLevels(const DomTreeT &DT) {
1340
3.85k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1341
3.85k
      const TreeNodePtr TN = NodeToTN.second.get();
1342
3.85k
      const NodePtr BB = TN->getBlock();
1343
3.85k
      if (!BB) 
continue348
;
1344
3.50k
1345
3.50k
      const TreeNodePtr IDom = TN->getIDom();
1346
3.50k
      if (!IDom && 
TN->getLevel() != 00
) {
1347
0
        errs() << "Node without an IDom " << BlockNamePrinter(BB)
1348
0
               << " has a nonzero level " << TN->getLevel() << "!\n";
1349
0
        errs().flush();
1350
0
1351
0
        return false;
1352
0
      }
1353
3.50k
1354
3.50k
      if (IDom && TN->getLevel() != IDom->getLevel() + 1) {
1355
0
        errs() << "Node " << BlockNamePrinter(BB) << " has level "
1356
0
               << TN->getLevel() << " while its IDom "
1357
0
               << BlockNamePrinter(IDom->getBlock()) << " has level "
1358
0
               << IDom->getLevel() << "!\n";
1359
0
        errs().flush();
1360
0
1361
0
        return false;
1362
0
      }
1363
3.50k
    }
1364
348
1365
348
    return true;
1366
348
  }
1367
1368
  // Check if the computed DFS numbers are correct. Note that DFS info may not
1369
  // be valid, and when that is the case, we don't verify the numbers.
1370
  // Running time: O(N log(N)).
1371
715
  static bool VerifyDFSNumbers(const DomTreeT &DT) {
1372
715
    if (!DT.DFSInfoValid || 
!DT.Parent1
)
1373
714
      return true;
1374
1
1375
1
    const NodePtr RootBB = IsPostDom ? 
nullptr0
: DT.getRoots()[0];
1376
1
    const TreeNodePtr Root = DT.getNode(RootBB);
1377
1
1378
1
    auto PrintNodeAndDFSNums = [](const TreeNodePtr TN) {
1379
0
      errs() << BlockNamePrinter(TN) << " {" << TN->getDFSNumIn() << ", "
1380
0
             << TN->getDFSNumOut() << '}';
1381
0
    };
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::DomTreeNodeBase<llvm::BasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::BasicBlock>*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::DomTreeNodeBase<llvm::BasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::BasicBlock>*) const
1382
1
1383
1
    // Verify the root's DFS In number. Although DFS numbering would also work
1384
1
    // if we started from some other value, we assume 0-based numbering.
1385
1
    if (Root->getDFSNumIn() != 0) {
1386
0
      errs() << "DFSIn number for the tree root is not:\n\t";
1387
0
      PrintNodeAndDFSNums(Root);
1388
0
      errs() << '\n';
1389
0
      errs().flush();
1390
0
      return false;
1391
0
    }
1392
1
1393
1
    // For each tree node verify if children's DFS numbers cover their parent's
1394
1
    // DFS numbers with no gaps.
1395
5
    
for (const auto &NodeToTN : DT.DomTreeNodes)1
{
1396
5
      const TreeNodePtr Node = NodeToTN.second.get();
1397
5
1398
5
      // Handle tree leaves.
1399
5
      if (Node->getChildren().empty()) {
1400
3
        if (Node->getDFSNumIn() + 1 != Node->getDFSNumOut()) {
1401
0
          errs() << "Tree leaf should have DFSOut = DFSIn + 1:\n\t";
1402
0
          PrintNodeAndDFSNums(Node);
1403
0
          errs() << '\n';
1404
0
          errs().flush();
1405
0
          return false;
1406
0
        }
1407
3
1408
3
        continue;
1409
3
      }
1410
2
1411
2
      // Make a copy and sort it such that it is possible to check if there are
1412
2
      // no gaps between DFS numbers of adjacent children.
1413
2
      SmallVector<TreeNodePtr, 8> Children(Node->begin(), Node->end());
1414
2
      llvm::sort(Children, [](const TreeNodePtr Ch1, const TreeNodePtr Ch2) {
1415
2
        return Ch1->getDFSNumIn() < Ch2->getDFSNumIn();
1416
2
      });
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) const
Line
Count
Source
1414
2
      llvm::sort(Children, [](const TreeNodePtr Ch1, const TreeNodePtr Ch2) {
1415
2
        return Ch1->getDFSNumIn() < Ch2->getDFSNumIn();
1416
2
      });
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) const
1417
2
1418
2
      auto PrintChildrenError = [Node, &Children, PrintNodeAndDFSNums](
1419
2
          const TreeNodePtr FirstCh, const TreeNodePtr SecondCh) {
1420
0
        assert(FirstCh);
1421
0
1422
0
        errs() << "Incorrect DFS numbers for:\n\tParent ";
1423
0
        PrintNodeAndDFSNums(Node);
1424
0
1425
0
        errs() << "\n\tChild ";
1426
0
        PrintNodeAndDFSNums(FirstCh);
1427
0
1428
0
        if (SecondCh) {
1429
0
          errs() << "\n\tSecond child ";
1430
0
          PrintNodeAndDFSNums(SecondCh);
1431
0
        }
1432
0
1433
0
        errs() << "\nAll children: ";
1434
0
        for (const TreeNodePtr Ch : Children) {
1435
0
          PrintNodeAndDFSNums(Ch);
1436
0
          errs() << ", ";
1437
0
        }
1438
0
1439
0
        errs() << '\n';
1440
0
        errs().flush();
1441
0
      };
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda0'(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda0'(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda0'(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda0'(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::operator()(llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) const
1442
2
1443
2
      if (Children.front()->getDFSNumIn() != Node->getDFSNumIn() + 1) {
1444
0
        PrintChildrenError(Children.front(), nullptr);
1445
0
        return false;
1446
0
      }
1447
2
1448
2
      if (Children.back()->getDFSNumOut() + 1 != Node->getDFSNumOut()) {
1449
0
        PrintChildrenError(Children.back(), nullptr);
1450
0
        return false;
1451
0
      }
1452
2
1453
4
      
for (size_t i = 0, e = Children.size() - 1; 2
i != e;
++i2
) {
1454
2
        if (Children[i]->getDFSNumOut() + 1 != Children[i + 1]->getDFSNumIn()) {
1455
0
          PrintChildrenError(Children[i], Children[i + 1]);
1456
0
          return false;
1457
0
        }
1458
2
      }
1459
2
    }
1460
1
1461
1
    return true;
1462
1
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)
Line
Count
Source
1371
367
  static bool VerifyDFSNumbers(const DomTreeT &DT) {
1372
367
    if (!DT.DFSInfoValid || 
!DT.Parent1
)
1373
366
      return true;
1374
1
1375
1
    const NodePtr RootBB = IsPostDom ? 
nullptr0
: DT.getRoots()[0];
1376
1
    const TreeNodePtr Root = DT.getNode(RootBB);
1377
1
1378
1
    auto PrintNodeAndDFSNums = [](const TreeNodePtr TN) {
1379
1
      errs() << BlockNamePrinter(TN) << " {" << TN->getDFSNumIn() << ", "
1380
1
             << TN->getDFSNumOut() << '}';
1381
1
    };
1382
1
1383
1
    // Verify the root's DFS In number. Although DFS numbering would also work
1384
1
    // if we started from some other value, we assume 0-based numbering.
1385
1
    if (Root->getDFSNumIn() != 0) {
1386
0
      errs() << "DFSIn number for the tree root is not:\n\t";
1387
0
      PrintNodeAndDFSNums(Root);
1388
0
      errs() << '\n';
1389
0
      errs().flush();
1390
0
      return false;
1391
0
    }
1392
1
1393
1
    // For each tree node verify if children's DFS numbers cover their parent's
1394
1
    // DFS numbers with no gaps.
1395
5
    
for (const auto &NodeToTN : DT.DomTreeNodes)1
{
1396
5
      const TreeNodePtr Node = NodeToTN.second.get();
1397
5
1398
5
      // Handle tree leaves.
1399
5
      if (Node->getChildren().empty()) {
1400
3
        if (Node->getDFSNumIn() + 1 != Node->getDFSNumOut()) {
1401
0
          errs() << "Tree leaf should have DFSOut = DFSIn + 1:\n\t";
1402
0
          PrintNodeAndDFSNums(Node);
1403
0
          errs() << '\n';
1404
0
          errs().flush();
1405
0
          return false;
1406
0
        }
1407
3
1408
3
        continue;
1409
3
      }
1410
2
1411
2
      // Make a copy and sort it such that it is possible to check if there are
1412
2
      // no gaps between DFS numbers of adjacent children.
1413
2
      SmallVector<TreeNodePtr, 8> Children(Node->begin(), Node->end());
1414
2
      llvm::sort(Children, [](const TreeNodePtr Ch1, const TreeNodePtr Ch2) {
1415
2
        return Ch1->getDFSNumIn() < Ch2->getDFSNumIn();
1416
2
      });
1417
2
1418
2
      auto PrintChildrenError = [Node, &Children, PrintNodeAndDFSNums](
1419
2
          const TreeNodePtr FirstCh, const TreeNodePtr SecondCh) {
1420
2
        assert(FirstCh);
1421
2
1422
2
        errs() << "Incorrect DFS numbers for:\n\tParent ";
1423
2
        PrintNodeAndDFSNums(Node);
1424
2
1425
2
        errs() << "\n\tChild ";
1426
2
        PrintNodeAndDFSNums(FirstCh);
1427
2
1428
2
        if (SecondCh) {
1429
2
          errs() << "\n\tSecond child ";
1430
2
          PrintNodeAndDFSNums(SecondCh);
1431
2
        }
1432
2
1433
2
        errs() << "\nAll children: ";
1434
2
        for (const TreeNodePtr Ch : Children) {
1435
2
          PrintNodeAndDFSNums(Ch);
1436
2
          errs() << ", ";
1437
2
        }
1438
2
1439
2
        errs() << '\n';
1440
2
        errs().flush();
1441
2
      };
1442
2
1443
2
      if (Children.front()->getDFSNumIn() != Node->getDFSNumIn() + 1) {
1444
0
        PrintChildrenError(Children.front(), nullptr);
1445
0
        return false;
1446
0
      }
1447
2
1448
2
      if (Children.back()->getDFSNumOut() + 1 != Node->getDFSNumOut()) {
1449
0
        PrintChildrenError(Children.back(), nullptr);
1450
0
        return false;
1451
0
      }
1452
2
1453
4
      
for (size_t i = 0, e = Children.size() - 1; 2
i != e;
++i2
) {
1454
2
        if (Children[i]->getDFSNumOut() + 1 != Children[i + 1]->getDFSNumIn()) {
1455
0
          PrintChildrenError(Children[i], Children[i + 1]);
1456
0
          return false;
1457
0
        }
1458
2
      }
1459
2
    }
1460
1
1461
1
    return true;
1462
1
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::VerifyDFSNumbers(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)
Line
Count
Source
1371
348
  static bool VerifyDFSNumbers(const DomTreeT &DT) {
1372
348
    if (!DT.DFSInfoValid || 
!DT.Parent0
)
1373
348
      return true;
1374
0
1375
0
    const NodePtr RootBB = IsPostDom ? nullptr : DT.getRoots()[0];
1376
0
    const TreeNodePtr Root = DT.getNode(RootBB);
1377
0
1378
0
    auto PrintNodeAndDFSNums = [](const TreeNodePtr TN) {
1379
0
      errs() << BlockNamePrinter(TN) << " {" << TN->getDFSNumIn() << ", "
1380
0
             << TN->getDFSNumOut() << '}';
1381
0
    };
1382
0
1383
0
    // Verify the root's DFS In number. Although DFS numbering would also work
1384
0
    // if we started from some other value, we assume 0-based numbering.
1385
0
    if (Root->getDFSNumIn() != 0) {
1386
0
      errs() << "DFSIn number for the tree root is not:\n\t";
1387
0
      PrintNodeAndDFSNums(Root);
1388
0
      errs() << '\n';
1389
0
      errs().flush();
1390
0
      return false;
1391
0
    }
1392
0
1393
0
    // For each tree node verify if children's DFS numbers cover their parent's
1394
0
    // DFS numbers with no gaps.
1395
0
    for (const auto &NodeToTN : DT.DomTreeNodes) {
1396
0
      const TreeNodePtr Node = NodeToTN.second.get();
1397
0
1398
0
      // Handle tree leaves.
1399
0
      if (Node->getChildren().empty()) {
1400
0
        if (Node->getDFSNumIn() + 1 != Node->getDFSNumOut()) {
1401
0
          errs() << "Tree leaf should have DFSOut = DFSIn + 1:\n\t";
1402
0
          PrintNodeAndDFSNums(Node);
1403
0
          errs() << '\n';
1404
0
          errs().flush();
1405
0
          return false;
1406
0
        }
1407
0
1408
0
        continue;
1409
0
      }
1410
0
1411
0
      // Make a copy and sort it such that it is possible to check if there are
1412
0
      // no gaps between DFS numbers of adjacent children.
1413
0
      SmallVector<TreeNodePtr, 8> Children(Node->begin(), Node->end());
1414
0
      llvm::sort(Children, [](const TreeNodePtr Ch1, const TreeNodePtr Ch2) {
1415
0
        return Ch1->getDFSNumIn() < Ch2->getDFSNumIn();
1416
0
      });
1417
0
1418
0
      auto PrintChildrenError = [Node, &Children, PrintNodeAndDFSNums](
1419
0
          const TreeNodePtr FirstCh, const TreeNodePtr SecondCh) {
1420
0
        assert(FirstCh);
1421
0
1422
0
        errs() << "Incorrect DFS numbers for:\n\tParent ";
1423
0
        PrintNodeAndDFSNums(Node);
1424
0
1425
0
        errs() << "\n\tChild ";
1426
0
        PrintNodeAndDFSNums(FirstCh);
1427
0
1428
0
        if (SecondCh) {
1429
0
          errs() << "\n\tSecond child ";
1430
0
          PrintNodeAndDFSNums(SecondCh);
1431
0
        }
1432
0
1433
0
        errs() << "\nAll children: ";
1434
0
        for (const TreeNodePtr Ch : Children) {
1435
0
          PrintNodeAndDFSNums(Ch);
1436
0
          errs() << ", ";
1437
0
        }
1438
0
1439
0
        errs() << '\n';
1440
0
        errs().flush();
1441
0
      };
1442
0
1443
0
      if (Children.front()->getDFSNumIn() != Node->getDFSNumIn() + 1) {
1444
0
        PrintChildrenError(Children.front(), nullptr);
1445
0
        return false;
1446
0
      }
1447
0
1448
0
      if (Children.back()->getDFSNumOut() + 1 != Node->getDFSNumOut()) {
1449
0
        PrintChildrenError(Children.back(), nullptr);
1450
0
        return false;
1451
0
      }
1452
0
1453
0
      for (size_t i = 0, e = Children.size() - 1; i != e; ++i) {
1454
0
        if (Children[i]->getDFSNumOut() + 1 != Children[i + 1]->getDFSNumIn()) {
1455
0
          PrintChildrenError(Children[i], Children[i + 1]);
1456
0
          return false;
1457
0
        }
1458
0
      }
1459
0
    }
1460
0
1461
0
    return true;
1462
0
  }
1463
1464
  // The below routines verify the correctness of the dominator tree relative to
1465
  // the CFG it's coming from.  A tree is a dominator tree iff it has two
1466
  // properties, called the parent property and the sibling property.  Tarjan
1467
  // and Lengauer prove (but don't explicitly name) the properties as part of
1468
  // the proofs in their 1972 paper, but the proofs are mostly part of proving
1469
  // things about semidominators and idoms, and some of them are simply asserted
1470
  // based on even earlier papers (see, e.g., lemma 2).  Some papers refer to
1471
  // these properties as "valid" and "co-valid".  See, e.g., "Dominators,
1472
  // directed bipolar orders, and independent spanning trees" by Loukas
1473
  // Georgiadis and Robert E. Tarjan, as well as "Dominator Tree Verification
1474
  // and Vertex-Disjoint Paths " by the same authors.
1475
1476
  // A very simple and direct explanation of these properties can be found in
1477
  // "An Experimental Study of Dynamic Dominators", found at
1478
  // https://arxiv.org/abs/1604.02711
1479
1480
  // The easiest way to think of the parent property is that it's a requirement
1481
  // of being a dominator.  Let's just take immediate dominators.  For PARENT to
1482
  // be an immediate dominator of CHILD, all paths in the CFG must go through
1483
  // PARENT before they hit CHILD.  This implies that if you were to cut PARENT
1484
  // out of the CFG, there should be no paths to CHILD that are reachable.  If
1485
  // there are, then you now have a path from PARENT to CHILD that goes around
1486
  // PARENT and still reaches CHILD, which by definition, means PARENT can't be
1487
  // a dominator of CHILD (let alone an immediate one).
1488
1489
  // The sibling property is similar.  It says that for each pair of sibling
1490
  // nodes in the dominator tree (LEFT and RIGHT) , they must not dominate each
1491
  // other.  If sibling LEFT dominated sibling RIGHT, it means there are no
1492
  // paths in the CFG from sibling LEFT to sibling RIGHT that do not go through
1493
  // LEFT, and thus, LEFT is really an ancestor (in the dominator tree) of
1494
  // RIGHT, not a sibling.
1495
1496
  // It is possible to verify the parent and sibling properties in
1497
  // linear time, but the algorithms are complex. Instead, we do it in a
1498
  // straightforward N^2 and N^3 way below, using direct path reachability.
1499
1500
  // Checks if the tree has the parent property: if for all edges from V to W in
1501
  // the input graph, such that V is reachable, the parent of W in the tree is
1502
  // an ancestor of V in the tree.
1503
  // Running time: O(N^2).
1504
  //
1505
  // This means that if a node gets disconnected from the graph, then all of
1506
  // the nodes it dominated previously will now become unreachable.
1507
715
  bool verifyParentProperty(const DomTreeT &DT) {
1508
6.68k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1509
6.68k
      const TreeNodePtr TN = NodeToTN.second.get();
1510
6.68k
      const NodePtr BB = TN->getBlock();
1511
6.68k
      if (!BB || 
TN->getChildren().empty()6.33k
)
continue3.24k
;
1512
3.44k
1513
3.44k
      LLVM_DEBUG(dbgs() << "Verifying parent property of node "
1514
3.44k
                        << BlockNamePrinter(TN) << "\n");
1515
3.44k
      clear();
1516
20.6k
      doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) {
1517
20.6k
        return From != BB && 
To != BB19.4k
;
1518
20.6k
      });
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
1516
8.06k
      doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) {
1517
8.06k
        return From != BB && 
To != BB7.67k
;
1518
8.06k
      });
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
1516
12.5k
      doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) {
1517
12.5k
        return From != BB && 
To != BB11.8k
;
1518
12.5k
      });
1519
3.44k
1520
3.44k
      for (TreeNodePtr Child : TN->getChildren())
1521
4.52k
        if (NodeToInfo.count(Child->getBlock()) != 0) {
1522
0
          errs() << "Child " << BlockNamePrinter(Child)
1523
0
                 << " reachable after its parent " << BlockNamePrinter(BB)
1524
0
                 << " is removed!\n";
1525
0
          errs().flush();
1526
0
1527
0
          return false;
1528
0
        }
1529
3.44k
    }
1530
715
1531
715
    return true;
1532
715
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)
Line
Count
Source
1507
367
  bool verifyParentProperty(const DomTreeT &DT) {
1508
2.83k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1509
2.83k
      const TreeNodePtr TN = NodeToTN.second.get();
1510
2.83k
      const NodePtr BB = TN->getBlock();
1511
2.83k
      if (!BB || TN->getChildren().empty()) 
continue1.09k
;
1512
1.73k
1513
1.73k
      LLVM_DEBUG(dbgs() << "Verifying parent property of node "
1514
1.73k
                        << BlockNamePrinter(TN) << "\n");
1515
1.73k
      clear();
1516
1.73k
      doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) {
1517
1.73k
        return From != BB && To != BB;
1518
1.73k
      });
1519
1.73k
1520
1.73k
      for (TreeNodePtr Child : TN->getChildren())
1521
2.46k
        if (NodeToInfo.count(Child->getBlock()) != 0) {
1522
0
          errs() << "Child " << BlockNamePrinter(Child)
1523
0
                 << " reachable after its parent " << BlockNamePrinter(BB)
1524
0
                 << " is removed!\n";
1525
0
          errs().flush();
1526
0
1527
0
          return false;
1528
0
        }
1529
1.73k
    }
1530
367
1531
367
    return true;
1532
367
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)
Line
Count
Source
1507
348
  bool verifyParentProperty(const DomTreeT &DT) {
1508
3.85k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1509
3.85k
      const TreeNodePtr TN = NodeToTN.second.get();
1510
3.85k
      const NodePtr BB = TN->getBlock();
1511
3.85k
      if (!BB || 
TN->getChildren().empty()3.50k
)
continue2.14k
;
1512
1.70k
1513
1.70k
      LLVM_DEBUG(dbgs() << "Verifying parent property of node "
1514
1.70k
                        << BlockNamePrinter(TN) << "\n");
1515
1.70k
      clear();
1516
1.70k
      doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) {
1517
1.70k
        return From != BB && To != BB;
1518
1.70k
      });
1519
1.70k
1520
1.70k
      for (TreeNodePtr Child : TN->getChildren())
1521
2.05k
        if (NodeToInfo.count(Child->getBlock()) != 0) {
1522
0
          errs() << "Child " << BlockNamePrinter(Child)
1523
0
                 << " reachable after its parent " << BlockNamePrinter(BB)
1524
0
                 << " is removed!\n";
1525
0
          errs().flush();
1526
0
1527
0
          return false;
1528
0
        }
1529
1.70k
    }
1530
348
1531
348
    return true;
1532
348
  }
1533
1534
  // Check if the tree has sibling property: if a node V does not dominate a
1535
  // node W for all siblings V and W in the tree.
1536
  // Running time: O(N^3).
1537
  //
1538
  // This means that if a node gets disconnected from the graph, then all of its
1539
  // siblings will now still be reachable.
1540
715
  bool verifySiblingProperty(const DomTreeT &DT) {
1541
6.68k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1542
6.68k
      const TreeNodePtr TN = NodeToTN.second.get();
1543
6.68k
      const NodePtr BB = TN->getBlock();
1544
6.68k
      if (!BB || 
TN->getChildren().empty()6.33k
)
continue3.24k
;
1545
3.44k
1546
3.44k
      const auto &Siblings = TN->getChildren();
1547
4.52k
      for (const TreeNodePtr N : Siblings) {
1548
4.52k
        clear();
1549
4.52k
        NodePtr BBN = N->getBlock();
1550
34.0k
        doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) {
1551
34.0k
          return From != BBN && To != BBN;
1552
34.0k
        });
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
1550
17.0k
        doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) {
1551
17.0k
          return From != BBN && To != BBN;
1552
17.0k
        });
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const
Line
Count
Source
1550
17.0k
        doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) {
1551
17.0k
          return From != BBN && To != BBN;
1552
17.0k
        });
1553
4.52k
1554
7.22k
        for (const TreeNodePtr S : Siblings) {
1555
7.22k
          if (S == N) 
continue4.52k
;
1556
2.70k
1557
2.70k
          if (NodeToInfo.count(S->getBlock()) == 0) {
1558
0
            errs() << "Node " << BlockNamePrinter(S)
1559
0
                   << " not reachable when its sibling " << BlockNamePrinter(N)
1560
0
                   << " is removed!\n";
1561
0
            errs().flush();
1562
0
1563
0
            return false;
1564
0
          }
1565
2.70k
        }
1566
4.52k
      }
1567
3.44k
    }
1568
715
1569
715
    return true;
1570
715
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)
Line
Count
Source
1540
367
  bool verifySiblingProperty(const DomTreeT &DT) {
1541
2.83k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1542
2.83k
      const TreeNodePtr TN = NodeToTN.second.get();
1543
2.83k
      const NodePtr BB = TN->getBlock();
1544
2.83k
      if (!BB || TN->getChildren().empty()) 
continue1.09k
;
1545
1.73k
1546
1.73k
      const auto &Siblings = TN->getChildren();
1547
2.46k
      for (const TreeNodePtr N : Siblings) {
1548
2.46k
        clear();
1549
2.46k
        NodePtr BBN = N->getBlock();
1550
2.46k
        doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) {
1551
2.46k
          return From != BBN && To != BBN;
1552
2.46k
        });
1553
2.46k
1554
4.40k
        for (const TreeNodePtr S : Siblings) {
1555
4.40k
          if (S == N) 
continue2.46k
;
1556
1.93k
1557
1.93k
          if (NodeToInfo.count(S->getBlock()) == 0) {
1558
0
            errs() << "Node " << BlockNamePrinter(S)
1559
0
                   << " not reachable when its sibling " << BlockNamePrinter(N)
1560
0
                   << " is removed!\n";
1561
0
            errs().flush();
1562
0
1563
0
            return false;
1564
0
          }
1565
1.93k
        }
1566
2.46k
      }
1567
1.73k
    }
1568
367
1569
367
    return true;
1570
367
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)
Line
Count
Source
1540
348
  bool verifySiblingProperty(const DomTreeT &DT) {
1541
3.85k
    for (auto &NodeToTN : DT.DomTreeNodes) {
1542
3.85k
      const TreeNodePtr TN = NodeToTN.second.get();
1543
3.85k
      const NodePtr BB = TN->getBlock();
1544
3.85k
      if (!BB || 
TN->getChildren().empty()3.50k
)
continue2.14k
;
1545
1.70k
1546
1.70k
      const auto &Siblings = TN->getChildren();
1547
2.05k
      for (const TreeNodePtr N : Siblings) {
1548
2.05k
        clear();
1549
2.05k
        NodePtr BBN = N->getBlock();
1550
2.05k
        doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) {
1551
2.05k
          return From != BBN && To != BBN;
1552
2.05k
        });
1553
2.05k
1554
2.82k
        for (const TreeNodePtr S : Siblings) {
1555
2.82k
          if (S == N) 
continue2.05k
;
1556
774
1557
774
          if (NodeToInfo.count(S->getBlock()) == 0) {
1558
0
            errs() << "Node " << BlockNamePrinter(S)
1559
0
                   << " not reachable when its sibling " << BlockNamePrinter(N)
1560
0
                   << " is removed!\n";
1561
0
            errs().flush();
1562
0
1563
0
            return false;
1564
0
          }
1565
774
        }
1566
2.05k
      }
1567
1.70k
    }
1568
348
1569
348
    return true;
1570
348
  }
1571
1572
  // Check if the given tree is the same as a freshly computed one for the same
1573
  // Parent.
1574
  // Running time: O(N^2), but faster in practise (same as tree construction).
1575
  //
1576
  // Note that this does not check if that the tree construction algorithm is
1577
  // correct and should be only used for fast (but possibly unsound)
1578
  // verification.
1579
717
  static bool IsSameAsFreshTree(const DomTreeT &DT) {
1580
717
    DomTreeT FreshTree;
1581
717
    FreshTree.recalculate(*DT.Parent);
1582
717
    const bool Different = DT.compare(FreshTree);
1583
717
1584
717
    if (Different) {
1585
2
      errs() << (DT.isPostDominator() ? 
"Post"1
:
""1
)
1586
2
             << "DominatorTree is different than a freshly computed one!\n"
1587
2
             << "\tCurrent:\n";
1588
2
      DT.print(errs());
1589
2
      errs() << "\n\tFreshly computed tree:\n";
1590
2
      FreshTree.print(errs());
1591
2
      errs().flush();
1592
2
    }
1593
717
1594
717
    return !Different;
1595
717
  }
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::IsSameAsFreshTree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::IsSameAsFreshTree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::IsSameAsFreshTree(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)
Line
Count
Source
1579
368
  static bool IsSameAsFreshTree(const DomTreeT &DT) {
1580
368
    DomTreeT FreshTree;
1581
368
    FreshTree.recalculate(*DT.Parent);
1582
368
    const bool Different = DT.compare(FreshTree);
1583
368
1584
368
    if (Different) {
1585
1
      errs() << (DT.isPostDominator() ? 
"Post"0
: "")
1586
1
             << "DominatorTree is different than a freshly computed one!\n"
1587
1
             << "\tCurrent:\n";
1588
1
      DT.print(errs());
1589
1
      errs() << "\n\tFreshly computed tree:\n";
1590
1
      FreshTree.print(errs());
1591
1
      errs().flush();
1592
1
    }
1593
368
1594
368
    return !Different;
1595
368
  }
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::IsSameAsFreshTree(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)
Line
Count
Source
1579
349
  static bool IsSameAsFreshTree(const DomTreeT &DT) {
1580
349
    DomTreeT FreshTree;
1581
349
    FreshTree.recalculate(*DT.Parent);
1582
349
    const bool Different = DT.compare(FreshTree);
1583
349
1584
349
    if (Different) {
1585
1
      errs() << (DT.isPostDominator() ? "Post" : 
""0
)
1586
1
             << "DominatorTree is different than a freshly computed one!\n"
1587
1
             << "\tCurrent:\n";
1588
1
      DT.print(errs());
1589
1
      errs() << "\n\tFreshly computed tree:\n";
1590
1
      FreshTree.print(errs());
1591
1
      errs().flush();
1592
1
    }
1593
349
1594
349
    return !Different;
1595
349
  }
1596
};
1597
1598
template <class DomTreeT>
1599
14.9M
void Calculate(DomTreeT &DT) {
1600
14.9M
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
1601
14.9M
}
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&)
Line
Count
Source
1599
2.61M
void Calculate(DomTreeT &DT) {
1600
2.61M
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
1601
2.61M
}
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&)
Line
Count
Source
1599
1.50M
void Calculate(DomTreeT &DT) {
1600
1.50M
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
1601
1.50M
}
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&)
Line
Count
Source
1599
10.2M
void Calculate(DomTreeT &DT) {
1600
10.2M
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
1601
10.2M
}
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&)
Line
Count
Source
1599
605k
void Calculate(DomTreeT &DT) {
1600
605k
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
1601
605k
}
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::VPBlockBase, false> >(llvm::DominatorTreeBase<llvm::VPBlockBase, false>&)
Line
Count
Source
1599
28
void Calculate(DomTreeT &DT) {
1600
28
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
1601
28
}
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<clang::CFGBlock, false> >(llvm::DominatorTreeBase<clang::CFGBlock, false>&)
Line
Count
Source
1599
8
void Calculate(DomTreeT &DT) {
1600
8
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
1601
8
}
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<clang::CFGBlock, true> >(llvm::DominatorTreeBase<clang::CFGBlock, true>&)
Line
Count
Source
1599
107
void Calculate(DomTreeT &DT) {
1600
107
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
1601
107
}
1602
1603
template <typename DomTreeT>
1604
void CalculateWithUpdates(DomTreeT &DT,
1605
52
                          ArrayRef<typename DomTreeT::UpdateType> Updates) {
1606
52
  // TODO: Move BUI creation in common method, reuse in ApplyUpdates.
1607
52
  typename SemiNCAInfo<DomTreeT>::BatchUpdateInfo BUI;
1608
52
  LLVM_DEBUG(dbgs() << "Legalizing " << BUI.Updates.size() << " updates\n");
1609
52
  cfg::LegalizeUpdates<typename DomTreeT::NodePtr>(Updates, BUI.Updates,
1610
52
                                                   DomTreeT::IsPostDominator);
1611
52
  const size_t NumLegalized = BUI.Updates.size();
1612
52
  BUI.FutureSuccessors.reserve(NumLegalized);
1613
52
  BUI.FuturePredecessors.reserve(NumLegalized);
1614
70
  for (auto &U : BUI.Updates) {
1615
70
    BUI.FutureSuccessors[U.getFrom()].push_back({U.getTo(), U.getKind()});
1616
70
    BUI.FuturePredecessors[U.getTo()].push_back({U.getFrom(), U.getKind()});
1617
70
  }
1618
52
1619
52
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, &BUI);
1620
52
}
Unexecuted instantiation: void llvm::DomTreeBuilder::CalculateWithUpdates<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::UpdateType>)
Unexecuted instantiation: void llvm::DomTreeBuilder::CalculateWithUpdates<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::UpdateType>)
void llvm::DomTreeBuilder::CalculateWithUpdates<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::BasicBlock, false>::UpdateType>)
Line
Count
Source
1605
52
                          ArrayRef<typename DomTreeT::UpdateType> Updates) {
1606
52
  // TODO: Move BUI creation in common method, reuse in ApplyUpdates.
1607
52
  typename SemiNCAInfo<DomTreeT>::BatchUpdateInfo BUI;
1608
52
  LLVM_DEBUG(dbgs() << "Legalizing " << BUI.Updates.size() << " updates\n");
1609
52
  cfg::LegalizeUpdates<typename DomTreeT::NodePtr>(Updates, BUI.Updates,
1610
52
                                                   DomTreeT::IsPostDominator);
1611
52
  const size_t NumLegalized = BUI.Updates.size();
1612
52
  BUI.FutureSuccessors.reserve(NumLegalized);
1613
52
  BUI.FuturePredecessors.reserve(NumLegalized);
1614
70
  for (auto &U : BUI.Updates) {
1615
70
    BUI.FutureSuccessors[U.getFrom()].push_back({U.getTo(), U.getKind()});
1616
70
    BUI.FuturePredecessors[U.getTo()].push_back({U.getFrom(), U.getKind()});
1617
70
  }
1618
52
1619
52
  SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, &BUI);
1620
52
}
Unexecuted instantiation: void llvm::DomTreeBuilder::CalculateWithUpdates<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::BasicBlock, true>::UpdateType>)
1621
1622
template <class DomTreeT>
1623
void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
1624
4.53k
                typename DomTreeT::NodePtr To) {
1625
4.53k
  if (DT.isPostDominator()) 
std::swap(From, To)142
;
1626
4.53k
  SemiNCAInfo<DomTreeT>::InsertEdge(DT, nullptr, From, To);
1627
4.53k
}
Unexecuted instantiation: void llvm::DomTreeBuilder::InsertEdge<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::NodePtr, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::NodePtr)
Unexecuted instantiation: void llvm::DomTreeBuilder::InsertEdge<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::NodePtr, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::NodePtr)
void llvm::DomTreeBuilder::InsertEdge<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DominatorTreeBase<llvm::BasicBlock, false>::NodePtr, llvm::DominatorTreeBase<llvm::BasicBlock, false>::NodePtr)
Line
Count
Source
1624
4.39k
                typename DomTreeT::NodePtr To) {
1625
4.39k
  if (DT.isPostDominator()) 
std::swap(From, To)0
;
1626
4.39k
  SemiNCAInfo<DomTreeT>::InsertEdge(DT, nullptr, From, To);
1627
4.39k
}
void llvm::DomTreeBuilder::InsertEdge<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DominatorTreeBase<llvm::BasicBlock, true>::NodePtr, llvm::DominatorTreeBase<llvm::BasicBlock, true>::NodePtr)
Line
Count
Source
1624
142
                typename DomTreeT::NodePtr To) {
1625
142
  if (DT.isPostDominator()) std::swap(From, To);
1626
142
  SemiNCAInfo<DomTreeT>::InsertEdge(DT, nullptr, From, To);
1627
142
}
1628
1629
template <class DomTreeT>
1630
void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
1631
12.9k
                typename DomTreeT::NodePtr To) {
1632
12.9k
  if (DT.isPostDominator()) 
std::swap(From, To)182
;
1633
12.9k
  SemiNCAInfo<DomTreeT>::DeleteEdge(DT, nullptr, From, To);
1634
12.9k
}
Unexecuted instantiation: void llvm::DomTreeBuilder::DeleteEdge<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::NodePtr, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::NodePtr)
Unexecuted instantiation: void llvm::DomTreeBuilder::DeleteEdge<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::NodePtr, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::NodePtr)
void llvm::DomTreeBuilder::DeleteEdge<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DominatorTreeBase<llvm::BasicBlock, false>::NodePtr, llvm::DominatorTreeBase<llvm::BasicBlock, false>::NodePtr)
Line
Count
Source
1631
12.7k
                typename DomTreeT::NodePtr To) {
1632
12.7k
  if (DT.isPostDominator()) 
std::swap(From, To)0
;
1633
12.7k
  SemiNCAInfo<DomTreeT>::DeleteEdge(DT, nullptr, From, To);
1634
12.7k
}
void llvm::DomTreeBuilder::DeleteEdge<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DominatorTreeBase<llvm::BasicBlock, true>::NodePtr, llvm::DominatorTreeBase<llvm::BasicBlock, true>::NodePtr)
Line
Count
Source
1631
182
                typename DomTreeT::NodePtr To) {
1632
182
  if (DT.isPostDominator()) std::swap(From, To);
1633
182
  SemiNCAInfo<DomTreeT>::DeleteEdge(DT, nullptr, From, To);
1634
182
}
1635
1636
template <class DomTreeT>
1637
void ApplyUpdates(DomTreeT &DT,
1638
521k
                  ArrayRef<typename DomTreeT::UpdateType> Updates) {
1639
521k
  SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, Updates);
1640
521k
}
Unexecuted instantiation: void llvm::DomTreeBuilder::ApplyUpdates<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::UpdateType>)
Unexecuted instantiation: void llvm::DomTreeBuilder::ApplyUpdates<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::UpdateType>)
void llvm::DomTreeBuilder::ApplyUpdates<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::BasicBlock, false>::UpdateType>)
Line
Count
Source
1638
521k
                  ArrayRef<typename DomTreeT::UpdateType> Updates) {
1639
521k
  SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, Updates);
1640
521k
}
void llvm::DomTreeBuilder::ApplyUpdates<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::BasicBlock, true>::UpdateType>)
Line
Count
Source
1638
326
                  ArrayRef<typename DomTreeT::UpdateType> Updates) {
1639
326
  SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, Updates);
1640
326
}
1641
1642
template <class DomTreeT>
1643
717
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL) {
1644
717
  SemiNCAInfo<DomTreeT> SNCA(nullptr);
1645
717
1646
717
  // Simplist check is to compare against a new tree. This will also
1647
717
  // usefully print the old and new trees, if they are different.
1648
717
  if (!SNCA.IsSameAsFreshTree(DT))
1649
2
    return false;
1650
715
1651
715
  // Common checks to verify the properties of the tree. O(N log N) at worst
1652
715
  if (!SNCA.verifyRoots(DT) || !SNCA.verifyReachability(DT) ||
1653
715
      !SNCA.VerifyLevels(DT) || !SNCA.VerifyDFSNumbers(DT))
1654
0
    return false;
1655
715
1656
715
  // Extra checks depending on VerificationLevel. Up to O(N^3)
1657
715
  if (VL == DomTreeT::VerificationLevel::Basic ||
1658
715
      VL == DomTreeT::VerificationLevel::Full)
1659
715
    if (!SNCA.verifyParentProperty(DT))
1660
0
      return false;
1661
715
  if (VL == DomTreeT::VerificationLevel::Full)
1662
715
    if (!SNCA.verifySiblingProperty(DT))
1663
0
      return false;
1664
715
1665
715
  return true;
1666
715
}
Unexecuted instantiation: bool llvm::DomTreeBuilder::Verify<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::VerificationLevel)
Unexecuted instantiation: bool llvm::DomTreeBuilder::Verify<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::VerificationLevel)
bool llvm::DomTreeBuilder::Verify<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DominatorTreeBase<llvm::BasicBlock, false>::VerificationLevel)
Line
Count
Source
1643
368
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL) {
1644
368
  SemiNCAInfo<DomTreeT> SNCA(nullptr);
1645
368
1646
368
  // Simplist check is to compare against a new tree. This will also
1647
368
  // usefully print the old and new trees, if they are different.
1648
368
  if (!SNCA.IsSameAsFreshTree(DT))
1649
1
    return false;
1650
367
1651
367
  // Common checks to verify the properties of the tree. O(N log N) at worst
1652
367
  if (!SNCA.verifyRoots(DT) || !SNCA.verifyReachability(DT) ||
1653
367
      !SNCA.VerifyLevels(DT) || !SNCA.VerifyDFSNumbers(DT))
1654
0
    return false;
1655
367
1656
367
  // Extra checks depending on VerificationLevel. Up to O(N^3)
1657
367
  if (VL == DomTreeT::VerificationLevel::Basic ||
1658
367
      VL == DomTreeT::VerificationLevel::Full)
1659
367
    if (!SNCA.verifyParentProperty(DT))
1660
0
      return false;
1661
367
  if (VL == DomTreeT::VerificationLevel::Full)
1662
367
    if (!SNCA.verifySiblingProperty(DT))
1663
0
      return false;
1664
367
1665
367
  return true;
1666
367
}
bool llvm::DomTreeBuilder::Verify<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DominatorTreeBase<llvm::BasicBlock, true>::VerificationLevel)
Line
Count
Source
1643
349
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL) {
1644
349
  SemiNCAInfo<DomTreeT> SNCA(nullptr);
1645
349
1646
349
  // Simplist check is to compare against a new tree. This will also
1647
349
  // usefully print the old and new trees, if they are different.
1648
349
  if (!SNCA.IsSameAsFreshTree(DT))
1649
1
    return false;
1650
348
1651
348
  // Common checks to verify the properties of the tree. O(N log N) at worst
1652
348
  if (!SNCA.verifyRoots(DT) || !SNCA.verifyReachability(DT) ||
1653
348
      !SNCA.VerifyLevels(DT) || !SNCA.VerifyDFSNumbers(DT))
1654
0
    return false;
1655
348
1656
348
  // Extra checks depending on VerificationLevel. Up to O(N^3)
1657
348
  if (VL == DomTreeT::VerificationLevel::Basic ||
1658
348
      VL == DomTreeT::VerificationLevel::Full)
1659
348
    if (!SNCA.verifyParentProperty(DT))
1660
0
      return false;
1661
348
  if (VL == DomTreeT::VerificationLevel::Full)
1662
348
    if (!SNCA.verifySiblingProperty(DT))
1663
0
      return false;
1664
348
1665
348
  return true;
1666
348
}
1667
1668
}  // namespace DomTreeBuilder
1669
}  // namespace llvm
1670
1671
#undef DEBUG_TYPE
1672
1673
#endif