17a7e6055SDimitry Andric //===-- PredicateInfo.cpp - PredicateInfo Builder--------------------===//
27a7e6055SDimitry Andric //
37a7e6055SDimitry Andric // The LLVM Compiler Infrastructure
47a7e6055SDimitry Andric //
57a7e6055SDimitry Andric // This file is distributed under the University of Illinois Open Source
67a7e6055SDimitry Andric // License. See LICENSE.TXT for details.
77a7e6055SDimitry Andric //
87a7e6055SDimitry Andric //===----------------------------------------------------------------===//
97a7e6055SDimitry Andric //
107a7e6055SDimitry Andric // This file implements the PredicateInfo class.
117a7e6055SDimitry Andric //
127a7e6055SDimitry Andric //===----------------------------------------------------------------===//
137a7e6055SDimitry Andric
147a7e6055SDimitry Andric #include "llvm/Transforms/Utils/PredicateInfo.h"
157a7e6055SDimitry Andric #include "llvm/ADT/DenseMap.h"
167a7e6055SDimitry Andric #include "llvm/ADT/DepthFirstIterator.h"
177a7e6055SDimitry Andric #include "llvm/ADT/STLExtras.h"
187a7e6055SDimitry Andric #include "llvm/ADT/SmallPtrSet.h"
197a7e6055SDimitry Andric #include "llvm/ADT/Statistic.h"
204ba319b5SDimitry Andric #include "llvm/ADT/StringExtras.h"
217a7e6055SDimitry Andric #include "llvm/Analysis/AssumptionCache.h"
227a7e6055SDimitry Andric #include "llvm/Analysis/CFG.h"
237a7e6055SDimitry Andric #include "llvm/IR/AssemblyAnnotationWriter.h"
247a7e6055SDimitry Andric #include "llvm/IR/DataLayout.h"
257a7e6055SDimitry Andric #include "llvm/IR/Dominators.h"
267a7e6055SDimitry Andric #include "llvm/IR/GlobalVariable.h"
277a7e6055SDimitry Andric #include "llvm/IR/IRBuilder.h"
284ba319b5SDimitry Andric #include "llvm/IR/InstIterator.h"
297a7e6055SDimitry Andric #include "llvm/IR/IntrinsicInst.h"
307a7e6055SDimitry Andric #include "llvm/IR/LLVMContext.h"
317a7e6055SDimitry Andric #include "llvm/IR/Metadata.h"
327a7e6055SDimitry Andric #include "llvm/IR/Module.h"
337a7e6055SDimitry Andric #include "llvm/IR/PatternMatch.h"
347a7e6055SDimitry Andric #include "llvm/Support/Debug.h"
357a7e6055SDimitry Andric #include "llvm/Support/DebugCounter.h"
367a7e6055SDimitry Andric #include "llvm/Support/FormattedStream.h"
374ba319b5SDimitry Andric #include "llvm/Transforms/Utils.h"
387a7e6055SDimitry Andric #include <algorithm>
397a7e6055SDimitry Andric #define DEBUG_TYPE "predicateinfo"
407a7e6055SDimitry Andric using namespace llvm;
417a7e6055SDimitry Andric using namespace PatternMatch;
427a7e6055SDimitry Andric using namespace llvm::PredicateInfoClasses;
437a7e6055SDimitry Andric
447a7e6055SDimitry Andric INITIALIZE_PASS_BEGIN(PredicateInfoPrinterLegacyPass, "print-predicateinfo",
457a7e6055SDimitry Andric "PredicateInfo Printer", false, false)
467a7e6055SDimitry Andric INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
477a7e6055SDimitry Andric INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
487a7e6055SDimitry Andric INITIALIZE_PASS_END(PredicateInfoPrinterLegacyPass, "print-predicateinfo",
497a7e6055SDimitry Andric "PredicateInfo Printer", false, false)
507a7e6055SDimitry Andric static cl::opt<bool> VerifyPredicateInfo(
517a7e6055SDimitry Andric "verify-predicateinfo", cl::init(false), cl::Hidden,
527a7e6055SDimitry Andric cl::desc("Verify PredicateInfo in legacy printer pass."));
537a7e6055SDimitry Andric DEBUG_COUNTER(RenameCounter, "predicateinfo-rename",
542cab237bSDimitry Andric "Controls which variables are renamed with predicateinfo");
552cab237bSDimitry Andric
562cab237bSDimitry Andric namespace {
577a7e6055SDimitry Andric // Given a predicate info that is a type of branching terminator, get the
587a7e6055SDimitry Andric // branching block.
getBranchBlock(const PredicateBase * PB)597a7e6055SDimitry Andric const BasicBlock *getBranchBlock(const PredicateBase *PB) {
607a7e6055SDimitry Andric assert(isa<PredicateWithEdge>(PB) &&
617a7e6055SDimitry Andric "Only branches and switches should have PHIOnly defs that "
627a7e6055SDimitry Andric "require branch blocks.");
637a7e6055SDimitry Andric return cast<PredicateWithEdge>(PB)->From;
647a7e6055SDimitry Andric }
657a7e6055SDimitry Andric
667a7e6055SDimitry Andric // Given a predicate info that is a type of branching terminator, get the
677a7e6055SDimitry Andric // branching terminator.
getBranchTerminator(const PredicateBase * PB)687a7e6055SDimitry Andric static Instruction *getBranchTerminator(const PredicateBase *PB) {
697a7e6055SDimitry Andric assert(isa<PredicateWithEdge>(PB) &&
707a7e6055SDimitry Andric "Not a predicate info type we know how to get a terminator from.");
717a7e6055SDimitry Andric return cast<PredicateWithEdge>(PB)->From->getTerminator();
727a7e6055SDimitry Andric }
737a7e6055SDimitry Andric
747a7e6055SDimitry Andric // Given a predicate info that is a type of branching terminator, get the
757a7e6055SDimitry Andric // edge this predicate info represents
767a7e6055SDimitry Andric const std::pair<BasicBlock *, BasicBlock *>
getBlockEdge(const PredicateBase * PB)777a7e6055SDimitry Andric getBlockEdge(const PredicateBase *PB) {
787a7e6055SDimitry Andric assert(isa<PredicateWithEdge>(PB) &&
797a7e6055SDimitry Andric "Not a predicate info type we know how to get an edge from.");
807a7e6055SDimitry Andric const auto *PEdge = cast<PredicateWithEdge>(PB);
817a7e6055SDimitry Andric return std::make_pair(PEdge->From, PEdge->To);
827a7e6055SDimitry Andric }
837a7e6055SDimitry Andric }
847a7e6055SDimitry Andric
857a7e6055SDimitry Andric namespace llvm {
867a7e6055SDimitry Andric namespace PredicateInfoClasses {
877a7e6055SDimitry Andric enum LocalNum {
887a7e6055SDimitry Andric // Operations that must appear first in the block.
897a7e6055SDimitry Andric LN_First,
907a7e6055SDimitry Andric // Operations that are somewhere in the middle of the block, and are sorted on
917a7e6055SDimitry Andric // demand.
927a7e6055SDimitry Andric LN_Middle,
937a7e6055SDimitry Andric // Operations that must appear last in a block, like successor phi node uses.
947a7e6055SDimitry Andric LN_Last
957a7e6055SDimitry Andric };
967a7e6055SDimitry Andric
977a7e6055SDimitry Andric // Associate global and local DFS info with defs and uses, so we can sort them
987a7e6055SDimitry Andric // into a global domination ordering.
997a7e6055SDimitry Andric struct ValueDFS {
1007a7e6055SDimitry Andric int DFSIn = 0;
1017a7e6055SDimitry Andric int DFSOut = 0;
1027a7e6055SDimitry Andric unsigned int LocalNum = LN_Middle;
1037a7e6055SDimitry Andric // Only one of Def or Use will be set.
1047a7e6055SDimitry Andric Value *Def = nullptr;
1057a7e6055SDimitry Andric Use *U = nullptr;
1067a7e6055SDimitry Andric // Neither PInfo nor EdgeOnly participate in the ordering
1077a7e6055SDimitry Andric PredicateBase *PInfo = nullptr;
1087a7e6055SDimitry Andric bool EdgeOnly = false;
1097a7e6055SDimitry Andric };
1107a7e6055SDimitry Andric
111a580b014SDimitry Andric // Perform a strict weak ordering on instructions and arguments.
valueComesBefore(OrderedInstructions & OI,const Value * A,const Value * B)112a580b014SDimitry Andric static bool valueComesBefore(OrderedInstructions &OI, const Value *A,
113a580b014SDimitry Andric const Value *B) {
114a580b014SDimitry Andric auto *ArgA = dyn_cast_or_null<Argument>(A);
115a580b014SDimitry Andric auto *ArgB = dyn_cast_or_null<Argument>(B);
116a580b014SDimitry Andric if (ArgA && !ArgB)
117a580b014SDimitry Andric return true;
118a580b014SDimitry Andric if (ArgB && !ArgA)
119a580b014SDimitry Andric return false;
120a580b014SDimitry Andric if (ArgA && ArgB)
121a580b014SDimitry Andric return ArgA->getArgNo() < ArgB->getArgNo();
1224ba319b5SDimitry Andric return OI.dfsBefore(cast<Instruction>(A), cast<Instruction>(B));
123a580b014SDimitry Andric }
124a580b014SDimitry Andric
1257a7e6055SDimitry Andric // This compares ValueDFS structures, creating OrderedBasicBlocks where
1267a7e6055SDimitry Andric // necessary to compare uses/defs in the same block. Doing so allows us to walk
1277a7e6055SDimitry Andric // the minimum number of instructions necessary to compute our def/use ordering.
1287a7e6055SDimitry Andric struct ValueDFS_Compare {
129a580b014SDimitry Andric OrderedInstructions &OI;
ValueDFS_Comparellvm::PredicateInfoClasses::ValueDFS_Compare130a580b014SDimitry Andric ValueDFS_Compare(OrderedInstructions &OI) : OI(OI) {}
131a580b014SDimitry Andric
operator ()llvm::PredicateInfoClasses::ValueDFS_Compare1327a7e6055SDimitry Andric bool operator()(const ValueDFS &A, const ValueDFS &B) const {
1337a7e6055SDimitry Andric if (&A == &B)
1347a7e6055SDimitry Andric return false;
1357a7e6055SDimitry Andric // The only case we can't directly compare them is when they in the same
1367a7e6055SDimitry Andric // block, and both have localnum == middle. In that case, we have to use
1377a7e6055SDimitry Andric // comesbefore to see what the real ordering is, because they are in the
1387a7e6055SDimitry Andric // same basic block.
1397a7e6055SDimitry Andric
1407a7e6055SDimitry Andric bool SameBlock = std::tie(A.DFSIn, A.DFSOut) == std::tie(B.DFSIn, B.DFSOut);
1417a7e6055SDimitry Andric
1427a7e6055SDimitry Andric // We want to put the def that will get used for a given set of phi uses,
1437a7e6055SDimitry Andric // before those phi uses.
1447a7e6055SDimitry Andric // So we sort by edge, then by def.
1457a7e6055SDimitry Andric // Note that only phi nodes uses and defs can come last.
1467a7e6055SDimitry Andric if (SameBlock && A.LocalNum == LN_Last && B.LocalNum == LN_Last)
1477a7e6055SDimitry Andric return comparePHIRelated(A, B);
1487a7e6055SDimitry Andric
1497a7e6055SDimitry Andric if (!SameBlock || A.LocalNum != LN_Middle || B.LocalNum != LN_Middle)
1507a7e6055SDimitry Andric return std::tie(A.DFSIn, A.DFSOut, A.LocalNum, A.Def, A.U) <
1517a7e6055SDimitry Andric std::tie(B.DFSIn, B.DFSOut, B.LocalNum, B.Def, B.U);
1527a7e6055SDimitry Andric return localComesBefore(A, B);
1537a7e6055SDimitry Andric }
1547a7e6055SDimitry Andric
1557a7e6055SDimitry Andric // For a phi use, or a non-materialized def, return the edge it represents.
1567a7e6055SDimitry Andric const std::pair<BasicBlock *, BasicBlock *>
getBlockEdgellvm::PredicateInfoClasses::ValueDFS_Compare1577a7e6055SDimitry Andric getBlockEdge(const ValueDFS &VD) const {
1587a7e6055SDimitry Andric if (!VD.Def && VD.U) {
1597a7e6055SDimitry Andric auto *PHI = cast<PHINode>(VD.U->getUser());
1607a7e6055SDimitry Andric return std::make_pair(PHI->getIncomingBlock(*VD.U), PHI->getParent());
1617a7e6055SDimitry Andric }
1627a7e6055SDimitry Andric // This is really a non-materialized def.
1637a7e6055SDimitry Andric return ::getBlockEdge(VD.PInfo);
1647a7e6055SDimitry Andric }
1657a7e6055SDimitry Andric
1667a7e6055SDimitry Andric // For two phi related values, return the ordering.
comparePHIRelatedllvm::PredicateInfoClasses::ValueDFS_Compare1677a7e6055SDimitry Andric bool comparePHIRelated(const ValueDFS &A, const ValueDFS &B) const {
1687a7e6055SDimitry Andric auto &ABlockEdge = getBlockEdge(A);
1697a7e6055SDimitry Andric auto &BBlockEdge = getBlockEdge(B);
1707a7e6055SDimitry Andric // Now sort by block edge and then defs before uses.
1717a7e6055SDimitry Andric return std::tie(ABlockEdge, A.Def, A.U) < std::tie(BBlockEdge, B.Def, B.U);
1727a7e6055SDimitry Andric }
1737a7e6055SDimitry Andric
1747a7e6055SDimitry Andric // Get the definition of an instruction that occurs in the middle of a block.
getMiddleDefllvm::PredicateInfoClasses::ValueDFS_Compare1757a7e6055SDimitry Andric Value *getMiddleDef(const ValueDFS &VD) const {
1767a7e6055SDimitry Andric if (VD.Def)
1777a7e6055SDimitry Andric return VD.Def;
1787a7e6055SDimitry Andric // It's possible for the defs and uses to be null. For branches, the local
1797a7e6055SDimitry Andric // numbering will say the placed predicaeinfos should go first (IE
1807a7e6055SDimitry Andric // LN_beginning), so we won't be in this function. For assumes, we will end
1817a7e6055SDimitry Andric // up here, beause we need to order the def we will place relative to the
1827a7e6055SDimitry Andric // assume. So for the purpose of ordering, we pretend the def is the assume
1837a7e6055SDimitry Andric // because that is where we will insert the info.
1847a7e6055SDimitry Andric if (!VD.U) {
1857a7e6055SDimitry Andric assert(VD.PInfo &&
1867a7e6055SDimitry Andric "No def, no use, and no predicateinfo should not occur");
1877a7e6055SDimitry Andric assert(isa<PredicateAssume>(VD.PInfo) &&
1887a7e6055SDimitry Andric "Middle of block should only occur for assumes");
1897a7e6055SDimitry Andric return cast<PredicateAssume>(VD.PInfo)->AssumeInst;
1907a7e6055SDimitry Andric }
1917a7e6055SDimitry Andric return nullptr;
1927a7e6055SDimitry Andric }
1937a7e6055SDimitry Andric
1947a7e6055SDimitry Andric // Return either the Def, if it's not null, or the user of the Use, if the def
1957a7e6055SDimitry Andric // is null.
getDefOrUserllvm::PredicateInfoClasses::ValueDFS_Compare1967a7e6055SDimitry Andric const Instruction *getDefOrUser(const Value *Def, const Use *U) const {
1977a7e6055SDimitry Andric if (Def)
1987a7e6055SDimitry Andric return cast<Instruction>(Def);
1997a7e6055SDimitry Andric return cast<Instruction>(U->getUser());
2007a7e6055SDimitry Andric }
2017a7e6055SDimitry Andric
2027a7e6055SDimitry Andric // This performs the necessary local basic block ordering checks to tell
2037a7e6055SDimitry Andric // whether A comes before B, where both are in the same basic block.
localComesBeforellvm::PredicateInfoClasses::ValueDFS_Compare2047a7e6055SDimitry Andric bool localComesBefore(const ValueDFS &A, const ValueDFS &B) const {
2057a7e6055SDimitry Andric auto *ADef = getMiddleDef(A);
2067a7e6055SDimitry Andric auto *BDef = getMiddleDef(B);
2077a7e6055SDimitry Andric
2087a7e6055SDimitry Andric // See if we have real values or uses. If we have real values, we are
2097a7e6055SDimitry Andric // guaranteed they are instructions or arguments. No matter what, we are
2107a7e6055SDimitry Andric // guaranteed they are in the same block if they are instructions.
2117a7e6055SDimitry Andric auto *ArgA = dyn_cast_or_null<Argument>(ADef);
2127a7e6055SDimitry Andric auto *ArgB = dyn_cast_or_null<Argument>(BDef);
2137a7e6055SDimitry Andric
214a580b014SDimitry Andric if (ArgA || ArgB)
215a580b014SDimitry Andric return valueComesBefore(OI, ArgA, ArgB);
2167a7e6055SDimitry Andric
2177a7e6055SDimitry Andric auto *AInst = getDefOrUser(ADef, A.U);
2187a7e6055SDimitry Andric auto *BInst = getDefOrUser(BDef, B.U);
219a580b014SDimitry Andric return valueComesBefore(OI, AInst, BInst);
2207a7e6055SDimitry Andric }
2217a7e6055SDimitry Andric };
2227a7e6055SDimitry Andric
2237a7e6055SDimitry Andric } // namespace PredicateInfoClasses
2247a7e6055SDimitry Andric
stackIsInScope(const ValueDFSStack & Stack,const ValueDFS & VDUse) const2257a7e6055SDimitry Andric bool PredicateInfo::stackIsInScope(const ValueDFSStack &Stack,
2267a7e6055SDimitry Andric const ValueDFS &VDUse) const {
2277a7e6055SDimitry Andric if (Stack.empty())
2287a7e6055SDimitry Andric return false;
2297a7e6055SDimitry Andric // If it's a phi only use, make sure it's for this phi node edge, and that the
2307a7e6055SDimitry Andric // use is in a phi node. If it's anything else, and the top of the stack is
2317a7e6055SDimitry Andric // EdgeOnly, we need to pop the stack. We deliberately sort phi uses next to
2327a7e6055SDimitry Andric // the defs they must go with so that we can know it's time to pop the stack
2337a7e6055SDimitry Andric // when we hit the end of the phi uses for a given def.
2347a7e6055SDimitry Andric if (Stack.back().EdgeOnly) {
2357a7e6055SDimitry Andric if (!VDUse.U)
2367a7e6055SDimitry Andric return false;
2377a7e6055SDimitry Andric auto *PHI = dyn_cast<PHINode>(VDUse.U->getUser());
2387a7e6055SDimitry Andric if (!PHI)
2397a7e6055SDimitry Andric return false;
2407a7e6055SDimitry Andric // Check edge
2417a7e6055SDimitry Andric BasicBlock *EdgePred = PHI->getIncomingBlock(*VDUse.U);
2427a7e6055SDimitry Andric if (EdgePred != getBranchBlock(Stack.back().PInfo))
2437a7e6055SDimitry Andric return false;
2447a7e6055SDimitry Andric
2457a7e6055SDimitry Andric // Use dominates, which knows how to handle edge dominance.
2467a7e6055SDimitry Andric return DT.dominates(getBlockEdge(Stack.back().PInfo), *VDUse.U);
2477a7e6055SDimitry Andric }
2487a7e6055SDimitry Andric
2497a7e6055SDimitry Andric return (VDUse.DFSIn >= Stack.back().DFSIn &&
2507a7e6055SDimitry Andric VDUse.DFSOut <= Stack.back().DFSOut);
2517a7e6055SDimitry Andric }
2527a7e6055SDimitry Andric
popStackUntilDFSScope(ValueDFSStack & Stack,const ValueDFS & VD)2537a7e6055SDimitry Andric void PredicateInfo::popStackUntilDFSScope(ValueDFSStack &Stack,
2547a7e6055SDimitry Andric const ValueDFS &VD) {
2557a7e6055SDimitry Andric while (!Stack.empty() && !stackIsInScope(Stack, VD))
2567a7e6055SDimitry Andric Stack.pop_back();
2577a7e6055SDimitry Andric }
2587a7e6055SDimitry Andric
2597a7e6055SDimitry Andric // Convert the uses of Op into a vector of uses, associating global and local
2607a7e6055SDimitry Andric // DFS info with each one.
convertUsesToDFSOrdered(Value * Op,SmallVectorImpl<ValueDFS> & DFSOrderedSet)2617a7e6055SDimitry Andric void PredicateInfo::convertUsesToDFSOrdered(
2627a7e6055SDimitry Andric Value *Op, SmallVectorImpl<ValueDFS> &DFSOrderedSet) {
2637a7e6055SDimitry Andric for (auto &U : Op->uses()) {
2647a7e6055SDimitry Andric if (auto *I = dyn_cast<Instruction>(U.getUser())) {
2657a7e6055SDimitry Andric ValueDFS VD;
2667a7e6055SDimitry Andric // Put the phi node uses in the incoming block.
2677a7e6055SDimitry Andric BasicBlock *IBlock;
2687a7e6055SDimitry Andric if (auto *PN = dyn_cast<PHINode>(I)) {
2697a7e6055SDimitry Andric IBlock = PN->getIncomingBlock(U);
2707a7e6055SDimitry Andric // Make phi node users appear last in the incoming block
2717a7e6055SDimitry Andric // they are from.
2727a7e6055SDimitry Andric VD.LocalNum = LN_Last;
2737a7e6055SDimitry Andric } else {
2747a7e6055SDimitry Andric // If it's not a phi node use, it is somewhere in the middle of the
2757a7e6055SDimitry Andric // block.
2767a7e6055SDimitry Andric IBlock = I->getParent();
2777a7e6055SDimitry Andric VD.LocalNum = LN_Middle;
2787a7e6055SDimitry Andric }
2797a7e6055SDimitry Andric DomTreeNode *DomNode = DT.getNode(IBlock);
2807a7e6055SDimitry Andric // It's possible our use is in an unreachable block. Skip it if so.
2817a7e6055SDimitry Andric if (!DomNode)
2827a7e6055SDimitry Andric continue;
2837a7e6055SDimitry Andric VD.DFSIn = DomNode->getDFSNumIn();
2847a7e6055SDimitry Andric VD.DFSOut = DomNode->getDFSNumOut();
2857a7e6055SDimitry Andric VD.U = &U;
2867a7e6055SDimitry Andric DFSOrderedSet.push_back(VD);
2877a7e6055SDimitry Andric }
2887a7e6055SDimitry Andric }
2897a7e6055SDimitry Andric }
2907a7e6055SDimitry Andric
2917a7e6055SDimitry Andric // Collect relevant operations from Comparison that we may want to insert copies
2927a7e6055SDimitry Andric // for.
collectCmpOps(CmpInst * Comparison,SmallVectorImpl<Value * > & CmpOperands)2937a7e6055SDimitry Andric void collectCmpOps(CmpInst *Comparison, SmallVectorImpl<Value *> &CmpOperands) {
2947a7e6055SDimitry Andric auto *Op0 = Comparison->getOperand(0);
2957a7e6055SDimitry Andric auto *Op1 = Comparison->getOperand(1);
2967a7e6055SDimitry Andric if (Op0 == Op1)
2977a7e6055SDimitry Andric return;
2987a7e6055SDimitry Andric CmpOperands.push_back(Comparison);
2997a7e6055SDimitry Andric // Only want real values, not constants. Additionally, operands with one use
3007a7e6055SDimitry Andric // are only being used in the comparison, which means they will not be useful
3017a7e6055SDimitry Andric // for us to consider for predicateinfo.
3027a7e6055SDimitry Andric //
3037a7e6055SDimitry Andric if ((isa<Instruction>(Op0) || isa<Argument>(Op0)) && !Op0->hasOneUse())
3047a7e6055SDimitry Andric CmpOperands.push_back(Op0);
3057a7e6055SDimitry Andric if ((isa<Instruction>(Op1) || isa<Argument>(Op1)) && !Op1->hasOneUse())
3067a7e6055SDimitry Andric CmpOperands.push_back(Op1);
3077a7e6055SDimitry Andric }
3087a7e6055SDimitry Andric
3097a7e6055SDimitry Andric // Add Op, PB to the list of value infos for Op, and mark Op to be renamed.
addInfoFor(SmallPtrSetImpl<Value * > & OpsToRename,Value * Op,PredicateBase * PB)3107a7e6055SDimitry Andric void PredicateInfo::addInfoFor(SmallPtrSetImpl<Value *> &OpsToRename, Value *Op,
3117a7e6055SDimitry Andric PredicateBase *PB) {
3127a7e6055SDimitry Andric OpsToRename.insert(Op);
3137a7e6055SDimitry Andric auto &OperandInfo = getOrCreateValueInfo(Op);
3147a7e6055SDimitry Andric AllInfos.push_back(PB);
3157a7e6055SDimitry Andric OperandInfo.Infos.push_back(PB);
3167a7e6055SDimitry Andric }
3177a7e6055SDimitry Andric
3187a7e6055SDimitry Andric // Process an assume instruction and place relevant operations we want to rename
3197a7e6055SDimitry Andric // into OpsToRename.
processAssume(IntrinsicInst * II,BasicBlock * AssumeBB,SmallPtrSetImpl<Value * > & OpsToRename)3207a7e6055SDimitry Andric void PredicateInfo::processAssume(IntrinsicInst *II, BasicBlock *AssumeBB,
3217a7e6055SDimitry Andric SmallPtrSetImpl<Value *> &OpsToRename) {
3227a7e6055SDimitry Andric // See if we have a comparison we support
3237a7e6055SDimitry Andric SmallVector<Value *, 8> CmpOperands;
3247a7e6055SDimitry Andric SmallVector<Value *, 2> ConditionsToProcess;
3257a7e6055SDimitry Andric CmpInst::Predicate Pred;
3267a7e6055SDimitry Andric Value *Operand = II->getOperand(0);
3277a7e6055SDimitry Andric if (m_c_And(m_Cmp(Pred, m_Value(), m_Value()),
3287a7e6055SDimitry Andric m_Cmp(Pred, m_Value(), m_Value()))
3297a7e6055SDimitry Andric .match(II->getOperand(0))) {
3307a7e6055SDimitry Andric ConditionsToProcess.push_back(cast<BinaryOperator>(Operand)->getOperand(0));
3317a7e6055SDimitry Andric ConditionsToProcess.push_back(cast<BinaryOperator>(Operand)->getOperand(1));
3327a7e6055SDimitry Andric ConditionsToProcess.push_back(Operand);
3337a7e6055SDimitry Andric } else if (isa<CmpInst>(Operand)) {
3347a7e6055SDimitry Andric
3357a7e6055SDimitry Andric ConditionsToProcess.push_back(Operand);
3367a7e6055SDimitry Andric }
3377a7e6055SDimitry Andric for (auto Cond : ConditionsToProcess) {
3387a7e6055SDimitry Andric if (auto *Cmp = dyn_cast<CmpInst>(Cond)) {
3397a7e6055SDimitry Andric collectCmpOps(Cmp, CmpOperands);
3407a7e6055SDimitry Andric // Now add our copy infos for our operands
3417a7e6055SDimitry Andric for (auto *Op : CmpOperands) {
3427a7e6055SDimitry Andric auto *PA = new PredicateAssume(Op, II, Cmp);
3437a7e6055SDimitry Andric addInfoFor(OpsToRename, Op, PA);
3447a7e6055SDimitry Andric }
3457a7e6055SDimitry Andric CmpOperands.clear();
3467a7e6055SDimitry Andric } else if (auto *BinOp = dyn_cast<BinaryOperator>(Cond)) {
3477a7e6055SDimitry Andric // Otherwise, it should be an AND.
3487a7e6055SDimitry Andric assert(BinOp->getOpcode() == Instruction::And &&
3497a7e6055SDimitry Andric "Should have been an AND");
3507a7e6055SDimitry Andric auto *PA = new PredicateAssume(BinOp, II, BinOp);
3517a7e6055SDimitry Andric addInfoFor(OpsToRename, BinOp, PA);
3527a7e6055SDimitry Andric } else {
3537a7e6055SDimitry Andric llvm_unreachable("Unknown type of condition");
3547a7e6055SDimitry Andric }
3557a7e6055SDimitry Andric }
3567a7e6055SDimitry Andric }
3577a7e6055SDimitry Andric
3587a7e6055SDimitry Andric // Process a block terminating branch, and place relevant operations to be
3597a7e6055SDimitry Andric // renamed into OpsToRename.
processBranch(BranchInst * BI,BasicBlock * BranchBB,SmallPtrSetImpl<Value * > & OpsToRename)3607a7e6055SDimitry Andric void PredicateInfo::processBranch(BranchInst *BI, BasicBlock *BranchBB,
3617a7e6055SDimitry Andric SmallPtrSetImpl<Value *> &OpsToRename) {
3627a7e6055SDimitry Andric BasicBlock *FirstBB = BI->getSuccessor(0);
3637a7e6055SDimitry Andric BasicBlock *SecondBB = BI->getSuccessor(1);
3647a7e6055SDimitry Andric SmallVector<BasicBlock *, 2> SuccsToProcess;
3657a7e6055SDimitry Andric SuccsToProcess.push_back(FirstBB);
3667a7e6055SDimitry Andric SuccsToProcess.push_back(SecondBB);
3677a7e6055SDimitry Andric SmallVector<Value *, 2> ConditionsToProcess;
3687a7e6055SDimitry Andric
3697a7e6055SDimitry Andric auto InsertHelper = [&](Value *Op, bool isAnd, bool isOr, Value *Cond) {
3707a7e6055SDimitry Andric for (auto *Succ : SuccsToProcess) {
3717a7e6055SDimitry Andric // Don't try to insert on a self-edge. This is mainly because we will
3727a7e6055SDimitry Andric // eliminate during renaming anyway.
3737a7e6055SDimitry Andric if (Succ == BranchBB)
3747a7e6055SDimitry Andric continue;
3757a7e6055SDimitry Andric bool TakenEdge = (Succ == FirstBB);
3767a7e6055SDimitry Andric // For and, only insert on the true edge
3777a7e6055SDimitry Andric // For or, only insert on the false edge
3787a7e6055SDimitry Andric if ((isAnd && !TakenEdge) || (isOr && TakenEdge))
3797a7e6055SDimitry Andric continue;
3807a7e6055SDimitry Andric PredicateBase *PB =
3817a7e6055SDimitry Andric new PredicateBranch(Op, BranchBB, Succ, Cond, TakenEdge);
3827a7e6055SDimitry Andric addInfoFor(OpsToRename, Op, PB);
3837a7e6055SDimitry Andric if (!Succ->getSinglePredecessor())
3847a7e6055SDimitry Andric EdgeUsesOnly.insert({BranchBB, Succ});
3857a7e6055SDimitry Andric }
3867a7e6055SDimitry Andric };
3877a7e6055SDimitry Andric
3887a7e6055SDimitry Andric // Match combinations of conditions.
3897a7e6055SDimitry Andric CmpInst::Predicate Pred;
3907a7e6055SDimitry Andric bool isAnd = false;
3917a7e6055SDimitry Andric bool isOr = false;
3927a7e6055SDimitry Andric SmallVector<Value *, 8> CmpOperands;
3937a7e6055SDimitry Andric if (match(BI->getCondition(), m_And(m_Cmp(Pred, m_Value(), m_Value()),
3947a7e6055SDimitry Andric m_Cmp(Pred, m_Value(), m_Value()))) ||
3957a7e6055SDimitry Andric match(BI->getCondition(), m_Or(m_Cmp(Pred, m_Value(), m_Value()),
3967a7e6055SDimitry Andric m_Cmp(Pred, m_Value(), m_Value())))) {
3977a7e6055SDimitry Andric auto *BinOp = cast<BinaryOperator>(BI->getCondition());
3987a7e6055SDimitry Andric if (BinOp->getOpcode() == Instruction::And)
3997a7e6055SDimitry Andric isAnd = true;
4007a7e6055SDimitry Andric else if (BinOp->getOpcode() == Instruction::Or)
4017a7e6055SDimitry Andric isOr = true;
4027a7e6055SDimitry Andric ConditionsToProcess.push_back(BinOp->getOperand(0));
4037a7e6055SDimitry Andric ConditionsToProcess.push_back(BinOp->getOperand(1));
4047a7e6055SDimitry Andric ConditionsToProcess.push_back(BI->getCondition());
4057a7e6055SDimitry Andric } else if (isa<CmpInst>(BI->getCondition())) {
4067a7e6055SDimitry Andric ConditionsToProcess.push_back(BI->getCondition());
4077a7e6055SDimitry Andric }
4087a7e6055SDimitry Andric for (auto Cond : ConditionsToProcess) {
4097a7e6055SDimitry Andric if (auto *Cmp = dyn_cast<CmpInst>(Cond)) {
4107a7e6055SDimitry Andric collectCmpOps(Cmp, CmpOperands);
4117a7e6055SDimitry Andric // Now add our copy infos for our operands
4127a7e6055SDimitry Andric for (auto *Op : CmpOperands)
4137a7e6055SDimitry Andric InsertHelper(Op, isAnd, isOr, Cmp);
4147a7e6055SDimitry Andric } else if (auto *BinOp = dyn_cast<BinaryOperator>(Cond)) {
4157a7e6055SDimitry Andric // This must be an AND or an OR.
4167a7e6055SDimitry Andric assert((BinOp->getOpcode() == Instruction::And ||
4177a7e6055SDimitry Andric BinOp->getOpcode() == Instruction::Or) &&
4187a7e6055SDimitry Andric "Should have been an AND or an OR");
4197a7e6055SDimitry Andric // The actual value of the binop is not subject to the same restrictions
4207a7e6055SDimitry Andric // as the comparison. It's either true or false on the true/false branch.
4217a7e6055SDimitry Andric InsertHelper(BinOp, false, false, BinOp);
4227a7e6055SDimitry Andric } else {
4237a7e6055SDimitry Andric llvm_unreachable("Unknown type of condition");
4247a7e6055SDimitry Andric }
4257a7e6055SDimitry Andric CmpOperands.clear();
4267a7e6055SDimitry Andric }
4277a7e6055SDimitry Andric }
4287a7e6055SDimitry Andric // Process a block terminating switch, and place relevant operations to be
4297a7e6055SDimitry Andric // renamed into OpsToRename.
processSwitch(SwitchInst * SI,BasicBlock * BranchBB,SmallPtrSetImpl<Value * > & OpsToRename)4307a7e6055SDimitry Andric void PredicateInfo::processSwitch(SwitchInst *SI, BasicBlock *BranchBB,
4317a7e6055SDimitry Andric SmallPtrSetImpl<Value *> &OpsToRename) {
4327a7e6055SDimitry Andric Value *Op = SI->getCondition();
4337a7e6055SDimitry Andric if ((!isa<Instruction>(Op) && !isa<Argument>(Op)) || Op->hasOneUse())
4347a7e6055SDimitry Andric return;
4357a7e6055SDimitry Andric
4367a7e6055SDimitry Andric // Remember how many outgoing edges there are to every successor.
4377a7e6055SDimitry Andric SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
4387a7e6055SDimitry Andric for (unsigned i = 0, e = SI->getNumSuccessors(); i != e; ++i) {
4397a7e6055SDimitry Andric BasicBlock *TargetBlock = SI->getSuccessor(i);
4407a7e6055SDimitry Andric ++SwitchEdges[TargetBlock];
4417a7e6055SDimitry Andric }
4427a7e6055SDimitry Andric
4437a7e6055SDimitry Andric // Now propagate info for each case value
4447a7e6055SDimitry Andric for (auto C : SI->cases()) {
4457a7e6055SDimitry Andric BasicBlock *TargetBlock = C.getCaseSuccessor();
4467a7e6055SDimitry Andric if (SwitchEdges.lookup(TargetBlock) == 1) {
4477a7e6055SDimitry Andric PredicateSwitch *PS = new PredicateSwitch(
4487a7e6055SDimitry Andric Op, SI->getParent(), TargetBlock, C.getCaseValue(), SI);
4497a7e6055SDimitry Andric addInfoFor(OpsToRename, Op, PS);
4507a7e6055SDimitry Andric if (!TargetBlock->getSinglePredecessor())
4517a7e6055SDimitry Andric EdgeUsesOnly.insert({BranchBB, TargetBlock});
4527a7e6055SDimitry Andric }
4537a7e6055SDimitry Andric }
4547a7e6055SDimitry Andric }
4557a7e6055SDimitry Andric
4567a7e6055SDimitry Andric // Build predicate info for our function
buildPredicateInfo()4577a7e6055SDimitry Andric void PredicateInfo::buildPredicateInfo() {
4587a7e6055SDimitry Andric DT.updateDFSNumbers();
4597a7e6055SDimitry Andric // Collect operands to rename from all conditional branch terminators, as well
4607a7e6055SDimitry Andric // as assume statements.
4617a7e6055SDimitry Andric SmallPtrSet<Value *, 8> OpsToRename;
4627a7e6055SDimitry Andric for (auto DTN : depth_first(DT.getRootNode())) {
4637a7e6055SDimitry Andric BasicBlock *BranchBB = DTN->getBlock();
4647a7e6055SDimitry Andric if (auto *BI = dyn_cast<BranchInst>(BranchBB->getTerminator())) {
4657a7e6055SDimitry Andric if (!BI->isConditional())
4667a7e6055SDimitry Andric continue;
46724d58133SDimitry Andric // Can't insert conditional information if they all go to the same place.
46824d58133SDimitry Andric if (BI->getSuccessor(0) == BI->getSuccessor(1))
46924d58133SDimitry Andric continue;
4707a7e6055SDimitry Andric processBranch(BI, BranchBB, OpsToRename);
4717a7e6055SDimitry Andric } else if (auto *SI = dyn_cast<SwitchInst>(BranchBB->getTerminator())) {
4727a7e6055SDimitry Andric processSwitch(SI, BranchBB, OpsToRename);
4737a7e6055SDimitry Andric }
4747a7e6055SDimitry Andric }
4757a7e6055SDimitry Andric for (auto &Assume : AC.assumptions()) {
4767a7e6055SDimitry Andric if (auto *II = dyn_cast_or_null<IntrinsicInst>(Assume))
4777a7e6055SDimitry Andric processAssume(II, II->getParent(), OpsToRename);
4787a7e6055SDimitry Andric }
4797a7e6055SDimitry Andric // Now rename all our operations.
4807a7e6055SDimitry Andric renameUses(OpsToRename);
4817a7e6055SDimitry Andric }
4827a7e6055SDimitry Andric
4834ba319b5SDimitry Andric // Create a ssa_copy declaration with custom mangling, because
4844ba319b5SDimitry Andric // Intrinsic::getDeclaration does not handle overloaded unnamed types properly:
4854ba319b5SDimitry Andric // all unnamed types get mangled to the same string. We use the pointer
4864ba319b5SDimitry Andric // to the type as name here, as it guarantees unique names for different
4874ba319b5SDimitry Andric // types and we remove the declarations when destroying PredicateInfo.
4884ba319b5SDimitry Andric // It is a workaround for PR38117, because solving it in a fully general way is
4894ba319b5SDimitry Andric // tricky (FIXME).
getCopyDeclaration(Module * M,Type * Ty)4904ba319b5SDimitry Andric static Function *getCopyDeclaration(Module *M, Type *Ty) {
4914ba319b5SDimitry Andric std::string Name = "llvm.ssa.copy." + utostr((uintptr_t) Ty);
4924ba319b5SDimitry Andric return cast<Function>(M->getOrInsertFunction(
4934ba319b5SDimitry Andric Name, getType(M->getContext(), Intrinsic::ssa_copy, Ty)));
4944ba319b5SDimitry Andric }
4954ba319b5SDimitry Andric
4967a7e6055SDimitry Andric // Given the renaming stack, make all the operands currently on the stack real
4977a7e6055SDimitry Andric // by inserting them into the IR. Return the last operation's value.
materializeStack(unsigned int & Counter,ValueDFSStack & RenameStack,Value * OrigOp)4987a7e6055SDimitry Andric Value *PredicateInfo::materializeStack(unsigned int &Counter,
4997a7e6055SDimitry Andric ValueDFSStack &RenameStack,
5007a7e6055SDimitry Andric Value *OrigOp) {
5017a7e6055SDimitry Andric // Find the first thing we have to materialize
5027a7e6055SDimitry Andric auto RevIter = RenameStack.rbegin();
5037a7e6055SDimitry Andric for (; RevIter != RenameStack.rend(); ++RevIter)
5047a7e6055SDimitry Andric if (RevIter->Def)
5057a7e6055SDimitry Andric break;
5067a7e6055SDimitry Andric
5077a7e6055SDimitry Andric size_t Start = RevIter - RenameStack.rbegin();
5087a7e6055SDimitry Andric // The maximum number of things we should be trying to materialize at once
5097a7e6055SDimitry Andric // right now is 4, depending on if we had an assume, a branch, and both used
5107a7e6055SDimitry Andric // and of conditions.
5117a7e6055SDimitry Andric for (auto RenameIter = RenameStack.end() - Start;
5127a7e6055SDimitry Andric RenameIter != RenameStack.end(); ++RenameIter) {
5137a7e6055SDimitry Andric auto *Op =
5147a7e6055SDimitry Andric RenameIter == RenameStack.begin() ? OrigOp : (RenameIter - 1)->Def;
5157a7e6055SDimitry Andric ValueDFS &Result = *RenameIter;
5167a7e6055SDimitry Andric auto *ValInfo = Result.PInfo;
5177a7e6055SDimitry Andric // For edge predicates, we can just place the operand in the block before
5187a7e6055SDimitry Andric // the terminator. For assume, we have to place it right before the assume
5197a7e6055SDimitry Andric // to ensure we dominate all of our uses. Always insert right before the
5207a7e6055SDimitry Andric // relevant instruction (terminator, assume), so that we insert in proper
5217a7e6055SDimitry Andric // order in the case of multiple predicateinfo in the same block.
5227a7e6055SDimitry Andric if (isa<PredicateWithEdge>(ValInfo)) {
5237a7e6055SDimitry Andric IRBuilder<> B(getBranchTerminator(ValInfo));
5244ba319b5SDimitry Andric Function *IF = getCopyDeclaration(F.getParent(), Op->getType());
525*b5893f02SDimitry Andric if (empty(IF->users()))
5264ba319b5SDimitry Andric CreatedDeclarations.insert(IF);
5277a7e6055SDimitry Andric CallInst *PIC =
5287a7e6055SDimitry Andric B.CreateCall(IF, Op, Op->getName() + "." + Twine(Counter++));
5297a7e6055SDimitry Andric PredicateMap.insert({PIC, ValInfo});
5307a7e6055SDimitry Andric Result.Def = PIC;
5317a7e6055SDimitry Andric } else {
5327a7e6055SDimitry Andric auto *PAssume = dyn_cast<PredicateAssume>(ValInfo);
5337a7e6055SDimitry Andric assert(PAssume &&
5347a7e6055SDimitry Andric "Should not have gotten here without it being an assume");
5357a7e6055SDimitry Andric IRBuilder<> B(PAssume->AssumeInst);
5364ba319b5SDimitry Andric Function *IF = getCopyDeclaration(F.getParent(), Op->getType());
537*b5893f02SDimitry Andric if (empty(IF->users()))
5384ba319b5SDimitry Andric CreatedDeclarations.insert(IF);
5397a7e6055SDimitry Andric CallInst *PIC = B.CreateCall(IF, Op);
5407a7e6055SDimitry Andric PredicateMap.insert({PIC, ValInfo});
5417a7e6055SDimitry Andric Result.Def = PIC;
5427a7e6055SDimitry Andric }
5437a7e6055SDimitry Andric }
5447a7e6055SDimitry Andric return RenameStack.back().Def;
5457a7e6055SDimitry Andric }
5467a7e6055SDimitry Andric
5477a7e6055SDimitry Andric // Instead of the standard SSA renaming algorithm, which is O(Number of
5487a7e6055SDimitry Andric // instructions), and walks the entire dominator tree, we walk only the defs +
5497a7e6055SDimitry Andric // uses. The standard SSA renaming algorithm does not really rely on the
5507a7e6055SDimitry Andric // dominator tree except to order the stack push/pops of the renaming stacks, so
5517a7e6055SDimitry Andric // that defs end up getting pushed before hitting the correct uses. This does
5527a7e6055SDimitry Andric // not require the dominator tree, only the *order* of the dominator tree. The
5537a7e6055SDimitry Andric // complete and correct ordering of the defs and uses, in dominator tree is
5547a7e6055SDimitry Andric // contained in the DFS numbering of the dominator tree. So we sort the defs and
5557a7e6055SDimitry Andric // uses into the DFS ordering, and then just use the renaming stack as per
5567a7e6055SDimitry Andric // normal, pushing when we hit a def (which is a predicateinfo instruction),
5577a7e6055SDimitry Andric // popping when we are out of the dfs scope for that def, and replacing any uses
5587a7e6055SDimitry Andric // with top of stack if it exists. In order to handle liveness without
5597a7e6055SDimitry Andric // propagating liveness info, we don't actually insert the predicateinfo
5607a7e6055SDimitry Andric // instruction def until we see a use that it would dominate. Once we see such
5617a7e6055SDimitry Andric // a use, we materialize the predicateinfo instruction in the right place and
5627a7e6055SDimitry Andric // use it.
5637a7e6055SDimitry Andric //
5647a7e6055SDimitry Andric // TODO: Use this algorithm to perform fast single-variable renaming in
5657a7e6055SDimitry Andric // promotememtoreg and memoryssa.
renameUses(SmallPtrSetImpl<Value * > & OpSet)566f9448bf3SDimitry Andric void PredicateInfo::renameUses(SmallPtrSetImpl<Value *> &OpSet) {
567f9448bf3SDimitry Andric // Sort OpsToRename since we are going to iterate it.
568f9448bf3SDimitry Andric SmallVector<Value *, 8> OpsToRename(OpSet.begin(), OpSet.end());
569a580b014SDimitry Andric auto Comparator = [&](const Value *A, const Value *B) {
570a580b014SDimitry Andric return valueComesBefore(OI, A, B);
571a580b014SDimitry Andric };
572*b5893f02SDimitry Andric llvm::sort(OpsToRename, Comparator);
573a580b014SDimitry Andric ValueDFS_Compare Compare(OI);
5747a7e6055SDimitry Andric // Compute liveness, and rename in O(uses) per Op.
5757a7e6055SDimitry Andric for (auto *Op : OpsToRename) {
5764ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Visiting " << *Op << "\n");
5777a7e6055SDimitry Andric unsigned Counter = 0;
5787a7e6055SDimitry Andric SmallVector<ValueDFS, 16> OrderedUses;
5797a7e6055SDimitry Andric const auto &ValueInfo = getValueInfo(Op);
5807a7e6055SDimitry Andric // Insert the possible copies into the def/use list.
5817a7e6055SDimitry Andric // They will become real copies if we find a real use for them, and never
5827a7e6055SDimitry Andric // created otherwise.
5837a7e6055SDimitry Andric for (auto &PossibleCopy : ValueInfo.Infos) {
5847a7e6055SDimitry Andric ValueDFS VD;
5857a7e6055SDimitry Andric // Determine where we are going to place the copy by the copy type.
5867a7e6055SDimitry Andric // The predicate info for branches always come first, they will get
5877a7e6055SDimitry Andric // materialized in the split block at the top of the block.
5887a7e6055SDimitry Andric // The predicate info for assumes will be somewhere in the middle,
5897a7e6055SDimitry Andric // it will get materialized in front of the assume.
5907a7e6055SDimitry Andric if (const auto *PAssume = dyn_cast<PredicateAssume>(PossibleCopy)) {
5917a7e6055SDimitry Andric VD.LocalNum = LN_Middle;
5927a7e6055SDimitry Andric DomTreeNode *DomNode = DT.getNode(PAssume->AssumeInst->getParent());
5937a7e6055SDimitry Andric if (!DomNode)
5947a7e6055SDimitry Andric continue;
5957a7e6055SDimitry Andric VD.DFSIn = DomNode->getDFSNumIn();
5967a7e6055SDimitry Andric VD.DFSOut = DomNode->getDFSNumOut();
5977a7e6055SDimitry Andric VD.PInfo = PossibleCopy;
5987a7e6055SDimitry Andric OrderedUses.push_back(VD);
5997a7e6055SDimitry Andric } else if (isa<PredicateWithEdge>(PossibleCopy)) {
6007a7e6055SDimitry Andric // If we can only do phi uses, we treat it like it's in the branch
6017a7e6055SDimitry Andric // block, and handle it specially. We know that it goes last, and only
6027a7e6055SDimitry Andric // dominate phi uses.
6037a7e6055SDimitry Andric auto BlockEdge = getBlockEdge(PossibleCopy);
6047a7e6055SDimitry Andric if (EdgeUsesOnly.count(BlockEdge)) {
6057a7e6055SDimitry Andric VD.LocalNum = LN_Last;
6067a7e6055SDimitry Andric auto *DomNode = DT.getNode(BlockEdge.first);
6077a7e6055SDimitry Andric if (DomNode) {
6087a7e6055SDimitry Andric VD.DFSIn = DomNode->getDFSNumIn();
6097a7e6055SDimitry Andric VD.DFSOut = DomNode->getDFSNumOut();
6107a7e6055SDimitry Andric VD.PInfo = PossibleCopy;
6117a7e6055SDimitry Andric VD.EdgeOnly = true;
6127a7e6055SDimitry Andric OrderedUses.push_back(VD);
6137a7e6055SDimitry Andric }
6147a7e6055SDimitry Andric } else {
6157a7e6055SDimitry Andric // Otherwise, we are in the split block (even though we perform
6167a7e6055SDimitry Andric // insertion in the branch block).
6177a7e6055SDimitry Andric // Insert a possible copy at the split block and before the branch.
6187a7e6055SDimitry Andric VD.LocalNum = LN_First;
6197a7e6055SDimitry Andric auto *DomNode = DT.getNode(BlockEdge.second);
6207a7e6055SDimitry Andric if (DomNode) {
6217a7e6055SDimitry Andric VD.DFSIn = DomNode->getDFSNumIn();
6227a7e6055SDimitry Andric VD.DFSOut = DomNode->getDFSNumOut();
6237a7e6055SDimitry Andric VD.PInfo = PossibleCopy;
6247a7e6055SDimitry Andric OrderedUses.push_back(VD);
6257a7e6055SDimitry Andric }
6267a7e6055SDimitry Andric }
6277a7e6055SDimitry Andric }
6287a7e6055SDimitry Andric }
6297a7e6055SDimitry Andric
6307a7e6055SDimitry Andric convertUsesToDFSOrdered(Op, OrderedUses);
6312cab237bSDimitry Andric // Here we require a stable sort because we do not bother to try to
6322cab237bSDimitry Andric // assign an order to the operands the uses represent. Thus, two
6332cab237bSDimitry Andric // uses in the same instruction do not have a strict sort order
6342cab237bSDimitry Andric // currently and will be considered equal. We could get rid of the
6352cab237bSDimitry Andric // stable sort by creating one if we wanted.
6362cab237bSDimitry Andric std::stable_sort(OrderedUses.begin(), OrderedUses.end(), Compare);
6377a7e6055SDimitry Andric SmallVector<ValueDFS, 8> RenameStack;
6387a7e6055SDimitry Andric // For each use, sorted into dfs order, push values and replaces uses with
6397a7e6055SDimitry Andric // top of stack, which will represent the reaching def.
6407a7e6055SDimitry Andric for (auto &VD : OrderedUses) {
6417a7e6055SDimitry Andric // We currently do not materialize copy over copy, but we should decide if
6427a7e6055SDimitry Andric // we want to.
6437a7e6055SDimitry Andric bool PossibleCopy = VD.PInfo != nullptr;
6447a7e6055SDimitry Andric if (RenameStack.empty()) {
6454ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Rename Stack is empty\n");
6467a7e6055SDimitry Andric } else {
6474ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Rename Stack Top DFS numbers are ("
6487a7e6055SDimitry Andric << RenameStack.back().DFSIn << ","
6497a7e6055SDimitry Andric << RenameStack.back().DFSOut << ")\n");
6507a7e6055SDimitry Andric }
6517a7e6055SDimitry Andric
6524ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Current DFS numbers are (" << VD.DFSIn << ","
6537a7e6055SDimitry Andric << VD.DFSOut << ")\n");
6547a7e6055SDimitry Andric
6557a7e6055SDimitry Andric bool ShouldPush = (VD.Def || PossibleCopy);
6567a7e6055SDimitry Andric bool OutOfScope = !stackIsInScope(RenameStack, VD);
6577a7e6055SDimitry Andric if (OutOfScope || ShouldPush) {
6587a7e6055SDimitry Andric // Sync to our current scope.
6597a7e6055SDimitry Andric popStackUntilDFSScope(RenameStack, VD);
6607a7e6055SDimitry Andric if (ShouldPush) {
6617a7e6055SDimitry Andric RenameStack.push_back(VD);
6627a7e6055SDimitry Andric }
6637a7e6055SDimitry Andric }
6647a7e6055SDimitry Andric // If we get to this point, and the stack is empty we must have a use
6657a7e6055SDimitry Andric // with no renaming needed, just skip it.
6667a7e6055SDimitry Andric if (RenameStack.empty())
6677a7e6055SDimitry Andric continue;
6687a7e6055SDimitry Andric // Skip values, only want to rename the uses
6697a7e6055SDimitry Andric if (VD.Def || PossibleCopy)
6707a7e6055SDimitry Andric continue;
6717a7e6055SDimitry Andric if (!DebugCounter::shouldExecute(RenameCounter)) {
6724ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Skipping execution due to debug counter\n");
6737a7e6055SDimitry Andric continue;
6747a7e6055SDimitry Andric }
6757a7e6055SDimitry Andric ValueDFS &Result = RenameStack.back();
6767a7e6055SDimitry Andric
6777a7e6055SDimitry Andric // If the possible copy dominates something, materialize our stack up to
6787a7e6055SDimitry Andric // this point. This ensures every comparison that affects our operation
6797a7e6055SDimitry Andric // ends up with predicateinfo.
6807a7e6055SDimitry Andric if (!Result.Def)
6817a7e6055SDimitry Andric Result.Def = materializeStack(Counter, RenameStack, Op);
6827a7e6055SDimitry Andric
6834ba319b5SDimitry Andric LLVM_DEBUG(dbgs() << "Found replacement " << *Result.Def << " for "
6844ba319b5SDimitry Andric << *VD.U->get() << " in " << *(VD.U->getUser())
6854ba319b5SDimitry Andric << "\n");
6867a7e6055SDimitry Andric assert(DT.dominates(cast<Instruction>(Result.Def), *VD.U) &&
6877a7e6055SDimitry Andric "Predicateinfo def should have dominated this use");
6887a7e6055SDimitry Andric VD.U->set(Result.Def);
6897a7e6055SDimitry Andric }
6907a7e6055SDimitry Andric }
6917a7e6055SDimitry Andric }
6927a7e6055SDimitry Andric
getOrCreateValueInfo(Value * Operand)6937a7e6055SDimitry Andric PredicateInfo::ValueInfo &PredicateInfo::getOrCreateValueInfo(Value *Operand) {
6947a7e6055SDimitry Andric auto OIN = ValueInfoNums.find(Operand);
6957a7e6055SDimitry Andric if (OIN == ValueInfoNums.end()) {
6967a7e6055SDimitry Andric // This will grow it
6977a7e6055SDimitry Andric ValueInfos.resize(ValueInfos.size() + 1);
6987a7e6055SDimitry Andric // This will use the new size and give us a 0 based number of the info
6997a7e6055SDimitry Andric auto InsertResult = ValueInfoNums.insert({Operand, ValueInfos.size() - 1});
7007a7e6055SDimitry Andric assert(InsertResult.second && "Value info number already existed?");
7017a7e6055SDimitry Andric return ValueInfos[InsertResult.first->second];
7027a7e6055SDimitry Andric }
7037a7e6055SDimitry Andric return ValueInfos[OIN->second];
7047a7e6055SDimitry Andric }
7057a7e6055SDimitry Andric
7067a7e6055SDimitry Andric const PredicateInfo::ValueInfo &
getValueInfo(Value * Operand) const7077a7e6055SDimitry Andric PredicateInfo::getValueInfo(Value *Operand) const {
7087a7e6055SDimitry Andric auto OINI = ValueInfoNums.lookup(Operand);
7097a7e6055SDimitry Andric assert(OINI != 0 && "Operand was not really in the Value Info Numbers");
7107a7e6055SDimitry Andric assert(OINI < ValueInfos.size() &&
7117a7e6055SDimitry Andric "Value Info Number greater than size of Value Info Table");
7127a7e6055SDimitry Andric return ValueInfos[OINI];
7137a7e6055SDimitry Andric }
7147a7e6055SDimitry Andric
PredicateInfo(Function & F,DominatorTree & DT,AssumptionCache & AC)7157a7e6055SDimitry Andric PredicateInfo::PredicateInfo(Function &F, DominatorTree &DT,
7167a7e6055SDimitry Andric AssumptionCache &AC)
717a580b014SDimitry Andric : F(F), DT(DT), AC(AC), OI(&DT) {
7187a7e6055SDimitry Andric // Push an empty operand info so that we can detect 0 as not finding one
7197a7e6055SDimitry Andric ValueInfos.resize(1);
7207a7e6055SDimitry Andric buildPredicateInfo();
7217a7e6055SDimitry Andric }
7227a7e6055SDimitry Andric
7234ba319b5SDimitry Andric // Remove all declarations we created . The PredicateInfo consumers are
7244ba319b5SDimitry Andric // responsible for remove the ssa_copy calls created.
~PredicateInfo()7254ba319b5SDimitry Andric PredicateInfo::~PredicateInfo() {
7264ba319b5SDimitry Andric // Collect function pointers in set first, as SmallSet uses a SmallVector
7274ba319b5SDimitry Andric // internally and we have to remove the asserting value handles first.
7284ba319b5SDimitry Andric SmallPtrSet<Function *, 20> FunctionPtrs;
7294ba319b5SDimitry Andric for (auto &F : CreatedDeclarations)
7304ba319b5SDimitry Andric FunctionPtrs.insert(&*F);
7314ba319b5SDimitry Andric CreatedDeclarations.clear();
7324ba319b5SDimitry Andric
7334ba319b5SDimitry Andric for (Function *F : FunctionPtrs) {
7344ba319b5SDimitry Andric assert(F->user_begin() == F->user_end() &&
7354ba319b5SDimitry Andric "PredicateInfo consumer did not remove all SSA copies.");
7364ba319b5SDimitry Andric F->eraseFromParent();
7374ba319b5SDimitry Andric }
7384ba319b5SDimitry Andric }
7397a7e6055SDimitry Andric
verifyPredicateInfo() const7407a7e6055SDimitry Andric void PredicateInfo::verifyPredicateInfo() const {}
7417a7e6055SDimitry Andric
7427a7e6055SDimitry Andric char PredicateInfoPrinterLegacyPass::ID = 0;
7437a7e6055SDimitry Andric
PredicateInfoPrinterLegacyPass()7447a7e6055SDimitry Andric PredicateInfoPrinterLegacyPass::PredicateInfoPrinterLegacyPass()
7457a7e6055SDimitry Andric : FunctionPass(ID) {
7467a7e6055SDimitry Andric initializePredicateInfoPrinterLegacyPassPass(
7477a7e6055SDimitry Andric *PassRegistry::getPassRegistry());
7487a7e6055SDimitry Andric }
7497a7e6055SDimitry Andric
getAnalysisUsage(AnalysisUsage & AU) const7507a7e6055SDimitry Andric void PredicateInfoPrinterLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {
7517a7e6055SDimitry Andric AU.setPreservesAll();
7527a7e6055SDimitry Andric AU.addRequiredTransitive<DominatorTreeWrapperPass>();
7537a7e6055SDimitry Andric AU.addRequired<AssumptionCacheTracker>();
7547a7e6055SDimitry Andric }
7557a7e6055SDimitry Andric
7564ba319b5SDimitry Andric // Replace ssa_copy calls created by PredicateInfo with their operand.
replaceCreatedSSACopys(PredicateInfo & PredInfo,Function & F)7574ba319b5SDimitry Andric static void replaceCreatedSSACopys(PredicateInfo &PredInfo, Function &F) {
7584ba319b5SDimitry Andric for (auto I = inst_begin(F), E = inst_end(F); I != E;) {
7594ba319b5SDimitry Andric Instruction *Inst = &*I++;
7604ba319b5SDimitry Andric const auto *PI = PredInfo.getPredicateInfoFor(Inst);
7614ba319b5SDimitry Andric auto *II = dyn_cast<IntrinsicInst>(Inst);
7624ba319b5SDimitry Andric if (!PI || !II || II->getIntrinsicID() != Intrinsic::ssa_copy)
7634ba319b5SDimitry Andric continue;
7644ba319b5SDimitry Andric
7654ba319b5SDimitry Andric Inst->replaceAllUsesWith(II->getOperand(0));
7664ba319b5SDimitry Andric Inst->eraseFromParent();
7674ba319b5SDimitry Andric }
7684ba319b5SDimitry Andric }
7694ba319b5SDimitry Andric
runOnFunction(Function & F)7707a7e6055SDimitry Andric bool PredicateInfoPrinterLegacyPass::runOnFunction(Function &F) {
7717a7e6055SDimitry Andric auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
7727a7e6055SDimitry Andric auto &AC = getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
7737a7e6055SDimitry Andric auto PredInfo = make_unique<PredicateInfo>(F, DT, AC);
7747a7e6055SDimitry Andric PredInfo->print(dbgs());
7757a7e6055SDimitry Andric if (VerifyPredicateInfo)
7767a7e6055SDimitry Andric PredInfo->verifyPredicateInfo();
7774ba319b5SDimitry Andric
7784ba319b5SDimitry Andric replaceCreatedSSACopys(*PredInfo, F);
7797a7e6055SDimitry Andric return false;
7807a7e6055SDimitry Andric }
7817a7e6055SDimitry Andric
run(Function & F,FunctionAnalysisManager & AM)7827a7e6055SDimitry Andric PreservedAnalyses PredicateInfoPrinterPass::run(Function &F,
7837a7e6055SDimitry Andric FunctionAnalysisManager &AM) {
7847a7e6055SDimitry Andric auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
7857a7e6055SDimitry Andric auto &AC = AM.getResult<AssumptionAnalysis>(F);
7867a7e6055SDimitry Andric OS << "PredicateInfo for function: " << F.getName() << "\n";
7874ba319b5SDimitry Andric auto PredInfo = make_unique<PredicateInfo>(F, DT, AC);
7884ba319b5SDimitry Andric PredInfo->print(OS);
7897a7e6055SDimitry Andric
7904ba319b5SDimitry Andric replaceCreatedSSACopys(*PredInfo, F);
7917a7e6055SDimitry Andric return PreservedAnalyses::all();
7927a7e6055SDimitry Andric }
7937a7e6055SDimitry Andric
7944ba319b5SDimitry Andric /// An assembly annotator class to print PredicateInfo information in
7957a7e6055SDimitry Andric /// comments.
7967a7e6055SDimitry Andric class PredicateInfoAnnotatedWriter : public AssemblyAnnotationWriter {
7977a7e6055SDimitry Andric friend class PredicateInfo;
7987a7e6055SDimitry Andric const PredicateInfo *PredInfo;
7997a7e6055SDimitry Andric
8007a7e6055SDimitry Andric public:
PredicateInfoAnnotatedWriter(const PredicateInfo * M)8017a7e6055SDimitry Andric PredicateInfoAnnotatedWriter(const PredicateInfo *M) : PredInfo(M) {}
8027a7e6055SDimitry Andric
emitBasicBlockStartAnnot(const BasicBlock * BB,formatted_raw_ostream & OS)8037a7e6055SDimitry Andric virtual void emitBasicBlockStartAnnot(const BasicBlock *BB,
8047a7e6055SDimitry Andric formatted_raw_ostream &OS) {}
8057a7e6055SDimitry Andric
emitInstructionAnnot(const Instruction * I,formatted_raw_ostream & OS)8067a7e6055SDimitry Andric virtual void emitInstructionAnnot(const Instruction *I,
8077a7e6055SDimitry Andric formatted_raw_ostream &OS) {
8087a7e6055SDimitry Andric if (const auto *PI = PredInfo->getPredicateInfoFor(I)) {
8097a7e6055SDimitry Andric OS << "; Has predicate info\n";
8107a7e6055SDimitry Andric if (const auto *PB = dyn_cast<PredicateBranch>(PI)) {
8117a7e6055SDimitry Andric OS << "; branch predicate info { TrueEdge: " << PB->TrueEdge
8127a7e6055SDimitry Andric << " Comparison:" << *PB->Condition << " Edge: [";
8137a7e6055SDimitry Andric PB->From->printAsOperand(OS);
8147a7e6055SDimitry Andric OS << ",";
8157a7e6055SDimitry Andric PB->To->printAsOperand(OS);
8167a7e6055SDimitry Andric OS << "] }\n";
8177a7e6055SDimitry Andric } else if (const auto *PS = dyn_cast<PredicateSwitch>(PI)) {
8187a7e6055SDimitry Andric OS << "; switch predicate info { CaseValue: " << *PS->CaseValue
8197a7e6055SDimitry Andric << " Switch:" << *PS->Switch << " Edge: [";
8207a7e6055SDimitry Andric PS->From->printAsOperand(OS);
8217a7e6055SDimitry Andric OS << ",";
8227a7e6055SDimitry Andric PS->To->printAsOperand(OS);
8237a7e6055SDimitry Andric OS << "] }\n";
8247a7e6055SDimitry Andric } else if (const auto *PA = dyn_cast<PredicateAssume>(PI)) {
8257a7e6055SDimitry Andric OS << "; assume predicate info {"
8267a7e6055SDimitry Andric << " Comparison:" << *PA->Condition << " }\n";
8277a7e6055SDimitry Andric }
8287a7e6055SDimitry Andric }
8297a7e6055SDimitry Andric }
8307a7e6055SDimitry Andric };
8317a7e6055SDimitry Andric
print(raw_ostream & OS) const8327a7e6055SDimitry Andric void PredicateInfo::print(raw_ostream &OS) const {
8337a7e6055SDimitry Andric PredicateInfoAnnotatedWriter Writer(this);
8347a7e6055SDimitry Andric F.print(OS, &Writer);
8357a7e6055SDimitry Andric }
8367a7e6055SDimitry Andric
dump() const8377a7e6055SDimitry Andric void PredicateInfo::dump() const {
8387a7e6055SDimitry Andric PredicateInfoAnnotatedWriter Writer(this);
8397a7e6055SDimitry Andric F.print(dbgs(), &Writer);
8407a7e6055SDimitry Andric }
8417a7e6055SDimitry Andric
run(Function & F,FunctionAnalysisManager & AM)8427a7e6055SDimitry Andric PreservedAnalyses PredicateInfoVerifierPass::run(Function &F,
8437a7e6055SDimitry Andric FunctionAnalysisManager &AM) {
8447a7e6055SDimitry Andric auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
8457a7e6055SDimitry Andric auto &AC = AM.getResult<AssumptionAnalysis>(F);
8467a7e6055SDimitry Andric make_unique<PredicateInfo>(F, DT, AC)->verifyPredicateInfo();
8477a7e6055SDimitry Andric
8487a7e6055SDimitry Andric return PreservedAnalyses::all();
8497a7e6055SDimitry Andric }
8507a7e6055SDimitry Andric }
851