1 //===- LoopVectorize.h ------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This is the LLVM loop vectorizer. This pass modifies 'vectorizable' loops 10 // and generates target-independent LLVM-IR. 11 // The vectorizer uses the TargetTransformInfo analysis to estimate the costs 12 // of instructions in order to estimate the profitability of vectorization. 13 // 14 // The loop vectorizer combines consecutive loop iterations into a single 15 // 'wide' iteration. After this transformation the index is incremented 16 // by the SIMD vector width, and not by one. 17 // 18 // This pass has four parts: 19 // 1. The main loop pass that drives the different parts. 20 // 2. LoopVectorizationLegality - A unit that checks for the legality 21 // of the vectorization. 22 // 3. InnerLoopVectorizer - A unit that performs the actual 23 // widening of instructions. 24 // 4. LoopVectorizationCostModel - A unit that checks for the profitability 25 // of vectorization. It decides on the optimal vector width, which 26 // can be one, if vectorization is not profitable. 27 // 28 // There is a development effort going on to migrate loop vectorizer to the 29 // VPlan infrastructure and to introduce outer loop vectorization support (see 30 // docs/VectorizationPlan.rst and 31 // http://lists.llvm.org/pipermail/llvm-dev/2017-December/119523.html). For this 32 // purpose, we temporarily introduced the VPlan-native vectorization path: an 33 // alternative vectorization path that is natively implemented on top of the 34 // VPlan infrastructure. See EnableVPlanNativePath for enabling. 35 // 36 //===----------------------------------------------------------------------===// 37 // 38 // The reduction-variable vectorization is based on the paper: 39 // D. Nuzman and R. Henderson. Multi-platform Auto-vectorization. 40 // 41 // Variable uniformity checks are inspired by: 42 // Karrenberg, R. and Hack, S. Whole Function Vectorization. 43 // 44 // The interleaved access vectorization is based on the paper: 45 // Dorit Nuzman, Ira Rosen and Ayal Zaks. Auto-Vectorization of Interleaved 46 // Data for SIMD 47 // 48 // Other ideas/concepts are from: 49 // A. Zaks and D. Nuzman. Autovectorization in GCC-two years later. 50 // 51 // S. Maleki, Y. Gao, M. Garzaran, T. Wong and D. Padua. An Evaluation of 52 // Vectorizing Compilers. 53 // 54 //===----------------------------------------------------------------------===// 55 56 #ifndef LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H 57 #define LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H 58 59 #include "llvm/IR/PassManager.h" 60 #include "llvm/Support/CommandLine.h" 61 #include "llvm/Support/Compiler.h" 62 #include "llvm/Transforms/Utils/ExtraPassManager.h" 63 #include <functional> 64 65 namespace llvm { 66 67 class AssumptionCache; 68 class BlockFrequencyInfo; 69 class DemandedBits; 70 class DominatorTree; 71 class Function; 72 class Instruction; 73 class Loop; 74 class LoopAccessInfoManager; 75 class LoopInfo; 76 class OptimizationRemarkEmitter; 77 class ProfileSummaryInfo; 78 class ScalarEvolution; 79 class TargetLibraryInfo; 80 class TargetTransformInfo; 81 82 LLVM_ABI extern cl::opt<bool> EnableLoopInterleaving; 83 LLVM_ABI extern cl::opt<bool> EnableLoopVectorization; 84 85 struct LoopVectorizeOptions { 86 /// If false, consider all loops for interleaving. 87 /// If true, only loops that explicitly request interleaving are considered. 88 bool InterleaveOnlyWhenForced; 89 90 /// If false, consider all loops for vectorization. 91 /// If true, only loops that explicitly request vectorization are considered. 92 bool VectorizeOnlyWhenForced; 93 94 /// The current defaults when creating the pass with no arguments are: 95 /// EnableLoopInterleaving = true and EnableLoopVectorization = true. This 96 /// means that interleaving default is consistent with the cl::opt flag, while 97 /// vectorization is not. 98 /// FIXME: The default for EnableLoopVectorization in the cl::opt should be 99 /// set to true, and the corresponding change to account for this be made in 100 /// opt.cpp. The initializations below will become: 101 /// InterleaveOnlyWhenForced(!EnableLoopInterleaving) 102 /// VectorizeOnlyWhenForced(!EnableLoopVectorization). LoopVectorizeOptionsLoopVectorizeOptions103 LoopVectorizeOptions() 104 : InterleaveOnlyWhenForced(false), VectorizeOnlyWhenForced(false) {} LoopVectorizeOptionsLoopVectorizeOptions105 LoopVectorizeOptions(bool InterleaveOnlyWhenForced, 106 bool VectorizeOnlyWhenForced) 107 : InterleaveOnlyWhenForced(InterleaveOnlyWhenForced), 108 VectorizeOnlyWhenForced(VectorizeOnlyWhenForced) {} 109 setInterleaveOnlyWhenForcedLoopVectorizeOptions110 LoopVectorizeOptions &setInterleaveOnlyWhenForced(bool Value) { 111 InterleaveOnlyWhenForced = Value; 112 return *this; 113 } 114 setVectorizeOnlyWhenForcedLoopVectorizeOptions115 LoopVectorizeOptions &setVectorizeOnlyWhenForced(bool Value) { 116 VectorizeOnlyWhenForced = Value; 117 return *this; 118 } 119 }; 120 121 /// Storage for information about made changes. 122 struct LoopVectorizeResult { 123 bool MadeAnyChange; 124 bool MadeCFGChange; 125 LoopVectorizeResultLoopVectorizeResult126 LoopVectorizeResult(bool MadeAnyChange, bool MadeCFGChange) 127 : MadeAnyChange(MadeAnyChange), MadeCFGChange(MadeCFGChange) {} 128 }; 129 130 /// The LoopVectorize Pass. 131 struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> { 132 private: 133 /// If false, consider all loops for interleaving. 134 /// If true, only loops that explicitly request interleaving are considered. 135 bool InterleaveOnlyWhenForced; 136 137 /// If false, consider all loops for vectorization. 138 /// If true, only loops that explicitly request vectorization are considered. 139 bool VectorizeOnlyWhenForced; 140 141 public: 142 LLVM_ABI LoopVectorizePass(LoopVectorizeOptions Opts = {}); 143 144 ScalarEvolution *SE; 145 LoopInfo *LI; 146 TargetTransformInfo *TTI; 147 DominatorTree *DT; 148 BlockFrequencyInfo *BFI; 149 TargetLibraryInfo *TLI; 150 DemandedBits *DB; 151 AssumptionCache *AC; 152 LoopAccessInfoManager *LAIs; 153 OptimizationRemarkEmitter *ORE; 154 ProfileSummaryInfo *PSI; 155 156 LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); 157 LLVM_ABI void 158 printPipeline(raw_ostream &OS, 159 function_ref<StringRef(StringRef)> MapClassName2PassName); 160 161 // Shim for old PM. 162 LLVM_ABI LoopVectorizeResult runImpl(Function &F); 163 164 LLVM_ABI bool processLoop(Loop *L); 165 }; 166 167 /// Reports a vectorization failure: print \p DebugMsg for debugging 168 /// purposes along with the corresponding optimization remark \p RemarkName. 169 /// If \p I is passed, it is an instruction that prevents vectorization. 170 /// Otherwise, the loop \p TheLoop is used for the location of the remark. 171 LLVM_ABI void reportVectorizationFailure( 172 const StringRef DebugMsg, const StringRef OREMsg, const StringRef ORETag, 173 OptimizationRemarkEmitter *ORE, Loop *TheLoop, Instruction *I = nullptr); 174 175 /// Same as above, but the debug message and optimization remark are identical 176 inline void reportVectorizationFailure(const StringRef DebugMsg, 177 const StringRef ORETag, 178 OptimizationRemarkEmitter *ORE, 179 Loop *TheLoop, 180 Instruction *I = nullptr) { 181 reportVectorizationFailure(DebugMsg, DebugMsg, ORETag, ORE, TheLoop, I); 182 } 183 184 /// A marker analysis to determine if extra passes should be run after loop 185 /// vectorization. 186 struct ShouldRunExtraVectorPasses 187 : public ShouldRunExtraPasses<ShouldRunExtraVectorPasses>, 188 public AnalysisInfoMixin<ShouldRunExtraVectorPasses> { 189 LLVM_ABI static AnalysisKey Key; 190 }; 191 } // end namespace llvm 192 193 #endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H 194