GenericDomTreeConstruction.h 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631
  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. /// [1] 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. /// that uses SLT to perform full constructions and SemiNCA for incremental
  25. /// updates.
  26. ///
  27. /// The file uses the Depth Based Search algorithm to perform incremental
  28. /// updates (insertion and deletions). The implemented algorithm is based on
  29. /// this publication:
  30. ///
  31. /// [2] An Experimental Study of Dynamic Dominators
  32. /// Loukas Georgiadis, et al., April 12 2016, pp. 5-7, 9-10:
  33. /// https://arxiv.org/pdf/1604.02711.pdf
  34. ///
  35. //===----------------------------------------------------------------------===//
  36. #ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
  37. #define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
  38. #include "llvm/ADT/ArrayRef.h"
  39. #include "llvm/ADT/DenseSet.h"
  40. #include "llvm/ADT/DepthFirstIterator.h"
  41. #include "llvm/ADT/PointerIntPair.h"
  42. #include "llvm/ADT/SmallPtrSet.h"
  43. #include "llvm/Support/Debug.h"
  44. #include "llvm/Support/GenericDomTree.h"
  45. #include <queue>
  46. #define DEBUG_TYPE "dom-tree-builder"
  47. namespace llvm {
  48. namespace DomTreeBuilder {
  49. template <typename DomTreeT>
  50. struct SemiNCAInfo {
  51. using NodePtr = typename DomTreeT::NodePtr;
  52. using NodeT = typename DomTreeT::NodeType;
  53. using TreeNodePtr = DomTreeNodeBase<NodeT> *;
  54. using RootsT = decltype(DomTreeT::Roots);
  55. static constexpr bool IsPostDom = DomTreeT::IsPostDominator;
  56. using GraphDiffT = GraphDiff<NodePtr, IsPostDom>;
  57. // Information record used by Semi-NCA during tree construction.
  58. struct InfoRec {
  59. unsigned DFSNum = 0;
  60. unsigned Parent = 0;
  61. unsigned Semi = 0;
  62. NodePtr Label = nullptr;
  63. NodePtr IDom = nullptr;
  64. SmallVector<NodePtr, 2> ReverseChildren;
  65. };
  66. // Number to node mapping is 1-based. Initialize the mapping to start with
  67. // a dummy element.
  68. std::vector<NodePtr> NumToNode = {nullptr};
  69. DenseMap<NodePtr, InfoRec> NodeToInfo;
  70. using UpdateT = typename DomTreeT::UpdateType;
  71. using UpdateKind = typename DomTreeT::UpdateKind;
  72. struct BatchUpdateInfo {
  73. // Note: Updates inside PreViewCFG are aleady legalized.
  74. BatchUpdateInfo(GraphDiffT &PreViewCFG, GraphDiffT *PostViewCFG = nullptr)
  75. : PreViewCFG(PreViewCFG), PostViewCFG(PostViewCFG),
  76. NumLegalized(PreViewCFG.getNumLegalizedUpdates()) {}
  77. // Remembers if the whole tree was recalculated at some point during the
  78. // current batch update.
  79. bool IsRecalculated = false;
  80. GraphDiffT &PreViewCFG;
  81. GraphDiffT *PostViewCFG;
  82. const size_t NumLegalized;
  83. };
  84. BatchUpdateInfo *BatchUpdates;
  85. using BatchUpdatePtr = BatchUpdateInfo *;
  86. // If BUI is a nullptr, then there's no batch update in progress.
  87. SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {}
  88. void clear() {
  89. NumToNode = {nullptr}; // Restore to initial state with a dummy start node.
  90. NodeToInfo.clear();
  91. // Don't reset the pointer to BatchUpdateInfo here -- if there's an update
  92. // in progress, we need this information to continue it.
  93. }
  94. template <bool Inversed>
  95. static SmallVector<NodePtr, 8> getChildren(NodePtr N, BatchUpdatePtr BUI) {
  96. if (BUI)
  97. return BUI->PreViewCFG.template getChildren<Inversed>(N);
  98. return getChildren<Inversed>(N);
  99. }
  100. template <bool Inversed>
  101. static SmallVector<NodePtr, 8> getChildren(NodePtr N) {
  102. using DirectedNodeT =
  103. std::conditional_t<Inversed, Inverse<NodePtr>, NodePtr>;
  104. auto R = children<DirectedNodeT>(N);
  105. SmallVector<NodePtr, 8> Res(detail::reverse_if<!Inversed>(R));
  106. // Remove nullptr children for clang.
  107. llvm::erase_value(Res, nullptr);
  108. return Res;
  109. }
  110. NodePtr getIDom(NodePtr BB) const {
  111. auto InfoIt = NodeToInfo.find(BB);
  112. if (InfoIt == NodeToInfo.end()) return nullptr;
  113. return InfoIt->second.IDom;
  114. }
  115. TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) {
  116. if (TreeNodePtr Node = DT.getNode(BB)) return Node;
  117. // Haven't calculated this node yet? Get or calculate the node for the
  118. // immediate dominator.
  119. NodePtr IDom = getIDom(BB);
  120. assert(IDom || DT.DomTreeNodes[nullptr]);
  121. TreeNodePtr IDomNode = getNodeForBlock(IDom, DT);
  122. // Add a new tree node for this NodeT, and link it as a child of
  123. // IDomNode
  124. return DT.createChild(BB, IDomNode);
  125. }
  126. static bool AlwaysDescend(NodePtr, NodePtr) { return true; }
  127. struct BlockNamePrinter {
  128. NodePtr N;
  129. BlockNamePrinter(NodePtr Block) : N(Block) {}
  130. BlockNamePrinter(TreeNodePtr TN) : N(TN ? TN->getBlock() : nullptr) {}
  131. friend raw_ostream &operator<<(raw_ostream &O, const BlockNamePrinter &BP) {
  132. if (!BP.N)
  133. O << "nullptr";
  134. else
  135. BP.N->printAsOperand(O, false);
  136. return O;
  137. }
  138. };
  139. using NodeOrderMap = DenseMap<NodePtr, unsigned>;
  140. // Custom DFS implementation which can skip nodes based on a provided
  141. // predicate. It also collects ReverseChildren so that we don't have to spend
  142. // time getting predecessors in SemiNCA.
  143. //
  144. // If IsReverse is set to true, the DFS walk will be performed backwards
  145. // relative to IsPostDom -- using reverse edges for dominators and forward
  146. // edges for postdominators.
  147. //
  148. // If SuccOrder is specified then in this order the DFS traverses the children
  149. // otherwise the order is implied by the results of getChildren().
  150. template <bool IsReverse = false, typename DescendCondition>
  151. unsigned runDFS(NodePtr V, unsigned LastNum, DescendCondition Condition,
  152. unsigned AttachToNum,
  153. const NodeOrderMap *SuccOrder = nullptr) {
  154. assert(V);
  155. SmallVector<NodePtr, 64> WorkList = {V};
  156. if (NodeToInfo.count(V) != 0) NodeToInfo[V].Parent = AttachToNum;
  157. while (!WorkList.empty()) {
  158. const NodePtr BB = WorkList.pop_back_val();
  159. auto &BBInfo = NodeToInfo[BB];
  160. // Visited nodes always have positive DFS numbers.
  161. if (BBInfo.DFSNum != 0) continue;
  162. BBInfo.DFSNum = BBInfo.Semi = ++LastNum;
  163. BBInfo.Label = BB;
  164. NumToNode.push_back(BB);
  165. constexpr bool Direction = IsReverse != IsPostDom; // XOR.
  166. auto Successors = getChildren<Direction>(BB, BatchUpdates);
  167. if (SuccOrder && Successors.size() > 1)
  168. llvm::sort(
  169. Successors.begin(), Successors.end(), [=](NodePtr A, NodePtr B) {
  170. return SuccOrder->find(A)->second < SuccOrder->find(B)->second;
  171. });
  172. for (const NodePtr Succ : Successors) {
  173. const auto SIT = NodeToInfo.find(Succ);
  174. // Don't visit nodes more than once but remember to collect
  175. // ReverseChildren.
  176. if (SIT != NodeToInfo.end() && SIT->second.DFSNum != 0) {
  177. if (Succ != BB) SIT->second.ReverseChildren.push_back(BB);
  178. continue;
  179. }
  180. if (!Condition(BB, Succ)) continue;
  181. // It's fine to add Succ to the map, because we know that it will be
  182. // visited later.
  183. auto &SuccInfo = NodeToInfo[Succ];
  184. WorkList.push_back(Succ);
  185. SuccInfo.Parent = LastNum;
  186. SuccInfo.ReverseChildren.push_back(BB);
  187. }
  188. }
  189. return LastNum;
  190. }
  191. // V is a predecessor of W. eval() returns V if V < W, otherwise the minimum
  192. // of sdom(U), where U > W and there is a virtual forest path from U to V. The
  193. // virtual forest consists of linked edges of processed vertices.
  194. //
  195. // We can follow Parent pointers (virtual forest edges) to determine the
  196. // ancestor U with minimum sdom(U). But it is slow and thus we employ the path
  197. // compression technique to speed up to O(m*log(n)). Theoretically the virtual
  198. // forest can be organized as balanced trees to achieve almost linear
  199. // O(m*alpha(m,n)) running time. But it requires two auxiliary arrays (Size
  200. // and Child) and is unlikely to be faster than the simple implementation.
  201. //
  202. // For each vertex V, its Label points to the vertex with the minimal sdom(U)
  203. // (Semi) in its path from V (included) to NodeToInfo[V].Parent (excluded).
  204. NodePtr eval(NodePtr V, unsigned LastLinked,
  205. SmallVectorImpl<InfoRec *> &Stack) {
  206. InfoRec *VInfo = &NodeToInfo[V];
  207. if (VInfo->Parent < LastLinked)
  208. return VInfo->Label;
  209. // Store ancestors except the last (root of a virtual tree) into a stack.
  210. assert(Stack.empty());
  211. do {
  212. Stack.push_back(VInfo);
  213. VInfo = &NodeToInfo[NumToNode[VInfo->Parent]];
  214. } while (VInfo->Parent >= LastLinked);
  215. // Path compression. Point each vertex's Parent to the root and update its
  216. // Label if any of its ancestors (PInfo->Label) has a smaller Semi.
  217. const InfoRec *PInfo = VInfo;
  218. const InfoRec *PLabelInfo = &NodeToInfo[PInfo->Label];
  219. do {
  220. VInfo = Stack.pop_back_val();
  221. VInfo->Parent = PInfo->Parent;
  222. const InfoRec *VLabelInfo = &NodeToInfo[VInfo->Label];
  223. if (PLabelInfo->Semi < VLabelInfo->Semi)
  224. VInfo->Label = PInfo->Label;
  225. else
  226. PLabelInfo = VLabelInfo;
  227. PInfo = VInfo;
  228. } while (!Stack.empty());
  229. return VInfo->Label;
  230. }
  231. // This function requires DFS to be run before calling it.
  232. void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) {
  233. const unsigned NextDFSNum(NumToNode.size());
  234. // Initialize IDoms to spanning tree parents.
  235. for (unsigned i = 1; i < NextDFSNum; ++i) {
  236. const NodePtr V = NumToNode[i];
  237. auto &VInfo = NodeToInfo[V];
  238. VInfo.IDom = NumToNode[VInfo.Parent];
  239. }
  240. // Step #1: Calculate the semidominators of all vertices.
  241. SmallVector<InfoRec *, 32> EvalStack;
  242. for (unsigned i = NextDFSNum - 1; i >= 2; --i) {
  243. NodePtr W = NumToNode[i];
  244. auto &WInfo = NodeToInfo[W];
  245. // Initialize the semi dominator to point to the parent node.
  246. WInfo.Semi = WInfo.Parent;
  247. for (const auto &N : WInfo.ReverseChildren) {
  248. if (NodeToInfo.count(N) == 0) // Skip unreachable predecessors.
  249. continue;
  250. const TreeNodePtr TN = DT.getNode(N);
  251. // Skip predecessors whose level is above the subtree we are processing.
  252. if (TN && TN->getLevel() < MinLevel)
  253. continue;
  254. unsigned SemiU = NodeToInfo[eval(N, i + 1, EvalStack)].Semi;
  255. if (SemiU < WInfo.Semi) WInfo.Semi = SemiU;
  256. }
  257. }
  258. // Step #2: Explicitly define the immediate dominator of each vertex.
  259. // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)).
  260. // Note that the parents were stored in IDoms and later got invalidated
  261. // during path compression in Eval.
  262. for (unsigned i = 2; i < NextDFSNum; ++i) {
  263. const NodePtr W = NumToNode[i];
  264. auto &WInfo = NodeToInfo[W];
  265. const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum;
  266. NodePtr WIDomCandidate = WInfo.IDom;
  267. while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
  268. WIDomCandidate = NodeToInfo[WIDomCandidate].IDom;
  269. WInfo.IDom = WIDomCandidate;
  270. }
  271. }
  272. // PostDominatorTree always has a virtual root that represents a virtual CFG
  273. // node that serves as a single exit from the function. All the other exits
  274. // (CFG nodes with terminators and nodes in infinite loops are logically
  275. // connected to this virtual CFG exit node).
  276. // This functions maps a nullptr CFG node to the virtual root tree node.
  277. void addVirtualRoot() {
  278. assert(IsPostDom && "Only postdominators have a virtual root");
  279. assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed");
  280. auto &BBInfo = NodeToInfo[nullptr];
  281. BBInfo.DFSNum = BBInfo.Semi = 1;
  282. BBInfo.Label = nullptr;
  283. NumToNode.push_back(nullptr); // NumToNode[1] = nullptr;
  284. }
  285. // For postdominators, nodes with no forward successors are trivial roots that
  286. // are always selected as tree roots. Roots with forward successors correspond
  287. // to CFG nodes within infinite loops.
  288. static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) {
  289. assert(N && "N must be a valid node");
  290. return !getChildren<false>(N, BUI).empty();
  291. }
  292. static NodePtr GetEntryNode(const DomTreeT &DT) {
  293. assert(DT.Parent && "Parent not set");
  294. return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent);
  295. }
  296. // Finds all roots without relaying on the set of roots already stored in the
  297. // tree.
  298. // We define roots to be some non-redundant set of the CFG nodes
  299. static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) {
  300. assert(DT.Parent && "Parent pointer is not set");
  301. RootsT Roots;
  302. // For dominators, function entry CFG node is always a tree root node.
  303. if (!IsPostDom) {
  304. Roots.push_back(GetEntryNode(DT));
  305. return Roots;
  306. }
  307. SemiNCAInfo SNCA(BUI);
  308. // PostDominatorTree always has a virtual root.
  309. SNCA.addVirtualRoot();
  310. unsigned Num = 1;
  311. LLVM_DEBUG(dbgs() << "\t\tLooking for trivial roots\n");
  312. // Step #1: Find all the trivial roots that are going to will definitely
  313. // remain tree roots.
  314. unsigned Total = 0;
  315. // It may happen that there are some new nodes in the CFG that are result of
  316. // the ongoing batch update, but we cannot really pretend that they don't
  317. // exist -- we won't see any outgoing or incoming edges to them, so it's
  318. // fine to discover them here, as they would end up appearing in the CFG at
  319. // some point anyway.
  320. for (const NodePtr N : nodes(DT.Parent)) {
  321. ++Total;
  322. // If it has no *successors*, it is definitely a root.
  323. if (!HasForwardSuccessors(N, BUI)) {
  324. Roots.push_back(N);
  325. // Run DFS not to walk this part of CFG later.
  326. Num = SNCA.runDFS(N, Num, AlwaysDescend, 1);
  327. LLVM_DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N)
  328. << "\n");
  329. LLVM_DEBUG(dbgs() << "Last visited node: "
  330. << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n");
  331. }
  332. }
  333. LLVM_DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n");
  334. // Step #2: Find all non-trivial root candidates. Those are CFG nodes that
  335. // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG
  336. // nodes in infinite loops).
  337. bool HasNonTrivialRoots = false;
  338. // Accounting for the virtual exit, see if we had any reverse-unreachable
  339. // nodes.
  340. if (Total + 1 != Num) {
  341. HasNonTrivialRoots = true;
  342. // SuccOrder is the order of blocks in the function. It is needed to make
  343. // the calculation of the FurthestAway node and the whole PostDomTree
  344. // immune to swap successors transformation (e.g. canonicalizing branch
  345. // predicates). SuccOrder is initialized lazily only for successors of
  346. // reverse unreachable nodes.
  347. Optional<NodeOrderMap> SuccOrder;
  348. auto InitSuccOrderOnce = [&]() {
  349. SuccOrder = NodeOrderMap();
  350. for (const auto Node : nodes(DT.Parent))
  351. if (SNCA.NodeToInfo.count(Node) == 0)
  352. for (const auto Succ : getChildren<false>(Node, SNCA.BatchUpdates))
  353. SuccOrder->try_emplace(Succ, 0);
  354. // Add mapping for all entries of SuccOrder.
  355. unsigned NodeNum = 0;
  356. for (const auto Node : nodes(DT.Parent)) {
  357. ++NodeNum;
  358. auto Order = SuccOrder->find(Node);
  359. if (Order != SuccOrder->end()) {
  360. assert(Order->second == 0);
  361. Order->second = NodeNum;
  362. }
  363. }
  364. };
  365. // Make another DFS pass over all other nodes to find the
  366. // reverse-unreachable blocks, and find the furthest paths we'll be able
  367. // to make.
  368. // Note that this looks N^2, but it's really 2N worst case, if every node
  369. // is unreachable. This is because we are still going to only visit each
  370. // unreachable node once, we may just visit it in two directions,
  371. // depending on how lucky we get.
  372. SmallPtrSet<NodePtr, 4> ConnectToExitBlock;
  373. for (const NodePtr I : nodes(DT.Parent)) {
  374. if (SNCA.NodeToInfo.count(I) == 0) {
  375. LLVM_DEBUG(dbgs()
  376. << "\t\t\tVisiting node " << BlockNamePrinter(I) << "\n");
  377. // Find the furthest away we can get by following successors, then
  378. // follow them in reverse. This gives us some reasonable answer about
  379. // the post-dom tree inside any infinite loop. In particular, it
  380. // guarantees we get to the farthest away point along *some*
  381. // path. This also matches the GCC's behavior.
  382. // If we really wanted a totally complete picture of dominance inside
  383. // this infinite loop, we could do it with SCC-like algorithms to find
  384. // the lowest and highest points in the infinite loop. In theory, it
  385. // would be nice to give the canonical backedge for the loop, but it's
  386. // expensive and does not always lead to a minimal set of roots.
  387. LLVM_DEBUG(dbgs() << "\t\t\tRunning forward DFS\n");
  388. if (!SuccOrder)
  389. InitSuccOrderOnce();
  390. assert(SuccOrder);
  391. const unsigned NewNum =
  392. SNCA.runDFS<true>(I, Num, AlwaysDescend, Num, &*SuccOrder);
  393. const NodePtr FurthestAway = SNCA.NumToNode[NewNum];
  394. LLVM_DEBUG(dbgs() << "\t\t\tFound a new furthest away node "
  395. << "(non-trivial root): "
  396. << BlockNamePrinter(FurthestAway) << "\n");
  397. ConnectToExitBlock.insert(FurthestAway);
  398. Roots.push_back(FurthestAway);
  399. LLVM_DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: "
  400. << NewNum << "\n\t\t\tRemoving DFS info\n");
  401. for (unsigned i = NewNum; i > Num; --i) {
  402. const NodePtr N = SNCA.NumToNode[i];
  403. LLVM_DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for "
  404. << BlockNamePrinter(N) << "\n");
  405. SNCA.NodeToInfo.erase(N);
  406. SNCA.NumToNode.pop_back();
  407. }
  408. const unsigned PrevNum = Num;
  409. LLVM_DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n");
  410. Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1);
  411. for (unsigned i = PrevNum + 1; i <= Num; ++i)
  412. LLVM_DEBUG(dbgs() << "\t\t\t\tfound node "
  413. << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
  414. }
  415. }
  416. }
  417. LLVM_DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n");
  418. LLVM_DEBUG(dbgs() << "Discovered CFG nodes:\n");
  419. LLVM_DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs()
  420. << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n");
  421. assert((Total + 1 == Num) && "Everything should have been visited");
  422. // Step #3: If we found some non-trivial roots, make them non-redundant.
  423. if (HasNonTrivialRoots) RemoveRedundantRoots(DT, BUI, Roots);
  424. LLVM_DEBUG(dbgs() << "Found roots: ");
  425. LLVM_DEBUG(for (auto *Root
  426. : Roots) dbgs()
  427. << BlockNamePrinter(Root) << " ");
  428. LLVM_DEBUG(dbgs() << "\n");
  429. return Roots;
  430. }
  431. // This function only makes sense for postdominators.
  432. // We define roots to be some set of CFG nodes where (reverse) DFS walks have
  433. // to start in order to visit all the CFG nodes (including the
  434. // reverse-unreachable ones).
  435. // When the search for non-trivial roots is done it may happen that some of
  436. // the non-trivial roots are reverse-reachable from other non-trivial roots,
  437. // which makes them redundant. This function removes them from the set of
  438. // input roots.
  439. static void RemoveRedundantRoots(const DomTreeT &DT, BatchUpdatePtr BUI,
  440. RootsT &Roots) {
  441. assert(IsPostDom && "This function is for postdominators only");
  442. LLVM_DEBUG(dbgs() << "Removing redundant roots\n");
  443. SemiNCAInfo SNCA(BUI);
  444. for (unsigned i = 0; i < Roots.size(); ++i) {
  445. auto &Root = Roots[i];
  446. // Trivial roots are always non-redundant.
  447. if (!HasForwardSuccessors(Root, BUI)) continue;
  448. LLVM_DEBUG(dbgs() << "\tChecking if " << BlockNamePrinter(Root)
  449. << " remains a root\n");
  450. SNCA.clear();
  451. // Do a forward walk looking for the other roots.
  452. const unsigned Num = SNCA.runDFS<true>(Root, 0, AlwaysDescend, 0);
  453. // Skip the start node and begin from the second one (note that DFS uses
  454. // 1-based indexing).
  455. for (unsigned x = 2; x <= Num; ++x) {
  456. const NodePtr N = SNCA.NumToNode[x];
  457. // If we wound another root in a (forward) DFS walk, remove the current
  458. // root from the set of roots, as it is reverse-reachable from the other
  459. // one.
  460. if (llvm::is_contained(Roots, N)) {
  461. LLVM_DEBUG(dbgs() << "\tForward DFS walk found another root "
  462. << BlockNamePrinter(N) << "\n\tRemoving root "
  463. << BlockNamePrinter(Root) << "\n");
  464. std::swap(Root, Roots.back());
  465. Roots.pop_back();
  466. // Root at the back takes the current root's place.
  467. // Start the next loop iteration with the same index.
  468. --i;
  469. break;
  470. }
  471. }
  472. }
  473. }
  474. template <typename DescendCondition>
  475. void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) {
  476. if (!IsPostDom) {
  477. assert(DT.Roots.size() == 1 && "Dominators should have a singe root");
  478. runDFS(DT.Roots[0], 0, DC, 0);
  479. return;
  480. }
  481. addVirtualRoot();
  482. unsigned Num = 1;
  483. for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0);
  484. }
  485. static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) {
  486. auto *Parent = DT.Parent;
  487. DT.reset();
  488. DT.Parent = Parent;
  489. // If the update is using the actual CFG, BUI is null. If it's using a view,
  490. // BUI is non-null and the PreCFGView is used. When calculating from
  491. // scratch, make the PreViewCFG equal to the PostCFGView, so Post is used.
  492. BatchUpdatePtr PostViewBUI = nullptr;
  493. if (BUI && BUI->PostViewCFG) {
  494. BUI->PreViewCFG = *BUI->PostViewCFG;
  495. PostViewBUI = BUI;
  496. }
  497. // This is rebuilding the whole tree, not incrementally, but PostViewBUI is
  498. // used in case the caller needs a DT update with a CFGView.
  499. SemiNCAInfo SNCA(PostViewBUI);
  500. // Step #0: Number blocks in depth-first order and initialize variables used
  501. // in later stages of the algorithm.
  502. DT.Roots = FindRoots(DT, PostViewBUI);
  503. SNCA.doFullDFSWalk(DT, AlwaysDescend);
  504. SNCA.runSemiNCA(DT);
  505. if (BUI) {
  506. BUI->IsRecalculated = true;
  507. LLVM_DEBUG(
  508. dbgs() << "DomTree recalculated, skipping future batch updates\n");
  509. }
  510. if (DT.Roots.empty()) return;
  511. // Add a node for the root. If the tree is a PostDominatorTree it will be
  512. // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates
  513. // all real exits (including multiple exit blocks, infinite loops).
  514. NodePtr Root = IsPostDom ? nullptr : DT.Roots[0];
  515. DT.RootNode = DT.createNode(Root);
  516. SNCA.attachNewSubtree(DT, DT.RootNode);
  517. }
  518. void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) {
  519. // Attach the first unreachable block to AttachTo.
  520. NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
  521. // Loop over all of the discovered blocks in the function...
  522. for (size_t i = 1, e = NumToNode.size(); i != e; ++i) {
  523. NodePtr W = NumToNode[i];
  524. // Don't replace this with 'count', the insertion side effect is important
  525. if (DT.DomTreeNodes[W]) continue; // Haven't calculated this node yet?
  526. NodePtr ImmDom = getIDom(W);
  527. // Get or calculate the node for the immediate dominator.
  528. TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT);
  529. // Add a new tree node for this BasicBlock, and link it as a child of
  530. // IDomNode.
  531. DT.createChild(W, IDomNode);
  532. }
  533. }
  534. void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) {
  535. NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock();
  536. for (size_t i = 1, e = NumToNode.size(); i != e; ++i) {
  537. const NodePtr N = NumToNode[i];
  538. const TreeNodePtr TN = DT.getNode(N);
  539. assert(TN);
  540. const TreeNodePtr NewIDom = DT.getNode(NodeToInfo[N].IDom);
  541. TN->setIDom(NewIDom);
  542. }
  543. }
  544. // Helper struct used during edge insertions.
  545. struct InsertionInfo {
  546. struct Compare {
  547. bool operator()(TreeNodePtr LHS, TreeNodePtr RHS) const {
  548. return LHS->getLevel() < RHS->getLevel();
  549. }
  550. };
  551. // Bucket queue of tree nodes ordered by descending level. For simplicity,
  552. // we use a priority_queue here.
  553. std::priority_queue<TreeNodePtr, SmallVector<TreeNodePtr, 8>,
  554. Compare>
  555. Bucket;
  556. SmallDenseSet<TreeNodePtr, 8> Visited;
  557. SmallVector<TreeNodePtr, 8> Affected;
  558. #ifndef NDEBUG
  559. SmallVector<TreeNodePtr, 8> VisitedUnaffected;
  560. #endif
  561. };
  562. static void InsertEdge(DomTreeT &DT, const BatchUpdatePtr BUI,
  563. const NodePtr From, const NodePtr To) {
  564. assert((From || IsPostDom) &&
  565. "From has to be a valid CFG node or a virtual root");
  566. assert(To && "Cannot be a nullptr");
  567. LLVM_DEBUG(dbgs() << "Inserting edge " << BlockNamePrinter(From) << " -> "
  568. << BlockNamePrinter(To) << "\n");
  569. TreeNodePtr FromTN = DT.getNode(From);
  570. if (!FromTN) {
  571. // Ignore edges from unreachable nodes for (forward) dominators.
  572. if (!IsPostDom) return;
  573. // The unreachable node becomes a new root -- a tree node for it.
  574. TreeNodePtr VirtualRoot = DT.getNode(nullptr);
  575. FromTN = DT.createChild(From, VirtualRoot);
  576. DT.Roots.push_back(From);
  577. }
  578. DT.DFSInfoValid = false;
  579. const TreeNodePtr ToTN = DT.getNode(To);
  580. if (!ToTN)
  581. InsertUnreachable(DT, BUI, FromTN, To);
  582. else
  583. InsertReachable(DT, BUI, FromTN, ToTN);
  584. }
  585. // Determines if some existing root becomes reverse-reachable after the
  586. // insertion. Rebuilds the whole tree if that situation happens.
  587. static bool UpdateRootsBeforeInsertion(DomTreeT &DT, const BatchUpdatePtr BUI,
  588. const TreeNodePtr From,
  589. const TreeNodePtr To) {
  590. assert(IsPostDom && "This function is only for postdominators");
  591. // Destination node is not attached to the virtual root, so it cannot be a
  592. // root.
  593. if (!DT.isVirtualRoot(To->getIDom())) return false;
  594. if (!llvm::is_contained(DT.Roots, To->getBlock()))
  595. return false; // To is not a root, nothing to update.
  596. LLVM_DEBUG(dbgs() << "\t\tAfter the insertion, " << BlockNamePrinter(To)
  597. << " is no longer a root\n\t\tRebuilding the tree!!!\n");
  598. CalculateFromScratch(DT, BUI);
  599. return true;
  600. }
  601. static bool isPermutation(const SmallVectorImpl<NodePtr> &A,
  602. const SmallVectorImpl<NodePtr> &B) {
  603. if (A.size() != B.size())
  604. return false;
  605. SmallPtrSet<NodePtr, 4> Set(A.begin(), A.end());
  606. for (NodePtr N : B)
  607. if (Set.count(N) == 0)
  608. return false;
  609. return true;
  610. }
  611. // Updates the set of roots after insertion or deletion. This ensures that
  612. // roots are the same when after a series of updates and when the tree would
  613. // be built from scratch.
  614. static void UpdateRootsAfterUpdate(DomTreeT &DT, const BatchUpdatePtr BUI) {
  615. assert(IsPostDom && "This function is only for postdominators");
  616. // The tree has only trivial roots -- nothing to update.
  617. if (std::none_of(DT.Roots.begin(), DT.Roots.end(), [BUI](const NodePtr N) {
  618. return HasForwardSuccessors(N, BUI);
  619. }))
  620. return;
  621. // Recalculate the set of roots.
  622. RootsT Roots = FindRoots(DT, BUI);
  623. if (!isPermutation(DT.Roots, Roots)) {
  624. // The roots chosen in the CFG have changed. This is because the
  625. // incremental algorithm does not really know or use the set of roots and
  626. // can make a different (implicit) decision about which node within an
  627. // infinite loop becomes a root.
  628. LLVM_DEBUG(dbgs() << "Roots are different in updated trees\n"
  629. << "The entire tree needs to be rebuilt\n");
  630. // It may be possible to update the tree without recalculating it, but
  631. // we do not know yet how to do it, and it happens rarely in practice.
  632. CalculateFromScratch(DT, BUI);
  633. }
  634. }
  635. // Handles insertion to a node already in the dominator tree.
  636. static void InsertReachable(DomTreeT &DT, const BatchUpdatePtr BUI,
  637. const TreeNodePtr From, const TreeNodePtr To) {
  638. LLVM_DEBUG(dbgs() << "\tReachable " << BlockNamePrinter(From->getBlock())
  639. << " -> " << BlockNamePrinter(To->getBlock()) << "\n");
  640. if (IsPostDom && UpdateRootsBeforeInsertion(DT, BUI, From, To)) return;
  641. // DT.findNCD expects both pointers to be valid. When From is a virtual
  642. // root, then its CFG block pointer is a nullptr, so we have to 'compute'
  643. // the NCD manually.
  644. const NodePtr NCDBlock =
  645. (From->getBlock() && To->getBlock())
  646. ? DT.findNearestCommonDominator(From->getBlock(), To->getBlock())
  647. : nullptr;
  648. assert(NCDBlock || DT.isPostDominator());
  649. const TreeNodePtr NCD = DT.getNode(NCDBlock);
  650. assert(NCD);
  651. LLVM_DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n");
  652. const unsigned NCDLevel = NCD->getLevel();
  653. // Based on Lemma 2.5 from [2], after insertion of (From,To), v is affected
  654. // iff depth(NCD)+1 < depth(v) && a path P from To to v exists where every
  655. // w on P s.t. depth(v) <= depth(w)
  656. //
  657. // This reduces to a widest path problem (maximizing the depth of the
  658. // minimum vertex in the path) which can be solved by a modified version of
  659. // Dijkstra with a bucket queue (named depth-based search in [2]).
  660. // To is in the path, so depth(NCD)+1 < depth(v) <= depth(To). Nothing
  661. // affected if this does not hold.
  662. if (NCDLevel + 1 >= To->getLevel())
  663. return;
  664. InsertionInfo II;
  665. SmallVector<TreeNodePtr, 8> UnaffectedOnCurrentLevel;
  666. II.Bucket.push(To);
  667. II.Visited.insert(To);
  668. while (!II.Bucket.empty()) {
  669. TreeNodePtr TN = II.Bucket.top();
  670. II.Bucket.pop();
  671. II.Affected.push_back(TN);
  672. const unsigned CurrentLevel = TN->getLevel();
  673. LLVM_DEBUG(dbgs() << "Mark " << BlockNamePrinter(TN) <<
  674. "as affected, CurrentLevel " << CurrentLevel << "\n");
  675. assert(TN->getBlock() && II.Visited.count(TN) && "Preconditions!");
  676. while (true) {
  677. // Unlike regular Dijkstra, we have an inner loop to expand more
  678. // vertices. The first iteration is for the (affected) vertex popped
  679. // from II.Bucket and the rest are for vertices in
  680. // UnaffectedOnCurrentLevel, which may eventually expand to affected
  681. // vertices.
  682. //
  683. // Invariant: there is an optimal path from `To` to TN with the minimum
  684. // depth being CurrentLevel.
  685. for (const NodePtr Succ : getChildren<IsPostDom>(TN->getBlock(), BUI)) {
  686. const TreeNodePtr SuccTN = DT.getNode(Succ);
  687. assert(SuccTN &&
  688. "Unreachable successor found at reachable insertion");
  689. const unsigned SuccLevel = SuccTN->getLevel();
  690. LLVM_DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ)
  691. << ", level = " << SuccLevel << "\n");
  692. // There is an optimal path from `To` to Succ with the minimum depth
  693. // being min(CurrentLevel, SuccLevel).
  694. //
  695. // If depth(NCD)+1 < depth(Succ) is not satisfied, Succ is unaffected
  696. // and no affected vertex may be reached by a path passing through it.
  697. // Stop here. Also, Succ may be visited by other predecessors but the
  698. // first visit has the optimal path. Stop if Succ has been visited.
  699. if (SuccLevel <= NCDLevel + 1 || !II.Visited.insert(SuccTN).second)
  700. continue;
  701. if (SuccLevel > CurrentLevel) {
  702. // Succ is unaffected but it may (transitively) expand to affected
  703. // vertices. Store it in UnaffectedOnCurrentLevel.
  704. LLVM_DEBUG(dbgs() << "\t\tMarking visited not affected "
  705. << BlockNamePrinter(Succ) << "\n");
  706. UnaffectedOnCurrentLevel.push_back(SuccTN);
  707. #ifndef NDEBUG
  708. II.VisitedUnaffected.push_back(SuccTN);
  709. #endif
  710. } else {
  711. // The condition is satisfied (Succ is affected). Add Succ to the
  712. // bucket queue.
  713. LLVM_DEBUG(dbgs() << "\t\tAdd " << BlockNamePrinter(Succ)
  714. << " to a Bucket\n");
  715. II.Bucket.push(SuccTN);
  716. }
  717. }
  718. if (UnaffectedOnCurrentLevel.empty())
  719. break;
  720. TN = UnaffectedOnCurrentLevel.pop_back_val();
  721. LLVM_DEBUG(dbgs() << " Next: " << BlockNamePrinter(TN) << "\n");
  722. }
  723. }
  724. // Finish by updating immediate dominators and levels.
  725. UpdateInsertion(DT, BUI, NCD, II);
  726. }
  727. // Updates immediate dominators and levels after insertion.
  728. static void UpdateInsertion(DomTreeT &DT, const BatchUpdatePtr BUI,
  729. const TreeNodePtr NCD, InsertionInfo &II) {
  730. LLVM_DEBUG(dbgs() << "Updating NCD = " << BlockNamePrinter(NCD) << "\n");
  731. for (const TreeNodePtr TN : II.Affected) {
  732. LLVM_DEBUG(dbgs() << "\tIDom(" << BlockNamePrinter(TN)
  733. << ") = " << BlockNamePrinter(NCD) << "\n");
  734. TN->setIDom(NCD);
  735. }
  736. #ifndef NDEBUG
  737. for (const TreeNodePtr TN : II.VisitedUnaffected)
  738. assert(TN->getLevel() == TN->getIDom()->getLevel() + 1 &&
  739. "TN should have been updated by an affected ancestor");
  740. #endif
  741. if (IsPostDom) UpdateRootsAfterUpdate(DT, BUI);
  742. }
  743. // Handles insertion to previously unreachable nodes.
  744. static void InsertUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI,
  745. const TreeNodePtr From, const NodePtr To) {
  746. LLVM_DEBUG(dbgs() << "Inserting " << BlockNamePrinter(From)
  747. << " -> (unreachable) " << BlockNamePrinter(To) << "\n");
  748. // Collect discovered edges to already reachable nodes.
  749. SmallVector<std::pair<NodePtr, TreeNodePtr>, 8> DiscoveredEdgesToReachable;
  750. // Discover and connect nodes that became reachable with the insertion.
  751. ComputeUnreachableDominators(DT, BUI, To, From, DiscoveredEdgesToReachable);
  752. LLVM_DEBUG(dbgs() << "Inserted " << BlockNamePrinter(From)
  753. << " -> (prev unreachable) " << BlockNamePrinter(To)
  754. << "\n");
  755. // Used the discovered edges and inset discovered connecting (incoming)
  756. // edges.
  757. for (const auto &Edge : DiscoveredEdgesToReachable) {
  758. LLVM_DEBUG(dbgs() << "\tInserting discovered connecting edge "
  759. << BlockNamePrinter(Edge.first) << " -> "
  760. << BlockNamePrinter(Edge.second) << "\n");
  761. InsertReachable(DT, BUI, DT.getNode(Edge.first), Edge.second);
  762. }
  763. }
  764. // Connects nodes that become reachable with an insertion.
  765. static void ComputeUnreachableDominators(
  766. DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr Root,
  767. const TreeNodePtr Incoming,
  768. SmallVectorImpl<std::pair<NodePtr, TreeNodePtr>>
  769. &DiscoveredConnectingEdges) {
  770. assert(!DT.getNode(Root) && "Root must not be reachable");
  771. // Visit only previously unreachable nodes.
  772. auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](NodePtr From,
  773. NodePtr To) {
  774. const TreeNodePtr ToTN = DT.getNode(To);
  775. if (!ToTN) return true;
  776. DiscoveredConnectingEdges.push_back({From, ToTN});
  777. return false;
  778. };
  779. SemiNCAInfo SNCA(BUI);
  780. SNCA.runDFS(Root, 0, UnreachableDescender, 0);
  781. SNCA.runSemiNCA(DT);
  782. SNCA.attachNewSubtree(DT, Incoming);
  783. LLVM_DEBUG(dbgs() << "After adding unreachable nodes\n");
  784. }
  785. static void DeleteEdge(DomTreeT &DT, const BatchUpdatePtr BUI,
  786. const NodePtr From, const NodePtr To) {
  787. assert(From && To && "Cannot disconnect nullptrs");
  788. LLVM_DEBUG(dbgs() << "Deleting edge " << BlockNamePrinter(From) << " -> "
  789. << BlockNamePrinter(To) << "\n");
  790. #ifndef NDEBUG
  791. // Ensure that the edge was in fact deleted from the CFG before informing
  792. // the DomTree about it.
  793. // The check is O(N), so run it only in debug configuration.
  794. auto IsSuccessor = [BUI](const NodePtr SuccCandidate, const NodePtr Of) {
  795. auto Successors = getChildren<IsPostDom>(Of, BUI);
  796. return llvm::is_contained(Successors, SuccCandidate);
  797. };
  798. (void)IsSuccessor;
  799. assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!");
  800. #endif
  801. const TreeNodePtr FromTN = DT.getNode(From);
  802. // Deletion in an unreachable subtree -- nothing to do.
  803. if (!FromTN) return;
  804. const TreeNodePtr ToTN = DT.getNode(To);
  805. if (!ToTN) {
  806. LLVM_DEBUG(
  807. dbgs() << "\tTo (" << BlockNamePrinter(To)
  808. << ") already unreachable -- there is no edge to delete\n");
  809. return;
  810. }
  811. const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To);
  812. const TreeNodePtr NCD = DT.getNode(NCDBlock);
  813. // If To dominates From -- nothing to do.
  814. if (ToTN != NCD) {
  815. DT.DFSInfoValid = false;
  816. const TreeNodePtr ToIDom = ToTN->getIDom();
  817. LLVM_DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom "
  818. << BlockNamePrinter(ToIDom) << "\n");
  819. // To remains reachable after deletion.
  820. // (Based on the caption under Figure 4. from [2].)
  821. if (FromTN != ToIDom || HasProperSupport(DT, BUI, ToTN))
  822. DeleteReachable(DT, BUI, FromTN, ToTN);
  823. else
  824. DeleteUnreachable(DT, BUI, ToTN);
  825. }
  826. if (IsPostDom) UpdateRootsAfterUpdate(DT, BUI);
  827. }
  828. // Handles deletions that leave destination nodes reachable.
  829. static void DeleteReachable(DomTreeT &DT, const BatchUpdatePtr BUI,
  830. const TreeNodePtr FromTN,
  831. const TreeNodePtr ToTN) {
  832. LLVM_DEBUG(dbgs() << "Deleting reachable " << BlockNamePrinter(FromTN)
  833. << " -> " << BlockNamePrinter(ToTN) << "\n");
  834. LLVM_DEBUG(dbgs() << "\tRebuilding subtree\n");
  835. // Find the top of the subtree that needs to be rebuilt.
  836. // (Based on the lemma 2.6 from [2].)
  837. const NodePtr ToIDom =
  838. DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock());
  839. assert(ToIDom || DT.isPostDominator());
  840. const TreeNodePtr ToIDomTN = DT.getNode(ToIDom);
  841. assert(ToIDomTN);
  842. const TreeNodePtr PrevIDomSubTree = ToIDomTN->getIDom();
  843. // Top of the subtree to rebuild is the root node. Rebuild the tree from
  844. // scratch.
  845. if (!PrevIDomSubTree) {
  846. LLVM_DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
  847. CalculateFromScratch(DT, BUI);
  848. return;
  849. }
  850. // Only visit nodes in the subtree starting at To.
  851. const unsigned Level = ToIDomTN->getLevel();
  852. auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) {
  853. return DT.getNode(To)->getLevel() > Level;
  854. };
  855. LLVM_DEBUG(dbgs() << "\tTop of subtree: " << BlockNamePrinter(ToIDomTN)
  856. << "\n");
  857. SemiNCAInfo SNCA(BUI);
  858. SNCA.runDFS(ToIDom, 0, DescendBelow, 0);
  859. LLVM_DEBUG(dbgs() << "\tRunning Semi-NCA\n");
  860. SNCA.runSemiNCA(DT, Level);
  861. SNCA.reattachExistingSubtree(DT, PrevIDomSubTree);
  862. }
  863. // Checks if a node has proper support, as defined on the page 3 and later
  864. // explained on the page 7 of [2].
  865. static bool HasProperSupport(DomTreeT &DT, const BatchUpdatePtr BUI,
  866. const TreeNodePtr TN) {
  867. LLVM_DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN)
  868. << "\n");
  869. auto TNB = TN->getBlock();
  870. for (const NodePtr Pred : getChildren<!IsPostDom>(TNB, BUI)) {
  871. LLVM_DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n");
  872. if (!DT.getNode(Pred)) continue;
  873. const NodePtr Support = DT.findNearestCommonDominator(TNB, Pred);
  874. LLVM_DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n");
  875. if (Support != TNB) {
  876. LLVM_DEBUG(dbgs() << "\t" << BlockNamePrinter(TN)
  877. << " is reachable from support "
  878. << BlockNamePrinter(Support) << "\n");
  879. return true;
  880. }
  881. }
  882. return false;
  883. }
  884. // Handle deletions that make destination node unreachable.
  885. // (Based on the lemma 2.7 from the [2].)
  886. static void DeleteUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI,
  887. const TreeNodePtr ToTN) {
  888. LLVM_DEBUG(dbgs() << "Deleting unreachable subtree "
  889. << BlockNamePrinter(ToTN) << "\n");
  890. assert(ToTN);
  891. assert(ToTN->getBlock());
  892. if (IsPostDom) {
  893. // Deletion makes a region reverse-unreachable and creates a new root.
  894. // Simulate that by inserting an edge from the virtual root to ToTN and
  895. // adding it as a new root.
  896. LLVM_DEBUG(dbgs() << "\tDeletion made a region reverse-unreachable\n");
  897. LLVM_DEBUG(dbgs() << "\tAdding new root " << BlockNamePrinter(ToTN)
  898. << "\n");
  899. DT.Roots.push_back(ToTN->getBlock());
  900. InsertReachable(DT, BUI, DT.getNode(nullptr), ToTN);
  901. return;
  902. }
  903. SmallVector<NodePtr, 16> AffectedQueue;
  904. const unsigned Level = ToTN->getLevel();
  905. // Traverse destination node's descendants with greater level in the tree
  906. // and collect visited nodes.
  907. auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) {
  908. const TreeNodePtr TN = DT.getNode(To);
  909. assert(TN);
  910. if (TN->getLevel() > Level) return true;
  911. if (!llvm::is_contained(AffectedQueue, To))
  912. AffectedQueue.push_back(To);
  913. return false;
  914. };
  915. SemiNCAInfo SNCA(BUI);
  916. unsigned LastDFSNum =
  917. SNCA.runDFS(ToTN->getBlock(), 0, DescendAndCollect, 0);
  918. TreeNodePtr MinNode = ToTN;
  919. // Identify the top of the subtree to rebuild by finding the NCD of all
  920. // the affected nodes.
  921. for (const NodePtr N : AffectedQueue) {
  922. const TreeNodePtr TN = DT.getNode(N);
  923. const NodePtr NCDBlock =
  924. DT.findNearestCommonDominator(TN->getBlock(), ToTN->getBlock());
  925. assert(NCDBlock || DT.isPostDominator());
  926. const TreeNodePtr NCD = DT.getNode(NCDBlock);
  927. assert(NCD);
  928. LLVM_DEBUG(dbgs() << "Processing affected node " << BlockNamePrinter(TN)
  929. << " with NCD = " << BlockNamePrinter(NCD)
  930. << ", MinNode =" << BlockNamePrinter(MinNode) << "\n");
  931. if (NCD != TN && NCD->getLevel() < MinNode->getLevel()) MinNode = NCD;
  932. }
  933. // Root reached, rebuild the whole tree from scratch.
  934. if (!MinNode->getIDom()) {
  935. LLVM_DEBUG(dbgs() << "The entire tree needs to be rebuilt\n");
  936. CalculateFromScratch(DT, BUI);
  937. return;
  938. }
  939. // Erase the unreachable subtree in reverse preorder to process all children
  940. // before deleting their parent.
  941. for (unsigned i = LastDFSNum; i > 0; --i) {
  942. const NodePtr N = SNCA.NumToNode[i];
  943. const TreeNodePtr TN = DT.getNode(N);
  944. LLVM_DEBUG(dbgs() << "Erasing node " << BlockNamePrinter(TN) << "\n");
  945. EraseNode(DT, TN);
  946. }
  947. // The affected subtree start at the To node -- there's no extra work to do.
  948. if (MinNode == ToTN) return;
  949. LLVM_DEBUG(dbgs() << "DeleteUnreachable: running DFS with MinNode = "
  950. << BlockNamePrinter(MinNode) << "\n");
  951. const unsigned MinLevel = MinNode->getLevel();
  952. const TreeNodePtr PrevIDom = MinNode->getIDom();
  953. assert(PrevIDom);
  954. SNCA.clear();
  955. // Identify nodes that remain in the affected subtree.
  956. auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) {
  957. const TreeNodePtr ToTN = DT.getNode(To);
  958. return ToTN && ToTN->getLevel() > MinLevel;
  959. };
  960. SNCA.runDFS(MinNode->getBlock(), 0, DescendBelow, 0);
  961. LLVM_DEBUG(dbgs() << "Previous IDom(MinNode) = "
  962. << BlockNamePrinter(PrevIDom) << "\nRunning Semi-NCA\n");
  963. // Rebuild the remaining part of affected subtree.
  964. SNCA.runSemiNCA(DT, MinLevel);
  965. SNCA.reattachExistingSubtree(DT, PrevIDom);
  966. }
  967. // Removes leaf tree nodes from the dominator tree.
  968. static void EraseNode(DomTreeT &DT, const TreeNodePtr TN) {
  969. assert(TN);
  970. assert(TN->getNumChildren() == 0 && "Not a tree leaf");
  971. const TreeNodePtr IDom = TN->getIDom();
  972. assert(IDom);
  973. auto ChIt = llvm::find(IDom->Children, TN);
  974. assert(ChIt != IDom->Children.end());
  975. std::swap(*ChIt, IDom->Children.back());
  976. IDom->Children.pop_back();
  977. DT.DomTreeNodes.erase(TN->getBlock());
  978. }
  979. //~~
  980. //===--------------------- DomTree Batch Updater --------------------------===
  981. //~~
  982. static void ApplyUpdates(DomTreeT &DT, GraphDiffT &PreViewCFG,
  983. GraphDiffT *PostViewCFG) {
  984. // Note: the PostViewCFG is only used when computing from scratch. It's data
  985. // should already included in the PreViewCFG for incremental updates.
  986. const size_t NumUpdates = PreViewCFG.getNumLegalizedUpdates();
  987. if (NumUpdates == 0)
  988. return;
  989. // Take the fast path for a single update and avoid running the batch update
  990. // machinery.
  991. if (NumUpdates == 1) {
  992. UpdateT Update = PreViewCFG.popUpdateForIncrementalUpdates();
  993. if (!PostViewCFG) {
  994. if (Update.getKind() == UpdateKind::Insert)
  995. InsertEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
  996. else
  997. DeleteEdge(DT, /*BUI=*/nullptr, Update.getFrom(), Update.getTo());
  998. } else {
  999. BatchUpdateInfo BUI(*PostViewCFG, PostViewCFG);
  1000. if (Update.getKind() == UpdateKind::Insert)
  1001. InsertEdge(DT, &BUI, Update.getFrom(), Update.getTo());
  1002. else
  1003. DeleteEdge(DT, &BUI, Update.getFrom(), Update.getTo());
  1004. }
  1005. return;
  1006. }
  1007. BatchUpdateInfo BUI(PreViewCFG, PostViewCFG);
  1008. // Recalculate the DominatorTree when the number of updates
  1009. // exceeds a threshold, which usually makes direct updating slower than
  1010. // recalculation. We select this threshold proportional to the
  1011. // size of the DominatorTree. The constant is selected
  1012. // by choosing the one with an acceptable performance on some real-world
  1013. // inputs.
  1014. // Make unittests of the incremental algorithm work
  1015. if (DT.DomTreeNodes.size() <= 100) {
  1016. if (BUI.NumLegalized > DT.DomTreeNodes.size())
  1017. CalculateFromScratch(DT, &BUI);
  1018. } else if (BUI.NumLegalized > DT.DomTreeNodes.size() / 40)
  1019. CalculateFromScratch(DT, &BUI);
  1020. // If the DominatorTree was recalculated at some point, stop the batch
  1021. // updates. Full recalculations ignore batch updates and look at the actual
  1022. // CFG.
  1023. for (size_t i = 0; i < BUI.NumLegalized && !BUI.IsRecalculated; ++i)
  1024. ApplyNextUpdate(DT, BUI);
  1025. }
  1026. static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) {
  1027. // Popping the next update, will move the PreViewCFG to the next snapshot.
  1028. UpdateT CurrentUpdate = BUI.PreViewCFG.popUpdateForIncrementalUpdates();
  1029. #if 0
  1030. // FIXME: The LLVM_DEBUG macro only plays well with a modular
  1031. // build of LLVM when the header is marked as textual, but doing
  1032. // so causes redefinition errors.
  1033. LLVM_DEBUG(dbgs() << "Applying update: ");
  1034. LLVM_DEBUG(CurrentUpdate.dump(); dbgs() << "\n");
  1035. #endif
  1036. if (CurrentUpdate.getKind() == UpdateKind::Insert)
  1037. InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
  1038. else
  1039. DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
  1040. }
  1041. //~~
  1042. //===--------------- DomTree correctness verification ---------------------===
  1043. //~~
  1044. // Check if the tree has correct roots. A DominatorTree always has a single
  1045. // root which is the function's entry node. A PostDominatorTree can have
  1046. // multiple roots - one for each node with no successors and for infinite
  1047. // loops.
  1048. // Running time: O(N).
  1049. bool verifyRoots(const DomTreeT &DT) {
  1050. if (!DT.Parent && !DT.Roots.empty()) {
  1051. errs() << "Tree has no parent but has roots!\n";
  1052. errs().flush();
  1053. return false;
  1054. }
  1055. if (!IsPostDom) {
  1056. if (DT.Roots.empty()) {
  1057. errs() << "Tree doesn't have a root!\n";
  1058. errs().flush();
  1059. return false;
  1060. }
  1061. if (DT.getRoot() != GetEntryNode(DT)) {
  1062. errs() << "Tree's root is not its parent's entry node!\n";
  1063. errs().flush();
  1064. return false;
  1065. }
  1066. }
  1067. RootsT ComputedRoots = FindRoots(DT, nullptr);
  1068. if (!isPermutation(DT.Roots, ComputedRoots)) {
  1069. errs() << "Tree has different roots than freshly computed ones!\n";
  1070. errs() << "\tPDT roots: ";
  1071. for (const NodePtr N : DT.Roots) errs() << BlockNamePrinter(N) << ", ";
  1072. errs() << "\n\tComputed roots: ";
  1073. for (const NodePtr N : ComputedRoots)
  1074. errs() << BlockNamePrinter(N) << ", ";
  1075. errs() << "\n";
  1076. errs().flush();
  1077. return false;
  1078. }
  1079. return true;
  1080. }
  1081. // Checks if the tree contains all reachable nodes in the input graph.
  1082. // Running time: O(N).
  1083. bool verifyReachability(const DomTreeT &DT) {
  1084. clear();
  1085. doFullDFSWalk(DT, AlwaysDescend);
  1086. for (auto &NodeToTN : DT.DomTreeNodes) {
  1087. const TreeNodePtr TN = NodeToTN.second.get();
  1088. const NodePtr BB = TN->getBlock();
  1089. // Virtual root has a corresponding virtual CFG node.
  1090. if (DT.isVirtualRoot(TN)) continue;
  1091. if (NodeToInfo.count(BB) == 0) {
  1092. errs() << "DomTree node " << BlockNamePrinter(BB)
  1093. << " not found by DFS walk!\n";
  1094. errs().flush();
  1095. return false;
  1096. }
  1097. }
  1098. for (const NodePtr N : NumToNode) {
  1099. if (N && !DT.getNode(N)) {
  1100. errs() << "CFG node " << BlockNamePrinter(N)
  1101. << " not found in the DomTree!\n";
  1102. errs().flush();
  1103. return false;
  1104. }
  1105. }
  1106. return true;
  1107. }
  1108. // Check if for every parent with a level L in the tree all of its children
  1109. // have level L + 1.
  1110. // Running time: O(N).
  1111. static bool VerifyLevels(const DomTreeT &DT) {
  1112. for (auto &NodeToTN : DT.DomTreeNodes) {
  1113. const TreeNodePtr TN = NodeToTN.second.get();
  1114. const NodePtr BB = TN->getBlock();
  1115. if (!BB) continue;
  1116. const TreeNodePtr IDom = TN->getIDom();
  1117. if (!IDom && TN->getLevel() != 0) {
  1118. errs() << "Node without an IDom " << BlockNamePrinter(BB)
  1119. << " has a nonzero level " << TN->getLevel() << "!\n";
  1120. errs().flush();
  1121. return false;
  1122. }
  1123. if (IDom && TN->getLevel() != IDom->getLevel() + 1) {
  1124. errs() << "Node " << BlockNamePrinter(BB) << " has level "
  1125. << TN->getLevel() << " while its IDom "
  1126. << BlockNamePrinter(IDom->getBlock()) << " has level "
  1127. << IDom->getLevel() << "!\n";
  1128. errs().flush();
  1129. return false;
  1130. }
  1131. }
  1132. return true;
  1133. }
  1134. // Check if the computed DFS numbers are correct. Note that DFS info may not
  1135. // be valid, and when that is the case, we don't verify the numbers.
  1136. // Running time: O(N log(N)).
  1137. static bool VerifyDFSNumbers(const DomTreeT &DT) {
  1138. if (!DT.DFSInfoValid || !DT.Parent)
  1139. return true;
  1140. const NodePtr RootBB = IsPostDom ? nullptr : *DT.root_begin();
  1141. const TreeNodePtr Root = DT.getNode(RootBB);
  1142. auto PrintNodeAndDFSNums = [](const TreeNodePtr TN) {
  1143. errs() << BlockNamePrinter(TN) << " {" << TN->getDFSNumIn() << ", "
  1144. << TN->getDFSNumOut() << '}';
  1145. };
  1146. // Verify the root's DFS In number. Although DFS numbering would also work
  1147. // if we started from some other value, we assume 0-based numbering.
  1148. if (Root->getDFSNumIn() != 0) {
  1149. errs() << "DFSIn number for the tree root is not:\n\t";
  1150. PrintNodeAndDFSNums(Root);
  1151. errs() << '\n';
  1152. errs().flush();
  1153. return false;
  1154. }
  1155. // For each tree node verify if children's DFS numbers cover their parent's
  1156. // DFS numbers with no gaps.
  1157. for (const auto &NodeToTN : DT.DomTreeNodes) {
  1158. const TreeNodePtr Node = NodeToTN.second.get();
  1159. // Handle tree leaves.
  1160. if (Node->isLeaf()) {
  1161. if (Node->getDFSNumIn() + 1 != Node->getDFSNumOut()) {
  1162. errs() << "Tree leaf should have DFSOut = DFSIn + 1:\n\t";
  1163. PrintNodeAndDFSNums(Node);
  1164. errs() << '\n';
  1165. errs().flush();
  1166. return false;
  1167. }
  1168. continue;
  1169. }
  1170. // Make a copy and sort it such that it is possible to check if there are
  1171. // no gaps between DFS numbers of adjacent children.
  1172. SmallVector<TreeNodePtr, 8> Children(Node->begin(), Node->end());
  1173. llvm::sort(Children, [](const TreeNodePtr Ch1, const TreeNodePtr Ch2) {
  1174. return Ch1->getDFSNumIn() < Ch2->getDFSNumIn();
  1175. });
  1176. auto PrintChildrenError = [Node, &Children, PrintNodeAndDFSNums](
  1177. const TreeNodePtr FirstCh, const TreeNodePtr SecondCh) {
  1178. assert(FirstCh);
  1179. errs() << "Incorrect DFS numbers for:\n\tParent ";
  1180. PrintNodeAndDFSNums(Node);
  1181. errs() << "\n\tChild ";
  1182. PrintNodeAndDFSNums(FirstCh);
  1183. if (SecondCh) {
  1184. errs() << "\n\tSecond child ";
  1185. PrintNodeAndDFSNums(SecondCh);
  1186. }
  1187. errs() << "\nAll children: ";
  1188. for (const TreeNodePtr Ch : Children) {
  1189. PrintNodeAndDFSNums(Ch);
  1190. errs() << ", ";
  1191. }
  1192. errs() << '\n';
  1193. errs().flush();
  1194. };
  1195. if (Children.front()->getDFSNumIn() != Node->getDFSNumIn() + 1) {
  1196. PrintChildrenError(Children.front(), nullptr);
  1197. return false;
  1198. }
  1199. if (Children.back()->getDFSNumOut() + 1 != Node->getDFSNumOut()) {
  1200. PrintChildrenError(Children.back(), nullptr);
  1201. return false;
  1202. }
  1203. for (size_t i = 0, e = Children.size() - 1; i != e; ++i) {
  1204. if (Children[i]->getDFSNumOut() + 1 != Children[i + 1]->getDFSNumIn()) {
  1205. PrintChildrenError(Children[i], Children[i + 1]);
  1206. return false;
  1207. }
  1208. }
  1209. }
  1210. return true;
  1211. }
  1212. // The below routines verify the correctness of the dominator tree relative to
  1213. // the CFG it's coming from. A tree is a dominator tree iff it has two
  1214. // properties, called the parent property and the sibling property. Tarjan
  1215. // and Lengauer prove (but don't explicitly name) the properties as part of
  1216. // the proofs in their 1972 paper, but the proofs are mostly part of proving
  1217. // things about semidominators and idoms, and some of them are simply asserted
  1218. // based on even earlier papers (see, e.g., lemma 2). Some papers refer to
  1219. // these properties as "valid" and "co-valid". See, e.g., "Dominators,
  1220. // directed bipolar orders, and independent spanning trees" by Loukas
  1221. // Georgiadis and Robert E. Tarjan, as well as "Dominator Tree Verification
  1222. // and Vertex-Disjoint Paths " by the same authors.
  1223. // A very simple and direct explanation of these properties can be found in
  1224. // "An Experimental Study of Dynamic Dominators", found at
  1225. // https://arxiv.org/abs/1604.02711
  1226. // The easiest way to think of the parent property is that it's a requirement
  1227. // of being a dominator. Let's just take immediate dominators. For PARENT to
  1228. // be an immediate dominator of CHILD, all paths in the CFG must go through
  1229. // PARENT before they hit CHILD. This implies that if you were to cut PARENT
  1230. // out of the CFG, there should be no paths to CHILD that are reachable. If
  1231. // there are, then you now have a path from PARENT to CHILD that goes around
  1232. // PARENT and still reaches CHILD, which by definition, means PARENT can't be
  1233. // a dominator of CHILD (let alone an immediate one).
  1234. // The sibling property is similar. It says that for each pair of sibling
  1235. // nodes in the dominator tree (LEFT and RIGHT) , they must not dominate each
  1236. // other. If sibling LEFT dominated sibling RIGHT, it means there are no
  1237. // paths in the CFG from sibling LEFT to sibling RIGHT that do not go through
  1238. // LEFT, and thus, LEFT is really an ancestor (in the dominator tree) of
  1239. // RIGHT, not a sibling.
  1240. // It is possible to verify the parent and sibling properties in linear time,
  1241. // but the algorithms are complex. Instead, we do it in a straightforward
  1242. // N^2 and N^3 way below, using direct path reachability.
  1243. // Checks if the tree has the parent property: if for all edges from V to W in
  1244. // the input graph, such that V is reachable, the parent of W in the tree is
  1245. // an ancestor of V in the tree.
  1246. // Running time: O(N^2).
  1247. //
  1248. // This means that if a node gets disconnected from the graph, then all of
  1249. // the nodes it dominated previously will now become unreachable.
  1250. bool verifyParentProperty(const DomTreeT &DT) {
  1251. for (auto &NodeToTN : DT.DomTreeNodes) {
  1252. const TreeNodePtr TN = NodeToTN.second.get();
  1253. const NodePtr BB = TN->getBlock();
  1254. if (!BB || TN->isLeaf())
  1255. continue;
  1256. LLVM_DEBUG(dbgs() << "Verifying parent property of node "
  1257. << BlockNamePrinter(TN) << "\n");
  1258. clear();
  1259. doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) {
  1260. return From != BB && To != BB;
  1261. });
  1262. for (TreeNodePtr Child : TN->children())
  1263. if (NodeToInfo.count(Child->getBlock()) != 0) {
  1264. errs() << "Child " << BlockNamePrinter(Child)
  1265. << " reachable after its parent " << BlockNamePrinter(BB)
  1266. << " is removed!\n";
  1267. errs().flush();
  1268. return false;
  1269. }
  1270. }
  1271. return true;
  1272. }
  1273. // Check if the tree has sibling property: if a node V does not dominate a
  1274. // node W for all siblings V and W in the tree.
  1275. // Running time: O(N^3).
  1276. //
  1277. // This means that if a node gets disconnected from the graph, then all of its
  1278. // siblings will now still be reachable.
  1279. bool verifySiblingProperty(const DomTreeT &DT) {
  1280. for (auto &NodeToTN : DT.DomTreeNodes) {
  1281. const TreeNodePtr TN = NodeToTN.second.get();
  1282. const NodePtr BB = TN->getBlock();
  1283. if (!BB || TN->isLeaf())
  1284. continue;
  1285. for (const TreeNodePtr N : TN->children()) {
  1286. clear();
  1287. NodePtr BBN = N->getBlock();
  1288. doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) {
  1289. return From != BBN && To != BBN;
  1290. });
  1291. for (const TreeNodePtr S : TN->children()) {
  1292. if (S == N) continue;
  1293. if (NodeToInfo.count(S->getBlock()) == 0) {
  1294. errs() << "Node " << BlockNamePrinter(S)
  1295. << " not reachable when its sibling " << BlockNamePrinter(N)
  1296. << " is removed!\n";
  1297. errs().flush();
  1298. return false;
  1299. }
  1300. }
  1301. }
  1302. }
  1303. return true;
  1304. }
  1305. // Check if the given tree is the same as a freshly computed one for the same
  1306. // Parent.
  1307. // Running time: O(N^2), but faster in practice (same as tree construction).
  1308. //
  1309. // Note that this does not check if that the tree construction algorithm is
  1310. // correct and should be only used for fast (but possibly unsound)
  1311. // verification.
  1312. static bool IsSameAsFreshTree(const DomTreeT &DT) {
  1313. DomTreeT FreshTree;
  1314. FreshTree.recalculate(*DT.Parent);
  1315. const bool Different = DT.compare(FreshTree);
  1316. if (Different) {
  1317. errs() << (DT.isPostDominator() ? "Post" : "")
  1318. << "DominatorTree is different than a freshly computed one!\n"
  1319. << "\tCurrent:\n";
  1320. DT.print(errs());
  1321. errs() << "\n\tFreshly computed tree:\n";
  1322. FreshTree.print(errs());
  1323. errs().flush();
  1324. }
  1325. return !Different;
  1326. }
  1327. };
  1328. template <class DomTreeT>
  1329. void Calculate(DomTreeT &DT) {
  1330. SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr);
  1331. }
  1332. template <typename DomTreeT>
  1333. void CalculateWithUpdates(DomTreeT &DT,
  1334. ArrayRef<typename DomTreeT::UpdateType> Updates) {
  1335. // FIXME: Updated to use the PreViewCFG and behave the same as until now.
  1336. // This behavior is however incorrect; this actually needs the PostViewCFG.
  1337. GraphDiff<typename DomTreeT::NodePtr, DomTreeT::IsPostDominator> PreViewCFG(
  1338. Updates, /*ReverseApplyUpdates=*/true);
  1339. typename SemiNCAInfo<DomTreeT>::BatchUpdateInfo BUI(PreViewCFG);
  1340. SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, &BUI);
  1341. }
  1342. template <class DomTreeT>
  1343. void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
  1344. typename DomTreeT::NodePtr To) {
  1345. if (DT.isPostDominator()) std::swap(From, To);
  1346. SemiNCAInfo<DomTreeT>::InsertEdge(DT, nullptr, From, To);
  1347. }
  1348. template <class DomTreeT>
  1349. void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From,
  1350. typename DomTreeT::NodePtr To) {
  1351. if (DT.isPostDominator()) std::swap(From, To);
  1352. SemiNCAInfo<DomTreeT>::DeleteEdge(DT, nullptr, From, To);
  1353. }
  1354. template <class DomTreeT>
  1355. void ApplyUpdates(DomTreeT &DT,
  1356. GraphDiff<typename DomTreeT::NodePtr,
  1357. DomTreeT::IsPostDominator> &PreViewCFG,
  1358. GraphDiff<typename DomTreeT::NodePtr,
  1359. DomTreeT::IsPostDominator> *PostViewCFG) {
  1360. SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, PreViewCFG, PostViewCFG);
  1361. }
  1362. template <class DomTreeT>
  1363. bool Verify(const DomTreeT &DT, typename DomTreeT::VerificationLevel VL) {
  1364. SemiNCAInfo<DomTreeT> SNCA(nullptr);
  1365. // Simplist check is to compare against a new tree. This will also
  1366. // usefully print the old and new trees, if they are different.
  1367. if (!SNCA.IsSameAsFreshTree(DT))
  1368. return false;
  1369. // Common checks to verify the properties of the tree. O(N log N) at worst.
  1370. if (!SNCA.verifyRoots(DT) || !SNCA.verifyReachability(DT) ||
  1371. !SNCA.VerifyLevels(DT) || !SNCA.VerifyDFSNumbers(DT))
  1372. return false;
  1373. // Extra checks depending on VerificationLevel. Up to O(N^3).
  1374. if (VL == DomTreeT::VerificationLevel::Basic ||
  1375. VL == DomTreeT::VerificationLevel::Full)
  1376. if (!SNCA.verifyParentProperty(DT))
  1377. return false;
  1378. if (VL == DomTreeT::VerificationLevel::Full)
  1379. if (!SNCA.verifySiblingProperty(DT))
  1380. return false;
  1381. return true;
  1382. }
  1383. } // namespace DomTreeBuilder
  1384. } // namespace llvm
  1385. #undef DEBUG_TYPE
  1386. #endif