LLVM 24.0.0git
SLPMemoryUtils.h
Go to the documentation of this file.
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/DenseMap.h"
22
23#include <cstdint>
24#include <optional>
25#include <tuple>
26
27namespace llvm {
28class AssumptionCache;
29class BasicBlock;
30class ConstantInt;
31class DataLayout;
32class DominatorTree;
33class FixedVectorType;
34class IRBuilderBase;
35class SCEV;
36class ScalarEvolution;
38class Type;
39class Value;
40class VectorType;
41} // namespace llvm
42
43namespace llvm::slpvectorizer {
44
45/// Caches the results of the expensive analyses that are queried repeatedly
46/// for the same values while the vectorization trees are built and their costs
47/// are estimated. The results may change once the vectorized code is emitted
48/// and the scalars are erased, so the cache is cleared after each successful
49/// vectorizeTree().
51public:
52 /// Cached llvm::getPointersDiff(), a miss may require SCEV analysis. The
53 /// result for (\p PtrA, \p PtrB) also serves the query for the swapped
54 /// pointers.
55 std::optional<int64_t>
56 getPointersDiff(Type *ElemTyA, Value *PtrA, Type *ElemTyB, Value *PtrB,
57 const DataLayout &DL, ScalarEvolution &SE,
58 bool StrictCheck = false, bool CheckType = true);
59
60 /// Cached llvm::isGuaranteedNotToBePoison().
62
63 void clear() {
64 PtrsDiffCache.clear();
65 NotPoisonCache.clear();
66 }
67
68private:
69 using PtrsDiffKeyT = std::tuple<Type *, Value *, Type *, Value *, unsigned>;
72};
73
74/// \p MaxDepth is the recursion limit for getUnderlyingObject.
75bool arePointersCompatible(Value *Ptr1, Value *Ptr2,
76 const TargetLibraryInfo &TLI, unsigned MaxDepth,
77 bool CompareOpcodes = true);
78
79/// Returns \p Stride scaled by the allocation size of \p ScalarTy, negated if
80/// \p IsReverse is set, or nullptr if \p Stride is not a constant.
82 const DataLayout &DL,
83 bool IsReverse = false);
84
85/// Casts \p V between the widened strided access type and the entry vector
86/// type \p DstTy.
88 const DataLayout &DL);
89
90/// Calculates minimal alignment as a common alignment.
91template <typename T> Align computeCommonAlignment(ArrayRef<Value *> VL);
92
93/// Checks if the provided list of pointers \p Pointers represents the strided
94/// pointers for type ElemTy. If they are not, nullptr is returned.
95/// Otherwise, SCEV* of the stride value is returned.
96/// If `PointerOps` can be rearranged into the following sequence:
97/// ```
98/// %x + c_0 * stride,
99/// %x + c_1 * stride,
100/// %x + c_2 * stride
101/// ...
102/// ```
103/// where each `c_i` is constant. The SCEV of the `stride` will be returned.
105 const DataLayout &DL, ScalarEvolution &SE,
106 SmallVectorImpl<unsigned> &SortedIndices);
107
108/// Checks if the \p VL can be transformed to a (masked)load + compress or
109/// (masked) interleaved load.
114 const DominatorTree &DT, const TargetLibraryInfo &TLI,
116 const function_ref<bool(Value *)> AreAllUsersVectorized, bool ReVec,
117 bool &IsMasked, unsigned &InterleaveFactor,
118 SmallVectorImpl<int> &CompressMask, VectorType *&LoadVecTy,
119 SLPAnalysisCache &Cache);
120
121/// Checks if the \p VL can be transformed to a (masked)load + compress or
122/// (masked) interleaved load.
127 const DominatorTree &DT, const TargetLibraryInfo &TLI,
129 const function_ref<bool(Value *)> AreAllUsersVectorized, bool ReVec,
130 SLPAnalysisCache &Cache);
131
132/// Checks if the simple loads of \p VL, mixed with the undef and poison lanes,
133/// can be replaced by a single load of the whole \p VL width. The loads must be
134/// consecutive and match their lanes, and the whole accessed range must be safe
135/// to load unconditionally.
138 const DominatorTree &DT,
139 const TargetLibraryInfo &TLI);
140
141/// Returns the distance in bytes from the start of the vector load to the
142/// first load of \p Scalars: the leading undef lanes are covered by the vector
143/// load.
145
146/// Checks if the stores \p VL with pointers \p PointerOps can be lowered as a
147/// single masked store. On success \p StoreVecTy is the widened store type and
148/// \p ReuseShuffleIndices is the expand mask that places each stored value at
149/// its element offset from the base (poison in the gaps).
151 ArrayRef<unsigned> Order,
152 const TargetTransformInfo &TTI, const DataLayout &DL,
153 ScalarEvolution &SE, Align CommonAlignment,
154 SmallVectorImpl<int> &ReuseShuffleIndices,
155 FixedVectorType *&StoreVecTy,
156 SLPAnalysisCache &Cache);
157
158/// Clusters \p VL pointers by (basic block, underlying object) pair and sorts
159/// each cluster by offset. Returns false and leaves \p SortedIndices empty if
160/// the accesses are not worth reordering.
162 Type *ElemTy, const DataLayout &DL,
163 ScalarEvolution &SE, unsigned MaxDepth,
164 SmallVectorImpl<unsigned> &SortedIndices,
165 SLPAnalysisCache &Cache);
166
167} // namespace llvm::slpvectorizer
168
169#endif // LLVM_LIB_TRANSFORMS_VECTORIZE_SLPVECTORIZER_SLPMEMORYUTILS_H
uint64_t uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
This file defines the DenseMap class.
This pass exposes codegen information to IR-level passes.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
This is the shared class of boolean and integer constants.
Definition Constants.h:87
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
Class to represent fixed width SIMD vectors.
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
This class represents an analyzed expression in the program.
The main scalar evolution driver.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM Value Representation.
Definition Value.h:75
Base class of all SIMD vector types.
An efficient, type-erasing, non-owning reference to a callable.
Caches the results of the expensive analyses that are queried repeatedly for the same values while th...
bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC)
Cached llvm::isGuaranteedNotToBePoison().
std::optional< int64_t > getPointersDiff(Type *ElemTyA, Value *PtrA, Type *ElemTyB, Value *PtrB, const DataLayout &DL, ScalarEvolution &SE, bool StrictCheck=false, bool CheckType=true)
Cached llvm::getPointersDiff(), a miss may require SCEV analysis.
A private "module" namespace for types and utilities used by this pass.
bool clusterSortPtrAccesses(ArrayRef< Value * > VL, ArrayRef< BasicBlock * > BBs, Type *ElemTy, const DataLayout &DL, ScalarEvolution &SE, unsigned MaxDepth, SmallVectorImpl< unsigned > &SortedIndices, SLPAnalysisCache &Cache)
Clusters VL pointers by (basic block, underlying object) pair and sorts each cluster by offset.
Value * createWidenedStridedCast(IRBuilderBase &Builder, Value *V, Type *DstTy, const DataLayout &DL)
Casts V between the widened strided access type and the entry vector type DstTy.
Align computeCommonAlignment(ArrayRef< Value * > VL)
Calculates minimal alignment as a common alignment.
const SCEV * calculateRtStride(ArrayRef< Value * > PointerOps, Type *ElemTy, const DataLayout &DL, ScalarEvolution &SE, SmallVectorImpl< unsigned > &SortedIndices)
Checks if the provided list of pointers Pointers represents the strided pointers for type ElemTy.
ConstantInt * getStrideBytesIfConstant(Value *Stride, Type *ScalarTy, const DataLayout &DL, bool IsReverse)
Returns Stride scaled by the allocation size of ScalarTy, negated if IsReverse is set,...
bool isMaskedStoreCompress(ArrayRef< Value * > VL, ArrayRef< Value * > PointerOps, ArrayRef< unsigned > Order, const TargetTransformInfo &TTI, const DataLayout &DL, ScalarEvolution &SE, Align CommonAlignment, SmallVectorImpl< int > &ReuseShuffleIndices, FixedVectorType *&StoreVecTy, SLPAnalysisCache &Cache)
Checks if the stores VL with pointers PointerOps can be lowered as a single masked store.
uint64_t getVectorLoadShift(ArrayRef< Value * > Scalars)
Returns the distance in bytes from the start of the vector load to the first load of Scalars: the lea...
bool canWidenLoadsOverUndefLanes(ArrayRef< Value * > VL, const DataLayout &DL, ScalarEvolution &SE, AssumptionCache &AC, const DominatorTree &DT, const TargetLibraryInfo &TLI)
Checks if the simple loads of VL, mixed with the undef and poison lanes, can be replaced by a single ...
bool isMaskedLoadCompress(ArrayRef< Value * > VL, ArrayRef< Value * > PointerOps, ArrayRef< unsigned > Order, const TargetTransformInfo &TTI, const DataLayout &DL, ScalarEvolution &SE, AssumptionCache &AC, const DominatorTree &DT, const TargetLibraryInfo &TLI, const TargetTransformInfo::TargetCostKind CostKind, const function_ref< bool(Value *)> AreAllUsersVectorized, bool ReVec, bool &IsMasked, unsigned &InterleaveFactor, SmallVectorImpl< int > &CompressMask, VectorType *&LoadVecTy, SLPAnalysisCache &Cache)
Checks if the VL can be transformed to a (masked)load + compress or (masked) interleaved load.
bool arePointersCompatible(Value *Ptr1, Value *Ptr2, const TargetLibraryInfo &TLI, unsigned MaxDepth, bool CompareOpcodes)
MaxDepth is the recursion limit for getUnderlyingObject.
This is an optimization pass for GlobalISel generic memory operations.
TargetTransformInfo TTI
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39