15ffd83dbSDimitry Andric //===---- llvm/Analysis/ScalarEvolutionExpander.h - SCEV Exprs --*- C++ -*-===// 25ffd83dbSDimitry Andric // 35ffd83dbSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45ffd83dbSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55ffd83dbSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65ffd83dbSDimitry Andric // 75ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 85ffd83dbSDimitry Andric // 95ffd83dbSDimitry Andric // This file defines the classes used to generate code from scalar expressions. 105ffd83dbSDimitry Andric // 115ffd83dbSDimitry Andric //===----------------------------------------------------------------------===// 125ffd83dbSDimitry Andric 13fe6060f1SDimitry Andric #ifndef LLVM_TRANSFORMS_UTILS_SCALAREVOLUTIONEXPANDER_H 14fe6060f1SDimitry Andric #define LLVM_TRANSFORMS_UTILS_SCALAREVOLUTIONEXPANDER_H 155ffd83dbSDimitry Andric 165ffd83dbSDimitry Andric #include "llvm/ADT/DenseMap.h" 175ffd83dbSDimitry Andric #include "llvm/ADT/DenseSet.h" 185ffd83dbSDimitry Andric #include "llvm/ADT/SmallVector.h" 1904eeddc0SDimitry Andric #include "llvm/Analysis/InstSimplifyFolder.h" 205ffd83dbSDimitry Andric #include "llvm/Analysis/ScalarEvolutionExpressions.h" 215ffd83dbSDimitry Andric #include "llvm/Analysis/ScalarEvolutionNormalization.h" 225ffd83dbSDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h" 235ffd83dbSDimitry Andric #include "llvm/IR/IRBuilder.h" 245ffd83dbSDimitry Andric #include "llvm/IR/ValueHandle.h" 255ffd83dbSDimitry Andric #include "llvm/Support/CommandLine.h" 26fe6060f1SDimitry Andric #include "llvm/Support/InstructionCost.h" 275ffd83dbSDimitry Andric 285ffd83dbSDimitry Andric namespace llvm { 295ffd83dbSDimitry Andric extern cl::opt<unsigned> SCEVCheapExpansionBudget; 305ffd83dbSDimitry Andric 31e8d8bef9SDimitry Andric /// struct for holding enough information to help calculate the cost of the 32e8d8bef9SDimitry Andric /// given SCEV when expanded into IR. 33e8d8bef9SDimitry Andric struct SCEVOperand { 34e8d8bef9SDimitry Andric explicit SCEVOperand(unsigned Opc, int Idx, const SCEV *S) : 35e8d8bef9SDimitry Andric ParentOpcode(Opc), OperandIdx(Idx), S(S) { } 36e8d8bef9SDimitry Andric /// LLVM instruction opcode that uses the operand. 37e8d8bef9SDimitry Andric unsigned ParentOpcode; 38e8d8bef9SDimitry Andric /// The use index of an expanded instruction. 39e8d8bef9SDimitry Andric int OperandIdx; 40e8d8bef9SDimitry Andric /// The SCEV operand to be costed. 41e8d8bef9SDimitry Andric const SCEV* S; 42e8d8bef9SDimitry Andric }; 43e8d8bef9SDimitry Andric 44*0fca6ea1SDimitry Andric struct PoisonFlags { 45*0fca6ea1SDimitry Andric unsigned NUW : 1; 46*0fca6ea1SDimitry Andric unsigned NSW : 1; 47*0fca6ea1SDimitry Andric unsigned Exact : 1; 48*0fca6ea1SDimitry Andric unsigned Disjoint : 1; 49*0fca6ea1SDimitry Andric unsigned NNeg : 1; 50*0fca6ea1SDimitry Andric 51*0fca6ea1SDimitry Andric PoisonFlags(const Instruction *I); 52*0fca6ea1SDimitry Andric void apply(Instruction *I); 53*0fca6ea1SDimitry Andric }; 54*0fca6ea1SDimitry Andric 555ffd83dbSDimitry Andric /// This class uses information about analyze scalars to rewrite expressions 565ffd83dbSDimitry Andric /// in canonical form. 575ffd83dbSDimitry Andric /// 585ffd83dbSDimitry Andric /// Clients should create an instance of this class when rewriting is needed, 595ffd83dbSDimitry Andric /// and destroy it when finished to allow the release of the associated 605ffd83dbSDimitry Andric /// memory. 615ffd83dbSDimitry Andric class SCEVExpander : public SCEVVisitor<SCEVExpander, Value *> { 62*0fca6ea1SDimitry Andric friend class SCEVExpanderCleaner; 63*0fca6ea1SDimitry Andric 645ffd83dbSDimitry Andric ScalarEvolution &SE; 655ffd83dbSDimitry Andric const DataLayout &DL; 665ffd83dbSDimitry Andric 675ffd83dbSDimitry Andric // New instructions receive a name to identify them with the current pass. 685ffd83dbSDimitry Andric const char *IVName; 695ffd83dbSDimitry Andric 70e8d8bef9SDimitry Andric /// Indicates whether LCSSA phis should be created for inserted values. 71e8d8bef9SDimitry Andric bool PreserveLCSSA; 72e8d8bef9SDimitry Andric 735ffd83dbSDimitry Andric // InsertedExpressions caches Values for reuse, so must track RAUW. 745ffd83dbSDimitry Andric DenseMap<std::pair<const SCEV *, Instruction *>, TrackingVH<Value>> 755ffd83dbSDimitry Andric InsertedExpressions; 765ffd83dbSDimitry Andric 775ffd83dbSDimitry Andric // InsertedValues only flags inserted instructions so needs no RAUW. 785ffd83dbSDimitry Andric DenseSet<AssertingVH<Value>> InsertedValues; 795ffd83dbSDimitry Andric DenseSet<AssertingVH<Value>> InsertedPostIncValues; 805ffd83dbSDimitry Andric 81e8d8bef9SDimitry Andric /// Keep track of the existing IR values re-used during expansion. 82e8d8bef9SDimitry Andric /// FIXME: Ideally re-used instructions would not be added to 83e8d8bef9SDimitry Andric /// InsertedValues/InsertedPostIncValues. 84e8d8bef9SDimitry Andric SmallPtrSet<Value *, 16> ReusedValues; 85e8d8bef9SDimitry Andric 86*0fca6ea1SDimitry Andric /// Original flags of instructions for which they were modified. Used 87*0fca6ea1SDimitry Andric /// by SCEVExpanderCleaner to undo changes. 88*0fca6ea1SDimitry Andric DenseMap<PoisoningVH<Instruction>, PoisonFlags> OrigFlags; 89*0fca6ea1SDimitry Andric 90fe6060f1SDimitry Andric // The induction variables generated. 91fe6060f1SDimitry Andric SmallVector<WeakVH, 2> InsertedIVs; 92fe6060f1SDimitry Andric 935ffd83dbSDimitry Andric /// A memoization of the "relevant" loop for a given SCEV. 945ffd83dbSDimitry Andric DenseMap<const SCEV *, const Loop *> RelevantLoops; 955ffd83dbSDimitry Andric 965ffd83dbSDimitry Andric /// Addrecs referring to any of the given loops are expanded in post-inc 975ffd83dbSDimitry Andric /// mode. For example, expanding {1,+,1}<L> in post-inc mode returns the add 985ffd83dbSDimitry Andric /// instruction that adds one to the phi for {0,+,1}<L>, as opposed to a new 995ffd83dbSDimitry Andric /// phi starting at 1. This is only supported in non-canonical mode. 1005ffd83dbSDimitry Andric PostIncLoopSet PostIncLoops; 1015ffd83dbSDimitry Andric 1025ffd83dbSDimitry Andric /// When this is non-null, addrecs expanded in the loop it indicates should 1035ffd83dbSDimitry Andric /// be inserted with increments at IVIncInsertPos. 1045ffd83dbSDimitry Andric const Loop *IVIncInsertLoop; 1055ffd83dbSDimitry Andric 1065ffd83dbSDimitry Andric /// When expanding addrecs in the IVIncInsertLoop loop, insert the IV 1075ffd83dbSDimitry Andric /// increment at this position. 1085ffd83dbSDimitry Andric Instruction *IVIncInsertPos; 1095ffd83dbSDimitry Andric 1105ffd83dbSDimitry Andric /// Phis that complete an IV chain. Reuse 1115ffd83dbSDimitry Andric DenseSet<AssertingVH<PHINode>> ChainedPhis; 1125ffd83dbSDimitry Andric 1135ffd83dbSDimitry Andric /// When true, SCEVExpander tries to expand expressions in "canonical" form. 1145ffd83dbSDimitry Andric /// When false, expressions are expanded in a more literal form. 1155ffd83dbSDimitry Andric /// 1165ffd83dbSDimitry Andric /// In "canonical" form addrecs are expanded as arithmetic based on a 1175ffd83dbSDimitry Andric /// canonical induction variable. Note that CanonicalMode doesn't guarantee 1185ffd83dbSDimitry Andric /// that all expressions are expanded in "canonical" form. For some 1195ffd83dbSDimitry Andric /// expressions literal mode can be preferred. 1205ffd83dbSDimitry Andric bool CanonicalMode; 1215ffd83dbSDimitry Andric 1225ffd83dbSDimitry Andric /// When invoked from LSR, the expander is in "strength reduction" mode. The 1235ffd83dbSDimitry Andric /// only difference is that phi's are only reused if they are already in 1245ffd83dbSDimitry Andric /// "expanded" form. 1255ffd83dbSDimitry Andric bool LSRMode; 1265ffd83dbSDimitry Andric 12704eeddc0SDimitry Andric typedef IRBuilder<InstSimplifyFolder, IRBuilderCallbackInserter> BuilderType; 1285ffd83dbSDimitry Andric BuilderType Builder; 1295ffd83dbSDimitry Andric 1305ffd83dbSDimitry Andric // RAII object that stores the current insertion point and restores it when 1315ffd83dbSDimitry Andric // the object is destroyed. This includes the debug location. Duplicated 1325ffd83dbSDimitry Andric // from InsertPointGuard to add SetInsertPoint() which is used to updated 1335ffd83dbSDimitry Andric // InsertPointGuards stack when insert points are moved during SCEV 1345ffd83dbSDimitry Andric // expansion. 1355ffd83dbSDimitry Andric class SCEVInsertPointGuard { 1365ffd83dbSDimitry Andric IRBuilderBase &Builder; 1375ffd83dbSDimitry Andric AssertingVH<BasicBlock> Block; 1385ffd83dbSDimitry Andric BasicBlock::iterator Point; 1395ffd83dbSDimitry Andric DebugLoc DbgLoc; 1405ffd83dbSDimitry Andric SCEVExpander *SE; 1415ffd83dbSDimitry Andric 1425ffd83dbSDimitry Andric SCEVInsertPointGuard(const SCEVInsertPointGuard &) = delete; 1435ffd83dbSDimitry Andric SCEVInsertPointGuard &operator=(const SCEVInsertPointGuard &) = delete; 1445ffd83dbSDimitry Andric 1455ffd83dbSDimitry Andric public: 1465ffd83dbSDimitry Andric SCEVInsertPointGuard(IRBuilderBase &B, SCEVExpander *SE) 1475ffd83dbSDimitry Andric : Builder(B), Block(B.GetInsertBlock()), Point(B.GetInsertPoint()), 1485ffd83dbSDimitry Andric DbgLoc(B.getCurrentDebugLocation()), SE(SE) { 1495ffd83dbSDimitry Andric SE->InsertPointGuards.push_back(this); 1505ffd83dbSDimitry Andric } 1515ffd83dbSDimitry Andric 1525ffd83dbSDimitry Andric ~SCEVInsertPointGuard() { 1535ffd83dbSDimitry Andric // These guards should always created/destroyed in FIFO order since they 1545ffd83dbSDimitry Andric // are used to guard lexically scoped blocks of code in 1555ffd83dbSDimitry Andric // ScalarEvolutionExpander. 1565ffd83dbSDimitry Andric assert(SE->InsertPointGuards.back() == this); 1575ffd83dbSDimitry Andric SE->InsertPointGuards.pop_back(); 1585ffd83dbSDimitry Andric Builder.restoreIP(IRBuilderBase::InsertPoint(Block, Point)); 1595ffd83dbSDimitry Andric Builder.SetCurrentDebugLocation(DbgLoc); 1605ffd83dbSDimitry Andric } 1615ffd83dbSDimitry Andric 1625ffd83dbSDimitry Andric BasicBlock::iterator GetInsertPoint() const { return Point; } 1635ffd83dbSDimitry Andric void SetInsertPoint(BasicBlock::iterator I) { Point = I; } 1645ffd83dbSDimitry Andric }; 1655ffd83dbSDimitry Andric 1665ffd83dbSDimitry Andric /// Stack of pointers to saved insert points, used to keep insert points 1675ffd83dbSDimitry Andric /// consistent when instructions are moved. 1685ffd83dbSDimitry Andric SmallVector<SCEVInsertPointGuard *, 8> InsertPointGuards; 1695ffd83dbSDimitry Andric 170fe6060f1SDimitry Andric #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS 1715ffd83dbSDimitry Andric const char *DebugType; 1725ffd83dbSDimitry Andric #endif 1735ffd83dbSDimitry Andric 1745ffd83dbSDimitry Andric friend struct SCEVVisitor<SCEVExpander, Value *>; 1755ffd83dbSDimitry Andric 1765ffd83dbSDimitry Andric public: 1775ffd83dbSDimitry Andric /// Construct a SCEVExpander in "canonical" mode. 1785ffd83dbSDimitry Andric explicit SCEVExpander(ScalarEvolution &se, const DataLayout &DL, 179e8d8bef9SDimitry Andric const char *name, bool PreserveLCSSA = true) 180e8d8bef9SDimitry Andric : SE(se), DL(DL), IVName(name), PreserveLCSSA(PreserveLCSSA), 181e8d8bef9SDimitry Andric IVIncInsertLoop(nullptr), IVIncInsertPos(nullptr), CanonicalMode(true), 182e8d8bef9SDimitry Andric LSRMode(false), 18304eeddc0SDimitry Andric Builder(se.getContext(), InstSimplifyFolder(DL), 184e8d8bef9SDimitry Andric IRBuilderCallbackInserter( 185e8d8bef9SDimitry Andric [this](Instruction *I) { rememberInstruction(I); })) { 186fe6060f1SDimitry Andric #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS 1875ffd83dbSDimitry Andric DebugType = ""; 1885ffd83dbSDimitry Andric #endif 1895ffd83dbSDimitry Andric } 1905ffd83dbSDimitry Andric 1915ffd83dbSDimitry Andric ~SCEVExpander() { 1925ffd83dbSDimitry Andric // Make sure the insert point guard stack is consistent. 1935ffd83dbSDimitry Andric assert(InsertPointGuards.empty()); 1945ffd83dbSDimitry Andric } 1955ffd83dbSDimitry Andric 196fe6060f1SDimitry Andric #ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS 1975ffd83dbSDimitry Andric void setDebugType(const char *s) { DebugType = s; } 1985ffd83dbSDimitry Andric #endif 1995ffd83dbSDimitry Andric 2005ffd83dbSDimitry Andric /// Erase the contents of the InsertedExpressions map so that users trying 2015ffd83dbSDimitry Andric /// to expand the same expression into multiple BasicBlocks or different 2025ffd83dbSDimitry Andric /// places within the same BasicBlock can do so. 2035ffd83dbSDimitry Andric void clear() { 2045ffd83dbSDimitry Andric InsertedExpressions.clear(); 2055ffd83dbSDimitry Andric InsertedValues.clear(); 2065ffd83dbSDimitry Andric InsertedPostIncValues.clear(); 207e8d8bef9SDimitry Andric ReusedValues.clear(); 208*0fca6ea1SDimitry Andric OrigFlags.clear(); 2095ffd83dbSDimitry Andric ChainedPhis.clear(); 210fe6060f1SDimitry Andric InsertedIVs.clear(); 2115ffd83dbSDimitry Andric } 2125ffd83dbSDimitry Andric 213fe6060f1SDimitry Andric ScalarEvolution *getSE() { return &SE; } 214fe6060f1SDimitry Andric const SmallVectorImpl<WeakVH> &getInsertedIVs() const { return InsertedIVs; } 215fe6060f1SDimitry Andric 216e8d8bef9SDimitry Andric /// Return a vector containing all instructions inserted during expansion. 217e8d8bef9SDimitry Andric SmallVector<Instruction *, 32> getAllInsertedInstructions() const { 218e8d8bef9SDimitry Andric SmallVector<Instruction *, 32> Result; 219bdd1243dSDimitry Andric for (const auto &VH : InsertedValues) { 220e8d8bef9SDimitry Andric Value *V = VH; 221e8d8bef9SDimitry Andric if (ReusedValues.contains(V)) 222e8d8bef9SDimitry Andric continue; 223e8d8bef9SDimitry Andric if (auto *Inst = dyn_cast<Instruction>(V)) 224e8d8bef9SDimitry Andric Result.push_back(Inst); 225e8d8bef9SDimitry Andric } 226bdd1243dSDimitry Andric for (const auto &VH : InsertedPostIncValues) { 227e8d8bef9SDimitry Andric Value *V = VH; 228e8d8bef9SDimitry Andric if (ReusedValues.contains(V)) 229e8d8bef9SDimitry Andric continue; 230e8d8bef9SDimitry Andric if (auto *Inst = dyn_cast<Instruction>(V)) 231e8d8bef9SDimitry Andric Result.push_back(Inst); 232e8d8bef9SDimitry Andric } 233e8d8bef9SDimitry Andric 234e8d8bef9SDimitry Andric return Result; 235e8d8bef9SDimitry Andric } 236e8d8bef9SDimitry Andric 2375ffd83dbSDimitry Andric /// Return true for expressions that can't be evaluated at runtime 2385ffd83dbSDimitry Andric /// within given \b Budget. 2395ffd83dbSDimitry Andric /// 240bdd1243dSDimitry Andric /// \p At is a parameter which specifies point in code where user is going to 241bdd1243dSDimitry Andric /// expand these expressions. Sometimes this knowledge can lead to 2425ffd83dbSDimitry Andric /// a less pessimistic cost estimation. 243bdd1243dSDimitry Andric bool isHighCostExpansion(ArrayRef<const SCEV *> Exprs, Loop *L, 244bdd1243dSDimitry Andric unsigned Budget, const TargetTransformInfo *TTI, 2455ffd83dbSDimitry Andric const Instruction *At) { 2465ffd83dbSDimitry Andric assert(TTI && "This function requires TTI to be provided."); 2475ffd83dbSDimitry Andric assert(At && "This function requires At instruction to be provided."); 2485ffd83dbSDimitry Andric if (!TTI) // In assert-less builds, avoid crashing 2495ffd83dbSDimitry Andric return true; // by always claiming to be high-cost. 250e8d8bef9SDimitry Andric SmallVector<SCEVOperand, 8> Worklist; 2515ffd83dbSDimitry Andric SmallPtrSet<const SCEV *, 8> Processed; 252fe6060f1SDimitry Andric InstructionCost Cost = 0; 253fe6060f1SDimitry Andric unsigned ScaledBudget = Budget * TargetTransformInfo::TCC_Basic; 254bdd1243dSDimitry Andric for (auto *Expr : Exprs) 255e8d8bef9SDimitry Andric Worklist.emplace_back(-1, -1, Expr); 2565ffd83dbSDimitry Andric while (!Worklist.empty()) { 257e8d8bef9SDimitry Andric const SCEVOperand WorkItem = Worklist.pop_back_val(); 258fe6060f1SDimitry Andric if (isHighCostExpansionHelper(WorkItem, L, *At, Cost, ScaledBudget, *TTI, 259fe6060f1SDimitry Andric Processed, Worklist)) 2605ffd83dbSDimitry Andric return true; 2615ffd83dbSDimitry Andric } 262fe6060f1SDimitry Andric assert(Cost <= ScaledBudget && "Should have returned from inner loop."); 2635ffd83dbSDimitry Andric return false; 2645ffd83dbSDimitry Andric } 2655ffd83dbSDimitry Andric 2665ffd83dbSDimitry Andric /// Return the induction variable increment's IV operand. 2675ffd83dbSDimitry Andric Instruction *getIVIncOperand(Instruction *IncV, Instruction *InsertPos, 2685ffd83dbSDimitry Andric bool allowScale); 2695ffd83dbSDimitry Andric 270bdd1243dSDimitry Andric /// Utility for hoisting \p IncV (with all subexpressions requried for its 271bdd1243dSDimitry Andric /// computation) before \p InsertPos. If \p RecomputePoisonFlags is set, drops 272bdd1243dSDimitry Andric /// all poison-generating flags from instructions being hoisted and tries to 273bdd1243dSDimitry Andric /// re-infer them in the new location. It should be used when we are going to 274bdd1243dSDimitry Andric /// introduce a new use in the new position that didn't exist before, and may 275bdd1243dSDimitry Andric /// trigger new UB in case of poison. 276bdd1243dSDimitry Andric bool hoistIVInc(Instruction *IncV, Instruction *InsertPos, 277bdd1243dSDimitry Andric bool RecomputePoisonFlags = false); 2785ffd83dbSDimitry Andric 279*0fca6ea1SDimitry Andric /// Return true if both increments directly increment the corresponding IV PHI 280*0fca6ea1SDimitry Andric /// nodes and have the same opcode. It is not safe to re-use the flags from 281*0fca6ea1SDimitry Andric /// the original increment, if it is more complex and SCEV expansion may have 282*0fca6ea1SDimitry Andric /// yielded a more simplified wider increment. 283*0fca6ea1SDimitry Andric static bool canReuseFlagsFromOriginalIVInc(PHINode *OrigPhi, PHINode *WidePhi, 284*0fca6ea1SDimitry Andric Instruction *OrigInc, 285*0fca6ea1SDimitry Andric Instruction *WideInc); 286*0fca6ea1SDimitry Andric 2875ffd83dbSDimitry Andric /// replace congruent phis with their most canonical representative. Return 2885ffd83dbSDimitry Andric /// the number of phis eliminated. 2895ffd83dbSDimitry Andric unsigned replaceCongruentIVs(Loop *L, const DominatorTree *DT, 2905ffd83dbSDimitry Andric SmallVectorImpl<WeakTrackingVH> &DeadInsts, 2915ffd83dbSDimitry Andric const TargetTransformInfo *TTI = nullptr); 2925ffd83dbSDimitry Andric 293fcaf7f86SDimitry Andric /// Return true if the given expression is safe to expand in the sense that 294fcaf7f86SDimitry Andric /// all materialized values are safe to speculate anywhere their operands are 295fcaf7f86SDimitry Andric /// defined, and the expander is capable of expanding the expression. 296fcaf7f86SDimitry Andric bool isSafeToExpand(const SCEV *S) const; 297fcaf7f86SDimitry Andric 298fcaf7f86SDimitry Andric /// Return true if the given expression is safe to expand in the sense that 299fcaf7f86SDimitry Andric /// all materialized values are defined and safe to speculate at the specified 300fcaf7f86SDimitry Andric /// location and their operands are defined at this location. 301fcaf7f86SDimitry Andric bool isSafeToExpandAt(const SCEV *S, const Instruction *InsertionPoint) const; 302fcaf7f86SDimitry Andric 3035ffd83dbSDimitry Andric /// Insert code to directly compute the specified SCEV expression into the 304e8d8bef9SDimitry Andric /// program. The code is inserted into the specified block. 3055f757f3fSDimitry Andric Value *expandCodeFor(const SCEV *SH, Type *Ty, BasicBlock::iterator I); 306e8d8bef9SDimitry Andric Value *expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I) { 3075f757f3fSDimitry Andric return expandCodeFor(SH, Ty, I->getIterator()); 308e8d8bef9SDimitry Andric } 3095ffd83dbSDimitry Andric 3105ffd83dbSDimitry Andric /// Insert code to directly compute the specified SCEV expression into the 311e8d8bef9SDimitry Andric /// program. The code is inserted into the SCEVExpander's current 3125ffd83dbSDimitry Andric /// insertion point. If a type is specified, the result will be expanded to 3135ffd83dbSDimitry Andric /// have that type, with a cast if necessary. 3145f757f3fSDimitry Andric Value *expandCodeFor(const SCEV *SH, Type *Ty = nullptr); 3155ffd83dbSDimitry Andric 3165ffd83dbSDimitry Andric /// Generates a code sequence that evaluates this predicate. The inserted 3175ffd83dbSDimitry Andric /// instructions will be at position \p Loc. The result will be of type i1 3185ffd83dbSDimitry Andric /// and will have a value of 0 when the predicate is false and 1 otherwise. 3195ffd83dbSDimitry Andric Value *expandCodeForPredicate(const SCEVPredicate *Pred, Instruction *Loc); 3205ffd83dbSDimitry Andric 3215ffd83dbSDimitry Andric /// A specialized variant of expandCodeForPredicate, handling the case when 32281ad6265SDimitry Andric /// we are expanding code for a SCEVComparePredicate. 32381ad6265SDimitry Andric Value *expandComparePredicate(const SCEVComparePredicate *Pred, 32481ad6265SDimitry Andric Instruction *Loc); 3255ffd83dbSDimitry Andric 3265ffd83dbSDimitry Andric /// Generates code that evaluates if the \p AR expression will overflow. 3275ffd83dbSDimitry Andric Value *generateOverflowCheck(const SCEVAddRecExpr *AR, Instruction *Loc, 3285ffd83dbSDimitry Andric bool Signed); 3295ffd83dbSDimitry Andric 3305ffd83dbSDimitry Andric /// A specialized variant of expandCodeForPredicate, handling the case when 3315ffd83dbSDimitry Andric /// we are expanding code for a SCEVWrapPredicate. 3325ffd83dbSDimitry Andric Value *expandWrapPredicate(const SCEVWrapPredicate *P, Instruction *Loc); 3335ffd83dbSDimitry Andric 3345ffd83dbSDimitry Andric /// A specialized variant of expandCodeForPredicate, handling the case when 3355ffd83dbSDimitry Andric /// we are expanding code for a SCEVUnionPredicate. 336e8d8bef9SDimitry Andric Value *expandUnionPredicate(const SCEVUnionPredicate *Pred, Instruction *Loc); 3375ffd83dbSDimitry Andric 3385ffd83dbSDimitry Andric /// Set the current IV increment loop and position. 3395ffd83dbSDimitry Andric void setIVIncInsertPos(const Loop *L, Instruction *Pos) { 3405ffd83dbSDimitry Andric assert(!CanonicalMode && 3415ffd83dbSDimitry Andric "IV increment positions are not supported in CanonicalMode"); 3425ffd83dbSDimitry Andric IVIncInsertLoop = L; 3435ffd83dbSDimitry Andric IVIncInsertPos = Pos; 3445ffd83dbSDimitry Andric } 3455ffd83dbSDimitry Andric 3465ffd83dbSDimitry Andric /// Enable post-inc expansion for addrecs referring to the given 3475ffd83dbSDimitry Andric /// loops. Post-inc expansion is only supported in non-canonical mode. 3485ffd83dbSDimitry Andric void setPostInc(const PostIncLoopSet &L) { 3495ffd83dbSDimitry Andric assert(!CanonicalMode && 3505ffd83dbSDimitry Andric "Post-inc expansion is not supported in CanonicalMode"); 3515ffd83dbSDimitry Andric PostIncLoops = L; 3525ffd83dbSDimitry Andric } 3535ffd83dbSDimitry Andric 3545ffd83dbSDimitry Andric /// Disable all post-inc expansion. 3555ffd83dbSDimitry Andric void clearPostInc() { 3565ffd83dbSDimitry Andric PostIncLoops.clear(); 3575ffd83dbSDimitry Andric 3585ffd83dbSDimitry Andric // When we change the post-inc loop set, cached expansions may no 3595ffd83dbSDimitry Andric // longer be valid. 3605ffd83dbSDimitry Andric InsertedPostIncValues.clear(); 3615ffd83dbSDimitry Andric } 3625ffd83dbSDimitry Andric 3635ffd83dbSDimitry Andric /// Disable the behavior of expanding expressions in canonical form rather 3645ffd83dbSDimitry Andric /// than in a more literal form. Non-canonical mode is useful for late 3655ffd83dbSDimitry Andric /// optimization passes. 3665ffd83dbSDimitry Andric void disableCanonicalMode() { CanonicalMode = false; } 3675ffd83dbSDimitry Andric 3685ffd83dbSDimitry Andric void enableLSRMode() { LSRMode = true; } 3695ffd83dbSDimitry Andric 3705ffd83dbSDimitry Andric /// Set the current insertion point. This is useful if multiple calls to 3715ffd83dbSDimitry Andric /// expandCodeFor() are going to be made with the same insert point and the 3725ffd83dbSDimitry Andric /// insert point may be moved during one of the expansions (e.g. if the 3735ffd83dbSDimitry Andric /// insert point is not a block terminator). 3745ffd83dbSDimitry Andric void setInsertPoint(Instruction *IP) { 3755ffd83dbSDimitry Andric assert(IP); 3765ffd83dbSDimitry Andric Builder.SetInsertPoint(IP); 3775ffd83dbSDimitry Andric } 3785ffd83dbSDimitry Andric 3795f757f3fSDimitry Andric void setInsertPoint(BasicBlock::iterator IP) { 3805f757f3fSDimitry Andric Builder.SetInsertPoint(IP->getParent(), IP); 3815f757f3fSDimitry Andric } 3825f757f3fSDimitry Andric 3835ffd83dbSDimitry Andric /// Clear the current insertion point. This is useful if the instruction 3845ffd83dbSDimitry Andric /// that had been serving as the insertion point may have been deleted. 3855ffd83dbSDimitry Andric void clearInsertPoint() { Builder.ClearInsertionPoint(); } 3865ffd83dbSDimitry Andric 3875ffd83dbSDimitry Andric /// Set location information used by debugging information. 3885ffd83dbSDimitry Andric void SetCurrentDebugLocation(DebugLoc L) { 3895ffd83dbSDimitry Andric Builder.SetCurrentDebugLocation(std::move(L)); 3905ffd83dbSDimitry Andric } 3915ffd83dbSDimitry Andric 3925ffd83dbSDimitry Andric /// Get location information used by debugging information. 393e8d8bef9SDimitry Andric DebugLoc getCurrentDebugLocation() const { 3945ffd83dbSDimitry Andric return Builder.getCurrentDebugLocation(); 3955ffd83dbSDimitry Andric } 3965ffd83dbSDimitry Andric 3975ffd83dbSDimitry Andric /// Return true if the specified instruction was inserted by the code 398e8d8bef9SDimitry Andric /// rewriter. If so, the client should not modify the instruction. Note that 399e8d8bef9SDimitry Andric /// this also includes instructions re-used during expansion. 4005ffd83dbSDimitry Andric bool isInsertedInstruction(Instruction *I) const { 4015ffd83dbSDimitry Andric return InsertedValues.count(I) || InsertedPostIncValues.count(I); 4025ffd83dbSDimitry Andric } 4035ffd83dbSDimitry Andric 4045ffd83dbSDimitry Andric void setChainedPhi(PHINode *PN) { ChainedPhis.insert(PN); } 4055ffd83dbSDimitry Andric 4065f757f3fSDimitry Andric /// Determine whether there is an existing expansion of S that can be reused. 4075f757f3fSDimitry Andric /// This is used to check whether S can be expanded cheaply. 4085ffd83dbSDimitry Andric /// 4095ffd83dbSDimitry Andric /// L is a hint which tells in which loop to look for the suitable value. 4105ffd83dbSDimitry Andric /// 4115ffd83dbSDimitry Andric /// Note that this function does not perform an exhaustive search. I.e if it 4125ffd83dbSDimitry Andric /// didn't find any value it does not mean that there is no such value. 4135f757f3fSDimitry Andric bool hasRelatedExistingExpansion(const SCEV *S, const Instruction *At, 41481ad6265SDimitry Andric Loop *L); 4155ffd83dbSDimitry Andric 416e8d8bef9SDimitry Andric /// Returns a suitable insert point after \p I, that dominates \p 417e8d8bef9SDimitry Andric /// MustDominate. Skips instructions inserted by the expander. 418e8d8bef9SDimitry Andric BasicBlock::iterator findInsertPointAfter(Instruction *I, 419fe6060f1SDimitry Andric Instruction *MustDominate) const; 420e8d8bef9SDimitry Andric 4215ffd83dbSDimitry Andric private: 4225ffd83dbSDimitry Andric LLVMContext &getContext() const { return SE.getContext(); } 4235ffd83dbSDimitry Andric 4245ffd83dbSDimitry Andric /// Recursive helper function for isHighCostExpansion. 425fe6060f1SDimitry Andric bool isHighCostExpansionHelper(const SCEVOperand &WorkItem, Loop *L, 426fe6060f1SDimitry Andric const Instruction &At, InstructionCost &Cost, 427fe6060f1SDimitry Andric unsigned Budget, 428fe6060f1SDimitry Andric const TargetTransformInfo &TTI, 4295ffd83dbSDimitry Andric SmallPtrSetImpl<const SCEV *> &Processed, 430e8d8bef9SDimitry Andric SmallVectorImpl<SCEVOperand> &Worklist); 4315ffd83dbSDimitry Andric 4325ffd83dbSDimitry Andric /// Insert the specified binary operator, doing a small amount of work to 4335ffd83dbSDimitry Andric /// avoid inserting an obviously redundant operation, and hoisting to an 4345ffd83dbSDimitry Andric /// outer loop when the opportunity is there and it is safe. 4355ffd83dbSDimitry Andric Value *InsertBinop(Instruction::BinaryOps Opcode, Value *LHS, Value *RHS, 4365ffd83dbSDimitry Andric SCEV::NoWrapFlags Flags, bool IsSafeToHoist); 4375ffd83dbSDimitry Andric 438fe6060f1SDimitry Andric /// We want to cast \p V. What would be the best place for such a cast? 439fe6060f1SDimitry Andric BasicBlock::iterator GetOptimalInsertionPointForCastOf(Value *V) const; 440fe6060f1SDimitry Andric 4415ffd83dbSDimitry Andric /// Arrange for there to be a cast of V to Ty at IP, reusing an existing 4425ffd83dbSDimitry Andric /// cast if a suitable one exists, moving an existing cast if a suitable one 4435ffd83dbSDimitry Andric /// exists but isn't in the right place, or creating a new one. 444e8d8bef9SDimitry Andric Value *ReuseOrCreateCast(Value *V, Type *Ty, Instruction::CastOps Op, 4455ffd83dbSDimitry Andric BasicBlock::iterator IP); 4465ffd83dbSDimitry Andric 4475ffd83dbSDimitry Andric /// Insert a cast of V to the specified type, which must be possible with a 4485ffd83dbSDimitry Andric /// noop cast, doing what we can to share the casts. 4495ffd83dbSDimitry Andric Value *InsertNoopCastOfTo(Value *V, Type *Ty); 4505ffd83dbSDimitry Andric 4515ffd83dbSDimitry Andric /// Expand a SCEVAddExpr with a pointer type into a GEP instead of using 4525ffd83dbSDimitry Andric /// ptrtoint+arithmetic+inttoptr. 4535f757f3fSDimitry Andric Value *expandAddToGEP(const SCEV *Op, Value *V); 4545ffd83dbSDimitry Andric 4555ffd83dbSDimitry Andric /// Find a previous Value in ExprValueMap for expand. 4565f757f3fSDimitry Andric /// DropPoisonGeneratingInsts is populated with instructions for which 4575f757f3fSDimitry Andric /// poison-generating flags must be dropped if the value is reused. 4585f757f3fSDimitry Andric Value *FindValueInExprValueMap( 4595f757f3fSDimitry Andric const SCEV *S, const Instruction *InsertPt, 4605f757f3fSDimitry Andric SmallVectorImpl<Instruction *> &DropPoisonGeneratingInsts); 4615ffd83dbSDimitry Andric 4625ffd83dbSDimitry Andric Value *expand(const SCEV *S); 4635f757f3fSDimitry Andric Value *expand(const SCEV *S, BasicBlock::iterator I) { 4645f757f3fSDimitry Andric setInsertPoint(I); 4655f757f3fSDimitry Andric return expand(S); 4665f757f3fSDimitry Andric } 4675f757f3fSDimitry Andric Value *expand(const SCEV *S, Instruction *I) { 4685f757f3fSDimitry Andric setInsertPoint(I); 4695f757f3fSDimitry Andric return expand(S); 4705f757f3fSDimitry Andric } 4715ffd83dbSDimitry Andric 4725ffd83dbSDimitry Andric /// Determine the most "relevant" loop for the given SCEV. 4735ffd83dbSDimitry Andric const Loop *getRelevantLoop(const SCEV *); 4745ffd83dbSDimitry Andric 47581ad6265SDimitry Andric Value *expandMinMaxExpr(const SCEVNAryExpr *S, Intrinsic::ID IntrinID, 47681ad6265SDimitry Andric Twine Name, bool IsSequential = false); 47704eeddc0SDimitry Andric 478e8d8bef9SDimitry Andric Value *visitConstant(const SCEVConstant *S) { return S->getValue(); } 479e8d8bef9SDimitry Andric 48006c3fb27SDimitry Andric Value *visitVScale(const SCEVVScale *S); 48106c3fb27SDimitry Andric 482e8d8bef9SDimitry Andric Value *visitPtrToIntExpr(const SCEVPtrToIntExpr *S); 4835ffd83dbSDimitry Andric 4845ffd83dbSDimitry Andric Value *visitTruncateExpr(const SCEVTruncateExpr *S); 4855ffd83dbSDimitry Andric 4865ffd83dbSDimitry Andric Value *visitZeroExtendExpr(const SCEVZeroExtendExpr *S); 4875ffd83dbSDimitry Andric 4885ffd83dbSDimitry Andric Value *visitSignExtendExpr(const SCEVSignExtendExpr *S); 4895ffd83dbSDimitry Andric 4905ffd83dbSDimitry Andric Value *visitAddExpr(const SCEVAddExpr *S); 4915ffd83dbSDimitry Andric 4925ffd83dbSDimitry Andric Value *visitMulExpr(const SCEVMulExpr *S); 4935ffd83dbSDimitry Andric 4945ffd83dbSDimitry Andric Value *visitUDivExpr(const SCEVUDivExpr *S); 4955ffd83dbSDimitry Andric 4965ffd83dbSDimitry Andric Value *visitAddRecExpr(const SCEVAddRecExpr *S); 4975ffd83dbSDimitry Andric 4985ffd83dbSDimitry Andric Value *visitSMaxExpr(const SCEVSMaxExpr *S); 4995ffd83dbSDimitry Andric 5005ffd83dbSDimitry Andric Value *visitUMaxExpr(const SCEVUMaxExpr *S); 5015ffd83dbSDimitry Andric 5025ffd83dbSDimitry Andric Value *visitSMinExpr(const SCEVSMinExpr *S); 5035ffd83dbSDimitry Andric 5045ffd83dbSDimitry Andric Value *visitUMinExpr(const SCEVUMinExpr *S); 5055ffd83dbSDimitry Andric 50604eeddc0SDimitry Andric Value *visitSequentialUMinExpr(const SCEVSequentialUMinExpr *S); 50704eeddc0SDimitry Andric 508e8d8bef9SDimitry Andric Value *visitUnknown(const SCEVUnknown *S) { return S->getValue(); } 5095ffd83dbSDimitry Andric 5105ffd83dbSDimitry Andric void rememberInstruction(Value *I); 5115ffd83dbSDimitry Andric 512*0fca6ea1SDimitry Andric void rememberFlags(Instruction *I); 513*0fca6ea1SDimitry Andric 5145ffd83dbSDimitry Andric bool isNormalAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L); 5155ffd83dbSDimitry Andric 5165ffd83dbSDimitry Andric bool isExpandedAddRecExprPHI(PHINode *PN, Instruction *IncV, const Loop *L); 5175ffd83dbSDimitry Andric 5185ffd83dbSDimitry Andric Value *expandAddRecExprLiterally(const SCEVAddRecExpr *); 5195ffd83dbSDimitry Andric PHINode *getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, 5205f757f3fSDimitry Andric const Loop *L, Type *&TruncTy, 5215f757f3fSDimitry Andric bool &InvertStep); 5225f757f3fSDimitry Andric Value *expandIVInc(PHINode *PN, Value *StepV, const Loop *L, 5235f757f3fSDimitry Andric bool useSubtract); 5245ffd83dbSDimitry Andric 5255ffd83dbSDimitry Andric void fixupInsertPoints(Instruction *I); 526e8d8bef9SDimitry Andric 527bdd1243dSDimitry Andric /// Create LCSSA PHIs for \p V, if it is required for uses at the Builder's 528bdd1243dSDimitry Andric /// current insertion point. 529bdd1243dSDimitry Andric Value *fixupLCSSAFormFor(Value *V); 530*0fca6ea1SDimitry Andric 531*0fca6ea1SDimitry Andric /// Replace congruent phi increments with their most canonical representative. 532*0fca6ea1SDimitry Andric /// May swap \p Phi and \p OrigPhi, if \p Phi is more canonical, due to its 533*0fca6ea1SDimitry Andric /// increment. 534*0fca6ea1SDimitry Andric void replaceCongruentIVInc(PHINode *&Phi, PHINode *&OrigPhi, Loop *L, 535*0fca6ea1SDimitry Andric const DominatorTree *DT, 536*0fca6ea1SDimitry Andric SmallVectorImpl<WeakTrackingVH> &DeadInsts); 5375ffd83dbSDimitry Andric }; 538e8d8bef9SDimitry Andric 539e8d8bef9SDimitry Andric /// Helper to remove instructions inserted during SCEV expansion, unless they 540e8d8bef9SDimitry Andric /// are marked as used. 541e8d8bef9SDimitry Andric class SCEVExpanderCleaner { 542e8d8bef9SDimitry Andric SCEVExpander &Expander; 543e8d8bef9SDimitry Andric 544e8d8bef9SDimitry Andric /// Indicates whether the result of the expansion is used. If false, the 545e8d8bef9SDimitry Andric /// instructions added during expansion are removed. 546e8d8bef9SDimitry Andric bool ResultUsed; 547e8d8bef9SDimitry Andric 548e8d8bef9SDimitry Andric public: 54904eeddc0SDimitry Andric SCEVExpanderCleaner(SCEVExpander &Expander) 55004eeddc0SDimitry Andric : Expander(Expander), ResultUsed(false) {} 551e8d8bef9SDimitry Andric 552fe6060f1SDimitry Andric ~SCEVExpanderCleaner() { cleanup(); } 553e8d8bef9SDimitry Andric 554e8d8bef9SDimitry Andric /// Indicate that the result of the expansion is used. 555e8d8bef9SDimitry Andric void markResultUsed() { ResultUsed = true; } 556fe6060f1SDimitry Andric 557fe6060f1SDimitry Andric void cleanup(); 558e8d8bef9SDimitry Andric }; 559e8d8bef9SDimitry Andric } // namespace llvm 5605ffd83dbSDimitry Andric 5615ffd83dbSDimitry Andric #endif 562