xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Transforms/Vectorize/LoopVectorize.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
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