xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Utils/PredicateInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- PredicateInfo.cpp - PredicateInfo Builder--------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the PredicateInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Transforms/Utils/PredicateInfo.h"
140b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
150b57cec5SDimitry Andric #include "llvm/ADT/DepthFirstIterator.h"
160b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
170b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
180b57cec5SDimitry Andric #include "llvm/Analysis/AssumptionCache.h"
190b57cec5SDimitry Andric #include "llvm/IR/AssemblyAnnotationWriter.h"
200b57cec5SDimitry Andric #include "llvm/IR/Dominators.h"
210b57cec5SDimitry Andric #include "llvm/IR/IRBuilder.h"
226e75b2fbSDimitry Andric #include "llvm/IR/InstIterator.h"
230b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
240b57cec5SDimitry Andric #include "llvm/IR/Module.h"
250b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h"
265ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h"
270b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
280b57cec5SDimitry Andric #include "llvm/Support/DebugCounter.h"
290b57cec5SDimitry Andric #include "llvm/Support/FormattedStream.h"
300b57cec5SDimitry Andric #include <algorithm>
310b57cec5SDimitry Andric #define DEBUG_TYPE "predicateinfo"
320b57cec5SDimitry Andric using namespace llvm;
330b57cec5SDimitry Andric using namespace PatternMatch;
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric static cl::opt<bool> VerifyPredicateInfo(
360b57cec5SDimitry Andric     "verify-predicateinfo", cl::init(false), cl::Hidden,
370b57cec5SDimitry Andric     cl::desc("Verify PredicateInfo in legacy printer pass."));
380b57cec5SDimitry Andric DEBUG_COUNTER(RenameCounter, "predicateinfo-rename",
390b57cec5SDimitry Andric               "Controls which variables are renamed with predicateinfo");
400b57cec5SDimitry Andric 
41e8d8bef9SDimitry Andric // Maximum number of conditions considered for renaming for each branch/assume.
42e8d8bef9SDimitry Andric // This limits renaming of deep and/or chains.
43e8d8bef9SDimitry Andric static const unsigned MaxCondsPerBranch = 8;
44e8d8bef9SDimitry Andric 
450b57cec5SDimitry Andric namespace {
460b57cec5SDimitry Andric // Given a predicate info that is a type of branching terminator, get the
470b57cec5SDimitry Andric // branching block.
480b57cec5SDimitry Andric const BasicBlock *getBranchBlock(const PredicateBase *PB) {
490b57cec5SDimitry Andric   assert(isa<PredicateWithEdge>(PB) &&
500b57cec5SDimitry Andric          "Only branches and switches should have PHIOnly defs that "
510b57cec5SDimitry Andric          "require branch blocks.");
520b57cec5SDimitry Andric   return cast<PredicateWithEdge>(PB)->From;
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric // Given a predicate info that is a type of branching terminator, get the
560b57cec5SDimitry Andric // branching terminator.
570b57cec5SDimitry Andric static Instruction *getBranchTerminator(const PredicateBase *PB) {
580b57cec5SDimitry Andric   assert(isa<PredicateWithEdge>(PB) &&
590b57cec5SDimitry Andric          "Not a predicate info type we know how to get a terminator from.");
600b57cec5SDimitry Andric   return cast<PredicateWithEdge>(PB)->From->getTerminator();
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric // Given a predicate info that is a type of branching terminator, get the
640b57cec5SDimitry Andric // edge this predicate info represents
65fe6060f1SDimitry Andric std::pair<BasicBlock *, BasicBlock *> getBlockEdge(const PredicateBase *PB) {
660b57cec5SDimitry Andric   assert(isa<PredicateWithEdge>(PB) &&
670b57cec5SDimitry Andric          "Not a predicate info type we know how to get an edge from.");
680b57cec5SDimitry Andric   const auto *PEdge = cast<PredicateWithEdge>(PB);
690b57cec5SDimitry Andric   return std::make_pair(PEdge->From, PEdge->To);
700b57cec5SDimitry Andric }
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric namespace llvm {
740b57cec5SDimitry Andric enum LocalNum {
750b57cec5SDimitry Andric   // Operations that must appear first in the block.
760b57cec5SDimitry Andric   LN_First,
770b57cec5SDimitry Andric   // Operations that are somewhere in the middle of the block, and are sorted on
780b57cec5SDimitry Andric   // demand.
790b57cec5SDimitry Andric   LN_Middle,
800b57cec5SDimitry Andric   // Operations that must appear last in a block, like successor phi node uses.
810b57cec5SDimitry Andric   LN_Last
820b57cec5SDimitry Andric };
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric // Associate global and local DFS info with defs and uses, so we can sort them
850b57cec5SDimitry Andric // into a global domination ordering.
860b57cec5SDimitry Andric struct ValueDFS {
870b57cec5SDimitry Andric   int DFSIn = 0;
880b57cec5SDimitry Andric   int DFSOut = 0;
890b57cec5SDimitry Andric   unsigned int LocalNum = LN_Middle;
900b57cec5SDimitry Andric   // Only one of Def or Use will be set.
910b57cec5SDimitry Andric   Value *Def = nullptr;
920b57cec5SDimitry Andric   Use *U = nullptr;
930b57cec5SDimitry Andric   // Neither PInfo nor EdgeOnly participate in the ordering
940b57cec5SDimitry Andric   PredicateBase *PInfo = nullptr;
950b57cec5SDimitry Andric   bool EdgeOnly = false;
960b57cec5SDimitry Andric };
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric // Perform a strict weak ordering on instructions and arguments.
995ffd83dbSDimitry Andric static bool valueComesBefore(const Value *A, const Value *B) {
1000b57cec5SDimitry Andric   auto *ArgA = dyn_cast_or_null<Argument>(A);
1010b57cec5SDimitry Andric   auto *ArgB = dyn_cast_or_null<Argument>(B);
1020b57cec5SDimitry Andric   if (ArgA && !ArgB)
1030b57cec5SDimitry Andric     return true;
1040b57cec5SDimitry Andric   if (ArgB && !ArgA)
1050b57cec5SDimitry Andric     return false;
1060b57cec5SDimitry Andric   if (ArgA && ArgB)
1070b57cec5SDimitry Andric     return ArgA->getArgNo() < ArgB->getArgNo();
1085ffd83dbSDimitry Andric   return cast<Instruction>(A)->comesBefore(cast<Instruction>(B));
1090b57cec5SDimitry Andric }
1100b57cec5SDimitry Andric 
1115ffd83dbSDimitry Andric // This compares ValueDFS structures. Doing so allows us to walk the minimum
1125ffd83dbSDimitry Andric // number of instructions necessary to compute our def/use ordering.
1130b57cec5SDimitry Andric struct ValueDFS_Compare {
1148bcb0991SDimitry Andric   DominatorTree &DT;
1155ffd83dbSDimitry Andric   ValueDFS_Compare(DominatorTree &DT) : DT(DT) {}
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric   bool operator()(const ValueDFS &A, const ValueDFS &B) const {
1180b57cec5SDimitry Andric     if (&A == &B)
1190b57cec5SDimitry Andric       return false;
1200b57cec5SDimitry Andric     // The only case we can't directly compare them is when they in the same
1210b57cec5SDimitry Andric     // block, and both have localnum == middle.  In that case, we have to use
1220b57cec5SDimitry Andric     // comesbefore to see what the real ordering is, because they are in the
1230b57cec5SDimitry Andric     // same basic block.
1240b57cec5SDimitry Andric 
1258bcb0991SDimitry Andric     assert((A.DFSIn != B.DFSIn || A.DFSOut == B.DFSOut) &&
1268bcb0991SDimitry Andric            "Equal DFS-in numbers imply equal out numbers");
1278bcb0991SDimitry Andric     bool SameBlock = A.DFSIn == B.DFSIn;
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric     // We want to put the def that will get used for a given set of phi uses,
1300b57cec5SDimitry Andric     // before those phi uses.
1310b57cec5SDimitry Andric     // So we sort by edge, then by def.
1320b57cec5SDimitry Andric     // Note that only phi nodes uses and defs can come last.
1330b57cec5SDimitry Andric     if (SameBlock && A.LocalNum == LN_Last && B.LocalNum == LN_Last)
1340b57cec5SDimitry Andric       return comparePHIRelated(A, B);
1350b57cec5SDimitry Andric 
1368bcb0991SDimitry Andric     bool isADef = A.Def;
1378bcb0991SDimitry Andric     bool isBDef = B.Def;
1380b57cec5SDimitry Andric     if (!SameBlock || A.LocalNum != LN_Middle || B.LocalNum != LN_Middle)
1398bcb0991SDimitry Andric       return std::tie(A.DFSIn, A.LocalNum, isADef) <
1408bcb0991SDimitry Andric              std::tie(B.DFSIn, B.LocalNum, isBDef);
1410b57cec5SDimitry Andric     return localComesBefore(A, B);
1420b57cec5SDimitry Andric   }
1430b57cec5SDimitry Andric 
1440b57cec5SDimitry Andric   // For a phi use, or a non-materialized def, return the edge it represents.
145fe6060f1SDimitry Andric   std::pair<BasicBlock *, BasicBlock *> getBlockEdge(const ValueDFS &VD) const {
1460b57cec5SDimitry Andric     if (!VD.Def && VD.U) {
1470b57cec5SDimitry Andric       auto *PHI = cast<PHINode>(VD.U->getUser());
1480b57cec5SDimitry Andric       return std::make_pair(PHI->getIncomingBlock(*VD.U), PHI->getParent());
1490b57cec5SDimitry Andric     }
1500b57cec5SDimitry Andric     // This is really a non-materialized def.
1510b57cec5SDimitry Andric     return ::getBlockEdge(VD.PInfo);
1520b57cec5SDimitry Andric   }
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric   // For two phi related values, return the ordering.
1550b57cec5SDimitry Andric   bool comparePHIRelated(const ValueDFS &A, const ValueDFS &B) const {
1568bcb0991SDimitry Andric     BasicBlock *ASrc, *ADest, *BSrc, *BDest;
1578bcb0991SDimitry Andric     std::tie(ASrc, ADest) = getBlockEdge(A);
1588bcb0991SDimitry Andric     std::tie(BSrc, BDest) = getBlockEdge(B);
1598bcb0991SDimitry Andric 
1608bcb0991SDimitry Andric #ifndef NDEBUG
1618bcb0991SDimitry Andric     // This function should only be used for values in the same BB, check that.
1628bcb0991SDimitry Andric     DomTreeNode *DomASrc = DT.getNode(ASrc);
1638bcb0991SDimitry Andric     DomTreeNode *DomBSrc = DT.getNode(BSrc);
1648bcb0991SDimitry Andric     assert(DomASrc->getDFSNumIn() == (unsigned)A.DFSIn &&
1658bcb0991SDimitry Andric            "DFS numbers for A should match the ones of the source block");
1668bcb0991SDimitry Andric     assert(DomBSrc->getDFSNumIn() == (unsigned)B.DFSIn &&
1678bcb0991SDimitry Andric            "DFS numbers for B should match the ones of the source block");
1688bcb0991SDimitry Andric     assert(A.DFSIn == B.DFSIn && "Values must be in the same block");
1698bcb0991SDimitry Andric #endif
1708bcb0991SDimitry Andric     (void)ASrc;
1718bcb0991SDimitry Andric     (void)BSrc;
1728bcb0991SDimitry Andric 
1738bcb0991SDimitry Andric     // Use DFS numbers to compare destination blocks, to guarantee a
1748bcb0991SDimitry Andric     // deterministic order.
1758bcb0991SDimitry Andric     DomTreeNode *DomADest = DT.getNode(ADest);
1768bcb0991SDimitry Andric     DomTreeNode *DomBDest = DT.getNode(BDest);
1778bcb0991SDimitry Andric     unsigned AIn = DomADest->getDFSNumIn();
1788bcb0991SDimitry Andric     unsigned BIn = DomBDest->getDFSNumIn();
1798bcb0991SDimitry Andric     bool isADef = A.Def;
1808bcb0991SDimitry Andric     bool isBDef = B.Def;
1818bcb0991SDimitry Andric     assert((!A.Def || !A.U) && (!B.Def || !B.U) &&
1828bcb0991SDimitry Andric            "Def and U cannot be set at the same time");
1838bcb0991SDimitry Andric     // Now sort by edge destination and then defs before uses.
1848bcb0991SDimitry Andric     return std::tie(AIn, isADef) < std::tie(BIn, isBDef);
1850b57cec5SDimitry Andric   }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   // Get the definition of an instruction that occurs in the middle of a block.
1880b57cec5SDimitry Andric   Value *getMiddleDef(const ValueDFS &VD) const {
1890b57cec5SDimitry Andric     if (VD.Def)
1900b57cec5SDimitry Andric       return VD.Def;
1910b57cec5SDimitry Andric     // It's possible for the defs and uses to be null.  For branches, the local
1920b57cec5SDimitry Andric     // numbering will say the placed predicaeinfos should go first (IE
1930b57cec5SDimitry Andric     // LN_beginning), so we won't be in this function. For assumes, we will end
1940b57cec5SDimitry Andric     // up here, beause we need to order the def we will place relative to the
1955ffd83dbSDimitry Andric     // assume.  So for the purpose of ordering, we pretend the def is right
1965ffd83dbSDimitry Andric     // after the assume, because that is where we will insert the info.
1970b57cec5SDimitry Andric     if (!VD.U) {
1980b57cec5SDimitry Andric       assert(VD.PInfo &&
1990b57cec5SDimitry Andric              "No def, no use, and no predicateinfo should not occur");
2000b57cec5SDimitry Andric       assert(isa<PredicateAssume>(VD.PInfo) &&
2010b57cec5SDimitry Andric              "Middle of block should only occur for assumes");
2025ffd83dbSDimitry Andric       return cast<PredicateAssume>(VD.PInfo)->AssumeInst->getNextNode();
2030b57cec5SDimitry Andric     }
2040b57cec5SDimitry Andric     return nullptr;
2050b57cec5SDimitry Andric   }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric   // Return either the Def, if it's not null, or the user of the Use, if the def
2080b57cec5SDimitry Andric   // is null.
2090b57cec5SDimitry Andric   const Instruction *getDefOrUser(const Value *Def, const Use *U) const {
2100b57cec5SDimitry Andric     if (Def)
2110b57cec5SDimitry Andric       return cast<Instruction>(Def);
2120b57cec5SDimitry Andric     return cast<Instruction>(U->getUser());
2130b57cec5SDimitry Andric   }
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric   // This performs the necessary local basic block ordering checks to tell
2160b57cec5SDimitry Andric   // whether A comes before B, where both are in the same basic block.
2170b57cec5SDimitry Andric   bool localComesBefore(const ValueDFS &A, const ValueDFS &B) const {
2180b57cec5SDimitry Andric     auto *ADef = getMiddleDef(A);
2190b57cec5SDimitry Andric     auto *BDef = getMiddleDef(B);
2200b57cec5SDimitry Andric 
2210b57cec5SDimitry Andric     // See if we have real values or uses. If we have real values, we are
2220b57cec5SDimitry Andric     // guaranteed they are instructions or arguments. No matter what, we are
2230b57cec5SDimitry Andric     // guaranteed they are in the same block if they are instructions.
2240b57cec5SDimitry Andric     auto *ArgA = dyn_cast_or_null<Argument>(ADef);
2250b57cec5SDimitry Andric     auto *ArgB = dyn_cast_or_null<Argument>(BDef);
2260b57cec5SDimitry Andric 
2270b57cec5SDimitry Andric     if (ArgA || ArgB)
2285ffd83dbSDimitry Andric       return valueComesBefore(ArgA, ArgB);
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric     auto *AInst = getDefOrUser(ADef, A.U);
2310b57cec5SDimitry Andric     auto *BInst = getDefOrUser(BDef, B.U);
2325ffd83dbSDimitry Andric     return valueComesBefore(AInst, BInst);
2330b57cec5SDimitry Andric   }
2340b57cec5SDimitry Andric };
2350b57cec5SDimitry Andric 
2365ffd83dbSDimitry Andric class PredicateInfoBuilder {
2375ffd83dbSDimitry Andric   // Used to store information about each value we might rename.
2385ffd83dbSDimitry Andric   struct ValueInfo {
2395ffd83dbSDimitry Andric     SmallVector<PredicateBase *, 4> Infos;
2405ffd83dbSDimitry Andric   };
2410b57cec5SDimitry Andric 
2425ffd83dbSDimitry Andric   PredicateInfo &PI;
2435ffd83dbSDimitry Andric   Function &F;
2445ffd83dbSDimitry Andric   DominatorTree &DT;
2455ffd83dbSDimitry Andric   AssumptionCache &AC;
2465ffd83dbSDimitry Andric 
2475ffd83dbSDimitry Andric   // This stores info about each operand or comparison result we make copies
2485ffd83dbSDimitry Andric   // of. The real ValueInfos start at index 1, index 0 is unused so that we
2495ffd83dbSDimitry Andric   // can more easily detect invalid indexing.
2505ffd83dbSDimitry Andric   SmallVector<ValueInfo, 32> ValueInfos;
2515ffd83dbSDimitry Andric 
2525ffd83dbSDimitry Andric   // This gives the index into the ValueInfos array for a given Value. Because
2535ffd83dbSDimitry Andric   // 0 is not a valid Value Info index, you can use DenseMap::lookup and tell
2545ffd83dbSDimitry Andric   // whether it returned a valid result.
2555ffd83dbSDimitry Andric   DenseMap<Value *, unsigned int> ValueInfoNums;
2565ffd83dbSDimitry Andric 
2575ffd83dbSDimitry Andric   // The set of edges along which we can only handle phi uses, due to critical
2585ffd83dbSDimitry Andric   // edges.
2595ffd83dbSDimitry Andric   DenseSet<std::pair<BasicBlock *, BasicBlock *>> EdgeUsesOnly;
2605ffd83dbSDimitry Andric 
2615ffd83dbSDimitry Andric   ValueInfo &getOrCreateValueInfo(Value *);
2625ffd83dbSDimitry Andric   const ValueInfo &getValueInfo(Value *) const;
2635ffd83dbSDimitry Andric 
2645ffd83dbSDimitry Andric   void processAssume(IntrinsicInst *, BasicBlock *,
2655ffd83dbSDimitry Andric                      SmallVectorImpl<Value *> &OpsToRename);
2665ffd83dbSDimitry Andric   void processBranch(BranchInst *, BasicBlock *,
2675ffd83dbSDimitry Andric                      SmallVectorImpl<Value *> &OpsToRename);
2685ffd83dbSDimitry Andric   void processSwitch(SwitchInst *, BasicBlock *,
2695ffd83dbSDimitry Andric                      SmallVectorImpl<Value *> &OpsToRename);
2705ffd83dbSDimitry Andric   void renameUses(SmallVectorImpl<Value *> &OpsToRename);
2715ffd83dbSDimitry Andric   void addInfoFor(SmallVectorImpl<Value *> &OpsToRename, Value *Op,
2725ffd83dbSDimitry Andric                   PredicateBase *PB);
2735ffd83dbSDimitry Andric 
2745ffd83dbSDimitry Andric   typedef SmallVectorImpl<ValueDFS> ValueDFSStack;
2755ffd83dbSDimitry Andric   void convertUsesToDFSOrdered(Value *, SmallVectorImpl<ValueDFS> &);
2765ffd83dbSDimitry Andric   Value *materializeStack(unsigned int &, ValueDFSStack &, Value *);
2775ffd83dbSDimitry Andric   bool stackIsInScope(const ValueDFSStack &, const ValueDFS &) const;
2785ffd83dbSDimitry Andric   void popStackUntilDFSScope(ValueDFSStack &, const ValueDFS &);
2795ffd83dbSDimitry Andric 
2805ffd83dbSDimitry Andric public:
2815ffd83dbSDimitry Andric   PredicateInfoBuilder(PredicateInfo &PI, Function &F, DominatorTree &DT,
2825ffd83dbSDimitry Andric                        AssumptionCache &AC)
2835ffd83dbSDimitry Andric       : PI(PI), F(F), DT(DT), AC(AC) {
2845ffd83dbSDimitry Andric     // Push an empty operand info so that we can detect 0 as not finding one
2855ffd83dbSDimitry Andric     ValueInfos.resize(1);
2865ffd83dbSDimitry Andric   }
2875ffd83dbSDimitry Andric 
2885ffd83dbSDimitry Andric   void buildPredicateInfo();
2895ffd83dbSDimitry Andric };
2905ffd83dbSDimitry Andric 
2915ffd83dbSDimitry Andric bool PredicateInfoBuilder::stackIsInScope(const ValueDFSStack &Stack,
2920b57cec5SDimitry Andric                                           const ValueDFS &VDUse) const {
2930b57cec5SDimitry Andric   if (Stack.empty())
2940b57cec5SDimitry Andric     return false;
2950b57cec5SDimitry Andric   // If it's a phi only use, make sure it's for this phi node edge, and that the
2960b57cec5SDimitry Andric   // use is in a phi node.  If it's anything else, and the top of the stack is
2970b57cec5SDimitry Andric   // EdgeOnly, we need to pop the stack.  We deliberately sort phi uses next to
2980b57cec5SDimitry Andric   // the defs they must go with so that we can know it's time to pop the stack
2990b57cec5SDimitry Andric   // when we hit the end of the phi uses for a given def.
3000b57cec5SDimitry Andric   if (Stack.back().EdgeOnly) {
3010b57cec5SDimitry Andric     if (!VDUse.U)
3020b57cec5SDimitry Andric       return false;
3030b57cec5SDimitry Andric     auto *PHI = dyn_cast<PHINode>(VDUse.U->getUser());
3040b57cec5SDimitry Andric     if (!PHI)
3050b57cec5SDimitry Andric       return false;
3060b57cec5SDimitry Andric     // Check edge
3070b57cec5SDimitry Andric     BasicBlock *EdgePred = PHI->getIncomingBlock(*VDUse.U);
3080b57cec5SDimitry Andric     if (EdgePred != getBranchBlock(Stack.back().PInfo))
3090b57cec5SDimitry Andric       return false;
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric     // Use dominates, which knows how to handle edge dominance.
3120b57cec5SDimitry Andric     return DT.dominates(getBlockEdge(Stack.back().PInfo), *VDUse.U);
3130b57cec5SDimitry Andric   }
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric   return (VDUse.DFSIn >= Stack.back().DFSIn &&
3160b57cec5SDimitry Andric           VDUse.DFSOut <= Stack.back().DFSOut);
3170b57cec5SDimitry Andric }
3180b57cec5SDimitry Andric 
3195ffd83dbSDimitry Andric void PredicateInfoBuilder::popStackUntilDFSScope(ValueDFSStack &Stack,
3200b57cec5SDimitry Andric                                                  const ValueDFS &VD) {
3210b57cec5SDimitry Andric   while (!Stack.empty() && !stackIsInScope(Stack, VD))
3220b57cec5SDimitry Andric     Stack.pop_back();
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric // Convert the uses of Op into a vector of uses, associating global and local
3260b57cec5SDimitry Andric // DFS info with each one.
3275ffd83dbSDimitry Andric void PredicateInfoBuilder::convertUsesToDFSOrdered(
3280b57cec5SDimitry Andric     Value *Op, SmallVectorImpl<ValueDFS> &DFSOrderedSet) {
3290b57cec5SDimitry Andric   for (auto &U : Op->uses()) {
3300b57cec5SDimitry Andric     if (auto *I = dyn_cast<Instruction>(U.getUser())) {
3310b57cec5SDimitry Andric       ValueDFS VD;
3320b57cec5SDimitry Andric       // Put the phi node uses in the incoming block.
3330b57cec5SDimitry Andric       BasicBlock *IBlock;
3340b57cec5SDimitry Andric       if (auto *PN = dyn_cast<PHINode>(I)) {
3350b57cec5SDimitry Andric         IBlock = PN->getIncomingBlock(U);
3360b57cec5SDimitry Andric         // Make phi node users appear last in the incoming block
3370b57cec5SDimitry Andric         // they are from.
3380b57cec5SDimitry Andric         VD.LocalNum = LN_Last;
3390b57cec5SDimitry Andric       } else {
3400b57cec5SDimitry Andric         // If it's not a phi node use, it is somewhere in the middle of the
3410b57cec5SDimitry Andric         // block.
3420b57cec5SDimitry Andric         IBlock = I->getParent();
3430b57cec5SDimitry Andric         VD.LocalNum = LN_Middle;
3440b57cec5SDimitry Andric       }
3450b57cec5SDimitry Andric       DomTreeNode *DomNode = DT.getNode(IBlock);
3460b57cec5SDimitry Andric       // It's possible our use is in an unreachable block. Skip it if so.
3470b57cec5SDimitry Andric       if (!DomNode)
3480b57cec5SDimitry Andric         continue;
3490b57cec5SDimitry Andric       VD.DFSIn = DomNode->getDFSNumIn();
3500b57cec5SDimitry Andric       VD.DFSOut = DomNode->getDFSNumOut();
3510b57cec5SDimitry Andric       VD.U = &U;
3520b57cec5SDimitry Andric       DFSOrderedSet.push_back(VD);
3530b57cec5SDimitry Andric     }
3540b57cec5SDimitry Andric   }
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric 
357e8d8bef9SDimitry Andric bool shouldRename(Value *V) {
358e8d8bef9SDimitry Andric   // Only want real values, not constants.  Additionally, operands with one use
359e8d8bef9SDimitry Andric   // are only being used in the comparison, which means they will not be useful
360e8d8bef9SDimitry Andric   // for us to consider for predicateinfo.
361e8d8bef9SDimitry Andric   return (isa<Instruction>(V) || isa<Argument>(V)) && !V->hasOneUse();
362e8d8bef9SDimitry Andric }
363e8d8bef9SDimitry Andric 
3640b57cec5SDimitry Andric // Collect relevant operations from Comparison that we may want to insert copies
3650b57cec5SDimitry Andric // for.
3660b57cec5SDimitry Andric void collectCmpOps(CmpInst *Comparison, SmallVectorImpl<Value *> &CmpOperands) {
3670b57cec5SDimitry Andric   auto *Op0 = Comparison->getOperand(0);
3680b57cec5SDimitry Andric   auto *Op1 = Comparison->getOperand(1);
3690b57cec5SDimitry Andric   if (Op0 == Op1)
3700b57cec5SDimitry Andric     return;
371e8d8bef9SDimitry Andric 
3720b57cec5SDimitry Andric   CmpOperands.push_back(Op0);
3730b57cec5SDimitry Andric   CmpOperands.push_back(Op1);
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric // Add Op, PB to the list of value infos for Op, and mark Op to be renamed.
3775ffd83dbSDimitry Andric void PredicateInfoBuilder::addInfoFor(SmallVectorImpl<Value *> &OpsToRename,
3785ffd83dbSDimitry Andric                                       Value *Op, PredicateBase *PB) {
3790b57cec5SDimitry Andric   auto &OperandInfo = getOrCreateValueInfo(Op);
3808bcb0991SDimitry Andric   if (OperandInfo.Infos.empty())
3818bcb0991SDimitry Andric     OpsToRename.push_back(Op);
3825ffd83dbSDimitry Andric   PI.AllInfos.push_back(PB);
3830b57cec5SDimitry Andric   OperandInfo.Infos.push_back(PB);
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric // Process an assume instruction and place relevant operations we want to rename
3870b57cec5SDimitry Andric // into OpsToRename.
3885ffd83dbSDimitry Andric void PredicateInfoBuilder::processAssume(
3895ffd83dbSDimitry Andric     IntrinsicInst *II, BasicBlock *AssumeBB,
3908bcb0991SDimitry Andric     SmallVectorImpl<Value *> &OpsToRename) {
391e8d8bef9SDimitry Andric   SmallVector<Value *, 4> Worklist;
392e8d8bef9SDimitry Andric   SmallPtrSet<Value *, 4> Visited;
393e8d8bef9SDimitry Andric   Worklist.push_back(II->getOperand(0));
394e8d8bef9SDimitry Andric   while (!Worklist.empty()) {
395e8d8bef9SDimitry Andric     Value *Cond = Worklist.pop_back_val();
396e8d8bef9SDimitry Andric     if (!Visited.insert(Cond).second)
397e8d8bef9SDimitry Andric       continue;
398e8d8bef9SDimitry Andric     if (Visited.size() > MaxCondsPerBranch)
399e8d8bef9SDimitry Andric       break;
4000b57cec5SDimitry Andric 
401e8d8bef9SDimitry Andric     Value *Op0, *Op1;
402e8d8bef9SDimitry Andric     if (match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))) {
403e8d8bef9SDimitry Andric       Worklist.push_back(Op1);
404e8d8bef9SDimitry Andric       Worklist.push_back(Op0);
4050b57cec5SDimitry Andric     }
406e8d8bef9SDimitry Andric 
407e8d8bef9SDimitry Andric     SmallVector<Value *, 4> Values;
408e8d8bef9SDimitry Andric     Values.push_back(Cond);
409e8d8bef9SDimitry Andric     if (auto *Cmp = dyn_cast<CmpInst>(Cond))
410e8d8bef9SDimitry Andric       collectCmpOps(Cmp, Values);
411e8d8bef9SDimitry Andric 
412e8d8bef9SDimitry Andric     for (Value *V : Values) {
413e8d8bef9SDimitry Andric       if (shouldRename(V)) {
414e8d8bef9SDimitry Andric         auto *PA = new PredicateAssume(V, II, Cond);
415e8d8bef9SDimitry Andric         addInfoFor(OpsToRename, V, PA);
4160b57cec5SDimitry Andric       }
4170b57cec5SDimitry Andric     }
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric }
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric // Process a block terminating branch, and place relevant operations to be
4220b57cec5SDimitry Andric // renamed into OpsToRename.
4235ffd83dbSDimitry Andric void PredicateInfoBuilder::processBranch(
4245ffd83dbSDimitry Andric     BranchInst *BI, BasicBlock *BranchBB,
4258bcb0991SDimitry Andric     SmallVectorImpl<Value *> &OpsToRename) {
4260b57cec5SDimitry Andric   BasicBlock *FirstBB = BI->getSuccessor(0);
4270b57cec5SDimitry Andric   BasicBlock *SecondBB = BI->getSuccessor(1);
4280b57cec5SDimitry Andric 
429e8d8bef9SDimitry Andric   for (BasicBlock *Succ : {FirstBB, SecondBB}) {
430e8d8bef9SDimitry Andric     bool TakenEdge = Succ == FirstBB;
4310b57cec5SDimitry Andric     // Don't try to insert on a self-edge. This is mainly because we will
4320b57cec5SDimitry Andric     // eliminate during renaming anyway.
4330b57cec5SDimitry Andric     if (Succ == BranchBB)
4340b57cec5SDimitry Andric       continue;
435e8d8bef9SDimitry Andric 
436e8d8bef9SDimitry Andric     SmallVector<Value *, 4> Worklist;
437e8d8bef9SDimitry Andric     SmallPtrSet<Value *, 4> Visited;
438e8d8bef9SDimitry Andric     Worklist.push_back(BI->getCondition());
439e8d8bef9SDimitry Andric     while (!Worklist.empty()) {
440e8d8bef9SDimitry Andric       Value *Cond = Worklist.pop_back_val();
441e8d8bef9SDimitry Andric       if (!Visited.insert(Cond).second)
4420b57cec5SDimitry Andric         continue;
443e8d8bef9SDimitry Andric       if (Visited.size() > MaxCondsPerBranch)
444e8d8bef9SDimitry Andric         break;
445e8d8bef9SDimitry Andric 
446e8d8bef9SDimitry Andric       Value *Op0, *Op1;
447e8d8bef9SDimitry Andric       if (TakenEdge ? match(Cond, m_LogicalAnd(m_Value(Op0), m_Value(Op1)))
448e8d8bef9SDimitry Andric                     : match(Cond, m_LogicalOr(m_Value(Op0), m_Value(Op1)))) {
449e8d8bef9SDimitry Andric         Worklist.push_back(Op1);
450e8d8bef9SDimitry Andric         Worklist.push_back(Op0);
451e8d8bef9SDimitry Andric       }
452e8d8bef9SDimitry Andric 
453e8d8bef9SDimitry Andric       SmallVector<Value *, 4> Values;
454e8d8bef9SDimitry Andric       Values.push_back(Cond);
455e8d8bef9SDimitry Andric       if (auto *Cmp = dyn_cast<CmpInst>(Cond))
456e8d8bef9SDimitry Andric         collectCmpOps(Cmp, Values);
457e8d8bef9SDimitry Andric 
458e8d8bef9SDimitry Andric       for (Value *V : Values) {
459e8d8bef9SDimitry Andric         if (shouldRename(V)) {
4600b57cec5SDimitry Andric           PredicateBase *PB =
461e8d8bef9SDimitry Andric               new PredicateBranch(V, BranchBB, Succ, Cond, TakenEdge);
462e8d8bef9SDimitry Andric           addInfoFor(OpsToRename, V, PB);
4630b57cec5SDimitry Andric           if (!Succ->getSinglePredecessor())
4640b57cec5SDimitry Andric             EdgeUsesOnly.insert({BranchBB, Succ});
4650b57cec5SDimitry Andric         }
4660b57cec5SDimitry Andric       }
4670b57cec5SDimitry Andric     }
4680b57cec5SDimitry Andric   }
4690b57cec5SDimitry Andric }
4700b57cec5SDimitry Andric // Process a block terminating switch, and place relevant operations to be
4710b57cec5SDimitry Andric // renamed into OpsToRename.
4725ffd83dbSDimitry Andric void PredicateInfoBuilder::processSwitch(
4735ffd83dbSDimitry Andric     SwitchInst *SI, BasicBlock *BranchBB,
4748bcb0991SDimitry Andric     SmallVectorImpl<Value *> &OpsToRename) {
4750b57cec5SDimitry Andric   Value *Op = SI->getCondition();
4760b57cec5SDimitry Andric   if ((!isa<Instruction>(Op) && !isa<Argument>(Op)) || Op->hasOneUse())
4770b57cec5SDimitry Andric     return;
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric   // Remember how many outgoing edges there are to every successor.
4800b57cec5SDimitry Andric   SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
481*0fca6ea1SDimitry Andric   for (BasicBlock *TargetBlock : successors(BranchBB))
4820b57cec5SDimitry Andric     ++SwitchEdges[TargetBlock];
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   // Now propagate info for each case value
4850b57cec5SDimitry Andric   for (auto C : SI->cases()) {
4860b57cec5SDimitry Andric     BasicBlock *TargetBlock = C.getCaseSuccessor();
4870b57cec5SDimitry Andric     if (SwitchEdges.lookup(TargetBlock) == 1) {
4880b57cec5SDimitry Andric       PredicateSwitch *PS = new PredicateSwitch(
4890b57cec5SDimitry Andric           Op, SI->getParent(), TargetBlock, C.getCaseValue(), SI);
4900b57cec5SDimitry Andric       addInfoFor(OpsToRename, Op, PS);
4910b57cec5SDimitry Andric       if (!TargetBlock->getSinglePredecessor())
4920b57cec5SDimitry Andric         EdgeUsesOnly.insert({BranchBB, TargetBlock});
4930b57cec5SDimitry Andric     }
4940b57cec5SDimitry Andric   }
4950b57cec5SDimitry Andric }
4960b57cec5SDimitry Andric 
4970b57cec5SDimitry Andric // Build predicate info for our function
4985ffd83dbSDimitry Andric void PredicateInfoBuilder::buildPredicateInfo() {
4990b57cec5SDimitry Andric   DT.updateDFSNumbers();
5000b57cec5SDimitry Andric   // Collect operands to rename from all conditional branch terminators, as well
5010b57cec5SDimitry Andric   // as assume statements.
5028bcb0991SDimitry Andric   SmallVector<Value *, 8> OpsToRename;
503bdd1243dSDimitry Andric   for (auto *DTN : depth_first(DT.getRootNode())) {
5040b57cec5SDimitry Andric     BasicBlock *BranchBB = DTN->getBlock();
5050b57cec5SDimitry Andric     if (auto *BI = dyn_cast<BranchInst>(BranchBB->getTerminator())) {
5060b57cec5SDimitry Andric       if (!BI->isConditional())
5070b57cec5SDimitry Andric         continue;
5080b57cec5SDimitry Andric       // Can't insert conditional information if they all go to the same place.
5090b57cec5SDimitry Andric       if (BI->getSuccessor(0) == BI->getSuccessor(1))
5100b57cec5SDimitry Andric         continue;
5110b57cec5SDimitry Andric       processBranch(BI, BranchBB, OpsToRename);
5120b57cec5SDimitry Andric     } else if (auto *SI = dyn_cast<SwitchInst>(BranchBB->getTerminator())) {
5130b57cec5SDimitry Andric       processSwitch(SI, BranchBB, OpsToRename);
5140b57cec5SDimitry Andric     }
5150b57cec5SDimitry Andric   }
5160b57cec5SDimitry Andric   for (auto &Assume : AC.assumptions()) {
5170b57cec5SDimitry Andric     if (auto *II = dyn_cast_or_null<IntrinsicInst>(Assume))
5180b57cec5SDimitry Andric       if (DT.isReachableFromEntry(II->getParent()))
5190b57cec5SDimitry Andric         processAssume(II, II->getParent(), OpsToRename);
5200b57cec5SDimitry Andric   }
5210b57cec5SDimitry Andric   // Now rename all our operations.
5220b57cec5SDimitry Andric   renameUses(OpsToRename);
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric 
5250b57cec5SDimitry Andric // Given the renaming stack, make all the operands currently on the stack real
5260b57cec5SDimitry Andric // by inserting them into the IR.  Return the last operation's value.
5275ffd83dbSDimitry Andric Value *PredicateInfoBuilder::materializeStack(unsigned int &Counter,
5280b57cec5SDimitry Andric                                              ValueDFSStack &RenameStack,
5290b57cec5SDimitry Andric                                              Value *OrigOp) {
5300b57cec5SDimitry Andric   // Find the first thing we have to materialize
5310b57cec5SDimitry Andric   auto RevIter = RenameStack.rbegin();
5320b57cec5SDimitry Andric   for (; RevIter != RenameStack.rend(); ++RevIter)
5330b57cec5SDimitry Andric     if (RevIter->Def)
5340b57cec5SDimitry Andric       break;
5350b57cec5SDimitry Andric 
5360b57cec5SDimitry Andric   size_t Start = RevIter - RenameStack.rbegin();
5370b57cec5SDimitry Andric   // The maximum number of things we should be trying to materialize at once
5380b57cec5SDimitry Andric   // right now is 4, depending on if we had an assume, a branch, and both used
5390b57cec5SDimitry Andric   // and of conditions.
5400b57cec5SDimitry Andric   for (auto RenameIter = RenameStack.end() - Start;
5410b57cec5SDimitry Andric        RenameIter != RenameStack.end(); ++RenameIter) {
5420b57cec5SDimitry Andric     auto *Op =
5430b57cec5SDimitry Andric         RenameIter == RenameStack.begin() ? OrigOp : (RenameIter - 1)->Def;
5440b57cec5SDimitry Andric     ValueDFS &Result = *RenameIter;
5450b57cec5SDimitry Andric     auto *ValInfo = Result.PInfo;
5465ffd83dbSDimitry Andric     ValInfo->RenamedOp = (RenameStack.end() - Start) == RenameStack.begin()
5475ffd83dbSDimitry Andric                              ? OrigOp
5485ffd83dbSDimitry Andric                              : (RenameStack.end() - Start - 1)->Def;
5490b57cec5SDimitry Andric     // For edge predicates, we can just place the operand in the block before
5500b57cec5SDimitry Andric     // the terminator.  For assume, we have to place it right before the assume
5510b57cec5SDimitry Andric     // to ensure we dominate all of our uses.  Always insert right before the
5520b57cec5SDimitry Andric     // relevant instruction (terminator, assume), so that we insert in proper
5530b57cec5SDimitry Andric     // order in the case of multiple predicateinfo in the same block.
5546e75b2fbSDimitry Andric     // The number of named values is used to detect if a new declaration was
5556e75b2fbSDimitry Andric     // added. If so, that declaration is tracked so that it can be removed when
5566e75b2fbSDimitry Andric     // the analysis is done. The corner case were a new declaration results in
5576e75b2fbSDimitry Andric     // a name clash and the old name being renamed is not considered as that
5586e75b2fbSDimitry Andric     // represents an invalid module.
5590b57cec5SDimitry Andric     if (isa<PredicateWithEdge>(ValInfo)) {
5600b57cec5SDimitry Andric       IRBuilder<> B(getBranchTerminator(ValInfo));
5616e75b2fbSDimitry Andric       auto NumDecls = F.getParent()->getNumNamedValues();
562fe6060f1SDimitry Andric       Function *IF = Intrinsic::getDeclaration(
563fe6060f1SDimitry Andric           F.getParent(), Intrinsic::ssa_copy, Op->getType());
5646e75b2fbSDimitry Andric       if (NumDecls != F.getParent()->getNumNamedValues())
5656e75b2fbSDimitry Andric         PI.CreatedDeclarations.insert(IF);
5660b57cec5SDimitry Andric       CallInst *PIC =
5670b57cec5SDimitry Andric           B.CreateCall(IF, Op, Op->getName() + "." + Twine(Counter++));
5685ffd83dbSDimitry Andric       PI.PredicateMap.insert({PIC, ValInfo});
5690b57cec5SDimitry Andric       Result.Def = PIC;
5700b57cec5SDimitry Andric     } else {
5710b57cec5SDimitry Andric       auto *PAssume = dyn_cast<PredicateAssume>(ValInfo);
5720b57cec5SDimitry Andric       assert(PAssume &&
5730b57cec5SDimitry Andric              "Should not have gotten here without it being an assume");
5745ffd83dbSDimitry Andric       // Insert the predicate directly after the assume. While it also holds
5755ffd83dbSDimitry Andric       // directly before it, assume(i1 true) is not a useful fact.
5765ffd83dbSDimitry Andric       IRBuilder<> B(PAssume->AssumeInst->getNextNode());
5776e75b2fbSDimitry Andric       auto NumDecls = F.getParent()->getNumNamedValues();
578fe6060f1SDimitry Andric       Function *IF = Intrinsic::getDeclaration(
579fe6060f1SDimitry Andric           F.getParent(), Intrinsic::ssa_copy, Op->getType());
5806e75b2fbSDimitry Andric       if (NumDecls != F.getParent()->getNumNamedValues())
5816e75b2fbSDimitry Andric         PI.CreatedDeclarations.insert(IF);
5820b57cec5SDimitry Andric       CallInst *PIC = B.CreateCall(IF, Op);
5835ffd83dbSDimitry Andric       PI.PredicateMap.insert({PIC, ValInfo});
5840b57cec5SDimitry Andric       Result.Def = PIC;
5850b57cec5SDimitry Andric     }
5860b57cec5SDimitry Andric   }
5870b57cec5SDimitry Andric   return RenameStack.back().Def;
5880b57cec5SDimitry Andric }
5890b57cec5SDimitry Andric 
5900b57cec5SDimitry Andric // Instead of the standard SSA renaming algorithm, which is O(Number of
5910b57cec5SDimitry Andric // instructions), and walks the entire dominator tree, we walk only the defs +
5920b57cec5SDimitry Andric // uses.  The standard SSA renaming algorithm does not really rely on the
5930b57cec5SDimitry Andric // dominator tree except to order the stack push/pops of the renaming stacks, so
5940b57cec5SDimitry Andric // that defs end up getting pushed before hitting the correct uses.  This does
5950b57cec5SDimitry Andric // not require the dominator tree, only the *order* of the dominator tree. The
5960b57cec5SDimitry Andric // complete and correct ordering of the defs and uses, in dominator tree is
5970b57cec5SDimitry Andric // contained in the DFS numbering of the dominator tree. So we sort the defs and
5980b57cec5SDimitry Andric // uses into the DFS ordering, and then just use the renaming stack as per
5990b57cec5SDimitry Andric // normal, pushing when we hit a def (which is a predicateinfo instruction),
6000b57cec5SDimitry Andric // popping when we are out of the dfs scope for that def, and replacing any uses
6010b57cec5SDimitry Andric // with top of stack if it exists.  In order to handle liveness without
6020b57cec5SDimitry Andric // propagating liveness info, we don't actually insert the predicateinfo
6030b57cec5SDimitry Andric // instruction def until we see a use that it would dominate.  Once we see such
6040b57cec5SDimitry Andric // a use, we materialize the predicateinfo instruction in the right place and
6050b57cec5SDimitry Andric // use it.
6060b57cec5SDimitry Andric //
6070b57cec5SDimitry Andric // TODO: Use this algorithm to perform fast single-variable renaming in
6080b57cec5SDimitry Andric // promotememtoreg and memoryssa.
6095ffd83dbSDimitry Andric void PredicateInfoBuilder::renameUses(SmallVectorImpl<Value *> &OpsToRename) {
6105ffd83dbSDimitry Andric   ValueDFS_Compare Compare(DT);
6110b57cec5SDimitry Andric   // Compute liveness, and rename in O(uses) per Op.
6120b57cec5SDimitry Andric   for (auto *Op : OpsToRename) {
6130b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Visiting " << *Op << "\n");
6140b57cec5SDimitry Andric     unsigned Counter = 0;
6150b57cec5SDimitry Andric     SmallVector<ValueDFS, 16> OrderedUses;
6160b57cec5SDimitry Andric     const auto &ValueInfo = getValueInfo(Op);
6170b57cec5SDimitry Andric     // Insert the possible copies into the def/use list.
6180b57cec5SDimitry Andric     // They will become real copies if we find a real use for them, and never
6190b57cec5SDimitry Andric     // created otherwise.
620bdd1243dSDimitry Andric     for (const auto &PossibleCopy : ValueInfo.Infos) {
6210b57cec5SDimitry Andric       ValueDFS VD;
6220b57cec5SDimitry Andric       // Determine where we are going to place the copy by the copy type.
6230b57cec5SDimitry Andric       // The predicate info for branches always come first, they will get
6240b57cec5SDimitry Andric       // materialized in the split block at the top of the block.
6250b57cec5SDimitry Andric       // The predicate info for assumes will be somewhere in the middle,
6260b57cec5SDimitry Andric       // it will get materialized in front of the assume.
6270b57cec5SDimitry Andric       if (const auto *PAssume = dyn_cast<PredicateAssume>(PossibleCopy)) {
6280b57cec5SDimitry Andric         VD.LocalNum = LN_Middle;
6290b57cec5SDimitry Andric         DomTreeNode *DomNode = DT.getNode(PAssume->AssumeInst->getParent());
6300b57cec5SDimitry Andric         if (!DomNode)
6310b57cec5SDimitry Andric           continue;
6320b57cec5SDimitry Andric         VD.DFSIn = DomNode->getDFSNumIn();
6330b57cec5SDimitry Andric         VD.DFSOut = DomNode->getDFSNumOut();
6340b57cec5SDimitry Andric         VD.PInfo = PossibleCopy;
6350b57cec5SDimitry Andric         OrderedUses.push_back(VD);
6360b57cec5SDimitry Andric       } else if (isa<PredicateWithEdge>(PossibleCopy)) {
6370b57cec5SDimitry Andric         // If we can only do phi uses, we treat it like it's in the branch
6380b57cec5SDimitry Andric         // block, and handle it specially. We know that it goes last, and only
6390b57cec5SDimitry Andric         // dominate phi uses.
6400b57cec5SDimitry Andric         auto BlockEdge = getBlockEdge(PossibleCopy);
6410b57cec5SDimitry Andric         if (EdgeUsesOnly.count(BlockEdge)) {
6420b57cec5SDimitry Andric           VD.LocalNum = LN_Last;
6430b57cec5SDimitry Andric           auto *DomNode = DT.getNode(BlockEdge.first);
6440b57cec5SDimitry Andric           if (DomNode) {
6450b57cec5SDimitry Andric             VD.DFSIn = DomNode->getDFSNumIn();
6460b57cec5SDimitry Andric             VD.DFSOut = DomNode->getDFSNumOut();
6470b57cec5SDimitry Andric             VD.PInfo = PossibleCopy;
6480b57cec5SDimitry Andric             VD.EdgeOnly = true;
6490b57cec5SDimitry Andric             OrderedUses.push_back(VD);
6500b57cec5SDimitry Andric           }
6510b57cec5SDimitry Andric         } else {
6520b57cec5SDimitry Andric           // Otherwise, we are in the split block (even though we perform
6530b57cec5SDimitry Andric           // insertion in the branch block).
6540b57cec5SDimitry Andric           // Insert a possible copy at the split block and before the branch.
6550b57cec5SDimitry Andric           VD.LocalNum = LN_First;
6560b57cec5SDimitry Andric           auto *DomNode = DT.getNode(BlockEdge.second);
6570b57cec5SDimitry Andric           if (DomNode) {
6580b57cec5SDimitry Andric             VD.DFSIn = DomNode->getDFSNumIn();
6590b57cec5SDimitry Andric             VD.DFSOut = DomNode->getDFSNumOut();
6600b57cec5SDimitry Andric             VD.PInfo = PossibleCopy;
6610b57cec5SDimitry Andric             OrderedUses.push_back(VD);
6620b57cec5SDimitry Andric           }
6630b57cec5SDimitry Andric         }
6640b57cec5SDimitry Andric       }
6650b57cec5SDimitry Andric     }
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric     convertUsesToDFSOrdered(Op, OrderedUses);
6680b57cec5SDimitry Andric     // Here we require a stable sort because we do not bother to try to
6690b57cec5SDimitry Andric     // assign an order to the operands the uses represent. Thus, two
6700b57cec5SDimitry Andric     // uses in the same instruction do not have a strict sort order
6710b57cec5SDimitry Andric     // currently and will be considered equal. We could get rid of the
6720b57cec5SDimitry Andric     // stable sort by creating one if we wanted.
6730b57cec5SDimitry Andric     llvm::stable_sort(OrderedUses, Compare);
6740b57cec5SDimitry Andric     SmallVector<ValueDFS, 8> RenameStack;
6750b57cec5SDimitry Andric     // For each use, sorted into dfs order, push values and replaces uses with
6760b57cec5SDimitry Andric     // top of stack, which will represent the reaching def.
6770b57cec5SDimitry Andric     for (auto &VD : OrderedUses) {
6780b57cec5SDimitry Andric       // We currently do not materialize copy over copy, but we should decide if
6790b57cec5SDimitry Andric       // we want to.
6800b57cec5SDimitry Andric       bool PossibleCopy = VD.PInfo != nullptr;
6810b57cec5SDimitry Andric       if (RenameStack.empty()) {
6820b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "Rename Stack is empty\n");
6830b57cec5SDimitry Andric       } else {
6840b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "Rename Stack Top DFS numbers are ("
6850b57cec5SDimitry Andric                           << RenameStack.back().DFSIn << ","
6860b57cec5SDimitry Andric                           << RenameStack.back().DFSOut << ")\n");
6870b57cec5SDimitry Andric       }
6880b57cec5SDimitry Andric 
6890b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Current DFS numbers are (" << VD.DFSIn << ","
6900b57cec5SDimitry Andric                         << VD.DFSOut << ")\n");
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric       bool ShouldPush = (VD.Def || PossibleCopy);
6930b57cec5SDimitry Andric       bool OutOfScope = !stackIsInScope(RenameStack, VD);
6940b57cec5SDimitry Andric       if (OutOfScope || ShouldPush) {
6950b57cec5SDimitry Andric         // Sync to our current scope.
6960b57cec5SDimitry Andric         popStackUntilDFSScope(RenameStack, VD);
6970b57cec5SDimitry Andric         if (ShouldPush) {
6980b57cec5SDimitry Andric           RenameStack.push_back(VD);
6990b57cec5SDimitry Andric         }
7000b57cec5SDimitry Andric       }
7010b57cec5SDimitry Andric       // If we get to this point, and the stack is empty we must have a use
7020b57cec5SDimitry Andric       // with no renaming needed, just skip it.
7030b57cec5SDimitry Andric       if (RenameStack.empty())
7040b57cec5SDimitry Andric         continue;
7050b57cec5SDimitry Andric       // Skip values, only want to rename the uses
7060b57cec5SDimitry Andric       if (VD.Def || PossibleCopy)
7070b57cec5SDimitry Andric         continue;
7080b57cec5SDimitry Andric       if (!DebugCounter::shouldExecute(RenameCounter)) {
7090b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "Skipping execution due to debug counter\n");
7100b57cec5SDimitry Andric         continue;
7110b57cec5SDimitry Andric       }
7120b57cec5SDimitry Andric       ValueDFS &Result = RenameStack.back();
7130b57cec5SDimitry Andric 
7140b57cec5SDimitry Andric       // If the possible copy dominates something, materialize our stack up to
7150b57cec5SDimitry Andric       // this point. This ensures every comparison that affects our operation
7160b57cec5SDimitry Andric       // ends up with predicateinfo.
7170b57cec5SDimitry Andric       if (!Result.Def)
7180b57cec5SDimitry Andric         Result.Def = materializeStack(Counter, RenameStack, Op);
7190b57cec5SDimitry Andric 
7200b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "Found replacement " << *Result.Def << " for "
7210b57cec5SDimitry Andric                         << *VD.U->get() << " in " << *(VD.U->getUser())
7220b57cec5SDimitry Andric                         << "\n");
7230b57cec5SDimitry Andric       assert(DT.dominates(cast<Instruction>(Result.Def), *VD.U) &&
7240b57cec5SDimitry Andric              "Predicateinfo def should have dominated this use");
7250b57cec5SDimitry Andric       VD.U->set(Result.Def);
7260b57cec5SDimitry Andric     }
7270b57cec5SDimitry Andric   }
7280b57cec5SDimitry Andric }
7290b57cec5SDimitry Andric 
7305ffd83dbSDimitry Andric PredicateInfoBuilder::ValueInfo &
7315ffd83dbSDimitry Andric PredicateInfoBuilder::getOrCreateValueInfo(Value *Operand) {
7320b57cec5SDimitry Andric   auto OIN = ValueInfoNums.find(Operand);
7330b57cec5SDimitry Andric   if (OIN == ValueInfoNums.end()) {
7340b57cec5SDimitry Andric     // This will grow it
7350b57cec5SDimitry Andric     ValueInfos.resize(ValueInfos.size() + 1);
7360b57cec5SDimitry Andric     // This will use the new size and give us a 0 based number of the info
7370b57cec5SDimitry Andric     auto InsertResult = ValueInfoNums.insert({Operand, ValueInfos.size() - 1});
7380b57cec5SDimitry Andric     assert(InsertResult.second && "Value info number already existed?");
7390b57cec5SDimitry Andric     return ValueInfos[InsertResult.first->second];
7400b57cec5SDimitry Andric   }
7410b57cec5SDimitry Andric   return ValueInfos[OIN->second];
7420b57cec5SDimitry Andric }
7430b57cec5SDimitry Andric 
7445ffd83dbSDimitry Andric const PredicateInfoBuilder::ValueInfo &
7455ffd83dbSDimitry Andric PredicateInfoBuilder::getValueInfo(Value *Operand) const {
7460b57cec5SDimitry Andric   auto OINI = ValueInfoNums.lookup(Operand);
7470b57cec5SDimitry Andric   assert(OINI != 0 && "Operand was not really in the Value Info Numbers");
7480b57cec5SDimitry Andric   assert(OINI < ValueInfos.size() &&
7490b57cec5SDimitry Andric          "Value Info Number greater than size of Value Info Table");
7500b57cec5SDimitry Andric   return ValueInfos[OINI];
7510b57cec5SDimitry Andric }
7520b57cec5SDimitry Andric 
7530b57cec5SDimitry Andric PredicateInfo::PredicateInfo(Function &F, DominatorTree &DT,
7540b57cec5SDimitry Andric                              AssumptionCache &AC)
7555ffd83dbSDimitry Andric     : F(F) {
7565ffd83dbSDimitry Andric   PredicateInfoBuilder Builder(*this, F, DT, AC);
7575ffd83dbSDimitry Andric   Builder.buildPredicateInfo();
7580b57cec5SDimitry Andric }
7590b57cec5SDimitry Andric 
7606e75b2fbSDimitry Andric // Remove all declarations we created . The PredicateInfo consumers are
7616e75b2fbSDimitry Andric // responsible for remove the ssa_copy calls created.
7626e75b2fbSDimitry Andric PredicateInfo::~PredicateInfo() {
7636e75b2fbSDimitry Andric   // Collect function pointers in set first, as SmallSet uses a SmallVector
7646e75b2fbSDimitry Andric   // internally and we have to remove the asserting value handles first.
7656e75b2fbSDimitry Andric   SmallPtrSet<Function *, 20> FunctionPtrs;
766bdd1243dSDimitry Andric   for (const auto &F : CreatedDeclarations)
7676e75b2fbSDimitry Andric     FunctionPtrs.insert(&*F);
7686e75b2fbSDimitry Andric   CreatedDeclarations.clear();
7696e75b2fbSDimitry Andric 
7706e75b2fbSDimitry Andric   for (Function *F : FunctionPtrs) {
7716e75b2fbSDimitry Andric     assert(F->user_begin() == F->user_end() &&
7726e75b2fbSDimitry Andric            "PredicateInfo consumer did not remove all SSA copies.");
7736e75b2fbSDimitry Andric     F->eraseFromParent();
7746e75b2fbSDimitry Andric   }
7756e75b2fbSDimitry Andric }
7766e75b2fbSDimitry Andric 
777bdd1243dSDimitry Andric std::optional<PredicateConstraint> PredicateBase::getConstraint() const {
778e8d8bef9SDimitry Andric   switch (Type) {
779e8d8bef9SDimitry Andric   case PT_Assume:
780e8d8bef9SDimitry Andric   case PT_Branch: {
781e8d8bef9SDimitry Andric     bool TrueEdge = true;
782e8d8bef9SDimitry Andric     if (auto *PBranch = dyn_cast<PredicateBranch>(this))
783e8d8bef9SDimitry Andric       TrueEdge = PBranch->TrueEdge;
784e8d8bef9SDimitry Andric 
785e8d8bef9SDimitry Andric     if (Condition == RenamedOp) {
786e8d8bef9SDimitry Andric       return {{CmpInst::ICMP_EQ,
787e8d8bef9SDimitry Andric                TrueEdge ? ConstantInt::getTrue(Condition->getType())
788e8d8bef9SDimitry Andric                         : ConstantInt::getFalse(Condition->getType())}};
789e8d8bef9SDimitry Andric     }
790e8d8bef9SDimitry Andric 
791e8d8bef9SDimitry Andric     CmpInst *Cmp = dyn_cast<CmpInst>(Condition);
792e8d8bef9SDimitry Andric     if (!Cmp) {
793e8d8bef9SDimitry Andric       // TODO: Make this an assertion once RenamedOp is fully accurate.
794bdd1243dSDimitry Andric       return std::nullopt;
795e8d8bef9SDimitry Andric     }
796e8d8bef9SDimitry Andric 
797e8d8bef9SDimitry Andric     CmpInst::Predicate Pred;
798e8d8bef9SDimitry Andric     Value *OtherOp;
799e8d8bef9SDimitry Andric     if (Cmp->getOperand(0) == RenamedOp) {
800e8d8bef9SDimitry Andric       Pred = Cmp->getPredicate();
801e8d8bef9SDimitry Andric       OtherOp = Cmp->getOperand(1);
802e8d8bef9SDimitry Andric     } else if (Cmp->getOperand(1) == RenamedOp) {
803e8d8bef9SDimitry Andric       Pred = Cmp->getSwappedPredicate();
804e8d8bef9SDimitry Andric       OtherOp = Cmp->getOperand(0);
805e8d8bef9SDimitry Andric     } else {
806e8d8bef9SDimitry Andric       // TODO: Make this an assertion once RenamedOp is fully accurate.
807bdd1243dSDimitry Andric       return std::nullopt;
808e8d8bef9SDimitry Andric     }
809e8d8bef9SDimitry Andric 
810e8d8bef9SDimitry Andric     // Invert predicate along false edge.
811e8d8bef9SDimitry Andric     if (!TrueEdge)
812e8d8bef9SDimitry Andric       Pred = CmpInst::getInversePredicate(Pred);
813e8d8bef9SDimitry Andric 
814e8d8bef9SDimitry Andric     return {{Pred, OtherOp}};
815e8d8bef9SDimitry Andric   }
816e8d8bef9SDimitry Andric   case PT_Switch:
817e8d8bef9SDimitry Andric     if (Condition != RenamedOp) {
818e8d8bef9SDimitry Andric       // TODO: Make this an assertion once RenamedOp is fully accurate.
819bdd1243dSDimitry Andric       return std::nullopt;
820e8d8bef9SDimitry Andric     }
821e8d8bef9SDimitry Andric 
822e8d8bef9SDimitry Andric     return {{CmpInst::ICMP_EQ, cast<PredicateSwitch>(this)->CaseValue}};
823e8d8bef9SDimitry Andric   }
824e8d8bef9SDimitry Andric   llvm_unreachable("Unknown predicate type");
825e8d8bef9SDimitry Andric }
826e8d8bef9SDimitry Andric 
8270b57cec5SDimitry Andric void PredicateInfo::verifyPredicateInfo() const {}
8280b57cec5SDimitry Andric 
8296e75b2fbSDimitry Andric // Replace ssa_copy calls created by PredicateInfo with their operand.
8306e75b2fbSDimitry Andric static void replaceCreatedSSACopys(PredicateInfo &PredInfo, Function &F) {
8316e75b2fbSDimitry Andric   for (Instruction &Inst : llvm::make_early_inc_range(instructions(F))) {
8326e75b2fbSDimitry Andric     const auto *PI = PredInfo.getPredicateInfoFor(&Inst);
8336e75b2fbSDimitry Andric     auto *II = dyn_cast<IntrinsicInst>(&Inst);
8346e75b2fbSDimitry Andric     if (!PI || !II || II->getIntrinsicID() != Intrinsic::ssa_copy)
8356e75b2fbSDimitry Andric       continue;
8366e75b2fbSDimitry Andric 
8376e75b2fbSDimitry Andric     Inst.replaceAllUsesWith(II->getOperand(0));
8386e75b2fbSDimitry Andric     Inst.eraseFromParent();
8396e75b2fbSDimitry Andric   }
8406e75b2fbSDimitry Andric }
8416e75b2fbSDimitry Andric 
8420b57cec5SDimitry Andric PreservedAnalyses PredicateInfoPrinterPass::run(Function &F,
8430b57cec5SDimitry Andric                                                 FunctionAnalysisManager &AM) {
8440b57cec5SDimitry Andric   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
8450b57cec5SDimitry Andric   auto &AC = AM.getResult<AssumptionAnalysis>(F);
8460b57cec5SDimitry Andric   OS << "PredicateInfo for function: " << F.getName() << "\n";
8478bcb0991SDimitry Andric   auto PredInfo = std::make_unique<PredicateInfo>(F, DT, AC);
8480b57cec5SDimitry Andric   PredInfo->print(OS);
8490b57cec5SDimitry Andric 
8506e75b2fbSDimitry Andric   replaceCreatedSSACopys(*PredInfo, F);
8510b57cec5SDimitry Andric   return PreservedAnalyses::all();
8520b57cec5SDimitry Andric }
8530b57cec5SDimitry Andric 
8540b57cec5SDimitry Andric /// An assembly annotator class to print PredicateInfo information in
8550b57cec5SDimitry Andric /// comments.
8560b57cec5SDimitry Andric class PredicateInfoAnnotatedWriter : public AssemblyAnnotationWriter {
8570b57cec5SDimitry Andric   friend class PredicateInfo;
8580b57cec5SDimitry Andric   const PredicateInfo *PredInfo;
8590b57cec5SDimitry Andric 
8600b57cec5SDimitry Andric public:
8610b57cec5SDimitry Andric   PredicateInfoAnnotatedWriter(const PredicateInfo *M) : PredInfo(M) {}
8620b57cec5SDimitry Andric 
8635ffd83dbSDimitry Andric   void emitBasicBlockStartAnnot(const BasicBlock *BB,
8645ffd83dbSDimitry Andric                                 formatted_raw_ostream &OS) override {}
8650b57cec5SDimitry Andric 
8665ffd83dbSDimitry Andric   void emitInstructionAnnot(const Instruction *I,
8675ffd83dbSDimitry Andric                             formatted_raw_ostream &OS) override {
8680b57cec5SDimitry Andric     if (const auto *PI = PredInfo->getPredicateInfoFor(I)) {
8690b57cec5SDimitry Andric       OS << "; Has predicate info\n";
8700b57cec5SDimitry Andric       if (const auto *PB = dyn_cast<PredicateBranch>(PI)) {
8710b57cec5SDimitry Andric         OS << "; branch predicate info { TrueEdge: " << PB->TrueEdge
8720b57cec5SDimitry Andric            << " Comparison:" << *PB->Condition << " Edge: [";
8730b57cec5SDimitry Andric         PB->From->printAsOperand(OS);
8740b57cec5SDimitry Andric         OS << ",";
8750b57cec5SDimitry Andric         PB->To->printAsOperand(OS);
8765ffd83dbSDimitry Andric         OS << "]";
8770b57cec5SDimitry Andric       } else if (const auto *PS = dyn_cast<PredicateSwitch>(PI)) {
8780b57cec5SDimitry Andric         OS << "; switch predicate info { CaseValue: " << *PS->CaseValue
8790b57cec5SDimitry Andric            << " Switch:" << *PS->Switch << " Edge: [";
8800b57cec5SDimitry Andric         PS->From->printAsOperand(OS);
8810b57cec5SDimitry Andric         OS << ",";
8820b57cec5SDimitry Andric         PS->To->printAsOperand(OS);
8835ffd83dbSDimitry Andric         OS << "]";
8840b57cec5SDimitry Andric       } else if (const auto *PA = dyn_cast<PredicateAssume>(PI)) {
8850b57cec5SDimitry Andric         OS << "; assume predicate info {"
8865ffd83dbSDimitry Andric            << " Comparison:" << *PA->Condition;
8870b57cec5SDimitry Andric       }
8885ffd83dbSDimitry Andric       OS << ", RenamedOp: ";
8895ffd83dbSDimitry Andric       PI->RenamedOp->printAsOperand(OS, false);
8905ffd83dbSDimitry Andric       OS << " }\n";
8910b57cec5SDimitry Andric     }
8920b57cec5SDimitry Andric   }
8930b57cec5SDimitry Andric };
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric void PredicateInfo::print(raw_ostream &OS) const {
8960b57cec5SDimitry Andric   PredicateInfoAnnotatedWriter Writer(this);
8970b57cec5SDimitry Andric   F.print(OS, &Writer);
8980b57cec5SDimitry Andric }
8990b57cec5SDimitry Andric 
9000b57cec5SDimitry Andric void PredicateInfo::dump() const {
9010b57cec5SDimitry Andric   PredicateInfoAnnotatedWriter Writer(this);
9020b57cec5SDimitry Andric   F.print(dbgs(), &Writer);
9030b57cec5SDimitry Andric }
9040b57cec5SDimitry Andric 
9050b57cec5SDimitry Andric PreservedAnalyses PredicateInfoVerifierPass::run(Function &F,
9060b57cec5SDimitry Andric                                                  FunctionAnalysisManager &AM) {
9070b57cec5SDimitry Andric   auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
9080b57cec5SDimitry Andric   auto &AC = AM.getResult<AssumptionAnalysis>(F);
9098bcb0991SDimitry Andric   std::make_unique<PredicateInfo>(F, DT, AC)->verifyPredicateInfo();
9100b57cec5SDimitry Andric 
9110b57cec5SDimitry Andric   return PreservedAnalyses::all();
9120b57cec5SDimitry Andric }
9130b57cec5SDimitry Andric }
914