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
22namespace llvm {
23class AssumptionCache;
24class BasicBlock;
25class DataLayout;
26class DominatorTree;
27class FixedVectorType;
28class SCEV;
29class ScalarEvolution;
30class TargetLibraryInfo;
31class Type;
32class Value;
33class VectorType;
34} // namespace llvm
35
36namespace llvm::slpvectorizer {
37
38/// \p MaxDepth is the recursion limit for getUnderlyingObject.
39bool arePointersCompatible(Value *Ptr1, Value *Ptr2,
40 const TargetLibraryInfo &TLI, unsigned MaxDepth,
41 bool CompareOpcodes = true);
42
43/// Calculates minimal alignment as a common alignment.
44template <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.
57const 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.
63bool 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.
75bool 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).
87bool 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.
97bool 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