xref: /llvm-project/llvm/lib/Transforms/Scalar/StructurizeCFG.cpp (revision b40ff5ac2d407074db4479c6e271f51c3f5db4c2)
1 //===- StructurizeCFG.cpp -------------------------------------------------===//
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 
9 #include "llvm/Transforms/Scalar/StructurizeCFG.h"
10 #include "llvm/ADT/DenseMap.h"
11 #include "llvm/ADT/MapVector.h"
12 #include "llvm/ADT/SCCIterator.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/SmallPtrSet.h"
15 #include "llvm/ADT/SmallSet.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/Analysis/InstructionSimplify.h"
18 #include "llvm/Analysis/RegionInfo.h"
19 #include "llvm/Analysis/RegionIterator.h"
20 #include "llvm/Analysis/RegionPass.h"
21 #include "llvm/Analysis/UniformityAnalysis.h"
22 #include "llvm/IR/BasicBlock.h"
23 #include "llvm/IR/CFG.h"
24 #include "llvm/IR/Constants.h"
25 #include "llvm/IR/Dominators.h"
26 #include "llvm/IR/Function.h"
27 #include "llvm/IR/InstrTypes.h"
28 #include "llvm/IR/Instruction.h"
29 #include "llvm/IR/Instructions.h"
30 #include "llvm/IR/Metadata.h"
31 #include "llvm/IR/PassManager.h"
32 #include "llvm/IR/PatternMatch.h"
33 #include "llvm/IR/ProfDataUtils.h"
34 #include "llvm/IR/Type.h"
35 #include "llvm/IR/Use.h"
36 #include "llvm/IR/Value.h"
37 #include "llvm/IR/ValueHandle.h"
38 #include "llvm/InitializePasses.h"
39 #include "llvm/Pass.h"
40 #include "llvm/Support/Casting.h"
41 #include "llvm/Support/CommandLine.h"
42 #include "llvm/Support/Debug.h"
43 #include "llvm/Support/raw_ostream.h"
44 #include "llvm/Transforms/Scalar.h"
45 #include "llvm/Transforms/Utils.h"
46 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
47 #include "llvm/Transforms/Utils/Local.h"
48 #include "llvm/Transforms/Utils/SSAUpdater.h"
49 #include <algorithm>
50 #include <cassert>
51 #include <utility>
52 
53 using namespace llvm;
54 using namespace llvm::PatternMatch;
55 
56 #define DEBUG_TYPE "structurizecfg"
57 
58 // The name for newly created blocks.
59 const char FlowBlockName[] = "Flow";
60 
61 namespace {
62 
63 static cl::opt<bool> ForceSkipUniformRegions(
64   "structurizecfg-skip-uniform-regions",
65   cl::Hidden,
66   cl::desc("Force whether the StructurizeCFG pass skips uniform regions"),
67   cl::init(false));
68 
69 static cl::opt<bool>
70     RelaxedUniformRegions("structurizecfg-relaxed-uniform-regions", cl::Hidden,
71                           cl::desc("Allow relaxed uniform region checks"),
72                           cl::init(true));
73 
74 // Definition of the complex types used in this pass.
75 
76 using BBValuePair = std::pair<BasicBlock *, Value *>;
77 
78 using RNVector = SmallVector<RegionNode *, 8>;
79 using BBVector = SmallVector<BasicBlock *, 8>;
80 using BranchVector = SmallVector<BranchInst *, 8>;
81 using BBValueVector = SmallVector<BBValuePair, 2>;
82 
83 using BBSet = SmallPtrSet<BasicBlock *, 8>;
84 
85 using PhiMap = MapVector<PHINode *, BBValueVector>;
86 using BB2BBVecMap = MapVector<BasicBlock *, BBVector>;
87 
88 using BBPhiMap = DenseMap<BasicBlock *, PhiMap>;
89 
90 using MaybeCondBranchWeights = std::optional<class CondBranchWeights>;
91 
92 class CondBranchWeights {
93   uint32_t TrueWeight;
94   uint32_t FalseWeight;
95 
96   CondBranchWeights(uint32_t T, uint32_t F) : TrueWeight(T), FalseWeight(F) {}
97 
98 public:
99   static MaybeCondBranchWeights tryParse(const BranchInst &Br) {
100     assert(Br.isConditional());
101 
102     uint64_t T, F;
103     if (!extractBranchWeights(Br, T, F))
104       return std::nullopt;
105 
106     return CondBranchWeights(T, F);
107   }
108 
109   static void setMetadata(BranchInst &Br,
110                           const MaybeCondBranchWeights &Weights) {
111     assert(Br.isConditional());
112     if (!Weights)
113       return;
114     uint32_t Arr[] = {Weights->TrueWeight, Weights->FalseWeight};
115     setBranchWeights(Br, Arr, false);
116   }
117 
118   CondBranchWeights invert() const {
119     return CondBranchWeights{FalseWeight, TrueWeight};
120   }
121 };
122 
123 using ValueWeightPair = std::pair<Value *, MaybeCondBranchWeights>;
124 
125 using BBPredicates = DenseMap<BasicBlock *, ValueWeightPair>;
126 using PredMap = DenseMap<BasicBlock *, BBPredicates>;
127 using BB2BBMap = DenseMap<BasicBlock *, BasicBlock *>;
128 
129 using BranchDebugLocMap = DenseMap<BasicBlock *, DebugLoc>;
130 
131 // A traits type that is intended to be used in graph algorithms. The graph
132 // traits starts at an entry node, and traverses the RegionNodes that are in
133 // the Nodes set.
134 struct SubGraphTraits {
135   using NodeRef = std::pair<RegionNode *, SmallDenseSet<RegionNode *> *>;
136   using BaseSuccIterator = GraphTraits<RegionNode *>::ChildIteratorType;
137 
138   // This wraps a set of Nodes into the iterator, so we know which edges to
139   // filter out.
140   class WrappedSuccIterator
141       : public iterator_adaptor_base<
142             WrappedSuccIterator, BaseSuccIterator,
143             typename std::iterator_traits<BaseSuccIterator>::iterator_category,
144             NodeRef, std::ptrdiff_t, NodeRef *, NodeRef> {
145     SmallDenseSet<RegionNode *> *Nodes;
146 
147   public:
148     WrappedSuccIterator(BaseSuccIterator It, SmallDenseSet<RegionNode *> *Nodes)
149         : iterator_adaptor_base(It), Nodes(Nodes) {}
150 
151     NodeRef operator*() const { return {*I, Nodes}; }
152   };
153 
154   static bool filterAll(const NodeRef &N) { return true; }
155   static bool filterSet(const NodeRef &N) { return N.second->count(N.first); }
156 
157   using ChildIteratorType =
158       filter_iterator<WrappedSuccIterator, bool (*)(const NodeRef &)>;
159 
160   static NodeRef getEntryNode(Region *R) {
161     return {GraphTraits<Region *>::getEntryNode(R), nullptr};
162   }
163 
164   static NodeRef getEntryNode(NodeRef N) { return N; }
165 
166   static iterator_range<ChildIteratorType> children(const NodeRef &N) {
167     auto *filter = N.second ? &filterSet : &filterAll;
168     return make_filter_range(
169         make_range<WrappedSuccIterator>(
170             {GraphTraits<RegionNode *>::child_begin(N.first), N.second},
171             {GraphTraits<RegionNode *>::child_end(N.first), N.second}),
172         filter);
173   }
174 
175   static ChildIteratorType child_begin(const NodeRef &N) {
176     return children(N).begin();
177   }
178 
179   static ChildIteratorType child_end(const NodeRef &N) {
180     return children(N).end();
181   }
182 };
183 
184 /// Finds the nearest common dominator of a set of BasicBlocks.
185 ///
186 /// For every BB you add to the set, you can specify whether we "remember" the
187 /// block.  When you get the common dominator, you can also ask whether it's one
188 /// of the blocks we remembered.
189 class NearestCommonDominator {
190   DominatorTree *DT;
191   BasicBlock *Result = nullptr;
192   bool ResultIsRemembered = false;
193 
194   /// Add BB to the resulting dominator.
195   void addBlock(BasicBlock *BB, bool Remember) {
196     if (!Result) {
197       Result = BB;
198       ResultIsRemembered = Remember;
199       return;
200     }
201 
202     BasicBlock *NewResult = DT->findNearestCommonDominator(Result, BB);
203     if (NewResult != Result)
204       ResultIsRemembered = false;
205     if (NewResult == BB)
206       ResultIsRemembered |= Remember;
207     Result = NewResult;
208   }
209 
210 public:
211   explicit NearestCommonDominator(DominatorTree *DomTree) : DT(DomTree) {}
212 
213   void addBlock(BasicBlock *BB) {
214     addBlock(BB, /* Remember = */ false);
215   }
216 
217   void addAndRememberBlock(BasicBlock *BB) {
218     addBlock(BB, /* Remember = */ true);
219   }
220 
221   /// Get the nearest common dominator of all the BBs added via addBlock() and
222   /// addAndRememberBlock().
223   BasicBlock *result() { return Result; }
224 
225   /// Is the BB returned by getResult() one of the blocks we added to the set
226   /// with addAndRememberBlock()?
227   bool resultIsRememberedBlock() { return ResultIsRemembered; }
228 };
229 
230 /// Transforms the control flow graph on one single entry/exit region
231 /// at a time.
232 ///
233 /// After the transform all "If"/"Then"/"Else" style control flow looks like
234 /// this:
235 ///
236 /// \verbatim
237 /// 1
238 /// ||
239 /// | |
240 /// 2 |
241 /// | /
242 /// |/
243 /// 3
244 /// ||   Where:
245 /// | |  1 = "If" block, calculates the condition
246 /// 4 |  2 = "Then" subregion, runs if the condition is true
247 /// | /  3 = "Flow" blocks, newly inserted flow blocks, rejoins the flow
248 /// |/   4 = "Else" optional subregion, runs if the condition is false
249 /// 5    5 = "End" block, also rejoins the control flow
250 /// \endverbatim
251 ///
252 /// Control flow is expressed as a branch where the true exit goes into the
253 /// "Then"/"Else" region, while the false exit skips the region
254 /// The condition for the optional "Else" region is expressed as a PHI node.
255 /// The incoming values of the PHI node are true for the "If" edge and false
256 /// for the "Then" edge.
257 ///
258 /// Additionally to that even complicated loops look like this:
259 ///
260 /// \verbatim
261 /// 1
262 /// ||
263 /// | |
264 /// 2 ^  Where:
265 /// | /  1 = "Entry" block
266 /// |/   2 = "Loop" optional subregion, with all exits at "Flow" block
267 /// 3    3 = "Flow" block, with back edge to entry block
268 /// |
269 /// \endverbatim
270 ///
271 /// The back edge of the "Flow" block is always on the false side of the branch
272 /// while the true side continues the general flow. So the loop condition
273 /// consist of a network of PHI nodes where the true incoming values expresses
274 /// breaks and the false values expresses continue states.
275 
276 class StructurizeCFG {
277   Type *Boolean;
278   ConstantInt *BoolTrue;
279   ConstantInt *BoolFalse;
280   Value *BoolPoison;
281 
282   Function *Func;
283   Region *ParentRegion;
284 
285   UniformityInfo *UA = nullptr;
286   DominatorTree *DT;
287 
288   SmallVector<RegionNode *, 8> Order;
289   BBSet Visited;
290   BBSet FlowSet;
291 
292   SmallVector<WeakVH, 8> AffectedPhis;
293   BBPhiMap DeletedPhis;
294   BB2BBVecMap AddedPhis;
295 
296   PredMap Predicates;
297   BranchVector Conditions;
298 
299   BB2BBMap Loops;
300   PredMap LoopPreds;
301   BranchVector LoopConds;
302 
303   BranchDebugLocMap TermDL;
304 
305   RegionNode *PrevNode;
306 
307   void orderNodes();
308 
309   void analyzeLoops(RegionNode *N);
310 
311   ValueWeightPair buildCondition(BranchInst *Term, unsigned Idx, bool Invert);
312 
313   void gatherPredicates(RegionNode *N);
314 
315   void collectInfos();
316 
317   void insertConditions(bool Loops);
318 
319   void simplifyConditions();
320 
321   void delPhiValues(BasicBlock *From, BasicBlock *To);
322 
323   void addPhiValues(BasicBlock *From, BasicBlock *To);
324 
325   void findUndefBlocks(BasicBlock *PHIBlock,
326                        const SmallSet<BasicBlock *, 8> &Incomings,
327                        SmallVector<BasicBlock *> &UndefBlks) const;
328   void setPhiValues();
329 
330   void simplifyAffectedPhis();
331 
332   void killTerminator(BasicBlock *BB);
333 
334   void changeExit(RegionNode *Node, BasicBlock *NewExit,
335                   bool IncludeDominator);
336 
337   BasicBlock *getNextFlow(BasicBlock *Dominator);
338 
339   BasicBlock *needPrefix(bool NeedEmpty);
340 
341   BasicBlock *needPostfix(BasicBlock *Flow, bool ExitUseAllowed);
342 
343   void setPrevNode(BasicBlock *BB);
344 
345   bool dominatesPredicates(BasicBlock *BB, RegionNode *Node);
346 
347   bool isPredictableTrue(RegionNode *Node);
348 
349   void wireFlow(bool ExitUseAllowed, BasicBlock *LoopEnd);
350 
351   void handleLoops(bool ExitUseAllowed, BasicBlock *LoopEnd);
352 
353   void createFlow();
354 
355   void rebuildSSA();
356 
357 public:
358   void init(Region *R);
359   bool run(Region *R, DominatorTree *DT);
360   bool makeUniformRegion(Region *R, UniformityInfo &UA);
361 };
362 
363 class StructurizeCFGLegacyPass : public RegionPass {
364   bool SkipUniformRegions;
365 
366 public:
367   static char ID;
368 
369   explicit StructurizeCFGLegacyPass(bool SkipUniformRegions_ = false)
370       : RegionPass(ID), SkipUniformRegions(SkipUniformRegions_) {
371     if (ForceSkipUniformRegions.getNumOccurrences())
372       SkipUniformRegions = ForceSkipUniformRegions.getValue();
373     initializeStructurizeCFGLegacyPassPass(*PassRegistry::getPassRegistry());
374   }
375 
376   bool runOnRegion(Region *R, RGPassManager &RGM) override {
377     StructurizeCFG SCFG;
378     SCFG.init(R);
379     if (SkipUniformRegions) {
380       UniformityInfo &UA =
381           getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
382       if (SCFG.makeUniformRegion(R, UA))
383         return false;
384     }
385     DominatorTree *DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
386     return SCFG.run(R, DT);
387   }
388 
389   StringRef getPassName() const override { return "Structurize control flow"; }
390 
391   void getAnalysisUsage(AnalysisUsage &AU) const override {
392     if (SkipUniformRegions)
393       AU.addRequired<UniformityInfoWrapperPass>();
394     AU.addRequired<DominatorTreeWrapperPass>();
395 
396     AU.addPreserved<DominatorTreeWrapperPass>();
397     RegionPass::getAnalysisUsage(AU);
398   }
399 };
400 
401 } // end anonymous namespace
402 
403 char StructurizeCFGLegacyPass::ID = 0;
404 
405 INITIALIZE_PASS_BEGIN(StructurizeCFGLegacyPass, "structurizecfg",
406                       "Structurize the CFG", false, false)
407 INITIALIZE_PASS_DEPENDENCY(UniformityInfoWrapperPass)
408 INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
409 INITIALIZE_PASS_DEPENDENCY(RegionInfoPass)
410 INITIALIZE_PASS_END(StructurizeCFGLegacyPass, "structurizecfg",
411                     "Structurize the CFG", false, false)
412 
413 /// Build up the general order of nodes, by performing a topological sort of the
414 /// parent region's nodes, while ensuring that there is no outer cycle node
415 /// between any two inner cycle nodes.
416 void StructurizeCFG::orderNodes() {
417   Order.resize(std::distance(GraphTraits<Region *>::nodes_begin(ParentRegion),
418                              GraphTraits<Region *>::nodes_end(ParentRegion)));
419   if (Order.empty())
420     return;
421 
422   SmallDenseSet<RegionNode *> Nodes;
423   auto EntryNode = SubGraphTraits::getEntryNode(ParentRegion);
424 
425   // A list of range indices of SCCs in Order, to be processed.
426   SmallVector<std::pair<unsigned, unsigned>, 8> WorkList;
427   unsigned I = 0, E = Order.size();
428   while (true) {
429     // Run through all the SCCs in the subgraph starting with Entry.
430     for (auto SCCI =
431              scc_iterator<SubGraphTraits::NodeRef, SubGraphTraits>::begin(
432                  EntryNode);
433          !SCCI.isAtEnd(); ++SCCI) {
434       auto &SCC = *SCCI;
435 
436       // An SCC up to the size of 2, can be reduced to an entry (the last node),
437       // and a possible additional node. Therefore, it is already in order, and
438       // there is no need to add it to the work-list.
439       unsigned Size = SCC.size();
440       if (Size > 2)
441         WorkList.emplace_back(I, I + Size);
442 
443       // Add the SCC nodes to the Order array.
444       for (const auto &N : SCC) {
445         assert(I < E && "SCC size mismatch!");
446         Order[I++] = N.first;
447       }
448     }
449     assert(I == E && "SCC size mismatch!");
450 
451     // If there are no more SCCs to order, then we are done.
452     if (WorkList.empty())
453       break;
454 
455     std::tie(I, E) = WorkList.pop_back_val();
456 
457     // Collect the set of nodes in the SCC's subgraph. These are only the
458     // possible child nodes; we do not add the entry (last node) otherwise we
459     // will have the same exact SCC all over again.
460     Nodes.clear();
461     Nodes.insert(Order.begin() + I, Order.begin() + E - 1);
462 
463     // Update the entry node.
464     EntryNode.first = Order[E - 1];
465     EntryNode.second = &Nodes;
466   }
467 }
468 
469 /// Determine the end of the loops
470 void StructurizeCFG::analyzeLoops(RegionNode *N) {
471   if (N->isSubRegion()) {
472     // Test for exit as back edge
473     BasicBlock *Exit = N->getNodeAs<Region>()->getExit();
474     if (Visited.count(Exit))
475       Loops[Exit] = N->getEntry();
476 
477   } else {
478     // Test for successors as back edge
479     BasicBlock *BB = N->getNodeAs<BasicBlock>();
480     BranchInst *Term = cast<BranchInst>(BB->getTerminator());
481 
482     for (BasicBlock *Succ : Term->successors())
483       if (Visited.count(Succ))
484         Loops[Succ] = BB;
485   }
486 }
487 
488 /// Build the condition for one edge
489 ValueWeightPair StructurizeCFG::buildCondition(BranchInst *Term, unsigned Idx,
490                                                bool Invert) {
491   Value *Cond = Invert ? BoolFalse : BoolTrue;
492   MaybeCondBranchWeights Weights;
493 
494   if (Term->isConditional()) {
495     Cond = Term->getCondition();
496     Weights = CondBranchWeights::tryParse(*Term);
497 
498     if (Idx != (unsigned)Invert) {
499       Cond = invertCondition(Cond);
500       if (Weights)
501         Weights = Weights->invert();
502     }
503   }
504   return {Cond, Weights};
505 }
506 
507 /// Analyze the predecessors of each block and build up predicates
508 void StructurizeCFG::gatherPredicates(RegionNode *N) {
509   RegionInfo *RI = ParentRegion->getRegionInfo();
510   BasicBlock *BB = N->getEntry();
511   BBPredicates &Pred = Predicates[BB];
512   BBPredicates &LPred = LoopPreds[BB];
513 
514   for (BasicBlock *P : predecessors(BB)) {
515     // Ignore it if it's a branch from outside into our region entry
516     if (!ParentRegion->contains(P))
517       continue;
518 
519     Region *R = RI->getRegionFor(P);
520     if (R == ParentRegion) {
521       // It's a top level block in our region
522       BranchInst *Term = cast<BranchInst>(P->getTerminator());
523       for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
524         BasicBlock *Succ = Term->getSuccessor(i);
525         if (Succ != BB)
526           continue;
527 
528         if (Visited.count(P)) {
529           // Normal forward edge
530           if (Term->isConditional()) {
531             // Try to treat it like an ELSE block
532             BasicBlock *Other = Term->getSuccessor(!i);
533             if (Visited.count(Other) && !Loops.count(Other) &&
534                 !Pred.count(Other) && !Pred.count(P)) {
535 
536               Pred[Other] = {BoolFalse, std::nullopt};
537               Pred[P] = {BoolTrue, std::nullopt};
538               continue;
539             }
540           }
541           Pred[P] = buildCondition(Term, i, false);
542         } else {
543           // Back edge
544           LPred[P] = buildCondition(Term, i, true);
545         }
546       }
547     } else {
548       // It's an exit from a sub region
549       while (R->getParent() != ParentRegion)
550         R = R->getParent();
551 
552       // Edge from inside a subregion to its entry, ignore it
553       if (*R == *N)
554         continue;
555 
556       BasicBlock *Entry = R->getEntry();
557       if (Visited.count(Entry))
558         Pred[Entry] = {BoolTrue, std::nullopt};
559       else
560         LPred[Entry] = {BoolFalse, std::nullopt};
561     }
562   }
563 }
564 
565 /// Collect various loop and predicate infos
566 void StructurizeCFG::collectInfos() {
567   // Reset predicate
568   Predicates.clear();
569 
570   // and loop infos
571   Loops.clear();
572   LoopPreds.clear();
573 
574   // Reset the visited nodes
575   Visited.clear();
576 
577   for (RegionNode *RN : reverse(Order)) {
578     LLVM_DEBUG(dbgs() << "Visiting: "
579                       << (RN->isSubRegion() ? "SubRegion with entry: " : "")
580                       << RN->getEntry()->getName() << "\n");
581 
582     // Analyze all the conditions leading to a node
583     gatherPredicates(RN);
584 
585     // Remember that we've seen this node
586     Visited.insert(RN->getEntry());
587 
588     // Find the last back edges
589     analyzeLoops(RN);
590   }
591 
592   // Reset the collected term debug locations
593   TermDL.clear();
594 
595   for (BasicBlock &BB : *Func) {
596     if (const DebugLoc &DL = BB.getTerminator()->getDebugLoc())
597       TermDL[&BB] = DL;
598   }
599 }
600 
601 /// Insert the missing branch conditions
602 void StructurizeCFG::insertConditions(bool Loops) {
603   BranchVector &Conds = Loops ? LoopConds : Conditions;
604   Value *Default = Loops ? BoolTrue : BoolFalse;
605   SSAUpdater PhiInserter;
606 
607   for (BranchInst *Term : Conds) {
608     assert(Term->isConditional());
609 
610     BasicBlock *Parent = Term->getParent();
611     BasicBlock *SuccTrue = Term->getSuccessor(0);
612     BasicBlock *SuccFalse = Term->getSuccessor(1);
613 
614     PhiInserter.Initialize(Boolean, "");
615     PhiInserter.AddAvailableValue(&Func->getEntryBlock(), Default);
616     PhiInserter.AddAvailableValue(Loops ? SuccFalse : Parent, Default);
617 
618     BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue];
619 
620     NearestCommonDominator Dominator(DT);
621     Dominator.addBlock(Parent);
622 
623     Value *ParentValue = nullptr;
624     MaybeCondBranchWeights ParentWeights = std::nullopt;
625     for (std::pair<BasicBlock *, ValueWeightPair> BBAndPred : Preds) {
626       BasicBlock *BB = BBAndPred.first;
627       auto [Pred, Weight] = BBAndPred.second;
628 
629       if (BB == Parent) {
630         ParentValue = Pred;
631         ParentWeights = Weight;
632         break;
633       }
634       PhiInserter.AddAvailableValue(BB, Pred);
635       Dominator.addAndRememberBlock(BB);
636     }
637 
638     if (ParentValue) {
639       Term->setCondition(ParentValue);
640       CondBranchWeights::setMetadata(*Term, ParentWeights);
641     } else {
642       if (!Dominator.resultIsRememberedBlock())
643         PhiInserter.AddAvailableValue(Dominator.result(), Default);
644 
645       Term->setCondition(PhiInserter.GetValueInMiddleOfBlock(Parent));
646     }
647   }
648 }
649 
650 /// Simplify any inverted conditions that were built by buildConditions.
651 void StructurizeCFG::simplifyConditions() {
652   SmallVector<Instruction *> InstToErase;
653   for (auto &I : concat<PredMap::value_type>(Predicates, LoopPreds)) {
654     auto &Preds = I.second;
655     for (auto &J : Preds) {
656       Value *Cond = J.second.first;
657       Instruction *Inverted;
658       if (match(Cond, m_Not(m_OneUse(m_Instruction(Inverted)))) &&
659           !Cond->use_empty()) {
660         if (auto *InvertedCmp = dyn_cast<CmpInst>(Inverted)) {
661           InvertedCmp->setPredicate(InvertedCmp->getInversePredicate());
662           Cond->replaceAllUsesWith(InvertedCmp);
663           InstToErase.push_back(cast<Instruction>(Cond));
664         }
665       }
666     }
667   }
668   for (auto *I : InstToErase)
669     I->eraseFromParent();
670 }
671 
672 /// Remove all PHI values coming from "From" into "To" and remember
673 /// them in DeletedPhis
674 void StructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
675   PhiMap &Map = DeletedPhis[To];
676   for (PHINode &Phi : To->phis()) {
677     bool Recorded = false;
678     while (Phi.getBasicBlockIndex(From) != -1) {
679       Value *Deleted = Phi.removeIncomingValue(From, false);
680       Map[&Phi].push_back(std::make_pair(From, Deleted));
681       if (!Recorded) {
682         AffectedPhis.push_back(&Phi);
683         Recorded = true;
684       }
685     }
686   }
687 }
688 
689 /// Add a dummy PHI value as soon as we knew the new predecessor
690 void StructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
691   for (PHINode &Phi : To->phis()) {
692     Value *Undef = UndefValue::get(Phi.getType());
693     Phi.addIncoming(Undef, From);
694   }
695   AddedPhis[To].push_back(From);
696 }
697 
698 /// When we are reconstructing a PHI inside \p PHIBlock with incoming values
699 /// from predecessors \p Incomings, we have a chance to mark the available value
700 /// from some blocks as undefined. The function will find out all such blocks
701 /// and return in \p UndefBlks.
702 void StructurizeCFG::findUndefBlocks(
703     BasicBlock *PHIBlock, const SmallSet<BasicBlock *, 8> &Incomings,
704     SmallVector<BasicBlock *> &UndefBlks) const {
705   //  We may get a post-structured CFG like below:
706   //
707   //  | P1
708   //  |/
709   //  F1
710   //  |\
711   //  | N
712   //  |/
713   //  F2
714   //  |\
715   //  | P2
716   //  |/
717   //  F3
718   //  |\
719   //  B
720   //
721   // B is the block that has a PHI being reconstructed. P1/P2 are predecessors
722   // of B before structurization. F1/F2/F3 are flow blocks inserted during
723   // structurization process. Block N is not a predecessor of B before
724   // structurization, but are placed between the predecessors(P1/P2) of B after
725   // structurization. This usually means that threads went to N never take the
726   // path N->F2->F3->B. For example, the threads take the branch F1->N may
727   // always take the branch F2->P2. So, when we are reconstructing a PHI
728   // originally in B, we can safely say the incoming value from N is undefined.
729   SmallSet<BasicBlock *, 8> VisitedBlock;
730   SmallVector<BasicBlock *, 8> Stack;
731   if (PHIBlock == ParentRegion->getExit()) {
732     for (auto P : predecessors(PHIBlock)) {
733       if (ParentRegion->contains(P))
734         Stack.push_back(P);
735     }
736   } else {
737     append_range(Stack, predecessors(PHIBlock));
738   }
739 
740   // Do a backward traversal over the CFG, and stop further searching if
741   // the block is not a Flow. If a block is neither flow block nor the
742   // incoming predecessor, then the incoming value from the block is
743   // undefined value for the PHI being reconstructed.
744   while (!Stack.empty()) {
745     BasicBlock *Current = Stack.pop_back_val();
746     if (!VisitedBlock.insert(Current).second)
747       continue;
748 
749     if (FlowSet.contains(Current)) {
750       for (auto P : predecessors(Current))
751         Stack.push_back(P);
752     } else if (!Incomings.contains(Current)) {
753       UndefBlks.push_back(Current);
754     }
755   }
756 }
757 
758 /// Add the real PHI value as soon as everything is set up
759 void StructurizeCFG::setPhiValues() {
760   SmallVector<PHINode *, 8> InsertedPhis;
761   SSAUpdater Updater(&InsertedPhis);
762   for (const auto &AddedPhi : AddedPhis) {
763     BasicBlock *To = AddedPhi.first;
764     const BBVector &From = AddedPhi.second;
765 
766     if (!DeletedPhis.count(To))
767       continue;
768 
769     SmallVector<BasicBlock *> UndefBlks;
770     bool CachedUndefs = false;
771     PhiMap &Map = DeletedPhis[To];
772     for (const auto &PI : Map) {
773       PHINode *Phi = PI.first;
774       Value *Undef = UndefValue::get(Phi->getType());
775       Updater.Initialize(Phi->getType(), "");
776       Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
777       Updater.AddAvailableValue(To, Undef);
778 
779       SmallSet<BasicBlock *, 8> Incomings;
780       SmallVector<BasicBlock *> ConstantPreds;
781       for (const auto &VI : PI.second) {
782         Incomings.insert(VI.first);
783         Updater.AddAvailableValue(VI.first, VI.second);
784         if (isa<Constant>(VI.second))
785           ConstantPreds.push_back(VI.first);
786       }
787 
788       if (!CachedUndefs) {
789         findUndefBlocks(To, Incomings, UndefBlks);
790         CachedUndefs = true;
791       }
792 
793       for (auto UB : UndefBlks) {
794         // If this undef block is dominated by any predecessor(before
795         // structurization) of reconstructed PHI with constant incoming value,
796         // don't mark the available value as undefined. Setting undef to such
797         // block will stop us from getting optimal phi insertion.
798         if (any_of(ConstantPreds,
799                    [&](BasicBlock *CP) { return DT->dominates(CP, UB); }))
800           continue;
801         Updater.AddAvailableValue(UB, Undef);
802       }
803 
804       for (BasicBlock *FI : From)
805         Phi->setIncomingValueForBlock(FI, Updater.GetValueAtEndOfBlock(FI));
806       AffectedPhis.push_back(Phi);
807     }
808 
809     DeletedPhis.erase(To);
810   }
811   assert(DeletedPhis.empty());
812 
813   AffectedPhis.append(InsertedPhis.begin(), InsertedPhis.end());
814 }
815 
816 void StructurizeCFG::simplifyAffectedPhis() {
817   bool Changed;
818   do {
819     Changed = false;
820     SimplifyQuery Q(Func->getDataLayout());
821     Q.DT = DT;
822     // Setting CanUseUndef to true might extend value liveness, set it to false
823     // to achieve better register pressure.
824     Q.CanUseUndef = false;
825     for (WeakVH VH : AffectedPhis) {
826       if (auto Phi = dyn_cast_or_null<PHINode>(VH)) {
827         if (auto NewValue = simplifyInstruction(Phi, Q)) {
828           Phi->replaceAllUsesWith(NewValue);
829           Phi->eraseFromParent();
830           Changed = true;
831         }
832       }
833     }
834   } while (Changed);
835 }
836 
837 /// Remove phi values from all successors and then remove the terminator.
838 void StructurizeCFG::killTerminator(BasicBlock *BB) {
839   Instruction *Term = BB->getTerminator();
840   if (!Term)
841     return;
842 
843   for (BasicBlock *Succ : successors(BB))
844     delPhiValues(BB, Succ);
845 
846   Term->eraseFromParent();
847 }
848 
849 /// Let node exit(s) point to NewExit
850 void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
851                                 bool IncludeDominator) {
852   if (Node->isSubRegion()) {
853     Region *SubRegion = Node->getNodeAs<Region>();
854     BasicBlock *OldExit = SubRegion->getExit();
855     BasicBlock *Dominator = nullptr;
856 
857     // Find all the edges from the sub region to the exit.
858     // We use make_early_inc_range here because we modify BB's terminator.
859     for (BasicBlock *BB : llvm::make_early_inc_range(predecessors(OldExit))) {
860       if (!SubRegion->contains(BB))
861         continue;
862 
863       // Modify the edges to point to the new exit
864       delPhiValues(BB, OldExit);
865       BB->getTerminator()->replaceUsesOfWith(OldExit, NewExit);
866       addPhiValues(BB, NewExit);
867 
868       // Find the new dominator (if requested)
869       if (IncludeDominator) {
870         if (!Dominator)
871           Dominator = BB;
872         else
873           Dominator = DT->findNearestCommonDominator(Dominator, BB);
874       }
875     }
876 
877     // Change the dominator (if requested)
878     if (Dominator)
879       DT->changeImmediateDominator(NewExit, Dominator);
880 
881     // Update the region info
882     SubRegion->replaceExit(NewExit);
883   } else {
884     BasicBlock *BB = Node->getNodeAs<BasicBlock>();
885     killTerminator(BB);
886     BranchInst *Br = BranchInst::Create(NewExit, BB);
887     Br->setDebugLoc(TermDL[BB]);
888     addPhiValues(BB, NewExit);
889     if (IncludeDominator)
890       DT->changeImmediateDominator(NewExit, BB);
891   }
892 }
893 
894 /// Create a new flow node and update dominator tree and region info
895 BasicBlock *StructurizeCFG::getNextFlow(BasicBlock *Dominator) {
896   LLVMContext &Context = Func->getContext();
897   BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
898                        Order.back()->getEntry();
899   BasicBlock *Flow = BasicBlock::Create(Context, FlowBlockName,
900                                         Func, Insert);
901   FlowSet.insert(Flow);
902 
903   // use a temporary variable to avoid a use-after-free if the map's storage is
904   // reallocated
905   DebugLoc DL = TermDL[Dominator];
906   TermDL[Flow] = std::move(DL);
907 
908   DT->addNewBlock(Flow, Dominator);
909   ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
910   return Flow;
911 }
912 
913 /// Create a new or reuse the previous node as flow node
914 BasicBlock *StructurizeCFG::needPrefix(bool NeedEmpty) {
915   BasicBlock *Entry = PrevNode->getEntry();
916 
917   if (!PrevNode->isSubRegion()) {
918     killTerminator(Entry);
919     if (!NeedEmpty || Entry->getFirstInsertionPt() == Entry->end())
920       return Entry;
921   }
922 
923   // create a new flow node
924   BasicBlock *Flow = getNextFlow(Entry);
925 
926   // and wire it up
927   changeExit(PrevNode, Flow, true);
928   PrevNode = ParentRegion->getBBNode(Flow);
929   return Flow;
930 }
931 
932 /// Returns the region exit if possible, otherwise just a new flow node
933 BasicBlock *StructurizeCFG::needPostfix(BasicBlock *Flow,
934                                         bool ExitUseAllowed) {
935   if (!Order.empty() || !ExitUseAllowed)
936     return getNextFlow(Flow);
937 
938   BasicBlock *Exit = ParentRegion->getExit();
939   DT->changeImmediateDominator(Exit, Flow);
940   addPhiValues(Flow, Exit);
941   return Exit;
942 }
943 
944 /// Set the previous node
945 void StructurizeCFG::setPrevNode(BasicBlock *BB) {
946   PrevNode = ParentRegion->contains(BB) ? ParentRegion->getBBNode(BB)
947                                         : nullptr;
948 }
949 
950 /// Does BB dominate all the predicates of Node?
951 bool StructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
952   BBPredicates &Preds = Predicates[Node->getEntry()];
953   return llvm::all_of(Preds,
954                       [&](std::pair<BasicBlock *, ValueWeightPair> Pred) {
955                         return DT->dominates(BB, Pred.first);
956                       });
957 }
958 
959 /// Can we predict that this node will always be called?
960 bool StructurizeCFG::isPredictableTrue(RegionNode *Node) {
961   BBPredicates &Preds = Predicates[Node->getEntry()];
962   bool Dominated = false;
963 
964   // Regionentry is always true
965   if (!PrevNode)
966     return true;
967 
968   for (std::pair<BasicBlock *, ValueWeightPair> Pred : Preds) {
969     BasicBlock *BB = Pred.first;
970     Value *V = Pred.second.first;
971 
972     if (V != BoolTrue)
973       return false;
974 
975     if (!Dominated && DT->dominates(BB, PrevNode->getEntry()))
976       Dominated = true;
977   }
978 
979   // TODO: The dominator check is too strict
980   return Dominated;
981 }
982 
983 /// Take one node from the order vector and wire it up
984 void StructurizeCFG::wireFlow(bool ExitUseAllowed,
985                               BasicBlock *LoopEnd) {
986   RegionNode *Node = Order.pop_back_val();
987   Visited.insert(Node->getEntry());
988 
989   if (isPredictableTrue(Node)) {
990     // Just a linear flow
991     if (PrevNode) {
992       changeExit(PrevNode, Node->getEntry(), true);
993     }
994     PrevNode = Node;
995   } else {
996     // Insert extra prefix node (or reuse last one)
997     BasicBlock *Flow = needPrefix(false);
998 
999     // Insert extra postfix node (or use exit instead)
1000     BasicBlock *Entry = Node->getEntry();
1001     BasicBlock *Next = needPostfix(Flow, ExitUseAllowed);
1002 
1003     // let it point to entry and next block
1004     BranchInst *Br = BranchInst::Create(Entry, Next, BoolPoison, Flow);
1005     Br->setDebugLoc(TermDL[Flow]);
1006     Conditions.push_back(Br);
1007     addPhiValues(Flow, Entry);
1008     DT->changeImmediateDominator(Entry, Flow);
1009 
1010     PrevNode = Node;
1011     while (!Order.empty() && !Visited.count(LoopEnd) &&
1012            dominatesPredicates(Entry, Order.back())) {
1013       handleLoops(false, LoopEnd);
1014     }
1015 
1016     changeExit(PrevNode, Next, false);
1017     setPrevNode(Next);
1018   }
1019 }
1020 
1021 void StructurizeCFG::handleLoops(bool ExitUseAllowed,
1022                                  BasicBlock *LoopEnd) {
1023   RegionNode *Node = Order.back();
1024   BasicBlock *LoopStart = Node->getEntry();
1025 
1026   if (!Loops.count(LoopStart)) {
1027     wireFlow(ExitUseAllowed, LoopEnd);
1028     return;
1029   }
1030 
1031   if (!isPredictableTrue(Node))
1032     LoopStart = needPrefix(true);
1033 
1034   LoopEnd = Loops[Node->getEntry()];
1035   wireFlow(false, LoopEnd);
1036   while (!Visited.count(LoopEnd)) {
1037     handleLoops(false, LoopEnd);
1038   }
1039 
1040   assert(LoopStart != &LoopStart->getParent()->getEntryBlock());
1041 
1042   // Create an extra loop end node
1043   LoopEnd = needPrefix(false);
1044   BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
1045   BranchInst *Br = BranchInst::Create(Next, LoopStart, BoolPoison, LoopEnd);
1046   Br->setDebugLoc(TermDL[LoopEnd]);
1047   LoopConds.push_back(Br);
1048   addPhiValues(LoopEnd, LoopStart);
1049   setPrevNode(Next);
1050 }
1051 
1052 /// After this function control flow looks like it should be, but
1053 /// branches and PHI nodes only have undefined conditions.
1054 void StructurizeCFG::createFlow() {
1055   BasicBlock *Exit = ParentRegion->getExit();
1056   bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
1057 
1058   AffectedPhis.clear();
1059   DeletedPhis.clear();
1060   AddedPhis.clear();
1061   Conditions.clear();
1062   LoopConds.clear();
1063 
1064   PrevNode = nullptr;
1065   Visited.clear();
1066 
1067   while (!Order.empty()) {
1068     handleLoops(EntryDominatesExit, nullptr);
1069   }
1070 
1071   if (PrevNode)
1072     changeExit(PrevNode, Exit, EntryDominatesExit);
1073   else
1074     assert(EntryDominatesExit);
1075 }
1076 
1077 /// Handle a rare case where the disintegrated nodes instructions
1078 /// no longer dominate all their uses. Not sure if this is really necessary
1079 void StructurizeCFG::rebuildSSA() {
1080   SSAUpdater Updater;
1081   for (BasicBlock *BB : ParentRegion->blocks())
1082     for (Instruction &I : *BB) {
1083       bool Initialized = false;
1084       // We may modify the use list as we iterate over it, so we use
1085       // make_early_inc_range.
1086       for (Use &U : llvm::make_early_inc_range(I.uses())) {
1087         Instruction *User = cast<Instruction>(U.getUser());
1088         if (User->getParent() == BB) {
1089           continue;
1090         } else if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
1091           if (UserPN->getIncomingBlock(U) == BB)
1092             continue;
1093         }
1094 
1095         if (DT->dominates(&I, User))
1096           continue;
1097 
1098         if (!Initialized) {
1099           Value *Undef = UndefValue::get(I.getType());
1100           Updater.Initialize(I.getType(), "");
1101           Updater.AddAvailableValue(&Func->getEntryBlock(), Undef);
1102           Updater.AddAvailableValue(BB, &I);
1103           Initialized = true;
1104         }
1105         Updater.RewriteUseAfterInsertions(U);
1106       }
1107     }
1108 }
1109 
1110 static bool hasOnlyUniformBranches(Region *R, unsigned UniformMDKindID,
1111                                    const UniformityInfo &UA) {
1112   // Bool for if all sub-regions are uniform.
1113   bool SubRegionsAreUniform = true;
1114   // Count of how many direct children are conditional.
1115   unsigned ConditionalDirectChildren = 0;
1116 
1117   for (auto *E : R->elements()) {
1118     if (!E->isSubRegion()) {
1119       auto Br = dyn_cast<BranchInst>(E->getEntry()->getTerminator());
1120       if (!Br || !Br->isConditional())
1121         continue;
1122 
1123       if (!UA.isUniform(Br))
1124         return false;
1125 
1126       // One of our direct children is conditional.
1127       ConditionalDirectChildren++;
1128 
1129       LLVM_DEBUG(dbgs() << "BB: " << Br->getParent()->getName()
1130                         << " has uniform terminator\n");
1131     } else {
1132       // Explicitly refuse to treat regions as uniform if they have non-uniform
1133       // subregions. We cannot rely on UniformityAnalysis for branches in
1134       // subregions because those branches may have been removed and re-created,
1135       // so we look for our metadata instead.
1136       //
1137       // Warning: It would be nice to treat regions as uniform based only on
1138       // their direct child basic blocks' terminators, regardless of whether
1139       // subregions are uniform or not. However, this requires a very careful
1140       // look at SIAnnotateControlFlow to make sure nothing breaks there.
1141       for (auto *BB : E->getNodeAs<Region>()->blocks()) {
1142         auto Br = dyn_cast<BranchInst>(BB->getTerminator());
1143         if (!Br || !Br->isConditional())
1144           continue;
1145 
1146         if (!Br->getMetadata(UniformMDKindID)) {
1147           // Early exit if we cannot have relaxed uniform regions.
1148           if (!RelaxedUniformRegions)
1149             return false;
1150 
1151           SubRegionsAreUniform = false;
1152           break;
1153         }
1154       }
1155     }
1156   }
1157 
1158   // Our region is uniform if:
1159   // 1. All conditional branches that are direct children are uniform (checked
1160   // above).
1161   // 2. And either:
1162   //   a. All sub-regions are uniform.
1163   //   b. There is one or less conditional branches among the direct children.
1164   return SubRegionsAreUniform || (ConditionalDirectChildren <= 1);
1165 }
1166 
1167 void StructurizeCFG::init(Region *R) {
1168   LLVMContext &Context = R->getEntry()->getContext();
1169 
1170   Boolean = Type::getInt1Ty(Context);
1171   BoolTrue = ConstantInt::getTrue(Context);
1172   BoolFalse = ConstantInt::getFalse(Context);
1173   BoolPoison = PoisonValue::get(Boolean);
1174 
1175   this->UA = nullptr;
1176 }
1177 
1178 bool StructurizeCFG::makeUniformRegion(Region *R, UniformityInfo &UA) {
1179   if (R->isTopLevelRegion())
1180     return false;
1181 
1182   this->UA = &UA;
1183 
1184   // TODO: We could probably be smarter here with how we handle sub-regions.
1185   // We currently rely on the fact that metadata is set by earlier invocations
1186   // of the pass on sub-regions, and that this metadata doesn't get lost --
1187   // but we shouldn't rely on metadata for correctness!
1188   unsigned UniformMDKindID =
1189       R->getEntry()->getContext().getMDKindID("structurizecfg.uniform");
1190 
1191   if (hasOnlyUniformBranches(R, UniformMDKindID, UA)) {
1192     LLVM_DEBUG(dbgs() << "Skipping region with uniform control flow: " << *R
1193                       << '\n');
1194 
1195     // Mark all direct child block terminators as having been treated as
1196     // uniform. To account for a possible future in which non-uniform
1197     // sub-regions are treated more cleverly, indirect children are not
1198     // marked as uniform.
1199     MDNode *MD = MDNode::get(R->getEntry()->getParent()->getContext(), {});
1200     for (RegionNode *E : R->elements()) {
1201       if (E->isSubRegion())
1202         continue;
1203 
1204       if (Instruction *Term = E->getEntry()->getTerminator())
1205         Term->setMetadata(UniformMDKindID, MD);
1206     }
1207 
1208     return true;
1209   }
1210   return false;
1211 }
1212 
1213 /// Run the transformation for each region found
1214 bool StructurizeCFG::run(Region *R, DominatorTree *DT) {
1215   if (R->isTopLevelRegion())
1216     return false;
1217 
1218   this->DT = DT;
1219 
1220   Func = R->getEntry()->getParent();
1221   assert(hasOnlySimpleTerminator(*Func) && "Unsupported block terminator.");
1222 
1223   ParentRegion = R;
1224 
1225   orderNodes();
1226   collectInfos();
1227   createFlow();
1228   insertConditions(false);
1229   insertConditions(true);
1230   setPhiValues();
1231   simplifyConditions();
1232   simplifyAffectedPhis();
1233   rebuildSSA();
1234 
1235   // Cleanup
1236   Order.clear();
1237   Visited.clear();
1238   DeletedPhis.clear();
1239   AddedPhis.clear();
1240   Predicates.clear();
1241   Conditions.clear();
1242   Loops.clear();
1243   LoopPreds.clear();
1244   LoopConds.clear();
1245   FlowSet.clear();
1246   TermDL.clear();
1247 
1248   return true;
1249 }
1250 
1251 Pass *llvm::createStructurizeCFGPass(bool SkipUniformRegions) {
1252   return new StructurizeCFGLegacyPass(SkipUniformRegions);
1253 }
1254 
1255 static void addRegionIntoQueue(Region &R, std::vector<Region *> &Regions) {
1256   Regions.push_back(&R);
1257   for (const auto &E : R)
1258     addRegionIntoQueue(*E, Regions);
1259 }
1260 
1261 StructurizeCFGPass::StructurizeCFGPass(bool SkipUniformRegions_)
1262     : SkipUniformRegions(SkipUniformRegions_) {
1263   if (ForceSkipUniformRegions.getNumOccurrences())
1264     SkipUniformRegions = ForceSkipUniformRegions.getValue();
1265 }
1266 
1267 void StructurizeCFGPass::printPipeline(
1268     raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
1269   static_cast<PassInfoMixin<StructurizeCFGPass> *>(this)->printPipeline(
1270       OS, MapClassName2PassName);
1271   if (SkipUniformRegions)
1272     OS << "<skip-uniform-regions>";
1273 }
1274 
1275 PreservedAnalyses StructurizeCFGPass::run(Function &F,
1276                                           FunctionAnalysisManager &AM) {
1277 
1278   bool Changed = false;
1279   DominatorTree *DT = &AM.getResult<DominatorTreeAnalysis>(F);
1280   auto &RI = AM.getResult<RegionInfoAnalysis>(F);
1281 
1282   UniformityInfo *UI = nullptr;
1283   if (SkipUniformRegions)
1284     UI = &AM.getResult<UniformityInfoAnalysis>(F);
1285 
1286   std::vector<Region *> Regions;
1287   addRegionIntoQueue(*RI.getTopLevelRegion(), Regions);
1288   while (!Regions.empty()) {
1289     Region *R = Regions.back();
1290     Regions.pop_back();
1291 
1292     StructurizeCFG SCFG;
1293     SCFG.init(R);
1294 
1295     if (SkipUniformRegions && SCFG.makeUniformRegion(R, *UI)) {
1296       Changed = true; // May have added metadata.
1297       continue;
1298     }
1299 
1300     Changed |= SCFG.run(R, DT);
1301   }
1302   if (!Changed)
1303     return PreservedAnalyses::all();
1304   PreservedAnalyses PA;
1305   PA.preserve<DominatorTreeAnalysis>();
1306   return PA;
1307 }
1308