37#ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
38#define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H
49#define DEBUG_TYPE "dom-tree-builder"
52namespace DomTreeBuilder {
54template <
typename DomTreeT>
56 using NodePtr =
typename DomTreeT::NodePtr;
57 using NodeT =
typename DomTreeT::NodeType;
59 using RootsT =
decltype(DomTreeT::Roots);
60 static constexpr bool IsPostDom = DomTreeT::IsPostDominator;
78 using UpdateT =
typename DomTreeT::UpdateType;
107 template <
bool Inversed>
110 return BUI->
PreViewCFG.template getChildren<Inversed>(
N);
111 return getChildren<Inversed>(
N);
114 template <
bool Inversed>
116 using DirectedNodeT =
117 std::conditional_t<Inversed, Inverse<NodePtr>,
NodePtr>;
118 auto R = children<DirectedNodeT>(
N);
128 if (InfoIt ==
NodeToInfo.end())
return nullptr;
130 return InfoIt->second.IDom;
140 assert(IDom || DT.DomTreeNodes[
nullptr]);
145 return DT.createChild(BB, IDomNode);
160 BP.
N->printAsOperand(O,
false);
178 template <
bool IsReverse = false,
typename DescendCondition>
180 unsigned AttachToNum,
186 while (!WorkList.
empty()) {
191 if (BBInfo.DFSNum != 0)
continue;
192 BBInfo.DFSNum = BBInfo.Semi = BBInfo.Label = ++LastNum;
196 auto Successors = getChildren<Direction>(BB,
BatchUpdates);
197 if (SuccOrder && Successors.size() > 1)
200 return SuccOrder->find(A)->second < SuccOrder->find(B)->second;
203 for (
const NodePtr Succ : Successors) {
207 if (SIT !=
NodeToInfo.end() && SIT->second.DFSNum != 0) {
208 if (Succ != BB) SIT->second.ReverseChildren.push_back(LastNum);
212 if (!Condition(BB, Succ))
continue;
218 SuccInfo.Parent = LastNum;
219 SuccInfo.ReverseChildren.push_back(LastNum);
239 unsigned eval(
unsigned V,
unsigned LastLinked,
243 if (VInfo->
Parent < LastLinked)
249 Stack.push_back(VInfo);
250 VInfo = NumToInfo[VInfo->
Parent];
251 }
while (VInfo->
Parent >= LastLinked);
258 VInfo = Stack.pop_back_val();
261 if (PLabelInfo->
Semi < VLabelInfo->
Semi)
264 PLabelInfo = VLabelInfo;
266 }
while (!Stack.empty());
272 const unsigned NextDFSNum(
NumToNode.size());
276 for (
unsigned i = 1; i < NextDFSNum; ++i) {
285 for (
unsigned i = NextDFSNum - 1; i >= 2; --i) {
286 auto &WInfo = *NumToInfo[i];
289 WInfo.Semi = WInfo.Parent;
290 for (
unsigned N : WInfo.ReverseChildren) {
291 unsigned SemiU = NumToInfo[
eval(
N, i + 1, EvalStack, NumToInfo)]->Semi;
292 if (SemiU < WInfo.Semi) WInfo.Semi = SemiU;
300 for (
unsigned i = 2; i < NextDFSNum; ++i) {
301 auto &WInfo = *NumToInfo[i];
303 const unsigned SDomNum = NumToInfo[WInfo.Semi]->DFSNum;
304 NodePtr WIDomCandidate = WInfo.IDom;
306 auto &WIDomCandidateInfo =
NodeToInfo.find(WIDomCandidate)->second;
307 if (WIDomCandidateInfo.DFSNum <= SDomNum)
309 WIDomCandidate = WIDomCandidateInfo.IDom;
312 WInfo.IDom = WIDomCandidate;
323 assert(
NumToNode.size() == 1 &&
"SNCAInfo must be freshly constructed");
326 BBInfo.DFSNum = BBInfo.Semi = BBInfo.Label = 1;
335 assert(
N &&
"N must be a valid node");
336 return !getChildren<false>(
N, BUI).empty();
340 assert(DT.Parent &&
"Parent not set");
348 assert(DT.Parent &&
"Parent pointer is not set");
392 bool HasNonTrivialRoots =
false;
395 if (
Total + 1 != Num) {
396 HasNonTrivialRoots =
true;
403 std::optional<NodeOrderMap> SuccOrder;
404 auto InitSuccOrderOnce = [&]() {
409 SuccOrder->try_emplace(Succ, 0);
412 unsigned NodeNum = 0;
413 for (
const auto Node :
nodes(DT.Parent)) {
415 auto Order = SuccOrder->find(
Node);
416 if (Order != SuccOrder->end()) {
417 assert(Order->second == 0);
418 Order->second = NodeNum;
450 const unsigned NewNum =
454 <<
"(non-trivial root): "
456 Roots.push_back(FurthestAway);
457 LLVM_DEBUG(
dbgs() <<
"\t\t\tPrev DFSNum: " << Num <<
", new DFSNum: "
458 << NewNum <<
"\n\t\t\tRemoving DFS info\n");
459 for (
unsigned i = NewNum; i > Num; --i) {
466 const unsigned PrevNum = Num;
469 for (
unsigned i = PrevNum + 1; i <= Num; ++i)
481 assert((
Total + 1 == Num) &&
"Everything should have been visited");
510 for (
unsigned i = 0; i < Roots.size(); ++i) {
511 auto &Root = Roots[i];
515 <<
" remains a root\n");
521 for (
unsigned x = 2; x <= Num; ++x) {
542 template <
typename DescendCondition>
545 assert(DT.Roots.size() == 1 &&
"Dominators should have a singe root");
546 runDFS(DT.Roots[0], 0, DC, 0);
552 for (
const NodePtr Root : DT.Roots) Num =
runDFS(Root, Num, DC, 1);
556 auto *Parent = DT.Parent;
580 dbgs() <<
"DomTree recalculated, skipping future batch updates\n");
583 if (DT.Roots.empty())
return;
590 DT.RootNode = DT.createNode(Root);
598 for (
size_t i = 1, e =
NumToNode.size(); i != e; ++i) {
602 if (DT.DomTreeNodes[W])
continue;
611 DT.createChild(W, IDomNode);
617 for (
size_t i = 1, e =
NumToNode.size(); i != e; ++i) {
630 return LHS->getLevel() <
RHS->getLevel();
636 std::priority_queue<TreeNodePtr, SmallVector<TreeNodePtr, 8>,
641#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
649 "From has to be a valid CFG node or a virtual root");
650 assert(To &&
"Cannot be a nullptr");
661 FromTN = DT.createChild(
From, VirtualRoot);
662 DT.Roots.push_back(
From);
665 DT.DFSInfoValid =
false;
682 if (!DT.isVirtualRoot(To->
getIDom()))
return false;
688 <<
" is no longer a root\n\t\tRebuilding the tree!!!\n");
696 if (
A.size() !=
B.size())
713 return HasForwardSuccessors(N, BUI);
726 <<
"The entire tree needs to be rebuilt\n");
744 ? DT.findNearestCommonDominator(
From->getBlock(), To->
getBlock())
746 assert(NCDBlock || DT.isPostDominator());
751 const unsigned NCDLevel = NCD->
getLevel();
771 while (!II.
Bucket.empty()) {
776 const unsigned CurrentLevel = TN->
getLevel();
778 "as affected, CurrentLevel " << CurrentLevel <<
"\n");
791 for (
const NodePtr Succ : getChildren<IsPostDom>(TN->
getBlock(), BUI)) {
794 "Unreachable successor found at reachable insertion");
795 const unsigned SuccLevel = SuccTN->
getLevel();
798 <<
", level = " << SuccLevel <<
"\n");
807 if (SuccLevel <= NCDLevel + 1 || !II.
Visited.insert(SuccTN).second)
810 if (SuccLevel > CurrentLevel) {
815 UnaffectedOnCurrentLevel.
push_back(SuccTN);
817 II.VisitedUnaffected.push_back(SuccTN);
823 <<
" to a Bucket\n");
828 if (UnaffectedOnCurrentLevel.
empty())
850#if defined(LLVM_ENABLE_ABI_BREAKING_CHECKS) && !defined(NDEBUG)
853 "TN should have been updated by an affected ancestor");
876 for (
const auto &Edge : DiscoveredEdgesToReachable) {
889 &DiscoveredConnectingEdges) {
890 assert(!DT.getNode(Root) &&
"Root must not be reachable");
893 auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](
NodePtr From,
896 if (!ToTN)
return true;
898 DiscoveredConnectingEdges.push_back({
From, ToTN});
903 SNCA.
runDFS(Root, 0, UnreachableDescender, 0);
912 assert(
From && To &&
"Cannot disconnect nullptrs");
916#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
920 auto IsSuccessor = [BUI](
const NodePtr SuccCandidate,
const NodePtr Of) {
921 auto Successors = getChildren<IsPostDom>(Of, BUI);
925 assert(!IsSuccessor(To,
From) &&
"Deleted edge still exists in the CFG!");
936 <<
") already unreachable -- there is no edge to delete\n");
940 const NodePtr NCDBlock = DT.findNearestCommonDominator(
From, To);
945 DT.DFSInfoValid =
false;
974 assert(ToIDom || DT.isPostDominator());
980 if (!PrevIDomSubTree) {
987 const unsigned Level = ToIDomTN->
getLevel();
989 return DT.getNode(To)->getLevel() > Level;
996 SNCA.
runDFS(ToIDom, 0, DescendBelow, 0);
1009 for (
const NodePtr Pred : getChildren<!IsPostDom>(TNB, BUI)) {
1011 if (!DT.getNode(Pred))
continue;
1013 const NodePtr Support = DT.findNearestCommonDominator(TNB, Pred);
1015 if (Support != TNB) {
1017 <<
" is reachable from support "
1039 LLVM_DEBUG(
dbgs() <<
"\tDeletion made a region reverse-unreachable\n");
1042 DT.Roots.push_back(ToTN->
getBlock());
1048 const unsigned Level = ToTN->
getLevel();
1052 auto DescendAndCollect = [Level, &AffectedQueue, &DT](
NodePtr,
NodePtr To) {
1055 if (TN->
getLevel() > Level)
return true;
1063 unsigned LastDFSNum =
1070 for (
const NodePtr N : AffectedQueue) {
1074 assert(NCDBlock || DT.isPostDominator());
1093 for (
unsigned i = LastDFSNum; i > 0; --i) {
1102 if (MinNode == ToTN)
return;
1104 LLVM_DEBUG(
dbgs() <<
"DeleteUnreachable: running DFS with MinNode = "
1106 const unsigned MinLevel = MinNode->
getLevel();
1114 return ToTN && ToTN->
getLevel() > MinLevel;
1135 assert(ChIt != IDom->Children.end());
1136 std::swap(*ChIt, IDom->Children.back());
1137 IDom->Children.pop_back();
1139 DT.DomTreeNodes.erase(TN->
getBlock());
1151 if (NumUpdates == 0)
1156 if (NumUpdates == 1) {
1159 if (Update.getKind() == UpdateKind::Insert)
1160 InsertEdge(DT,
nullptr, Update.getFrom(), Update.getTo());
1162 DeleteEdge(DT,
nullptr, Update.getFrom(), Update.getTo());
1165 if (Update.getKind() == UpdateKind::Insert)
1166 InsertEdge(DT, &BUI, Update.getFrom(), Update.getTo());
1168 DeleteEdge(DT, &BUI, Update.getFrom(), Update.getTo());
1182 if (DT.DomTreeNodes.size() <= 100) {
1185 }
else if (BUI.
NumLegalized > DT.DomTreeNodes.size() / 40)
1206 if (CurrentUpdate.getKind() == UpdateKind::Insert)
1207 InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1209 DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo());
1222 if (!DT.Parent && !DT.Roots.empty()) {
1223 errs() <<
"Tree has no parent but has roots!\n";
1229 if (DT.Roots.empty()) {
1230 errs() <<
"Tree doesn't have a root!\n";
1236 errs() <<
"Tree's root is not its parent's entry node!\n";
1244 errs() <<
"Tree has different roots than freshly computed ones!\n";
1245 errs() <<
"\tPDT roots: ";
1247 errs() <<
"\n\tComputed roots: ";
1248 for (
const NodePtr N : ComputedRoots)
1264 for (
auto &NodeToTN : DT.DomTreeNodes) {
1269 if (DT.isVirtualRoot(TN))
continue;
1273 <<
" not found by DFS walk!\n";
1281 if (
N && !DT.getNode(
N)) {
1283 <<
" not found in the DomTree!\n";
1297 for (
auto &NodeToTN : DT.DomTreeNodes) {
1303 if (!IDom && TN->
getLevel() != 0) {
1305 <<
" has a nonzero level " << TN->
getLevel() <<
"!\n";
1313 << TN->
getLevel() <<
" while its IDom "
1329 if (!DT.DFSInfoValid || !DT.Parent)
1335 auto PrintNodeAndDFSNums = [](
const TreeNodePtr TN) {
1337 << TN->getDFSNumOut() <<
'}';
1343 errs() <<
"DFSIn number for the tree root is not:\n\t";
1344 PrintNodeAndDFSNums(Root);
1352 for (
const auto &NodeToTN : DT.DomTreeNodes) {
1356 if (
Node->isLeaf()) {
1357 if (
Node->getDFSNumIn() + 1 !=
Node->getDFSNumOut()) {
1358 errs() <<
"Tree leaf should have DFSOut = DFSIn + 1:\n\t";
1359 PrintNodeAndDFSNums(
Node);
1375 auto PrintChildrenError = [
Node, &Children, PrintNodeAndDFSNums](
1379 errs() <<
"Incorrect DFS numbers for:\n\tParent ";
1380 PrintNodeAndDFSNums(
Node);
1382 errs() <<
"\n\tChild ";
1383 PrintNodeAndDFSNums(FirstCh);
1386 errs() <<
"\n\tSecond child ";
1387 PrintNodeAndDFSNums(SecondCh);
1390 errs() <<
"\nAll children: ";
1392 PrintNodeAndDFSNums(Ch);
1400 if (Children.front()->getDFSNumIn() !=
Node->getDFSNumIn() + 1) {
1401 PrintChildrenError(Children.front(),
nullptr);
1405 if (Children.back()->getDFSNumOut() + 1 !=
Node->getDFSNumOut()) {
1406 PrintChildrenError(Children.back(),
nullptr);
1410 for (
size_t i = 0, e = Children.size() - 1; i != e; ++i) {
1411 if (Children[i]->getDFSNumOut() + 1 != Children[i + 1]->getDFSNumIn()) {
1412 PrintChildrenError(Children[i], Children[i + 1]);
1465 for (
auto &NodeToTN : DT.DomTreeNodes) {
1475 return From != BB && To != BB;
1479 if (
NodeToInfo.count(Child->getBlock()) != 0) {
1482 <<
" is removed!\n";
1499 for (
auto &NodeToTN : DT.DomTreeNodes) {
1509 return From != BBN && To != BBN;
1513 if (S ==
N)
continue;
1518 <<
" is removed!\n";
1539 FreshTree.recalculate(*DT.Parent);
1540 const bool Different = DT.compare(FreshTree);
1543 errs() << (DT.isPostDominator() ?
"Post" :
"")
1544 <<
"DominatorTree is different than a freshly computed one!\n"
1547 errs() <<
"\n\tFreshly computed tree:\n";
1548 FreshTree.print(
errs());
1556template <
class DomTreeT>
1561template <
typename DomTreeT>
1572template <
class DomTreeT>
1574 typename DomTreeT::NodePtr To) {
1579template <
class DomTreeT>
1581 typename DomTreeT::NodePtr To) {
1586template <
class DomTreeT>
1589 DomTreeT::IsPostDominator> &PreViewCFG,
1591 DomTreeT::IsPostDominator> *PostViewCFG) {
1595template <
class DomTreeT>
1596bool Verify(
const DomTreeT &DT,
typename DomTreeT::VerificationLevel VL) {
1610 if (VL == DomTreeT::VerificationLevel::Basic ||
1611 VL == DomTreeT::VerificationLevel::Full)
1614 if (VL == DomTreeT::VerificationLevel::Full)
Unify divergent function exit nodes
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
This file defines a set of templates that efficiently compute a dominator tree over a generic graph.
Loop::LoopBounds::Direction Direction
ppc ctr loops PowerPC CTR Loops Verify
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Base class for the actual dominator tree node.
iterator_range< iterator > children()
void setIDom(DomTreeNodeBase *NewIDom)
DomTreeNodeBase * getIDom() const
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
size_t getNumChildren() const
unsigned getLevel() const
cfg::Update< NodePtr > popUpdateForIncrementalUpdates()
unsigned getNumLegalizedUpdates() const
Implements a dense probed hash-table based set with some number of buckets stored inline.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements an extremely fast bulk output stream that can only output to a stream.
void CalculateWithUpdates(DomTreeT &DT, ArrayRef< typename DomTreeT::UpdateType > Updates)
void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From, typename DomTreeT::NodePtr To)
void Calculate(DomTreeT &DT)
void ApplyUpdates(DomTreeT &DT, GraphDiff< typename DomTreeT::NodePtr, DomTreeT::IsPostDominator > &PreViewCFG, GraphDiff< typename DomTreeT::NodePtr, DomTreeT::IsPostDominator > *PostViewCFG)
void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From, typename DomTreeT::NodePtr To)
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
BatchUpdateInfo(GraphDiffT &PreViewCFG, GraphDiffT *PostViewCFG=nullptr)
const size_t NumLegalized
friend raw_ostream & operator<<(raw_ostream &O, const BlockNamePrinter &BP)
BlockNamePrinter(NodePtr Block)
BlockNamePrinter(TreeNodePtr TN)
SmallVector< unsigned, 4 > ReverseChildren
bool operator()(TreeNodePtr LHS, TreeNodePtr RHS) const
std::priority_queue< TreeNodePtr, SmallVector< TreeNodePtr, 8 >, Compare > Bucket
SmallVector< TreeNodePtr, 8 > Affected
SmallDenseSet< TreeNodePtr, 8 > Visited
NodePtr getIDom(NodePtr BB) const
SemiNCAInfo(BatchUpdatePtr BUI)
static SmallVector< NodePtr, 8 > getChildren(NodePtr N)
static void UpdateInsertion(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr NCD, InsertionInfo &II)
static void DeleteEdge(DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr From, const NodePtr To)
void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC)
DenseMap< NodePtr, unsigned > NodeOrderMap
static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI)
static SmallVector< NodePtr, 8 > getChildren(NodePtr N, BatchUpdatePtr BUI)
static void ComputeUnreachableDominators(DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr Root, const TreeNodePtr Incoming, SmallVectorImpl< std::pair< NodePtr, TreeNodePtr > > &DiscoveredConnectingEdges)
static bool VerifyLevels(const DomTreeT &DT)
decltype(DomTreeT::Roots) RootsT
bool verifyReachability(const DomTreeT &DT)
unsigned eval(unsigned V, unsigned LastLinked, SmallVectorImpl< InfoRec * > &Stack, ArrayRef< InfoRec * > NumToInfo)
static bool IsSameAsFreshTree(const DomTreeT &DT)
static void EraseNode(DomTreeT &DT, const TreeNodePtr TN)
static constexpr bool IsPostDom
typename DomTreeT::NodePtr NodePtr
static void ApplyUpdates(DomTreeT &DT, GraphDiffT &PreViewCFG, GraphDiffT *PostViewCFG)
typename DomTreeT::UpdateKind UpdateKind
static bool UpdateRootsBeforeInsertion(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr From, const TreeNodePtr To)
bool verifySiblingProperty(const DomTreeT &DT)
typename DomTreeT::NodeType NodeT
void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo)
static NodePtr GetEntryNode(const DomTreeT &DT)
static bool AlwaysDescend(NodePtr, NodePtr)
static void UpdateRootsAfterUpdate(DomTreeT &DT, const BatchUpdatePtr BUI)
unsigned runDFS(NodePtr V, unsigned LastNum, DescendCondition Condition, unsigned AttachToNum, const NodeOrderMap *SuccOrder=nullptr)
static void DeleteReachable(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr FromTN, const TreeNodePtr ToTN)
static void RemoveRedundantRoots(const DomTreeT &DT, BatchUpdatePtr BUI, RootsT &Roots)
static bool HasProperSupport(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr TN)
static bool isPermutation(const SmallVectorImpl< NodePtr > &A, const SmallVectorImpl< NodePtr > &B)
static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI)
std::vector< NodePtr > NumToNode
TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT)
typename DomTreeT::UpdateType UpdateT
static void InsertReachable(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr From, const TreeNodePtr To)
static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI)
static void InsertUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr From, const NodePtr To)
static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI)
DenseMap< NodePtr, InfoRec > NodeToInfo
static bool VerifyDFSNumbers(const DomTreeT &DT)
static void DeleteUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI, const TreeNodePtr ToTN)
void attachNewSubtree(DomTreeT &DT, const TreeNodePtr AttachTo)
static void InsertEdge(DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr From, const NodePtr To)
BatchUpdateInfo * BatchUpdates
bool verifyParentProperty(const DomTreeT &DT)
bool verifyRoots(const DomTreeT &DT)
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...