33 #ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H 34 #define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H 45 #define DEBUG_TYPE "dom-tree-builder" 48 namespace DomTreeBuilder {
50 template <
typename DomTreeT>
55 using RootsT = decltype(DomTreeT::Roots);
56 static constexpr
bool IsPostDom = DomTreeT::IsPostDominator;
73 using UpdateT =
typename DomTreeT::UpdateType;
90 bool IsRecalculated =
false;
100 NumToNode = {
nullptr};
106 template <
bool Inverse>
111 auto RChildren =
reverse(children<NodePtr>(N));
112 return ResultTy(RChildren.begin(), RChildren.end());
116 auto IChildren = inverse_children<NodePtr>(
N);
117 return ResultTy(IChildren.begin(), IChildren.end());
120 using Tag = std::integral_constant<bool, Inverse>;
129 if (!BUI)
return Res;
136 auto FCIt = FutureChildren.find(N);
137 if (FCIt == FutureChildren.end())
return Res;
139 for (
auto ChildAndKind : FCIt->second) {
140 const NodePtr Child = ChildAndKind.getPointer();
144 if (UK == UpdateKind::Insert) {
148 &&
"Expected child not found in the CFG");
156 "Unexpected child found in the CFG");
168 auto InfoIt = NodeToInfo.
find(BB);
169 if (InfoIt == NodeToInfo.
end())
return nullptr;
171 return InfoIt->second.IDom;
175 if (
TreeNodePtr Node = DT.getNode(BB))
return Node;
181 assert(IDom || DT.DomTreeNodes[
nullptr]);
186 return (DT.DomTreeNodes[BB] = IDomNode->
addChild(
203 BP.
N->printAsOperand(O,
false);
216 template <
bool IsReverse = false,
typename DescendCondition>
218 unsigned AttachToNum) {
221 if (NodeToInfo.
count(V) != 0) NodeToInfo[V].
Parent = AttachToNum;
223 while (!WorkList.
empty()) {
225 auto &BBInfo = NodeToInfo[BB];
228 if (BBInfo.DFSNum != 0)
continue;
229 BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
231 NumToNode.push_back(BB);
233 constexpr
bool Direction = IsReverse !=
IsPostDom;
236 const auto SIT = NodeToInfo.
find(Succ);
239 if (SIT != NodeToInfo.
end() && SIT->second.DFSNum != 0) {
240 if (Succ != BB) SIT->second.ReverseChildren.push_back(BB);
244 if (!Condition(BB, Succ))
continue;
248 auto &SuccInfo = NodeToInfo[Succ];
250 SuccInfo.Parent = LastNum;
251 SuccInfo.ReverseChildren.push_back(BB);
259 auto &VInInfo = NodeToInfo[VIn];
260 if (VInInfo.DFSNum < LastLinked)
266 if (VInInfo.Parent >= LastLinked)
269 while (!Work.
empty()) {
271 auto &VInfo = NodeToInfo[V];
272 NodePtr VAncestor = NumToNode[VInfo.Parent];
275 if (Visited.
insert(VAncestor).second && VInfo.Parent >= LastLinked) {
282 if (VInfo.Parent < LastLinked)
285 auto &VAInfo = NodeToInfo[VAncestor];
286 NodePtr VAncestorLabel = VAInfo.Label;
288 if (NodeToInfo[VAncestorLabel].
Semi < NodeToInfo[VLabel].
Semi)
289 VInfo.Label = VAncestorLabel;
290 VInfo.Parent = VAInfo.Parent;
293 return VInInfo.Label;
298 const unsigned NextDFSNum(NumToNode.size());
300 for (
unsigned i = 1; i < NextDFSNum; ++i) {
301 const NodePtr V = NumToNode[i];
302 auto &VInfo = NodeToInfo[V];
303 VInfo.IDom = NumToNode[VInfo.Parent];
307 for (
unsigned i = NextDFSNum - 1; i >= 2; --i) {
309 auto &WInfo = NodeToInfo[
W];
312 WInfo.Semi = WInfo.Parent;
313 for (
const auto &
N : WInfo.ReverseChildren) {
314 if (NodeToInfo.
count(
N) == 0)
319 if (TN && TN->
getLevel() < MinLevel)
322 unsigned SemiU = NodeToInfo[
eval(
N, i + 1)].Semi;
323 if (SemiU < WInfo.Semi) WInfo.Semi = SemiU;
331 for (
unsigned i = 2; i < NextDFSNum; ++i) {
333 auto &WInfo = NodeToInfo[
W];
334 const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
335 NodePtr WIDomCandidate = WInfo.IDom;
336 while (NodeToInfo[WIDomCandidate].
DFSNum > SDomNum)
337 WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
339 WInfo.IDom = WIDomCandidate;
349 assert(IsPostDom &&
"Only postdominators have a virtual root");
350 assert(NumToNode.size() == 1 &&
"SNCAInfo must be freshly constructed");
352 auto &BBInfo = NodeToInfo[
nullptr];
353 BBInfo.DFSNum = BBInfo.Semi = 1;
354 BBInfo.Label =
nullptr;
356 NumToNode.push_back(
nullptr);
363 assert(N &&
"N must be a valid node");
368 assert(DT.Parent &&
"Parent not set");
376 assert(DT.Parent &&
"Parent pointer is not set");
388 SNCA.addVirtualRoot();
420 bool HasNonTrivialRoots =
false;
423 if (Total + 1 != Num) {
424 HasNonTrivialRoots =
true;
434 if (SNCA.NodeToInfo.count(
I) == 0) {
449 const unsigned NewNum = SNCA.runDFS<
true>(
I, Num,
AlwaysDescend, Num);
450 const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
452 <<
"(non-trivial root): " 454 ConnectToExitBlock.
insert(FurthestAway);
455 Roots.push_back(FurthestAway);
456 LLVM_DEBUG(
dbgs() <<
"\t\t\tPrev DFSNum: " << Num <<
", new DFSNum: " 457 << NewNum <<
"\n\t\t\tRemoving DFS info\n");
458 for (
unsigned i = NewNum; i > Num; --i) {
459 const NodePtr N = SNCA.NumToNode[i];
462 SNCA.NodeToInfo.erase(N);
463 SNCA.NumToNode.pop_back();
465 const unsigned PrevNum = Num;
467 Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
468 for (
unsigned i = PrevNum + 1; i <= Num; ++i)
475 LLVM_DEBUG(
dbgs() <<
"Total: " << Total <<
", Num: " << Num <<
"\n");
480 assert((Total + 1 == Num) &&
"Everything should have been visited");
504 assert(IsPostDom &&
"This function is for postdominators only");
509 for (
unsigned i = 0; i < Roots.size(); ++i) {
510 auto &Root = Roots[i];
514 <<
" remains a root\n");
517 const unsigned Num = SNCA.runDFS<
true>(Root, 0,
AlwaysDescend, 0);
520 for (
unsigned x = 2; x <= Num; ++x) {
521 const NodePtr N = SNCA.NumToNode[x];
541 template <
typename DescendCondition>
544 assert(DT.Roots.size() == 1 &&
"Dominators should have a singe root");
545 runDFS(DT.Roots[0], 0, DC, 0);
551 for (
const NodePtr Root : DT.Roots) Num =
runDFS(Root, Num, DC, 0);
570 dbgs() <<
"DomTree recalculated, skipping future batch updates\n");
573 if (DT.Roots.empty())
return;
578 NodePtr Root = IsPostDom ? nullptr : DT.Roots[0];
580 DT.RootNode = (DT.DomTreeNodes[Root] =
581 llvm::make_unique<DomTreeNodeBase<NodeT>>(Root,
nullptr))
583 SNCA.attachNewSubtree(DT, DT.RootNode);
588 NodeToInfo[NumToNode[1]].IDom = AttachTo->
getBlock();
590 for (
size_t i = 1, e = NumToNode.size(); i != e; ++i) {
596 if (DT.DomTreeNodes[W])
continue;
611 NodeToInfo[NumToNode[1]].IDom = AttachTo->
getBlock();
612 for (
size_t i = 1, e = NumToNode.size(); i != e; ++i) {
627 return First.first > Second.first;
631 std::priority_queue<BucketElementTy, SmallVector<BucketElementTy, 8>,
642 assert((From || IsPostDom) &&
643 "From has to be a valid CFG node or a virtual root");
644 assert(To &&
"Cannot be a nullptr");
651 if (!IsPostDom)
return;
659 DT.Roots.push_back(From);
662 DT.DFSInfoValid =
false;
676 assert(IsPostDom &&
"This function is only for postdominators");
679 if (!DT.isVirtualRoot(To->
getIDom()))
return false;
682 if (RIt == DT.Roots.end())
686 <<
" is no longer a root\n\t\tRebuilding the tree!!!\n");
696 assert(IsPostDom &&
"This function is only for postdominators");
706 if (DT.Roots.size() != Roots.size() ||
707 !std::is_permutation(DT.Roots.begin(), DT.Roots.end(), Roots.begin())) {
714 <<
"The entire tree needs to be rebuilt\n");
735 assert(NCDBlock || DT.isPostDominator());
744 if (NCD == To || NCD == ToIDom)
return;
749 <<
" as affected\n");
751 const unsigned ToLevel = To->
getLevel();
753 <<
" into a Bucket\n");
754 II.
Bucket.push({ToLevel, To});
756 while (!II.
Bucket.empty()) {
758 const unsigned CurrentLevel = CurrentNode->
getLevel();
763 II.
Visited.insert({CurrentNode, CurrentLevel});
778 const unsigned NCDLevel = NCD->
getLevel();
780 << RootLevel <<
"\n");
794 assert(SuccTN &&
"Unreachable successor found at reachable insertion");
795 const unsigned SuccLevel = SuccTN->
getLevel();
798 <<
", level = " << SuccLevel <<
"\n");
801 if (Processed.count(Next) > 0)
806 if (SuccLevel > RootLevel) {
808 if (II.
Visited.count(SuccTN) != 0) {
810 << II.
Visited[SuccTN] <<
"\n\t\t\tcurrent level " 811 << RootLevel <<
")\n");
815 if (II.
Visited[SuccTN] >= RootLevel)
821 II.
Visited.insert({SuccTN, RootLevel});
824 }
else if ((SuccLevel > NCDLevel + 1) &&
829 II.
Bucket.push({SuccLevel, SuccTN});
833 Processed.insert(Next);
834 }
while (!Stack.
empty());
854 dbgs() <<
"Updating levels for visited but not affected nodes\n");
881 for (
const auto &Edge : DiscoveredEdgesToReachable) {
894 &DiscoveredConnectingEdges) {
895 assert(!DT.getNode(Root) &&
"Root must not be reachable");
898 auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](
NodePtr From,
901 if (!ToTN)
return true;
903 DiscoveredConnectingEdges.push_back({
From, ToTN});
908 SNCA.runDFS(Root, 0, UnreachableDescender, 0);
910 SNCA.attachNewSubtree(DT, Incoming);
917 assert(From && To &&
"Cannot disconnect nullptrs");
925 auto IsSuccessor = [BUI](
const NodePtr SuccCandidate,
const NodePtr Of) {
927 return llvm::find(Successors, SuccCandidate) != Successors.end();
930 assert(!IsSuccessor(To, From) &&
"Deleted edge still exists in the CFG!");
941 <<
") already unreachable -- there is no edge to delete\n");
945 const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To);
950 DT.DFSInfoValid =
false;
979 assert(ToIDom || DT.isPostDominator());
985 if (!PrevIDomSubTree) {
992 const unsigned Level = ToIDomTN->getLevel();
994 return DT.getNode(To)->getLevel() >
Level;
1001 SNCA.runDFS(ToIDom, 0, DescendBelow, 0);
1003 SNCA.runSemiNCA(DT, Level);
1004 SNCA.reattachExistingSubtree(DT, PrevIDomSubTree);
1016 if (!DT.getNode(Pred))
continue;
1019 DT.findNearestCommonDominator(TN->
getBlock(), Pred);
1023 <<
" is reachable from support " 1045 LLVM_DEBUG(
dbgs() <<
"\tDeletion made a region reverse-unreachable\n");
1048 DT.Roots.push_back(ToTN->
getBlock());
1058 auto DescendAndCollect = [
Level, &AffectedQueue, &DT](
NodePtr, NodePtr To) {
1062 if (
llvm::find(AffectedQueue, To) == AffectedQueue.end())
1063 AffectedQueue.push_back(To);
1069 unsigned LastDFSNum =
1070 SNCA.runDFS(ToTN->
getBlock(), 0, DescendAndCollect, 0);
1076 for (
const NodePtr
N : AffectedQueue) {
1078 const NodePtr NCDBlock =
1080 assert(NCDBlock || DT.isPostDominator());
1099 for (
unsigned i = LastDFSNum; i > 0; --i) {
1100 const NodePtr
N = SNCA.NumToNode[i];
1108 if (MinNode == ToTN)
return;
1110 LLVM_DEBUG(
dbgs() <<
"DeleteUnreachable: running DFS with MinNode = " 1112 const unsigned MinLevel = MinNode->
getLevel();
1118 auto DescendBelow = [MinLevel, &DT](
NodePtr, NodePtr To) {
1120 return ToTN && ToTN->
getLevel() > MinLevel;
1122 SNCA.runDFS(MinNode->
getBlock(), 0, DescendBelow, 0);
1128 SNCA.runSemiNCA(DT, MinLevel);
1129 SNCA.reattachExistingSubtree(DT, PrevIDom);
1141 assert(ChIt != IDom->Children.end());
1142 std::swap(*ChIt, IDom->Children.back());
1143 IDom->Children.pop_back();
1145 DT.DomTreeNodes.erase(TN->
getBlock());
1153 const size_t NumUpdates = Updates.
size();
1154 if (NumUpdates == 0)
1159 if (NumUpdates == 1) {
1160 const auto &Update = Updates.
front();
1161 if (Update.getKind() == UpdateKind::Insert)
1162 DT.insertEdge(Update.getFrom(), Update.getTo());
1164 DT.deleteEdge(Update.getFrom(), Update.getTo());
1185 LLVM_DEBUG(
dbgs() <<
"About to apply " << NumLegalized <<
" updates\n");
1186 LLVM_DEBUG(
if (NumLegalized < 32)
for (
const auto &U
1202 if (DT.DomTreeNodes.size() <= 100) {
1203 if (NumLegalized > DT.DomTreeNodes.size())
1205 }
else if (NumLegalized > DT.DomTreeNodes.size() / 40)
1225 assert(FS.back().getPointer() == CurrentUpdate.getTo() &&
1226 FS.back().getInt() == CurrentUpdate.getKind());
1231 assert(
FP.back().getPointer() == CurrentUpdate.getFrom() &&
1232 FP.back().getInt() == CurrentUpdate.getKind());
1236 if (CurrentUpdate.getKind() == UpdateKind::Insert)
1237 InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1239 DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1252 if (!DT.Parent && !DT.Roots.empty()) {
1253 errs() <<
"Tree has no parent but has roots!\n";
1259 if (DT.Roots.empty()) {
1260 errs() <<
"Tree doesn't have a root!\n";
1266 errs() <<
"Tree's root is not its parent's entry node!\n";
1273 if (DT.Roots.size() != ComputedRoots.size() ||
1274 !std::is_permutation(DT.Roots.begin(), DT.Roots.end(),
1275 ComputedRoots.begin())) {
1276 errs() <<
"Tree has different roots than freshly computed ones!\n";
1277 errs() <<
"\tPDT roots: ";
1279 errs() <<
"\n\tComputed roots: ";
1280 for (
const NodePtr N : ComputedRoots)
1296 for (
auto &NodeToTN : DT.DomTreeNodes) {
1301 if (DT.isVirtualRoot(TN))
continue;
1303 if (NodeToInfo.
count(BB) == 0) {
1305 <<
" not found by DFS walk!\n";
1312 for (
const NodePtr N : NumToNode) {
1313 if (
N && !DT.getNode(
N)) {
1315 <<
" not found in the DomTree!\n";
1329 for (
auto &NodeToTN : DT.DomTreeNodes) {
1335 if (!IDom && TN->
getLevel() != 0) {
1337 <<
" has a nonzero level " << TN->
getLevel() <<
"!\n";
1345 << TN->
getLevel() <<
" while its IDom " 1361 if (!DT.DFSInfoValid || !DT.Parent)
1364 const NodePtr RootBB = IsPostDom ? nullptr : DT.getRoots()[0];
1367 auto PrintNodeAndDFSNums = [](
const TreeNodePtr TN) {
1369 << TN->getDFSNumOut() <<
'}';
1375 errs() <<
"DFSIn number for the tree root is not:\n\t";
1376 PrintNodeAndDFSNums(Root);
1384 for (
const auto &NodeToTN : DT.DomTreeNodes) {
1390 errs() <<
"Tree leaf should have DFSOut = DFSIn + 1:\n\t";
1391 PrintNodeAndDFSNums(Node);
1407 auto PrintChildrenError = [Node, &Children, PrintNodeAndDFSNums](
1411 errs() <<
"Incorrect DFS numbers for:\n\tParent ";
1412 PrintNodeAndDFSNums(Node);
1414 errs() <<
"\n\tChild ";
1415 PrintNodeAndDFSNums(FirstCh);
1418 errs() <<
"\n\tSecond child ";
1419 PrintNodeAndDFSNums(SecondCh);
1422 errs() <<
"\nAll children: ";
1424 PrintNodeAndDFSNums(Ch);
1432 if (Children.front()->getDFSNumIn() != Node->
getDFSNumIn() + 1) {
1433 PrintChildrenError(Children.front(),
nullptr);
1437 if (Children.back()->getDFSNumOut() + 1 != Node->
getDFSNumOut()) {
1438 PrintChildrenError(Children.back(),
nullptr);
1442 for (
size_t i = 0, e = Children.size() - 1; i != e; ++i) {
1443 if (Children[i]->getDFSNumOut() + 1 != Children[i + 1]->getDFSNumIn()) {
1444 PrintChildrenError(Children[i], Children[i + 1]);
1497 for (
auto &NodeToTN : DT.DomTreeNodes) {
1506 return From != BB && To != BB;
1510 if (NodeToInfo.
count(Child->getBlock()) != 0) {
1513 <<
" is removed!\n";
1530 for (
auto &NodeToTN : DT.DomTreeNodes) {
1540 return From != BBN && To != BBN;
1544 if (S ==
N)
continue;
1546 if (NodeToInfo.
count(S->getBlock()) == 0) {
1549 <<
" is removed!\n";
1570 FreshTree.recalculate(*DT.Parent);
1571 const bool Different = DT.compare(FreshTree);
1574 errs() << (DT.isPostDominator() ?
"Post" :
"")
1575 <<
"DominatorTree is different than a freshly computed one!\n" 1578 errs() <<
"\n\tFreshly computed tree:\n";
1579 FreshTree.print(
errs());
1587 template <
class DomTreeT>
1592 template <
typename DomTreeT>
1598 cfg::LegalizeUpdates<typename DomTreeT::NodePtr>(Updates, BUI.
Updates,
1599 DomTreeT::IsPostDominator);
1611 template <
class DomTreeT>
1614 if (DT.isPostDominator())
std::swap(From, To);
1618 template <
class DomTreeT>
1621 if (DT.isPostDominator())
std::swap(From, To);
1625 template <
class DomTreeT>
1631 template <
class DomTreeT>
1632 bool Verify(
const DomTreeT &DT,
typename DomTreeT::VerificationLevel VL) {
1637 if (!SNCA.IsSameAsFreshTree(DT))
1641 if (!SNCA.verifyRoots(DT) || !SNCA.verifyReachability(DT) ||
1642 !SNCA.VerifyLevels(DT) || !SNCA.VerifyDFSNumbers(DT))
1648 if (!SNCA.verifyParentProperty(DT))
1651 if (!SNCA.verifySiblingProperty(DT))
SmallDenseSet< TreeNodePtr, 8 > Affected
const T & front() const
front - Get the first element.
NodePtr getIDom(NodePtr BB) const
static void UpdateInsertion(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr NCD, InsertionInfo &II)
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
DenseMap< NodePtr, InfoRec > NodeToInfo
static void EraseNode(DomTreeT &DT, const TreeNodePtr TN)
This class represents lattice values for constants.
bool verifyReachability(const DomTreeT &DT)
std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
static void UpdateRootsAfterUpdate(DomTreeT &DT, const BatchUpdatePtr BUI)
void push_back(const T &Elt)
void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC)
SmallDenseMap< TreeNodePtr, unsigned, 8 > Visited
std::integral_constant< bool, Inverse > Tag
std::enable_if<!std::is_array< T >::value, std::unique_ptr< T > >::type make_unique(Args &&... args)
Constructs a new T() with the given args and returns a unique_ptr<T> which owns the object...
std::pair< unsigned, TreeNodePtr > BucketElementTy
SmallVector< UpdateT, 4 > Updates
std::priority_queue< BucketElementTy, SmallVector< BucketElementTy, 8 >, DecreasingLevel > Bucket
static bool VerifyLevels(const DomTreeT &DT)
NodeType
ISD::NodeType enum - This enum defines the target-independent operators for a SelectionDAG.
static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI)
decltype(DomTreeT::Roots) RootsT
NodePtr eval(NodePtr VIn, unsigned LastLinked)
void runSemiNCA(DomTreeT &DT, const unsigned MinLevel=0)
static ManagedStatic< DebugCounter > DC
static void RemoveRedundantRoots(const DomTreeT &DT, BatchUpdatePtr BUI, RootsT &Roots)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly...
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
static bool IsSameAsFreshTree(const DomTreeT &DT)
bool operator()(const BucketElementTy &First, const BucketElementTy &Second) const
static void DeleteEdge(DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr From, const NodePtr To)
Base class for the actual dominator tree node.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
const std::vector< DomTreeNodeBase * > & getChildren() const
static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI)
bool verifySiblingProperty(const DomTreeT &DT)
typename DomTreeT::NodePtr NodePtr
unsigned runDFS(NodePtr V, unsigned LastNum, DescendCondition Condition, unsigned AttachToNum)
iterator find(const_arg_type_t< KeyT > Val)
typename DomTreeT::UpdateKind UpdateKind
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree...
static ResultTy Get(NodePtr N, std::integral_constant< bool, true >)
typename DomTreeT::UpdateType UpdateT
PointerIntPair - This class implements a pair of a pointer and small integer.
std::shared_ptr< Node > NodePtr
Short-hand for a Node pointer.
size_t size() const
size - Get the array size.
DomTreeNodeBase * getIDom() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static ResultTy Get(NodePtr N, BatchUpdatePtr BUI)
static void UpdateLevelsAfterInsertion(InsertionInfo &II)
BlockNamePrinter(NodePtr Block)
static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI)
unsigned getDFSNumOut() const
iterator erase(const_iterator CI)
SmallVector< NodePtr, 2 > ReverseChildren
static void DeleteReachable(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr FromTN, const TreeNodePtr ToTN)
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
static bool UpdateRootsBeforeInsertion(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr From, const TreeNodePtr To)
void sort(IteratorTy Start, IteratorTy End)
static void ApplyUpdates(DomTreeT &DT, ArrayRef< UpdateT > Updates)
SmallVector< TreeNodePtr, 8 > AffectedQueue
bool verifyRoots(const DomTreeT &DT)
void CalculateWithUpdates(DomTreeT &DT, ArrayRef< typename DomTreeT::UpdateType > Updates)
typename DomTreeT::NodeType NodeT
bool verifyParentProperty(const DomTreeT &DT)
static void VisitInsertion(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr TN, const unsigned RootLevel, const TreeNodePtr NCD, InsertionInfo &II)
static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI)
static constexpr bool IsPostDom
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
BlockNamePrinter(TreeNodePtr TN)
BlockVerifier::State From
size_t getNumChildren() const
static bool HasProperSupport(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr TN)
LLVM_NODISCARD T pop_back_val()
static bool VerifyDFSNumbers(const DomTreeT &DT)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Implements a dense probed hash-table based set with some number of buckets stored inline...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static void DeleteUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr ToTN)
bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL)
static bool AlwaysDescend(NodePtr, NodePtr)
friend raw_ostream & operator<<(raw_ostream &O, const BlockNamePrinter &BP)
std::unique_ptr< DomTreeNodeBase > addChild(std::unique_ptr< DomTreeNodeBase > C)
SemiNCAInfo(BatchUpdatePtr BUI)
SmallVector< TreeNodePtr, 8 > VisitedNotAffectedQueue
void Calculate(DomTreeT &DT)
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
iterator_range< typename GraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
void attachNewSubtree(DomTreeT &DT, const TreeNodePtr AttachTo)
LLVM_NODISCARD bool empty() const
void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo)
static NodePtr GetEntryNode(const DomTreeT &DT)
static void InsertEdge(DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr From, const NodePtr To)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
static void InsertReachable(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr From, const TreeNodePtr To)
static void ComputeUnreachableDominators(DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr Root, const TreeNodePtr Incoming, SmallVectorImpl< std::pair< NodePtr, TreeNodePtr >> &DiscoveredConnectingEdges)
std::vector< NodePtr > NumToNode
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
unsigned getLevel() const
This file defines a set of templates that efficiently compute a dominator tree over a generic graph...
static void InsertUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr From, const NodePtr To)
TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT)
DenseMap< NodePtr, SmallVector< NodePtrAndKind, 4 > > FutureSuccessors
DenseMap< NodePtr, SmallVector< NodePtrAndKind, 4 > > FuturePredecessors
static ResultTy Get(NodePtr N, std::integral_constant< bool, false >)
BatchUpdateInfo * BatchUpdates
void setIDom(DomTreeNodeBase *NewIDom)