| 1 | //===- SLPMemoryUtils.h - SLP pointer/stride helpers -----------*- 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 | // Internal header used by SLPVectorizer.cpp. It declares free pointer and |
| 10 | // stride helpers that do not depend on BoUpSLP or any other SLP-private type. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPMEMORYUTILS_H |
| 15 | #define LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPMEMORYUTILS_H |
| 16 | |
| 17 | #include "llvm/ADT/ArrayRef.h" |
| 18 | #include "llvm/ADT/STLFunctionalExtras.h" |
| 19 | #include "llvm/Analysis/TargetTransformInfo.h" |
| 20 | #include "llvm/Support/Alignment.h" |
| 21 | |
| 22 | namespace llvm { |
| 23 | class AssumptionCache; |
| 24 | class BasicBlock; |
| 25 | class DataLayout; |
| 26 | class DominatorTree; |
| 27 | class FixedVectorType; |
| 28 | class SCEV; |
| 29 | class ScalarEvolution; |
| 30 | class TargetLibraryInfo; |
| 31 | class Type; |
| 32 | class Value; |
| 33 | class VectorType; |
| 34 | } // namespace llvm |
| 35 | |
| 36 | namespace llvm::slpvectorizer { |
| 37 | |
| 38 | /// \p MaxDepth is the recursion limit for getUnderlyingObject. |
| 39 | bool arePointersCompatible(Value *Ptr1, Value *Ptr2, |
| 40 | const TargetLibraryInfo &TLI, unsigned MaxDepth, |
| 41 | bool CompareOpcodes = true); |
| 42 | |
| 43 | /// Calculates minimal alignment as a common alignment. |
| 44 | template <typename T> Align computeCommonAlignment(ArrayRef<Value *> VL); |
| 45 | |
| 46 | /// Checks if the provided list of pointers \p Pointers represents the strided |
| 47 | /// pointers for type ElemTy. If they are not, nullptr is returned. |
| 48 | /// Otherwise, SCEV* of the stride value is returned. |
| 49 | /// If `PointerOps` can be rearranged into the following sequence: |
| 50 | /// ``` |
| 51 | /// %x + c_0 * stride, |
| 52 | /// %x + c_1 * stride, |
| 53 | /// %x + c_2 * stride |
| 54 | /// ... |
| 55 | /// ``` |
| 56 | /// where each `c_i` is constant. The SCEV of the `stride` will be returned. |
| 57 | const SCEV *calculateRtStride(ArrayRef<Value *> PointerOps, Type *ElemTy, |
| 58 | const DataLayout &DL, ScalarEvolution &SE, |
| 59 | SmallVectorImpl<unsigned> &SortedIndices); |
| 60 | |
| 61 | /// Checks if the \p VL can be transformed to a (masked)load + compress or |
| 62 | /// (masked) interleaved load. |
| 63 | bool isMaskedLoadCompress( |
| 64 | ArrayRef<Value *> VL, ArrayRef<Value *> PointerOps, |
| 65 | ArrayRef<unsigned> Order, const TargetTransformInfo &TTI, |
| 66 | const DataLayout &DL, ScalarEvolution &SE, AssumptionCache &AC, |
| 67 | const DominatorTree &DT, const TargetLibraryInfo &TLI, |
| 68 | const TargetTransformInfo::TargetCostKind CostKind, |
| 69 | const function_ref<bool(Value *)> AreAllUsersVectorized, bool ReVec, |
| 70 | bool &IsMasked, unsigned &InterleaveFactor, |
| 71 | SmallVectorImpl<int> &CompressMask, VectorType *&LoadVecTy); |
| 72 | |
| 73 | /// Checks if the \p VL can be transformed to a (masked)load + compress or |
| 74 | /// (masked) interleaved load. |
| 75 | bool isMaskedLoadCompress( |
| 76 | ArrayRef<Value *> VL, ArrayRef<Value *> PointerOps, |
| 77 | ArrayRef<unsigned> Order, const TargetTransformInfo &TTI, |
| 78 | const DataLayout &DL, ScalarEvolution &SE, AssumptionCache &AC, |
| 79 | const DominatorTree &DT, const TargetLibraryInfo &TLI, |
| 80 | const TargetTransformInfo::TargetCostKind CostKind, |
| 81 | const function_ref<bool(Value *)> AreAllUsersVectorized, bool ReVec); |
| 82 | |
| 83 | /// Checks if the stores \p VL with pointers \p PointerOps can be lowered as a |
| 84 | /// single masked store. On success \p StoreVecTy is the widened store type and |
| 85 | /// \p ReuseShuffleIndices is the expand mask that places each stored value at |
| 86 | /// its element offset from the base (poison in the gaps). |
| 87 | bool isMaskedStoreCompress(ArrayRef<Value *> VL, ArrayRef<Value *> PointerOps, |
| 88 | ArrayRef<unsigned> Order, |
| 89 | const TargetTransformInfo &TTI, const DataLayout &DL, |
| 90 | ScalarEvolution &SE, Align CommonAlignment, |
| 91 | SmallVectorImpl<int> &ReuseShuffleIndices, |
| 92 | FixedVectorType *&StoreVecTy); |
| 93 | |
| 94 | /// Clusters \p VL pointers by (basic block, underlying object) pair and sorts |
| 95 | /// each cluster by offset. Returns false and leaves \p SortedIndices empty if |
| 96 | /// the accesses are not worth reordering. |
| 97 | bool clusterSortPtrAccesses(ArrayRef<Value *> VL, ArrayRef<BasicBlock *> BBs, |
| 98 | Type *ElemTy, const DataLayout &DL, |
| 99 | ScalarEvolution &SE, unsigned MaxDepth, |
| 100 | SmallVectorImpl<unsigned> &SortedIndices); |
| 101 | |
| 102 | } // namespace llvm::slpvectorizer |
| 103 | |
| 104 | #endif // LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPMEMORYUTILS_H |
| 105 | |