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