LLVM: lib/Transforms/Utils/PredicateInfo.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
28#define DEBUG_TYPE "predicateinfo"
29using namespace llvm;
31
34 cl::desc("Verify PredicateInfo in legacy printer pass."));
36 "Controls which variables are renamed with predicateinfo");
37
38
39
41
42namespace {
43
44
47 "Only branches and switches should have PHIOnly defs that "
48 "require branch blocks.");
50}
51
52
53
56 "Not a predicate info type we know how to get a terminator from.");
58}
59
60
61
62std::pair<BasicBlock *, BasicBlock *> getBlockEdge(const PredicateBase *PB) {
64 "Not a predicate info type we know how to get an edge from.");
66 return std::make_pair(PEdge->From, PEdge->To);
67}
68}
69
70namespace llvm {
80
81
82
91
92
93
97
100 return false;
101
102
105 assert(A.DFSOut == B.DFSOut &&
106 "Equal DFS-in numbers imply equal out numbers");
107
108
109 if (A.LocalNum != B.LocalNum)
110 return A.LocalNum < B.LocalNum;
111
112
113
114
115
118
119
122
123
124
126 assert(A.PInfo && B.PInfo && "Must be predicate info def");
127 return false;
128 }
129
130
132 if (VD.U) {
134 return std::make_pair(PHI->getIncomingBlock(*VD.U), PHI->getParent());
135 }
136
137 return ::getBlockEdge(VD.PInfo);
138 }
139
140
142 BasicBlock *ASrc, *ADest, *BSrc, *BDest;
145
146#ifndef NDEBUG
147
151 "DFS numbers for A should match the ones of the source block");
153 "DFS numbers for B should match the ones of the source block");
154 assert(A.DFSIn == B.DFSIn && "Values must be in the same block");
155#endif
156 (void)ASrc;
157 (void)BSrc;
158
159
160
165 bool isAUse = A.U;
166 bool isBUse = B.U;
167 assert((.PInfo ||
.U) && (
.PInfo ||
.U) &&
168 "Def and U cannot be set at the same time");
169
170 return std::tie(AIn, isAUse) < std::tie(BIn, isBUse);
171 }
172
174 if (VD.U)
176
177
178
179 assert(VD.PInfo && "No use, and no predicateinfo should not occur");
181 "Middle of block should only occur for assumes");
183 }
184
185
186
192};
193
195
196 struct ValueInfo {
198 };
199
204
205
206
207
209
210
211
212
214
216
217 ValueInfo &getOrCreateValueInfo(Value *);
218 const ValueInfo &getValueInfo(Value *) const;
219
229
230 struct StackEntry {
232 Value *Def = nullptr;
233
234 StackEntry(const ValueDFS *V) : V(V) {}
235 };
236
239 Value *materializeStack(unsigned int &, ValueDFSStack &, Value *);
240 bool stackIsInScope(const ValueDFSStack &, const ValueDFS &) const;
241 void popStackUntilDFSScope(ValueDFSStack &, const ValueDFS &);
242
243public:
246 : PI(PI), F(F), DT(DT), AC(AC), Allocator(Allocator) {
247
248 ValueInfos.resize(1);
249 }
250
252};
253
254bool PredicateInfoBuilder::stackIsInScope(const ValueDFSStack &Stack,
255 const ValueDFS &VDUse) const {
256 assert(!Stack.empty() && "Should not be called with empty stack");
257
258
259
260
261
262 const ValueDFS &Top = *Stack.back().V;
263 assert(Top.PInfo && "RenameStack should only contain predicate infos (defs)");
265 if (!VDUse.U) {
266 assert(VDUse.PInfo && "A non-use VDUse should have a predicate info");
267
269
270
271 getBlockEdge(Top.PInfo) == getBlockEdge(VDUse.PInfo);
272 }
274 if ()
275 return false;
276
277 BasicBlock *EdgePred = PHI->getIncomingBlock(*VDUse.U);
278 if (EdgePred != getBranchBlock(Top.PInfo))
279 return false;
280
281
282 return DT.dominates(getBlockEdge(Top.PInfo), *VDUse.U);
283 }
284
286}
287
288void PredicateInfoBuilder::popStackUntilDFSScope(ValueDFSStack &Stack,
290 while (.empty() && !stackIsInScope(Stack, VD))
291 Stack.pop_back();
292}
293
294
295
296void PredicateInfoBuilder::convertUsesToDFSOrdered(
298 for (auto &U : Op->uses()) {
300
301
302 if (I->isLifetimeStartOrEnd())
303 continue;
304
305 ValueDFS VD;
306
309 IBlock = PN->getIncomingBlock(U);
310
311
313 } else {
314
315
318 }
319 DomTreeNode *DomNode = DT.getNode(IBlock);
320
321 if (!DomNode)
322 continue;
327 }
328 }
329}
330
337
338
339
341 auto *Op0 = Comparison->getOperand(0);
342 auto *Op1 = Comparison->getOperand(1);
343 if (Op0 == Op1)
344 return;
345
348}
349
350
353 auto &OperandInfo = getOrCreateValueInfo(Op);
354 if (OperandInfo.Infos.empty())
356 OperandInfo.Infos.push_back(PB);
357}
358
359
360
361void PredicateInfoBuilder::processAssume(
365 SmallPtrSet<Value *, 4> Visited;
367 while (!Worklist.empty()) {
370 continue;
372 break;
373
374 Value *Op0, *Op1;
378 }
379
386
387 for (Value *V : Values) {
389 auto *PA = new (Allocator) PredicateAssume(V, II, Cond);
390 addInfoFor(OpsToRename, V, PA);
391 }
392 }
393 }
394}
395
396
397
398void PredicateInfoBuilder::processBranch(
403
404 for (BasicBlock *Succ : {FirstBB, SecondBB}) {
405 bool TakenEdge = Succ == FirstBB;
406
407
408 if (Succ == BranchBB)
409 continue;
410
412 SmallPtrSet<Value *, 4> Visited;
414 while (!Worklist.empty()) {
417 continue;
419 break;
420
421 Value *Op0, *Op1;
426 }
427
434
435 for (Value *V : Values) {
437 PredicateBase *PB = new (Allocator)
438 PredicateBranch(V, BranchBB, Succ, Cond, TakenEdge);
439 addInfoFor(OpsToRename, V, PB);
440 }
441 }
442 }
443 }
444}
445
446
447void PredicateInfoBuilder::processSwitch(
452 return;
453
454
455 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
456 for (BasicBlock *TargetBlock : successors(BranchBB))
457 ++SwitchEdges[TargetBlock];
458
459
460 for (auto C : SI->cases()) {
461 BasicBlock *TargetBlock = C.getCaseSuccessor();
462 if (SwitchEdges.lookup(TargetBlock) == 1) {
463 PredicateSwitch *PS = new (Allocator) PredicateSwitch(
464 Op, SI->getParent(), TargetBlock, C.getCaseValue(), SI);
465 addInfoFor(OpsToRename, Op, PS);
466 }
467 }
468}
469
470
472 DT.updateDFSNumbers();
473
474
477 if (!DT.isReachableFromEntry(&BB))
478 continue;
479
482 continue;
483
485 continue;
486 processBranch(BI, &BB, OpsToRename);
488 processSwitch(SI, &BB, OpsToRename);
489 }
490 }
491 for (auto &Assume : AC.assumptions()) {
493 if (DT.isReachableFromEntry(II->getParent()))
494 processAssume(II, II->getParent(), OpsToRename);
495 }
496
497 renameUses(OpsToRename);
498}
499
500
501
502Value *PredicateInfoBuilder::materializeStack(unsigned int &Counter,
503 ValueDFSStack &RenameStack,
505
506 auto RevIter = RenameStack.rbegin();
507 for (; RevIter != RenameStack.rend(); ++RevIter)
508 if (RevIter->Def)
509 break;
510
511 size_t Start = RevIter - RenameStack.rbegin();
512
513
514
515 for (auto RenameIter = RenameStack.end() - Start;
516 RenameIter != RenameStack.end(); ++RenameIter) {
517 auto *Op =
518 RenameIter == RenameStack.begin() ? OrigOp : (RenameIter - 1)->Def;
519 StackEntry &Result = *RenameIter;
520 auto *ValInfo = Result.V->PInfo;
521 ValInfo->RenamedOp = (RenameStack.end() - Start) == RenameStack.begin()
522 ? OrigOp
523 : (RenameStack.end() - Start - 1)->Def;
525 const Twine &Name = "") {
526
528 };
529
530
531
532
533
535 BitCastInst *PIC = CreateSSACopy(getBranchTerminator(ValInfo), Op,
536 Op->getName() + "." + Twine(Counter++));
537 PI.PredicateMap.insert({PIC, ValInfo});
539 } else {
542 "Should not have gotten here without it being an assume");
543
544
545 BitCastInst *PIC = CreateSSACopy(PAssume->AssumeInst->getNextNode(), Op);
546 PI.PredicateMap.insert({PIC, ValInfo});
548 }
549 }
550 return RenameStack.back().Def;
551}
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
573 ValueDFS_Compare Compare(DT);
574
575 for (auto *Op : OpsToRename) {
577 unsigned Counter = 0;
579 const auto &ValueInfo = getValueInfo(Op);
580
581
582
583 for (const auto &PossibleCopy : ValueInfo.Infos) {
584 ValueDFS VD;
585
586
587
588
589
592 DomTreeNode *DomNode = DT.getNode(PAssume->AssumeInst->getParent());
593 if (!DomNode)
594 continue;
597 VD.PInfo = PossibleCopy;
600
601
602
603 auto BlockEdge = getBlockEdge(PossibleCopy);
604 if (!BlockEdge.second->getSinglePredecessor()) {
606 auto *DomNode = DT.getNode(BlockEdge.first);
607 if (DomNode) {
610 VD.PInfo = PossibleCopy;
612 }
613 } else {
614
615
616
618 auto *DomNode = DT.getNode(BlockEdge.second);
619 if (DomNode) {
622 VD.PInfo = PossibleCopy;
624 }
625 }
626 }
627 }
628
629 convertUsesToDFSOrdered(Op, OrderedUses);
630
631
632
633
634
637
638
639 for (const ValueDFS &VD : OrderedUses) {
640
641
642 if (RenameStack.empty()) {
644 } else {
645 LLVM_DEBUG(dbgs() << "Rename Stack Top DFS numbers are ("
646 << RenameStack.back().V->DFSIn << ","
647 << RenameStack.back().V->DFSOut << ")\n");
648 }
649
651 << VD.DFSOut << ")\n");
652
653
654 popStackUntilDFSScope(RenameStack, VD);
655
658 continue;
659 }
660
661
662
663 if (RenameStack.empty())
664 continue;
666 LLVM_DEBUG(dbgs() << "Skipping execution due to debug counter\n");
667 continue;
668 }
669 StackEntry &Result = RenameStack.back();
670
671
672
673
675 Result.Def = materializeStack(Counter, RenameStack, Op);
676
678 << *VD.U->get() << " in " << *(VD.U->getUser())
679 << "\n");
681 "Predicateinfo def should have dominated this use");
683 }
684 }
685}
686
687PredicateInfoBuilder::ValueInfo &
688PredicateInfoBuilder::getOrCreateValueInfo(Value *Operand) {
689 auto Res = ValueInfoNums.try_emplace(Operand, ValueInfos.size());
690 if (Res.second) {
691
692 ValueInfos.resize(ValueInfos.size() + 1);
693 }
694 return ValueInfos[Res.first->second];
695}
696
697const PredicateInfoBuilder::ValueInfo &
698PredicateInfoBuilder::getValueInfo(Value *Operand) const {
699 auto OINI = ValueInfoNums.lookup(Operand);
700 assert(OINI != 0 && "Operand was not really in the Value Info Numbers");
701 assert(OINI < ValueInfos.size() &&
702 "Value Info Number greater than size of Value Info Table");
703 return ValueInfos[OINI];
704}
705
708 : F(F) {
710 Builder.buildPredicateInfo();
711}
712
714 switch (Type) {
717 bool TrueEdge = true;
719 TrueEdge = PBranch->TrueEdge;
720
725 }
726
730 }
731
733 if (!Cmp) {
734
735 return std::nullopt;
736 }
737
740 if (Cmp->getOperand(0) == RenamedOp) {
741 Pred = Cmp->getPredicate();
742 OtherOp = Cmp->getOperand(1);
743 } else if (Cmp->getOperand(1) == RenamedOp) {
744 Pred = Cmp->getSwappedPredicate();
745 OtherOp = Cmp->getOperand(0);
746 } else {
747
748 return std::nullopt;
749 }
750
751
752 if (!TrueEdge)
754
755 return {{Pred, OtherOp}};
756 }
759
760 return std::nullopt;
761 }
762
764 }
766}
767
769
770
773 const auto *PI = PredInfo.getPredicateInfoFor(&Inst);
774 if (!PI)
775 continue;
776
778 Inst.getType() == Inst.getOperand(0)->getType());
779 Inst.replaceAllUsesWith(Inst.getOperand(0));
780 Inst.eraseFromParent();
781 }
782}
783
788 OS << "PredicateInfo for function: " << F.getName() << "\n";
790 auto PredInfo = std::make_unique(F, DT, AC, Allocator);
791 PredInfo->print(OS);
792
795}
796
797
798
802
803public:
805
808
811 if (const auto *PI = PredInfo->getPredicateInfoFor(I)) {
813 OS << "; branch predicate info { TrueEdge: " << PB->TrueEdge
814 << " Comparison:" << *PB->Condition << " Edge: [";
815 PB->From->printAsOperand(OS);
816 OS << ",";
817 PB->To->printAsOperand(OS);
818 OS << "]";
820 OS << "; switch predicate info { CaseValue: " << *PS->CaseValue
821 << " Edge: [";
822 PS->From->printAsOperand(OS);
823 OS << ",";
824 PS->To->printAsOperand(OS);
825 OS << "]";
827 OS << "; assume predicate info {"
828 << " Comparison:" << *PA->Condition;
829 }
830 OS << ", RenamedOp: ";
831 PI->RenamedOp->printAsOperand(OS, false);
832 OS << " }\n";
833 }
834 }
835};
836
839 F.print(OS, &Writer);
840}
841
844 F.print(dbgs(), &Writer);
845}
846
852 std::make_unique(F, DT, AC, Allocator)->verifyPredicateInfo();
853
855}
856}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
uint64_t IntrinsicInst * II
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
static cl::opt< bool > VerifyPredicateInfo("verify-predicateinfo", cl::init(false), cl::Hidden, cl::desc("Verify PredicateInfo in legacy printer pass."))
static const unsigned MaxCondsPerBranch
Definition PredicateInfo.cpp:40
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
This class represents a no-op cast from one type to another.
Conditional or Unconditional Branch instruction.
bool isConditional() const
BasicBlock * getSuccessor(unsigned i) const
Value * getCondition() const
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
static bool shouldExecute(CounterInfo &Counter)
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
unsigned getDFSNumOut() const
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool comesBefore(const Instruction *Other) const
Given an instruction Other in the same basic block as this instruction, return true if this instructi...
A wrapper class for inspecting calls to intrinsic functions.
LLVM_ABI std::optional< PredicateConstraint > getConstraint() const
Fetch condition in the form of PredicateConstraint, if possible.
Definition PredicateInfo.cpp:713
PredicateInfoAnnotatedWriter(const PredicateInfo *M)
Definition PredicateInfo.cpp:804
void emitInstructionAnnot(const Instruction *I, formatted_raw_ostream &OS) override
emitInstructionAnnot - This may be implemented to emit a string right before an instruction is emitte...
Definition PredicateInfo.cpp:809
friend class PredicateInfo
Definition PredicateInfo.cpp:800
void emitBasicBlockStartAnnot(const BasicBlock *BB, formatted_raw_ostream &OS) override
emitBasicBlockStartAnnot - This may be implemented to emit a string right after the basic block label...
Definition PredicateInfo.cpp:806
PredicateInfoBuilder(PredicateInfo &PI, Function &F, DominatorTree &DT, AssumptionCache &AC, BumpPtrAllocator &Allocator)
Definition PredicateInfo.cpp:244
void buildPredicateInfo()
Definition PredicateInfo.cpp:471
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition PredicateInfo.cpp:784
Encapsulates PredicateInfo, including all data associated with memory accesses.
friend class PredicateInfoAnnotatedWriter
LLVM_ABI void verifyPredicateInfo() const
Definition PredicateInfo.cpp:768
friend class PredicateInfoBuilder
LLVM_ABI void print(raw_ostream &) const
Definition PredicateInfo.cpp:837
LLVM_ABI PredicateInfo(Function &, DominatorTree &, AssumptionCache &, BumpPtrAllocator &)
Definition PredicateInfo.cpp:706
LLVM_ABI void dump() const
Definition PredicateInfo.cpp:842
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
formatted_raw_ostream - A raw_ostream that wraps another one and keeps track of line and column posit...
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
void stable_sort(R &&Range)
void collectCmpOps(CmpInst *Comparison, SmallVectorImpl< Value * > &CmpOperands)
Definition PredicateInfo.cpp:340
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
static void replaceCreatedSSACopys(PredicateInfo &PredInfo, Function &F)
Definition PredicateInfo.cpp:771
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...
bool shouldRename(Value *V)
Definition PredicateInfo.cpp:331
DomTreeNodeBase< BasicBlock > DomTreeNode
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LocalNum
Definition PredicateInfo.cpp:71
@ LN_First
Definition PredicateInfo.cpp:73
@ LN_Last
Definition PredicateInfo.cpp:78
@ LN_Middle
Definition PredicateInfo.cpp:76
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition PredicateInfo.cpp:847
std::pair< BasicBlock *, BasicBlock * > getBlockEdge(const ValueDFS &VD) const
Definition PredicateInfo.cpp:131
bool operator()(const ValueDFS &A, const ValueDFS &B) const
Definition PredicateInfo.cpp:98
const Instruction * getDefOrUser(const ValueDFS &VD) const
Definition PredicateInfo.cpp:173
bool comparePHIRelated(const ValueDFS &A, const ValueDFS &B) const
Definition PredicateInfo.cpp:141
ValueDFS_Compare(DominatorTree &DT)
Definition PredicateInfo.cpp:96
bool localComesBefore(const ValueDFS &A, const ValueDFS &B) const
Definition PredicateInfo.cpp:187
DominatorTree & DT
Definition PredicateInfo.cpp:95
Definition PredicateInfo.cpp:83
int DFSOut
Definition PredicateInfo.cpp:85
Use * U
Definition PredicateInfo.cpp:88
PredicateBase * PInfo
Definition PredicateInfo.cpp:89
unsigned int LocalNum
Definition PredicateInfo.cpp:86
int DFSIn
Definition PredicateInfo.cpp:84