Florian Hahn | 45e5d5b | 2018-06-08 17:30:45 +0000 | [diff] [blame^] | 1 | //===- VPRecipeBuilder.h - Helper class to build recipes --------*- C++ -*-===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | |
| 10 | #ifndef LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H |
| 11 | #define LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H |
| 12 | |
| 13 | #include "LoopVectorizationPlanner.h" |
| 14 | #include "VPlan.h" |
| 15 | #include "llvm/ADT/DenseMap.h" |
| 16 | #include "llvm/IR/IRBuilder.h" |
| 17 | |
| 18 | namespace llvm { |
| 19 | |
| 20 | class LoopVectorizationLegality; |
| 21 | class LoopVectorizationCostModel; |
| 22 | class TargetTransformInfo; |
| 23 | class TargetLibraryInfo; |
| 24 | |
| 25 | /// Helper class to create VPRecipies from IR instructions. |
| 26 | class VPRecipeBuilder { |
| 27 | /// The loop that we evaluate. |
| 28 | Loop *OrigLoop; |
| 29 | |
| 30 | /// Target Library Info. |
| 31 | const TargetLibraryInfo *TLI; |
| 32 | |
| 33 | /// Target Transform Info. |
| 34 | const TargetTransformInfo *TTI; |
| 35 | |
| 36 | /// The legality analysis. |
| 37 | LoopVectorizationLegality *Legal; |
| 38 | |
| 39 | /// The profitablity analysis. |
| 40 | LoopVectorizationCostModel &CM; |
| 41 | |
| 42 | VPBuilder &Builder; |
| 43 | |
| 44 | /// When we if-convert we need to create edge masks. We have to cache values |
| 45 | /// so that we don't end up with exponential recursion/IR. Note that |
| 46 | /// if-conversion currently takes place during VPlan-construction, so these |
| 47 | /// caches are only used at that stage. |
| 48 | using EdgeMaskCacheTy = |
| 49 | DenseMap<std::pair<BasicBlock *, BasicBlock *>, VPValue *>; |
| 50 | using BlockMaskCacheTy = DenseMap<BasicBlock *, VPValue *>; |
| 51 | EdgeMaskCacheTy EdgeMaskCache; |
| 52 | BlockMaskCacheTy BlockMaskCache; |
| 53 | |
| 54 | public: |
| 55 | /// A helper function that computes the predicate of the block BB, assuming |
| 56 | /// that the header block of the loop is set to True. It returns the *entry* |
| 57 | /// mask for the block BB. |
| 58 | VPValue *createBlockInMask(BasicBlock *BB, VPlanPtr &Plan); |
| 59 | |
| 60 | /// A helper function that computes the predicate of the edge between SRC |
| 61 | /// and DST. |
| 62 | VPValue *createEdgeMask(BasicBlock *Src, BasicBlock *Dst, VPlanPtr &Plan); |
| 63 | |
| 64 | /// Check if \I belongs to an Interleave Group within the given VF \p Range, |
| 65 | /// \return true in the first returned value if so and false otherwise. |
| 66 | /// Build a new VPInterleaveGroup Recipe if \I is the primary member of an IG |
| 67 | /// for \p Range.Start, and provide it as the second returned value. |
| 68 | /// Note that if \I is an adjunct member of an IG for \p Range.Start, the |
| 69 | /// \return value is <true, nullptr>, as it is handled by another recipe. |
| 70 | /// \p Range.End may be decreased to ensure same decision from \p Range.Start |
| 71 | /// to \p Range.End. |
| 72 | VPInterleaveRecipe *tryToInterleaveMemory(Instruction *I, VFRange &Range); |
| 73 | |
| 74 | /// Check if \I is a memory instruction to be widened for \p Range.Start and |
| 75 | /// potentially masked. Such instructions are handled by a recipe that takes |
| 76 | /// an additional VPInstruction for the mask. |
| 77 | VPWidenMemoryInstructionRecipe * |
| 78 | tryToWidenMemory(Instruction *I, VFRange &Range, VPlanPtr &Plan); |
| 79 | |
| 80 | /// Check if an induction recipe should be constructed for \I within the given |
| 81 | /// VF \p Range. If so build and return it. If not, return null. \p Range.End |
| 82 | /// may be decreased to ensure same decision from \p Range.Start to |
| 83 | /// \p Range.End. |
| 84 | VPWidenIntOrFpInductionRecipe *tryToOptimizeInduction(Instruction *I, |
| 85 | VFRange &Range); |
| 86 | |
| 87 | /// Handle non-loop phi nodes. Currently all such phi nodes are turned into |
| 88 | /// a sequence of select instructions as the vectorizer currently performs |
| 89 | /// full if-conversion. |
| 90 | VPBlendRecipe *tryToBlend(Instruction *I, VPlanPtr &Plan); |
| 91 | |
| 92 | /// Check if \p I can be widened within the given VF \p Range. If \p I can be |
| 93 | /// widened for \p Range.Start, check if the last recipe of \p VPBB can be |
| 94 | /// extended to include \p I or else build a new VPWidenRecipe for it and |
| 95 | /// append it to \p VPBB. Return true if \p I can be widened for Range.Start, |
| 96 | /// false otherwise. Range.End may be decreased to ensure same decision from |
| 97 | /// \p Range.Start to \p Range.End. |
| 98 | bool tryToWiden(Instruction *I, VPBasicBlock *VPBB, VFRange &Range); |
| 99 | |
| 100 | /// Create a replicating region for instruction \p I that requires |
| 101 | /// predication. \p PredRecipe is a VPReplicateRecipe holding \p I. |
| 102 | VPRegionBlock *createReplicateRegion(Instruction *I, VPRecipeBase *PredRecipe, |
| 103 | VPlanPtr &Plan); |
| 104 | |
| 105 | public: |
| 106 | VPRecipeBuilder(Loop *OrigLoop, const TargetLibraryInfo *TLI, |
| 107 | const TargetTransformInfo *TTI, |
| 108 | LoopVectorizationLegality *Legal, |
| 109 | LoopVectorizationCostModel &CM, VPBuilder &Builder) |
| 110 | : OrigLoop(OrigLoop), TLI(TLI), TTI(TTI), Legal(Legal), CM(CM), |
| 111 | Builder(Builder) {} |
| 112 | |
| 113 | /// Check if a recipe can be create for \p I withing the given VF \p Range. |
| 114 | /// If a recipe can be created, it adds it to \p VPBB. |
| 115 | bool tryToCreateRecipe(Instruction *Instr, VFRange &Range, VPlanPtr &Plan, |
| 116 | VPBasicBlock *VPBB); |
| 117 | |
| 118 | /// Build a VPReplicationRecipe for \p I and enclose it within a Region if it |
| 119 | /// is predicated. \return \p VPBB augmented with this new recipe if \p I is |
| 120 | /// not predicated, otherwise \return a new VPBasicBlock that succeeds the new |
| 121 | /// Region. Update the packing decision of predicated instructions if they |
| 122 | /// feed \p I. Range.End may be decreased to ensure same recipe behavior from |
| 123 | /// \p Range.Start to \p Range.End. |
| 124 | VPBasicBlock *handleReplication( |
| 125 | Instruction *I, VFRange &Range, VPBasicBlock *VPBB, |
| 126 | DenseMap<Instruction *, VPReplicateRecipe *> &PredInst2Recipe, |
| 127 | VPlanPtr &Plan); |
| 128 | }; |
| 129 | } // end namespace llvm |
| 130 | |
| 131 | #endif // LLVM_TRANSFORMS_VECTORIZE_VPRECIPEBUILDER_H |