Home | History | Annotate | Line # | Download | only in Vectorize
      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 three 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/Proposal/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 <functional>
     62 
     63 namespace llvm {
     64 
     65 class AAResults;
     66 class AssumptionCache;
     67 class BlockFrequencyInfo;
     68 class DemandedBits;
     69 class DominatorTree;
     70 class Function;
     71 class Loop;
     72 class LoopAccessInfo;
     73 class LoopInfo;
     74 class OptimizationRemarkEmitter;
     75 class ProfileSummaryInfo;
     76 class ScalarEvolution;
     77 class TargetLibraryInfo;
     78 class TargetTransformInfo;
     79 
     80 extern cl::opt<bool> EnableLoopInterleaving;
     81 extern cl::opt<bool> EnableLoopVectorization;
     82 
     83 struct LoopVectorizeOptions {
     84   /// If false, consider all loops for interleaving.
     85   /// If true, only loops that explicitly request interleaving are considered.
     86   bool InterleaveOnlyWhenForced;
     87 
     88   /// If false, consider all loops for vectorization.
     89   /// If true, only loops that explicitly request vectorization are considered.
     90   bool VectorizeOnlyWhenForced;
     91 
     92   /// The current defaults when creating the pass with no arguments are:
     93   /// EnableLoopInterleaving = true and EnableLoopVectorization = true. This
     94   /// means that interleaving default is consistent with the cl::opt flag, while
     95   /// vectorization is not.
     96   /// FIXME: The default for EnableLoopVectorization in the cl::opt should be
     97   /// set to true, and the corresponding change to account for this be made in
     98   /// opt.cpp. The initializations below will become:
     99   /// InterleaveOnlyWhenForced(!EnableLoopInterleaving)
    100   /// VectorizeOnlyWhenForced(!EnableLoopVectorization).
    101   LoopVectorizeOptions()
    102       : InterleaveOnlyWhenForced(false), VectorizeOnlyWhenForced(false) {}
    103   LoopVectorizeOptions(bool InterleaveOnlyWhenForced,
    104                        bool VectorizeOnlyWhenForced)
    105       : InterleaveOnlyWhenForced(InterleaveOnlyWhenForced),
    106         VectorizeOnlyWhenForced(VectorizeOnlyWhenForced) {}
    107 
    108   LoopVectorizeOptions &setInterleaveOnlyWhenForced(bool Value) {
    109     InterleaveOnlyWhenForced = Value;
    110     return *this;
    111   }
    112 
    113   LoopVectorizeOptions &setVectorizeOnlyWhenForced(bool Value) {
    114     VectorizeOnlyWhenForced = Value;
    115     return *this;
    116   }
    117 };
    118 
    119 /// Storage for information about made changes.
    120 struct LoopVectorizeResult {
    121   bool MadeAnyChange;
    122   bool MadeCFGChange;
    123 
    124   LoopVectorizeResult(bool MadeAnyChange, bool MadeCFGChange)
    125       : MadeAnyChange(MadeAnyChange), MadeCFGChange(MadeCFGChange) {}
    126 };
    127 
    128 /// The LoopVectorize Pass.
    129 struct LoopVectorizePass : public PassInfoMixin<LoopVectorizePass> {
    130 private:
    131   /// If false, consider all loops for interleaving.
    132   /// If true, only loops that explicitly request interleaving are considered.
    133   bool InterleaveOnlyWhenForced;
    134 
    135   /// If false, consider all loops for vectorization.
    136   /// If true, only loops that explicitly request vectorization are considered.
    137   bool VectorizeOnlyWhenForced;
    138 
    139 public:
    140   LoopVectorizePass(LoopVectorizeOptions Opts = {});
    141 
    142   ScalarEvolution *SE;
    143   LoopInfo *LI;
    144   TargetTransformInfo *TTI;
    145   DominatorTree *DT;
    146   BlockFrequencyInfo *BFI;
    147   TargetLibraryInfo *TLI;
    148   DemandedBits *DB;
    149   AAResults *AA;
    150   AssumptionCache *AC;
    151   std::function<const LoopAccessInfo &(Loop &)> *GetLAA;
    152   OptimizationRemarkEmitter *ORE;
    153   ProfileSummaryInfo *PSI;
    154 
    155   PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
    156 
    157   // Shim for old PM.
    158   LoopVectorizeResult
    159   runImpl(Function &F, ScalarEvolution &SE_, LoopInfo &LI_,
    160           TargetTransformInfo &TTI_, DominatorTree &DT_,
    161           BlockFrequencyInfo &BFI_, TargetLibraryInfo *TLI_, DemandedBits &DB_,
    162           AAResults &AA_, AssumptionCache &AC_,
    163           std::function<const LoopAccessInfo &(Loop &)> &GetLAA_,
    164           OptimizationRemarkEmitter &ORE_, ProfileSummaryInfo *PSI_);
    165 
    166   bool processLoop(Loop *L);
    167 };
    168 
    169 /// Reports a vectorization failure: print \p DebugMsg for debugging
    170 /// purposes along with the corresponding optimization remark \p RemarkName.
    171 /// If \p I is passed, it is an instruction that prevents vectorization.
    172 /// Otherwise, the loop \p TheLoop is used for the location of the remark.
    173 void reportVectorizationFailure(const StringRef DebugMsg,
    174     const StringRef OREMsg, const StringRef ORETag,
    175     OptimizationRemarkEmitter *ORE, Loop *TheLoop, Instruction *I = nullptr);
    176 
    177 /// Reports an informative message: print \p Msg for debugging purposes as well
    178 /// as an optimization remark. Uses either \p I as location of the remark, or
    179 /// otherwise \p TheLoop.
    180 void reportVectorizationInfo(const StringRef OREMsg, const StringRef ORETag,
    181                              OptimizationRemarkEmitter *ORE, Loop *TheLoop,
    182                              Instruction *I = nullptr);
    183 
    184 } // end namespace llvm
    185 
    186 #endif // LLVM_TRANSFORMS_VECTORIZE_LOOPVECTORIZE_H
    187