LLVM 24.0.0git
StructurizeCFG.cpp
Go to the documentation of this file.
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
10#include "ScalarOptions.h"
11#include "llvm/ADT/DenseMap.h"
13#include "llvm/ADT/MapVector.h"
15#include "llvm/ADT/STLExtras.h"
23#include "llvm/IR/BasicBlock.h"
24#include "llvm/IR/CFG.h"
25#include "llvm/IR/Constants.h"
26#include "llvm/IR/Dominators.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/InstrTypes.h"
29#include "llvm/IR/Instruction.h"
31#include "llvm/IR/Metadata.h"
32#include "llvm/IR/PassManager.h"
35#include "llvm/IR/Type.h"
36#include "llvm/IR/Use.h"
37#include "llvm/IR/Value.h"
38#include "llvm/IR/ValueHandle.h"
40#include "llvm/Pass.h"
42#include "llvm/Support/Debug.h"
50#include <cassert>
51#include <utility>
52
53using namespace llvm;
54using namespace llvm::PatternMatch;
55
56#define DEBUG_TYPE "structurizecfg"
57
58// The name for newly created blocks.
59const char FlowBlockName[] = "Flow";
60
61namespace {
62
63// Definition of the complex types used in this pass.
64
65using BBValuePair = std::pair<BasicBlock *, Value *>;
66
67using RNVector = SmallVector<RegionNode *, 8>;
68using BBVector = SmallVector<BasicBlock *, 8>;
69using BranchVector = SmallVector<CondBrInst *, 8>;
70using BBValueVector = SmallVector<BBValuePair, 2>;
71
73
75using BB2BBVecMap = MapVector<BasicBlock *, BBVector>;
76
77using BBPhiMap = DenseMap<BasicBlock *, PhiMap>;
78
79using MaybeCondBranchWeights = std::optional<class CondBranchWeights>;
80
81class CondBranchWeights {
82 uint32_t TrueWeight;
83 uint32_t FalseWeight;
84
85 CondBranchWeights(uint32_t T, uint32_t F) : TrueWeight(T), FalseWeight(F) {}
86
87public:
88 static MaybeCondBranchWeights tryParse(const CondBrInst &Br) {
89 uint64_t T, F;
90 if (!extractBranchWeights(Br, T, F))
91 return std::nullopt;
92
93 return CondBranchWeights(T, F);
94 }
95
96 static void setMetadata(CondBrInst &Br,
97 const MaybeCondBranchWeights &Weights) {
98 if (!Weights)
99 return;
100 uint32_t Arr[] = {Weights->TrueWeight, Weights->FalseWeight};
101 setBranchWeights(Br, Arr, false);
102 }
103
104 CondBranchWeights invert() const {
105 return CondBranchWeights{FalseWeight, TrueWeight};
106 }
107};
108
109struct PredInfo {
110 Value *Pred;
111 MaybeCondBranchWeights Weights;
112};
113
117using Val2BBMap = DenseMap<Value *, BasicBlock *>;
118
119// A traits type that is intended to be used in graph algorithms. The graph
120// traits starts at an entry node, and traverses the RegionNodes that are in
121// the Nodes set.
122struct SubGraphTraits {
123 using NodeRef = std::pair<RegionNode *, SmallDenseSet<RegionNode *> *>;
124 using BaseSuccIterator = GraphTraits<RegionNode *>::ChildIteratorType;
125
126 // This wraps a set of Nodes into the iterator, so we know which edges to
127 // filter out.
128 class WrappedSuccIterator
129 : public iterator_adaptor_base<
130 WrappedSuccIterator, BaseSuccIterator,
131 std::iterator_traits<BaseSuccIterator>::iterator_category, NodeRef,
132 std::ptrdiff_t, NodeRef *, NodeRef> {
134
135 public:
136 WrappedSuccIterator(BaseSuccIterator It, SmallDenseSet<RegionNode *> *Nodes)
137 : iterator_adaptor_base(It), Nodes(Nodes) {}
138
139 NodeRef operator*() const { return {*I, Nodes}; }
140 };
141
142 static bool filterAll(const NodeRef &N) { return true; }
143 static bool filterSet(const NodeRef &N) { return N.second->count(N.first); }
144
145 using ChildIteratorType =
146 filter_iterator<WrappedSuccIterator, bool (*)(const NodeRef &)>;
147
148 static NodeRef getEntryNode(Region *R) {
149 return {GraphTraits<Region *>::getEntryNode(R), nullptr};
150 }
151
152 static NodeRef getEntryNode(NodeRef N) { return N; }
153
154 static iterator_range<ChildIteratorType> children(const NodeRef &N) {
155 auto *filter = N.second ? &filterSet : &filterAll;
156 return make_filter_range(
159 {GraphTraits<RegionNode *>::child_end(N.first), N.second}),
160 filter);
161 }
162
163 static ChildIteratorType child_begin(const NodeRef &N) {
164 return children(N).begin();
165 }
166
167 static ChildIteratorType child_end(const NodeRef &N) {
168 return children(N).end();
169 }
170};
171
172/// Finds the nearest common dominator of a set of BasicBlocks.
173///
174/// For every BB you add to the set, you can specify whether we "remember" the
175/// block. When you get the common dominator, you can also ask whether it's one
176/// of the blocks we remembered.
177class NearestCommonDominator {
178 DominatorTree *DT;
179 BasicBlock *Result = nullptr;
180 bool ResultIsRemembered = false;
181
182 /// Add BB to the resulting dominator.
183 void addBlock(BasicBlock *BB, bool Remember) {
184 if (!Result) {
185 Result = BB;
186 ResultIsRemembered = Remember;
187 return;
188 }
189
190 BasicBlock *NewResult = DT->findNearestCommonDominator(Result, BB);
191 if (NewResult != Result)
192 ResultIsRemembered = false;
193 if (NewResult == BB)
194 ResultIsRemembered |= Remember;
195 Result = NewResult;
196 }
197
198public:
199 explicit NearestCommonDominator(DominatorTree *DomTree) : DT(DomTree) {}
200
201 void addBlock(BasicBlock *BB) {
202 addBlock(BB, /* Remember = */ false);
203 }
204
205 void addAndRememberBlock(BasicBlock *BB) {
206 addBlock(BB, /* Remember = */ true);
207 }
208
209 /// Get the nearest common dominator of all the BBs added via addBlock() and
210 /// addAndRememberBlock().
211 BasicBlock *result() { return Result; }
212
213 /// Is the BB returned by getResult() one of the blocks we added to the set
214 /// with addAndRememberBlock()?
215 bool resultIsRememberedBlock() { return ResultIsRemembered; }
216};
217
218/// Transforms the control flow graph on one single entry/exit region
219/// at a time.
220///
221/// After the transform all "If"/"Then"/"Else" style control flow looks like
222/// this:
223///
224/// \verbatim
225/// 1
226/// ||
227/// | |
228/// 2 |
229/// | /
230/// |/
231/// 3
232/// || Where:
233/// | | 1 = "If" block, calculates the condition
234/// 4 | 2 = "Then" subregion, runs if the condition is true
235/// | / 3 = "Flow" blocks, newly inserted flow blocks, rejoins the flow
236/// |/ 4 = "Else" optional subregion, runs if the condition is false
237/// 5 5 = "End" block, also rejoins the control flow
238/// \endverbatim
239///
240/// Control flow is expressed as a branch where the true exit goes into the
241/// "Then"/"Else" region, while the false exit skips the region
242/// The condition for the optional "Else" region is expressed as a PHI node.
243/// The incoming values of the PHI node are true for the "If" edge and false
244/// for the "Then" edge.
245///
246/// Additionally to that even complicated loops look like this:
247///
248/// \verbatim
249/// 1
250/// ||
251/// | |
252/// 2 ^ Where:
253/// | / 1 = "Entry" block
254/// |/ 2 = "Loop" optional subregion, with all exits at "Flow" block
255/// 3 3 = "Flow" block, with back edge to entry block
256/// |
257/// \endverbatim
258///
259/// The back edge of the "Flow" block is always on the false side of the branch
260/// while the true side continues the general flow. So the loop condition
261/// consist of a network of PHI nodes where the true incoming values expresses
262/// breaks and the false values expresses continue states.
263
264class StructurizeCFG {
265 Type *Boolean;
266 ConstantInt *BoolTrue;
267 ConstantInt *BoolFalse;
268 Value *BoolPoison;
270 Function *Func;
271 Region *ParentRegion;
272
273 DominatorTree *DT;
274
276 BBSet Visited;
277 BBSet FlowSet;
278
279 SmallVector<WeakVH, 8> AffectedPhis;
280 BBPhiMap DeletedPhis;
281 BB2BBVecMap AddedPhis;
282
283 PredMap Predicates;
284 BranchVector Conditions;
285
286 BB2BBMap Loops;
287 PredMap LoopPreds;
288 BranchVector LoopConds;
289
290 Val2BBMap HoistedValues;
291
292 RegionNode *PrevNode;
293
294 void hoistZeroCostElseBlockPhiValues(BasicBlock *ElseBB, BasicBlock *ThenBB);
295
296 bool isHoistableInstruction(Instruction *I, BasicBlock *BB,
297 BasicBlock *HoistTo);
298
299 void orderNodes();
300
301 void analyzeLoops(RegionNode *N);
302
303 PredInfo buildCondition(CondBrInst *Term, unsigned Idx, bool Invert);
304
305 void gatherPredicates(RegionNode *N);
306
307 void collectInfos();
308
309 void insertConditions(bool Loops, SSAUpdaterBulk &PhiInserter);
310
311 void simplifyConditions();
312
313 void delPhiValues(BasicBlock *From, BasicBlock *To);
314
315 void addPhiValues(BasicBlock *From, BasicBlock *To);
316
317 void findUndefBlocks(BasicBlock *PHIBlock,
318 const SmallPtrSet<BasicBlock *, 8> &Incomings,
319 SmallVector<BasicBlock *> &UndefBlks) const;
320
321 void mergeIfCompatible(EquivalenceClasses<PHINode *> &PhiClasses, PHINode *A,
322 PHINode *B);
323
324 void setPhiValues();
325
326 void simplifyAffectedPhis();
327
328 void simplifyHoistedPhis();
329
330 DebugLoc killTerminator(BasicBlock *BB);
331
332 void changeExit(RegionNode *Node, BasicBlock *NewExit,
333 bool IncludeDominator);
334
335 BasicBlock *getNextFlow(BasicBlock *Dominator);
336
337 std::pair<BasicBlock *, DebugLoc> needPrefix(bool NeedEmpty);
338
339 BasicBlock *needPostfix(BasicBlock *Flow, bool ExitUseAllowed);
340
341 void setPrevNode(BasicBlock *BB);
342
343 bool dominatesPredicates(BasicBlock *BB, RegionNode *Node);
344
345 bool isPredictableTrue(RegionNode *Node);
346
347 void wireFlow(bool ExitUseAllowed, BasicBlock *LoopEnd);
348
349 void handleLoops(bool ExitUseAllowed, BasicBlock *LoopEnd);
350
351 void createFlow();
352
353 void rebuildSSA();
354
355public:
356 void init(Region *R);
357 bool run(Region *R, DominatorTree *DT, const TargetTransformInfo *TTI);
358 bool makeUniformRegion(Region *R, const UniformityInfo &UA);
359};
360
361class StructurizeCFGLegacyPass : public FunctionPass {
362 bool SkipUniformRegions;
363
364public:
365 static char ID;
366
367 explicit StructurizeCFGLegacyPass(bool SkipUniformRegions_ = false)
368 : FunctionPass(ID), SkipUniformRegions(SkipUniformRegions_) {
370 }
371
372 bool runOnFunction(Function &F) override;
373
374 StringRef getPassName() const override { return "Structurize control flow"; }
375
376 void getAnalysisUsage(AnalysisUsage &AU) const override {
381
383 }
384};
385
386} // end anonymous namespace
387
388char StructurizeCFGLegacyPass::ID = 0;
389
390INITIALIZE_PASS_BEGIN(StructurizeCFGLegacyPass, "structurizecfg",
391 "Structurize the CFG", false, false)
396INITIALIZE_PASS_END(StructurizeCFGLegacyPass, "structurizecfg",
397 "Structurize the CFG", false, false)
398
399/// Checks whether an instruction is zero cost instruction and checks if the
400/// operands are from different BB. If so, this instruction can be coalesced
401/// if its hoisted to predecessor block. So, this returns true.
402bool StructurizeCFG::isHoistableInstruction(Instruction *I, BasicBlock *BB,
403 BasicBlock *HoistTo) {
404 if (I->getParent() != BB || isa<PHINode>(I))
405 return false;
406
407 // If the instruction is not a zero cost instruction, return false.
408 auto Cost = TTI->getInstructionCost(I, TargetTransformInfo::TCK_Latency);
410 Cost.isValid()
411 ? Cost.getValue()
413 if (CostVal != 0)
414 return false;
415
416 // Check if all operands are available at the hoisting destination.
417 for (auto &Op : I->operands()) {
418 if (auto *OpI = dyn_cast<Instruction>(Op)) {
419 // Operand must dominate the hoisting destination.
420 if (!DT->dominates(OpI->getParent(), HoistTo))
421 return false;
422 }
423 }
424
425 return true;
426}
427
428/// Structurization can introduce unnecessary VGPR copies due to register
429/// coalescing interference. For example, if the Else block has a zero-cost
430/// instruction and the Then block modifies the VGPR value, only one value is
431/// live at a time in merge block before structurization. After structurization,
432/// the coalescer may incorrectly treat the Then value as live in the Else block
433/// (via the path Then → Flow → Else), leading to unnecessary VGPR copies.
434///
435/// This function examines phi nodes whose incoming values are zero-cost
436/// instructions in the Else block. It identifies such values that can be safely
437/// hoisted and moves them to the nearest common dominator of Then and Else
438/// blocks. A follow-up function after setting PhiNodes assigns the hoisted
439/// value to poison phi nodes along the if→flow edge, aiding register coalescing
440/// and minimizing unnecessary live ranges.
441void StructurizeCFG::hoistZeroCostElseBlockPhiValues(BasicBlock *ElseBB,
442 BasicBlock *ThenBB) {
443
444 BasicBlock *ElseSucc = ElseBB->getSingleSuccessor();
445 BasicBlock *CommonDominator = DT->findNearestCommonDominator(ElseBB, ThenBB);
446
447 if (!ElseSucc || !CommonDominator)
448 return;
449 // Only hoist in a simple if-else: ThenBB must branch directly to ElseSucc
450 // and ElseSucc must have exactly 2 predecessors (ThenBB and ElseBB).
451 // simplifyHoistedPhis assumes this exact shape; with additional predecessors
452 // the hoisted value leaks into unrelated control-flow paths.
453 if (ThenBB->getSingleSuccessor() != ElseSucc ||
454 !ElseSucc->hasNPredecessors(2))
455 return;
456 Instruction *Term = CommonDominator->getTerminator();
457 for (PHINode &Phi : ElseSucc->phis()) {
458 Value *ElseVal = Phi.getIncomingValueForBlock(ElseBB);
459 auto *Inst = dyn_cast<Instruction>(ElseVal);
460 if (!Inst || !isHoistableInstruction(Inst, ElseBB, CommonDominator))
461 continue;
462 Inst->removeFromParent();
463 Inst->insertInto(CommonDominator, Term->getIterator());
464 HoistedValues[Inst] = CommonDominator;
465 }
466}
467
468/// Build up the general order of nodes, by performing a topological sort of the
469/// parent region's nodes, while ensuring that there is no outer cycle node
470/// between any two inner cycle nodes.
471void StructurizeCFG::orderNodes() {
472 Order.resize(std::distance(GraphTraits<Region *>::nodes_begin(ParentRegion),
473 GraphTraits<Region *>::nodes_end(ParentRegion)));
474 if (Order.empty())
475 return;
476
477 SmallDenseSet<RegionNode *> Nodes;
478 auto EntryNode = SubGraphTraits::getEntryNode(ParentRegion);
479
480 // A list of range indices of SCCs in Order, to be processed.
482 unsigned I = 0, E = Order.size();
483 while (true) {
484 // Run through all the SCCs in the subgraph starting with Entry.
485 for (auto SCCI =
487 EntryNode);
488 !SCCI.isAtEnd(); ++SCCI) {
489 auto &SCC = *SCCI;
490
491 // An SCC up to the size of 2, can be reduced to an entry (the last node),
492 // and a possible additional node. Therefore, it is already in order, and
493 // there is no need to add it to the work-list.
494 unsigned Size = SCC.size();
495 if (Size > 2)
496 WorkList.emplace_back(I, I + Size);
497
498 // Add the SCC nodes to the Order array.
499 for (const auto &N : SCC) {
500 assert(I < E && "SCC size mismatch!");
501 Order[I++] = N.first;
502 }
503 }
504 assert(I == E && "SCC size mismatch!");
505
506 // If there are no more SCCs to order, then we are done.
507 if (WorkList.empty())
508 break;
509
510 std::tie(I, E) = WorkList.pop_back_val();
511
512 // Collect the set of nodes in the SCC's subgraph. These are only the
513 // possible child nodes; we do not add the entry (last node) otherwise we
514 // will have the same exact SCC all over again.
515 Nodes.clear();
516 Nodes.insert(Order.begin() + I, Order.begin() + E - 1);
517
518 // Update the entry node.
519 EntryNode.first = Order[E - 1];
520 EntryNode.second = &Nodes;
521 }
522}
523
524/// Determine the end of the loops
525void StructurizeCFG::analyzeLoops(RegionNode *N) {
526 if (N->isSubRegion()) {
527 // Test for exit as back edge
528 BasicBlock *Exit = N->getNodeAs<Region>()->getExit();
529 if (Visited.count(Exit))
530 Loops[Exit] = N->getEntry();
531
532 } else {
533 // Test for successors as back edge
534 // TODO: support other terminators other than branches.
535 BasicBlock *BB = N->getNodeAs<BasicBlock>();
537 for (BasicBlock *Succ : successors(BB))
538 if (Visited.count(Succ))
539 Loops[Succ] = BB;
540 }
541}
542
543/// Build the condition for one edge
544PredInfo StructurizeCFG::buildCondition(CondBrInst *Term, unsigned Idx,
545 bool Invert) {
546 Value *Cond = Term->getCondition();
547 auto Weights = CondBranchWeights::tryParse(*Term);
548 if (Idx != (unsigned)Invert) {
550 if (Weights)
551 Weights = Weights->invert();
552 }
553 return {Cond, Weights};
554}
555
556/// Analyze the predecessors of each block and build up predicates
557void StructurizeCFG::gatherPredicates(RegionNode *N) {
558 RegionInfo *RI = ParentRegion->getRegionInfo();
559 BasicBlock *BB = N->getEntry();
560 BBPredicates &Pred = Predicates[BB];
561 BBPredicates &LPred = LoopPreds[BB];
562
563 for (BasicBlock *P : predecessors(BB)) {
564 // Ignore it if it's a branch from outside into our region entry
565 if (!ParentRegion->contains(P))
566 continue;
567
568 Region *R = RI->getRegionFor(P);
569 if (R == ParentRegion) {
570 if (isa<UncondBrInst>(P->getTerminator())) {
571 if (Visited.count(P))
572 Pred[P] = {BoolTrue, std::nullopt};
573 else
574 LPred[P] = {BoolFalse, std::nullopt};
575 } else if (auto *CondBr = dyn_cast<CondBrInst>(P->getTerminator())) {
576 bool Idx = CondBr->getSuccessor(0) == BB ? 0 : 1;
577 if (Visited.count(P)) {
578 // Normal forward edge
579 // Try to treat Other like an ELSE block
580 BasicBlock *Other = CondBr->getSuccessor(!Idx);
581 if (Visited.count(Other) && !Loops.count(Other) &&
582 !Pred.count(Other) && !Pred.count(P)) {
583 hoistZeroCostElseBlockPhiValues(BB, Other);
584 Pred[Other] = {BoolFalse, std::nullopt};
585 Pred[P] = {BoolTrue, std::nullopt};
586 } else
587 Pred[P] = buildCondition(CondBr, Idx, false);
588 } else {
589 // Back edge
590 LPred[P] = buildCondition(CondBr, Idx, true);
591 }
592 }
593 } else {
594 // It's an exit from a sub region
595 while (R->getParent() != ParentRegion)
596 R = R->getParent();
597
598 // Edge from inside a subregion to its entry, ignore it
599 if (*R == *N)
600 continue;
601
602 BasicBlock *Entry = R->getEntry();
603 if (Visited.count(Entry))
604 Pred[Entry] = {BoolTrue, std::nullopt};
605 else
606 LPred[Entry] = {BoolFalse, std::nullopt};
607 }
608 }
609}
610
611/// Collect various loop and predicate infos
612void StructurizeCFG::collectInfos() {
613 // Reset predicate
614 Predicates.clear();
615
616 // and loop infos
617 Loops.clear();
618 LoopPreds.clear();
619
620 // Reset the visited nodes
621 Visited.clear();
622
623 for (RegionNode *RN : reverse(Order)) {
624 LLVM_DEBUG(dbgs() << "Visiting: "
625 << (RN->isSubRegion() ? "SubRegion with entry: " : "")
626 << RN->getEntry()->getName() << "\n");
627
628 // Analyze all the conditions leading to a node
629 gatherPredicates(RN);
630
631 // Remember that we've seen this node
632 Visited.insert(RN->getEntry());
633
634 // Find the last back edges
635 analyzeLoops(RN);
636 }
637}
638
639/// Insert the missing branch conditions
640void StructurizeCFG::insertConditions(bool Loops, SSAUpdaterBulk &PhiInserter) {
641 BranchVector &Conds = Loops ? LoopConds : Conditions;
642 Value *Default = Loops ? BoolTrue : BoolFalse;
643
644 for (CondBrInst *Term : Conds) {
645 BasicBlock *Parent = Term->getParent();
646 BasicBlock *SuccTrue = Term->getSuccessor(0);
647 BasicBlock *SuccFalse = Term->getSuccessor(1);
648
649 unsigned Variable = PhiInserter.AddVariable("", Boolean);
650 PhiInserter.AddAvailableValue(Variable, Loops ? SuccFalse : Parent,
651 Default);
652
653 BBPredicates &Preds = Loops ? LoopPreds[SuccFalse] : Predicates[SuccTrue];
654
655 NearestCommonDominator Dominator(DT);
656 Dominator.addBlock(Parent);
657
658 PredInfo ParentInfo{nullptr, std::nullopt};
659 for (auto [BB, PI] : Preds) {
660 if (BB == Parent) {
661 ParentInfo = PI;
662 break;
663 }
664 PhiInserter.AddAvailableValue(Variable, BB, PI.Pred);
665 Dominator.addAndRememberBlock(BB);
666 }
667
668 if (ParentInfo.Pred) {
669 Term->setCondition(ParentInfo.Pred);
670 CondBranchWeights::setMetadata(*Term, ParentInfo.Weights);
671 } else {
672 if (!Dominator.resultIsRememberedBlock())
673 PhiInserter.AddAvailableValue(Variable, Dominator.result(), Default);
674
675 PhiInserter.AddUse(Variable, &Term->getOperandUse(0));
676 }
677 }
678}
679
680/// Simplify any inverted conditions that were built by buildConditions.
681void StructurizeCFG::simplifyConditions() {
682 SmallVector<Instruction *> InstToErase;
683 for (auto &I : concat<PredMap::value_type>(Predicates, LoopPreds)) {
684 auto &Preds = I.second;
685 for (auto [BB, PI] : Preds) {
686 Instruction *Inverted;
687 if (match(PI.Pred, m_Not(m_OneUse(m_Instruction(Inverted)))) &&
688 !PI.Pred->use_empty()) {
689 if (auto *InvertedCmp = dyn_cast<CmpInst>(Inverted)) {
690 InvertedCmp->setPredicate(InvertedCmp->getInversePredicate());
691 PI.Pred->replaceAllUsesWith(InvertedCmp);
692 InstToErase.push_back(cast<Instruction>(PI.Pred));
693 }
694 }
695 }
696 }
697 for (auto *I : InstToErase)
698 I->eraseFromParent();
699}
700
701/// Remove all PHI values coming from "From" into "To" and remember
702/// them in DeletedPhis
703void StructurizeCFG::delPhiValues(BasicBlock *From, BasicBlock *To) {
704 PhiMap &Map = DeletedPhis[To];
705 for (PHINode &Phi : To->phis()) {
706 bool Recorded = false;
707 while (Phi.getBasicBlockIndex(From) != -1) {
708 Value *Deleted = Phi.removeIncomingValue(From, false);
709 Map[&Phi].push_back(std::make_pair(From, Deleted));
710 if (!Recorded) {
711 AffectedPhis.push_back(&Phi);
712 Recorded = true;
713 }
714 }
715 }
716}
717
718/// Add a dummy PHI value as soon as we knew the new predecessor
719void StructurizeCFG::addPhiValues(BasicBlock *From, BasicBlock *To) {
720 for (PHINode &Phi : To->phis()) {
721 Value *Poison = PoisonValue::get(Phi.getType());
722 Phi.addIncoming(Poison, From);
723 }
724 AddedPhis[To].push_back(From);
725}
726
727/// When we are reconstructing a PHI inside \p PHIBlock with incoming values
728/// from predecessors \p Incomings, we have a chance to mark the available value
729/// from some blocks as undefined. The function will find out all such blocks
730/// and return in \p UndefBlks.
731void StructurizeCFG::findUndefBlocks(
732 BasicBlock *PHIBlock, const SmallPtrSet<BasicBlock *, 8> &Incomings,
733 SmallVector<BasicBlock *> &UndefBlks) const {
734 // We may get a post-structured CFG like below:
735 //
736 // | P1
737 // |/
738 // F1
739 // |\
740 // | N
741 // |/
742 // F2
743 // |\
744 // | P2
745 // |/
746 // F3
747 // |\
748 // B
749 //
750 // B is the block that has a PHI being reconstructed. P1/P2 are predecessors
751 // of B before structurization. F1/F2/F3 are flow blocks inserted during
752 // structurization process. Block N is not a predecessor of B before
753 // structurization, but are placed between the predecessors(P1/P2) of B after
754 // structurization. This usually means that threads went to N never take the
755 // path N->F2->F3->B. For example, the threads take the branch F1->N may
756 // always take the branch F2->P2. So, when we are reconstructing a PHI
757 // originally in B, we can safely say the incoming value from N is undefined.
758 SmallPtrSet<BasicBlock *, 8> VisitedBlock;
759 SmallVector<BasicBlock *, 8> Stack;
760 if (PHIBlock == ParentRegion->getExit()) {
761 for (auto P : predecessors(PHIBlock)) {
762 if (ParentRegion->contains(P))
763 Stack.push_back(P);
764 }
765 } else {
766 append_range(Stack, predecessors(PHIBlock));
767 }
768
769 // Do a backward traversal over the CFG, and stop further searching if
770 // the block is not a Flow. If a block is neither flow block nor the
771 // incoming predecessor, then the incoming value from the block is
772 // undefined value for the PHI being reconstructed.
773 while (!Stack.empty()) {
774 BasicBlock *Current = Stack.pop_back_val();
775 if (!VisitedBlock.insert(Current).second)
776 continue;
777
778 if (FlowSet.contains(Current))
779 llvm::append_range(Stack, predecessors(Current));
780 else if (!Incomings.contains(Current))
781 UndefBlks.push_back(Current);
782 }
783}
784
785// If two phi nodes have compatible incoming values (for each
786// incoming block, either they have the same incoming value or only one phi
787// node has an incoming value), let them share the merged incoming values. The
788// merge process is guided by the equivalence information from \p PhiClasses.
789// The function will possibly update the incoming values of leader phi in
790// DeletedPhis.
791void StructurizeCFG::mergeIfCompatible(
792 EquivalenceClasses<PHINode *> &PhiClasses, PHINode *A, PHINode *B) {
793 auto ItA = PhiClasses.findLeader(PhiClasses.insert(A));
794 auto ItB = PhiClasses.findLeader(PhiClasses.insert(B));
795 // They are already in the same class, no work needed.
796 if (ItA == ItB)
797 return;
798
799 PHINode *LeaderA = *ItA;
800 PHINode *LeaderB = *ItB;
801 BBValueVector &IncomingA = DeletedPhis[LeaderA->getParent()][LeaderA];
802 BBValueVector &IncomingB = DeletedPhis[LeaderB->getParent()][LeaderB];
803
804 DenseMap<BasicBlock *, Value *> Mergeable(IncomingA.begin(), IncomingA.end());
805 for (auto [BB, V] : IncomingB) {
806 auto BBIt = Mergeable.find(BB);
807 if (BBIt != Mergeable.end() && BBIt->second != V)
808 return;
809 // Either IncomingA does not have this value or IncomingA has the same
810 // value.
811 Mergeable.insert({BB, V});
812 }
813
814 // Update the incoming value of leaderA.
815 IncomingA.assign(Mergeable.begin(), Mergeable.end());
816 PhiClasses.unionSets(ItA, ItB);
817}
818
819/// Add the real PHI value as soon as everything is set up
820void StructurizeCFG::setPhiValues() {
821 SmallVector<PHINode *, 8> InsertedPhis;
822 SSAUpdater Updater(&InsertedPhis);
823 DenseMap<BasicBlock *, SmallVector<BasicBlock *>> UndefBlksMap;
824
825 // Find phi nodes that have compatible incoming values (either they have
826 // the same value for the same block or only one phi node has an incoming
827 // value, see example below). We only search again the phi's that are
828 // referenced by another phi, which is the case we care about.
829 //
830 // For example (-- means no incoming value):
831 // phi1 : BB1:phi2 BB2:v BB3:--
832 // phi2: BB1:-- BB2:v BB3:w
833 //
834 // Then we can merge these incoming values and let phi1, phi2 use the
835 // same set of incoming values:
836 //
837 // phi1&phi2: BB1:phi2 BB2:v BB3:w
838 //
839 // By doing this, phi1 and phi2 would share more intermediate phi nodes.
840 // This would help reduce the number of phi nodes during SSA reconstruction
841 // and ultimately result in fewer COPY instructions.
842 //
843 // This should be correct, because if a phi node does not have incoming
844 // value from certain block, this means the block is not the predecessor
845 // of the parent block, so we actually don't care about its incoming value.
846 EquivalenceClasses<PHINode *> PhiClasses;
847 for (const auto &[To, From] : AddedPhis) {
848 auto OldPhiIt = DeletedPhis.find(To);
849 if (OldPhiIt == DeletedPhis.end())
850 continue;
851
852 PhiMap &BlkPhis = OldPhiIt->second;
853 SmallVector<BasicBlock *> &UndefBlks = UndefBlksMap[To];
854 SmallPtrSet<BasicBlock *, 8> Incomings;
855
856 // Get the undefined blocks shared by all the phi nodes.
857 if (!BlkPhis.empty()) {
858 Incomings.insert_range(llvm::make_first_range(BlkPhis.front().second));
859 findUndefBlocks(To, Incomings, UndefBlks);
860 }
861
862 for (const auto &[Phi, Incomings] : OldPhiIt->second) {
863 SmallVector<PHINode *> IncomingPHIs;
864 for (const auto &[BB, V] : Incomings) {
865 // First, for each phi, check whether it has incoming value which is
866 // another phi.
867 if (PHINode *P = dyn_cast<PHINode>(V))
868 IncomingPHIs.push_back(P);
869 }
870
871 for (auto *OtherPhi : IncomingPHIs) {
872 // Skip phis that are unrelated to the phi reconstruction for now.
873 if (!DeletedPhis.contains(OtherPhi->getParent()))
874 continue;
875 mergeIfCompatible(PhiClasses, Phi, OtherPhi);
876 }
877 }
878 }
879
880 for (const auto &AddedPhi : AddedPhis) {
881 BasicBlock *To = AddedPhi.first;
882 const BBVector &From = AddedPhi.second;
883
884 auto It = DeletedPhis.find(To);
885 if (It == DeletedPhis.end())
886 continue;
887
888 PhiMap &Map = It->second;
889 SmallVector<BasicBlock *> &UndefBlks = UndefBlksMap[To];
890 for (const auto &[Phi, Incoming] : Map) {
891 Value *Poison = PoisonValue::get(Phi->getType());
892 Updater.Initialize(Phi->getType(), "");
893 Updater.AddAvailableValue(&Func->getEntryBlock(), Poison);
894 Updater.AddAvailableValue(To, Poison);
895
896 // Use leader phi's incoming if there is.
897 auto LeaderIt = PhiClasses.findLeader(Phi);
898 bool UseIncomingOfLeader =
899 LeaderIt != PhiClasses.member_end() && *LeaderIt != Phi;
900 const auto &IncomingMap =
901 UseIncomingOfLeader ? DeletedPhis[(*LeaderIt)->getParent()][*LeaderIt]
902 : Incoming;
903
904 SmallVector<BasicBlock *> ConstantPreds;
905 for (const auto &[BB, V] : IncomingMap) {
906 Updater.AddAvailableValue(BB, V);
907 if (isa<Constant>(V))
908 ConstantPreds.push_back(BB);
909 }
910
911 for (auto UB : UndefBlks) {
912 // If this undef block is dominated by any predecessor(before
913 // structurization) of reconstructed PHI with constant incoming value,
914 // don't mark the available value as undefined. Setting undef to such
915 // block will stop us from getting optimal phi insertion.
916 if (any_of(ConstantPreds,
917 [&](BasicBlock *CP) { return DT->dominates(CP, UB); }))
918 continue;
919 // Maybe already get a value through sharing with other phi nodes.
920 if (Updater.HasValueForBlock(UB))
921 continue;
922
923 Updater.AddAvailableValue(UB, Poison);
924 }
925
926 for (BasicBlock *FI : From)
927 Phi->setIncomingValueForBlock(FI, Updater.GetValueAtEndOfBlock(FI));
928 AffectedPhis.push_back(Phi);
929 }
930 }
931
932 AffectedPhis.append(InsertedPhis.begin(), InsertedPhis.end());
933}
934
935/// Updates PHI nodes after hoisted zero cost instructions by replacing poison
936/// entries on Flow nodes with the appropriate hoisted values
937void StructurizeCFG::simplifyHoistedPhis() {
938 for (WeakVH VH : AffectedPhis) {
939 PHINode *Phi = dyn_cast_or_null<PHINode>(VH);
940 if (!Phi || Phi->getNumIncomingValues() != 2)
941 continue;
942
943 for (int i = 0; i < 2; i++) {
944 Value *V = Phi->getIncomingValue(i);
945 auto BBIt = HoistedValues.find(V);
946
947 if (BBIt == HoistedValues.end())
948 continue;
949
950 Value *OtherV = Phi->getIncomingValue(!i);
951 PHINode *OtherPhi = dyn_cast<PHINode>(OtherV);
952 if (!OtherPhi)
953 continue;
954
955 int PoisonValBBIdx = -1;
956 for (size_t i = 0; i < OtherPhi->getNumIncomingValues(); i++) {
957 if (!isa<PoisonValue>(OtherPhi->getIncomingValue(i)))
958 continue;
959 PoisonValBBIdx = i;
960 break;
961 }
962 if (PoisonValBBIdx == -1 ||
963 !DT->dominates(BBIt->second,
964 OtherPhi->getIncomingBlock(PoisonValBBIdx)))
965 continue;
966
967 OtherPhi->setIncomingValue(PoisonValBBIdx, V);
968 if (DT->dominates(OtherV, Phi))
969 Phi->setIncomingValue(i, OtherV);
970 }
971 }
972}
973
974void StructurizeCFG::simplifyAffectedPhis() {
975 bool Changed;
976 do {
977 Changed = false;
978 SimplifyQuery Q(Func->getDataLayout());
979 Q.DT = DT;
980 // Setting CanUseUndef to true might extend value liveness, set it to false
981 // to achieve better register pressure.
982 Q.CanUseUndef = false;
983 for (WeakVH VH : AffectedPhis) {
984 if (auto Phi = dyn_cast_or_null<PHINode>(VH)) {
985 if (auto NewValue = simplifyInstruction(Phi, Q)) {
986 Phi->replaceAllUsesWith(NewValue);
987 Phi->eraseFromParent();
988 Changed = true;
989 }
990 }
991 }
992 } while (Changed);
993}
994
995/// Remove phi values from all successors and then remove the terminator.
996DebugLoc StructurizeCFG::killTerminator(BasicBlock *BB) {
998 if (!Term)
999 return DebugLoc();
1000
1001 for (BasicBlock *Succ : successors(BB))
1002 delPhiValues(BB, Succ);
1003
1004 DebugLoc DL = Term->getDebugLoc();
1005 Term->eraseFromParent();
1006 return DL;
1007}
1008
1009/// Let node exit(s) point to NewExit
1010void StructurizeCFG::changeExit(RegionNode *Node, BasicBlock *NewExit,
1011 bool IncludeDominator) {
1012 if (Node->isSubRegion()) {
1013 Region *SubRegion = Node->getNodeAs<Region>();
1014 BasicBlock *OldExit = SubRegion->getExit();
1015 BasicBlock *Dominator = nullptr;
1016
1017 // Find all the edges from the sub region to the exit.
1018 // We use make_early_inc_range here because we modify BB's terminator.
1019 for (BasicBlock *BB : llvm::make_early_inc_range(predecessors(OldExit))) {
1020 if (!SubRegion->contains(BB))
1021 continue;
1022
1023 // Modify the edges to point to the new exit
1024 delPhiValues(BB, OldExit);
1025 BB->getTerminator()->replaceUsesOfWith(OldExit, NewExit);
1026 addPhiValues(BB, NewExit);
1027
1028 // Find the new dominator (if requested)
1029 if (IncludeDominator) {
1030 if (!Dominator)
1031 Dominator = BB;
1032 else
1033 Dominator = DT->findNearestCommonDominator(Dominator, BB);
1034 }
1035 }
1036
1037 // Change the dominator (if requested)
1038 if (Dominator)
1039 DT->changeImmediateDominator(NewExit, Dominator);
1040
1041 // Update the region info
1042 SubRegion->replaceExit(NewExit);
1043 } else {
1044 BasicBlock *BB = Node->getNodeAs<BasicBlock>();
1045 DebugLoc DL = killTerminator(BB);
1046 UncondBrInst *Br = UncondBrInst::Create(NewExit, BB);
1047 Br->setDebugLoc(DL);
1048 addPhiValues(BB, NewExit);
1049 if (IncludeDominator)
1050 DT->changeImmediateDominator(NewExit, BB);
1051 }
1052}
1053
1054/// Create a new flow node and update dominator tree and region info
1055BasicBlock *StructurizeCFG::getNextFlow(BasicBlock *Dominator) {
1056 LLVMContext &Context = Func->getContext();
1057 BasicBlock *Insert = Order.empty() ? ParentRegion->getExit() :
1058 Order.back()->getEntry();
1060 Func, Insert);
1061 FlowSet.insert(Flow);
1062 DT->addNewBlock(Flow, Dominator);
1063 ParentRegion->getRegionInfo()->setRegionFor(Flow, ParentRegion);
1064 return Flow;
1065}
1066
1067/// Create a new or reuse the previous node as flow node. Returns a block and a
1068/// debug location to be used for new instructions in that block.
1069std::pair<BasicBlock *, DebugLoc> StructurizeCFG::needPrefix(bool NeedEmpty) {
1070 BasicBlock *Entry = PrevNode->getEntry();
1071
1072 if (!PrevNode->isSubRegion()) {
1073 DebugLoc DL = killTerminator(Entry);
1074 if (!NeedEmpty || Entry->getFirstInsertionPt() == Entry->end())
1075 return {Entry, DL};
1076 }
1077
1078 // create a new flow node
1079 BasicBlock *Flow = getNextFlow(Entry);
1080
1081 // and wire it up
1082 changeExit(PrevNode, Flow, true);
1083 PrevNode = ParentRegion->getBBNode(Flow);
1084 return {Flow, DebugLoc()};
1085}
1086
1087/// Returns the region exit if possible, otherwise just a new flow node
1088BasicBlock *StructurizeCFG::needPostfix(BasicBlock *Flow,
1089 bool ExitUseAllowed) {
1090 if (!Order.empty() || !ExitUseAllowed)
1091 return getNextFlow(Flow);
1092
1093 BasicBlock *Exit = ParentRegion->getExit();
1094 DT->changeImmediateDominator(Exit, Flow);
1095 addPhiValues(Flow, Exit);
1096 return Exit;
1097}
1098
1099/// Set the previous node
1100void StructurizeCFG::setPrevNode(BasicBlock *BB) {
1101 PrevNode = ParentRegion->contains(BB) ? ParentRegion->getBBNode(BB)
1102 : nullptr;
1103}
1104
1105/// Does BB dominate all the predicates of Node?
1106bool StructurizeCFG::dominatesPredicates(BasicBlock *BB, RegionNode *Node) {
1107 BBPredicates &Preds = Predicates[Node->getEntry()];
1108 return llvm::all_of(
1109 Preds, [&](const auto &Pred) { return DT->dominates(BB, Pred.first); });
1110}
1111
1112/// Can we predict that this node will always be called?
1113bool StructurizeCFG::isPredictableTrue(RegionNode *Node) {
1114 BBPredicates &Preds = Predicates[Node->getEntry()];
1115 bool Dominated = false;
1116
1117 // Regionentry is always true
1118 if (!PrevNode)
1119 return true;
1120
1121 for (auto [BB, PI] : Preds) {
1122 if (PI.Pred != BoolTrue)
1123 return false;
1124
1125 if (!Dominated && DT->dominates(BB, PrevNode->getEntry()))
1126 Dominated = true;
1127 }
1128
1129 // TODO: The dominator check is too strict
1130 return Dominated;
1131}
1132
1133/// Take one node from the order vector and wire it up
1134void StructurizeCFG::wireFlow(bool ExitUseAllowed,
1135 BasicBlock *LoopEnd) {
1136 RegionNode *Node = Order.pop_back_val();
1137 Visited.insert(Node->getEntry());
1138
1139 if (isPredictableTrue(Node)) {
1140 // Just a linear flow
1141 if (PrevNode) {
1142 changeExit(PrevNode, Node->getEntry(), true);
1143 }
1144 PrevNode = Node;
1145 } else {
1146 // Insert extra prefix node (or reuse last one)
1147 auto [Flow, DL] = needPrefix(false);
1148
1149 // Insert extra postfix node (or use exit instead)
1150 BasicBlock *Entry = Node->getEntry();
1151 BasicBlock *Next = needPostfix(Flow, ExitUseAllowed);
1152
1153 // let it point to entry and next block
1154 CondBrInst *Br = CondBrInst::Create(BoolPoison, Entry, Next, Flow);
1155 Br->setDebugLoc(DL);
1156 Conditions.push_back(Br);
1157 addPhiValues(Flow, Entry);
1158 DT->changeImmediateDominator(Entry, Flow);
1159
1160 PrevNode = Node;
1161 while (!Order.empty() && !Visited.count(LoopEnd) &&
1162 dominatesPredicates(Entry, Order.back())) {
1163 handleLoops(false, LoopEnd);
1164 }
1165
1166 changeExit(PrevNode, Next, false);
1167 setPrevNode(Next);
1168 }
1169}
1170
1171void StructurizeCFG::handleLoops(bool ExitUseAllowed,
1172 BasicBlock *LoopEnd) {
1173 RegionNode *Node = Order.back();
1174 BasicBlock *LoopStart = Node->getEntry();
1175
1176 if (!Loops.count(LoopStart)) {
1177 wireFlow(ExitUseAllowed, LoopEnd);
1178 return;
1179 }
1180
1181 if (!isPredictableTrue(Node))
1182 LoopStart = needPrefix(true).first;
1183
1184 LoopEnd = Loops[Node->getEntry()];
1185 wireFlow(false, LoopEnd);
1186 while (!Visited.count(LoopEnd)) {
1187 handleLoops(false, LoopEnd);
1188 }
1189
1190 assert(LoopStart != &LoopStart->getParent()->getEntryBlock());
1191
1192 // Create an extra loop end node
1193 DebugLoc DL;
1194 std::tie(LoopEnd, DL) = needPrefix(false);
1195 BasicBlock *Next = needPostfix(LoopEnd, ExitUseAllowed);
1196 CondBrInst *Br = CondBrInst::Create(BoolPoison, Next, LoopStart, LoopEnd);
1197 Br->setDebugLoc(DL);
1198 LoopConds.push_back(Br);
1199 addPhiValues(LoopEnd, LoopStart);
1200 setPrevNode(Next);
1201}
1202
1203/// After this function control flow looks like it should be, but
1204/// branches and PHI nodes only have undefined conditions.
1205void StructurizeCFG::createFlow() {
1206 BasicBlock *Exit = ParentRegion->getExit();
1207 bool EntryDominatesExit = DT->dominates(ParentRegion->getEntry(), Exit);
1208
1209 AffectedPhis.clear();
1210 DeletedPhis.clear();
1211 AddedPhis.clear();
1212 Conditions.clear();
1213 LoopConds.clear();
1214
1215 PrevNode = nullptr;
1216 Visited.clear();
1217
1218 while (!Order.empty()) {
1219 handleLoops(EntryDominatesExit, nullptr);
1220 }
1221
1222 if (PrevNode)
1223 changeExit(PrevNode, Exit, EntryDominatesExit);
1224 else
1225 assert(EntryDominatesExit);
1226}
1227
1228/// Handle a rare case where the disintegrated nodes instructions
1229/// no longer dominate all their uses.
1230void StructurizeCFG::rebuildSSA() {
1231 SSAUpdater Updater;
1232 for (BasicBlock *BB : ParentRegion->blocks())
1233 for (Instruction &I : *BB) {
1234 bool Initialized = false;
1235 // We may modify the use list as we iterate over it, so we use
1236 // make_early_inc_range.
1237 for (Use &U : llvm::make_early_inc_range(I.uses())) {
1238 Instruction *User = cast<Instruction>(U.getUser());
1239 if (User->getParent() == BB) {
1240 continue;
1241 } else if (PHINode *UserPN = dyn_cast<PHINode>(User)) {
1242 if (UserPN->getIncomingBlock(U) == BB)
1243 continue;
1244 }
1245
1246 if (DT->dominates(&I, User))
1247 continue;
1248
1249 if (!Initialized) {
1250 Value *Poison = PoisonValue::get(I.getType());
1251 Updater.Initialize(I.getType(), "");
1252 Updater.AddAvailableValue(&Func->getEntryBlock(), Poison);
1253 Updater.AddAvailableValue(BB, &I);
1254 Initialized = true;
1255 }
1256 Updater.RewriteUseAfterInsertions(U);
1257 }
1258 }
1259}
1260
1261/// Can region \p R be left unstructurized because all of its own control flow
1262/// is uniform?
1263///
1264/// Only the terminators of direct child blocks are checked. Sub-regions are
1265/// processed before their parent, so any divergent control flow inside a
1266/// sub-region has already been structurized and is self-contained: it is
1267/// entered only through the sub-region's entry, and it rejoins either at Flow
1268/// blocks inside the sub-region or, if the sub-region's entry dominates its
1269/// exit, at the exit block itself. Uniform control flow around a sub-region
1270/// therefore does not need structurizing, whatever the sub-region contains.
1271/// (The branches inside sub-regions could not be checked anyway, because they
1272/// may have been removed and re-created since UniformityAnalysis ran.)
1273///
1274/// FIXME: This does not hold for a sub-region whose entry block ends in a
1275/// callbr, because run() leaves such regions unstructurized.
1277 return none_of(R->elements(), [&](RegionNode *E) {
1278 if (E->isSubRegion())
1279 return false;
1280 auto *Br = dyn_cast<CondBrInst>(E->getEntry()->getTerminator());
1281 return Br && UA.isDivergentTerminator(Br);
1282 });
1283}
1284
1285void StructurizeCFG::init(Region *R) {
1286 LLVMContext &Context = R->getEntry()->getContext();
1287
1288 Boolean = Type::getInt1Ty(Context);
1289 BoolTrue = ConstantInt::getTrue(Context);
1290 BoolFalse = ConstantInt::getFalse(Context);
1291 BoolPoison = PoisonValue::get(Boolean);
1292}
1293
1294bool StructurizeCFG::makeUniformRegion(Region *R, const UniformityInfo &UA) {
1295 if (R->isTopLevelRegion())
1296 return false;
1297
1298 if (hasOnlyUniformBranches(R, UA)) {
1299 LLVM_DEBUG(dbgs() << "Skipping region with uniform control flow: " << *R
1300 << '\n');
1301
1302 // Mark all direct child block terminators as having been treated as
1303 // uniform. Indirect children must not be marked, because sub-regions may
1304 // contain divergent control flow.
1305 LLVMContext &Ctx = R->getEntry()->getContext();
1306 unsigned UniformMDKindID = Ctx.getMDKindID("structurizecfg.uniform");
1307 MDNode *MD = MDNode::get(Ctx, {});
1308 for (RegionNode *E : R->elements()) {
1309 if (E->isSubRegion())
1310 continue;
1311
1312 E->getEntry()->getTerminator()->setMetadata(UniformMDKindID, MD);
1313 }
1314
1315 return true;
1316 }
1317 return false;
1318}
1319
1320/// Run the transformation for each region found
1321bool StructurizeCFG::run(Region *R, DominatorTree *DT,
1322 const TargetTransformInfo *TTI) {
1323 // CallBr and its corresponding direct target blocks are for now ignored by
1324 // this pass. This is not a limitation for the currently intended uses cases
1325 // of callbr in the AMDGPU backend.
1326 // Parent and child regions are not affected by this (current) restriction.
1327 // See `llvm/test/Transforms/StructurizeCFG/callbr.ll` for details.
1328 if (R->isTopLevelRegion() || isa<CallBrInst>(R->getEntry()->getTerminator()))
1329 return false;
1330
1331 this->DT = DT;
1332 this->TTI = TTI;
1333 Func = R->getEntry()->getParent();
1334
1335 ParentRegion = R;
1336
1337 orderNodes();
1338 collectInfos();
1339 createFlow();
1340
1341 SSAUpdaterBulk PhiInserter;
1342 insertConditions(false, PhiInserter);
1343 insertConditions(true, PhiInserter);
1344 PhiInserter.RewriteAndOptimizeAllUses(*DT);
1345
1346 setPhiValues();
1347 simplifyHoistedPhis();
1348 simplifyConditions();
1349 simplifyAffectedPhis();
1350 rebuildSSA();
1351
1352 // Cleanup
1353 Order.clear();
1354 Visited.clear();
1355 DeletedPhis.clear();
1356 AddedPhis.clear();
1357 Predicates.clear();
1358 Conditions.clear();
1359 Loops.clear();
1360 LoopPreds.clear();
1361 LoopConds.clear();
1362 FlowSet.clear();
1363
1364 return true;
1365}
1366
1367Pass *llvm::createStructurizeCFGPass(bool SkipUniformRegions) {
1368 return new StructurizeCFGLegacyPass(SkipUniformRegions);
1369}
1370
1371static void addRegionIntoQueue(Region &R, std::vector<Region *> &Regions) {
1372 Regions.push_back(&R);
1373 for (const auto &E : R)
1374 addRegionIntoQueue(*E, Regions);
1375}
1376
1378 : SkipUniformRegions(SkipUniformRegions_) {}
1379
1381 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
1382 static_cast<PassInfoMixin<StructurizeCFGPass> *>(this)->printPipeline(
1383 OS, MapClassName2PassName);
1384 if (SkipUniformRegions)
1385 OS << "<skip-uniform-regions>";
1386}
1387
1388/// Structurize every region in \p RI, processing inner regions before the
1389/// regions that contain them. If \p UI is non-null, skip uniform regions.
1390static bool runImpl(DominatorTree &DT, RegionInfo &RI,
1391 const TargetTransformInfo &TTI, const UniformityInfo *UI) {
1392 bool Changed = false;
1393 std::vector<Region *> Regions;
1394 addRegionIntoQueue(*RI.getTopLevelRegion(), Regions);
1395 while (!Regions.empty()) {
1396 Region *R = Regions.back();
1397 Regions.pop_back();
1398
1399 StructurizeCFG SCFG;
1400 SCFG.init(R);
1401
1402 if (UI && SCFG.makeUniformRegion(R, *UI)) {
1403 Changed = true; // May have added metadata.
1404 continue;
1405 }
1406
1407 Changed |= SCFG.run(R, &DT, &TTI);
1408 }
1409 return Changed;
1410}
1411
1412bool StructurizeCFGLegacyPass::runOnFunction(Function &F) {
1413 const ScalarOptions &Opts = getScalarOptions(F);
1414 const UniformityInfo *UI = nullptr;
1415 if (valueOr(Opts.structurizecfg_skip_uniform_regions, SkipUniformRegions))
1416 UI = &getAnalysis<UniformityInfoWrapperPass>().getUniformityInfo();
1417 DominatorTree &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1418 RegionInfo &RI = getAnalysis<RegionInfoPass>().getRegionInfo();
1419 const TargetTransformInfo &TTI =
1420 getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
1421 return runImpl(DT, RI, TTI, UI);
1422}
1423
1427 auto &RI = AM.getResult<RegionInfoAnalysis>(F);
1429 const ScalarOptions &Opts = getScalarOptions(F);
1430 const UniformityInfo *UI = nullptr;
1431 if (valueOr(Opts.structurizecfg_skip_uniform_regions, SkipUniformRegions))
1433
1434 if (!runImpl(DT, RI, TTI, UI))
1435 return PreservedAnalyses::all();
1438 return PA;
1439}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool runImpl(MachineFunction &MF)
Definition CFIFixup.cpp:304
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DenseMap< BasicBlock *, Instruction * > BBPredicates
This file defines the DenseMap class.
@ Default
static bool runOnFunction(Function &F, bool PostInlining)
Generic implementation of equivalence classes through the use Tarjan's efficient union-find algorithm...
Hexagon Hardware Loops
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file implements a map that provides insertion order iteration.
This file contains the declarations for metadata subclasses.
#define T
#define P(N)
if(PassOpts->AAPipeline)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
Annotate SI Control Flow
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
SmallDenseMap< const PHINode *, PhiInfo, 16 > PhiMap
static void addRegionIntoQueue(Region &R, std::vector< Region * > &Regions)
const char FlowBlockName[]
static bool hasOnlyUniformBranches(Region *R, const UniformityInfo &UA)
Can region R be left unstructurized because all of its own control flow is uniform?
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
LLVM IR instance of the generic uniformity analysis.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition BasicBlock.h:509
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
LLVM_ABI bool hasNPredecessors(unsigned N) const
Return true if this block has exactly N predecessors.
const Instruction * getTerminatorOrNull() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:248
LLVM_ABI const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
A debug info location.
Definition DebugLoc.h:126
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:762
bool empty() const
Definition DenseMap.h:716
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
DomTreeNodeBase< NodeT > * addNewBlock(NodeT *BB, NodeT *DomBB)
Add a new node to the dominator tree information.
Legacy analysis pass which computes a DominatorTree.
Definition Dominators.h:277
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
This represents a collection of equivalence classes and supports three efficient operations: insert a...
const ECValue & insert(const ElemTy &Data)
Insert a new value into the union/find set, ignoring the request if the value already exists.
member_iterator member_end() const
member_iterator findLeader(const ElemTy &V) const
Given a value in the set, return a member iterator for the equivalence class it is in.
member_iterator unionSets(const ElemTy &V1, const ElemTy &V2)
Merge the two equivalence sets for the specified values, inserting them if they do not already exist ...
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
const BasicBlock & getEntryBlock() const
Definition Function.h:794
const DataLayout & getDataLayout() const
Get the data layout of the module this function belongs to.
Definition Function.cpp:356
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition Function.cpp:352
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
LLVM_ABI unsigned getMDKindID(StringRef Name) const
getMDKindID - Return a unique non-zero ID for the specified metadata kind.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
void setIncomingValue(unsigned i, Value *V)
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
Definition Pass.h:97
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
void replaceExit(BlockT *BB)
Replace the exit basic block of the region with the new basic block.
block_range blocks()
Returns a range view of the basic blocks in the region.
Definition RegionInfo.h:616
BlockT * getExit() const
Get the exit BasicBlock of the Region.
Definition RegionInfo.h:360
RegionNodeT * getBBNode(BlockT *BB) const
Get the BasicBlock RegionNode for a BasicBlock.
bool contains(const BlockT *BB) const
Check if the region contains a BasicBlock.
RegionInfoT * getRegionInfo() const
Return the RegionInfo object, that belongs to this Region.
Definition RegionInfo.h:427
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
Definition RegionInfo.h:323
Analysis pass that exposes the RegionInfo for a function.
Definition RegionInfo.h:953
RegionT * getTopLevelRegion() const
Definition RegionInfo.h:857
RegionT * getRegionFor(BlockT *BB) const
Get the smallest region that contains a BasicBlock.
bool isSubRegion() const
Is this RegionNode a subregion?
Definition RegionInfo.h:189
BlockT * getEntry() const
Get the entry BasicBlock of this RegionNode.
Definition RegionInfo.h:175
Helper class for SSA formation on a set of values defined in multiple blocks.
LLVM_ABI unsigned AddVariable(StringRef Name, Type *Ty)
Add a new variable to the SSA rewriter.
LLVM_ABI void AddAvailableValue(unsigned Var, BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
LLVM_ABI void AddUse(unsigned Var, Use *U)
Record a use of the symbolic value.
LLVM_ABI void RewriteAndOptimizeAllUses(DominatorTree &DT)
Rewrite all uses and simplify the inserted PHI nodes.
LLVM_ABI void RewriteUseAfterInsertions(Use &U)
Rewrite a use like RewriteUse but handling in-block definitions.
LLVM_ABI void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
LLVM_ABI void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition DenseSet.h:293
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Analysis pass providing the TargetTransformInfo.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
@ TCK_Latency
The latency of instruction.
@ TCC_Expensive
The cost of a 'div' instruction on x86.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
Analysis pass which computes UniformityInfo.
Legacy analysis pass which computes a CycleInfo.
LLVM_ABI bool replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Definition User.cpp:25
LLVM Value Representation.
Definition Value.h:75
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
CRTP base class for adapting an iterator to a different type.
Definition iterator.h:240
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
static scc_iterator begin(const GraphT &G)
bool isAtEnd() const
Direct loop termination test which is more efficient than comparison with end().
Changed
@ Entry
Definition COFF.h:862
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
GenericUniformityInfo< SSAContext > UniformityInfo
unsigned char Boolean
Definition ConvertUTF.h:132
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
APInt operator*(APInt a, uint64_t RHS)
Definition APInt.h:2261
auto successors(const MachineBasicBlock *BB)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
const ScalarOptions & getScalarOptions(const LLVMContext &C)
LLVM_ABI Pass * createStructurizeCFGPass(bool SkipUniformRegions=false)
When SkipUniformRegions is true the structizer will not structurize regions that only contain uniform...
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1167
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
auto make_first_range(ContainerTy &&c)
Given a container of pairs, return a range over the first elements.
Definition STLExtras.h:1415
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:552
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
@ Other
Any other memory.
Definition ModRef.h:68
TargetTransformInfo TTI
DWARFExpression::Operation Op
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto predecessors(const MachineBasicBlock *BB)
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
constexpr bool valueOr(BoolOrDefault X, bool Default)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI Value * invertCondition(Value *Condition)
Invert the given true/false value, possibly reusing an existing copy.
Definition Local.cpp:4000
filter_iterator_impl< WrappedIteratorT, PredicateT, detail::fwd_or_bidi_tag< WrappedIteratorT > > filter_iterator
Defines filter_iterator to a suitable specialization of filter_iterator_impl, based on the underlying...
Definition STLExtras.h:539
LLVM_ABI void initializeStructurizeCFGLegacyPassPass(PassRegistry &)
#define N
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI StructurizeCFGPass(bool SkipUniformRegions=false)