LLVM 22.0.0git
VPlanUtils.h
Go to the documentation of this file.
1//===- VPlanUtils.h - VPlan-related utilities -------------------*- 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#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANUTILS_H
10#define LLVM_TRANSFORMS_VECTORIZE_VPLANUTILS_H
11
12#include "VPlan.h"
14
15namespace llvm {
16class MemoryLocation;
17class ScalarEvolution;
18class SCEV;
20} // namespace llvm
21
22namespace llvm {
23
24namespace vputils {
25/// Returns true if only the first lane of \p Def is used.
26bool onlyFirstLaneUsed(const VPValue *Def);
27
28/// Returns true if only the first part of \p Def is used.
29bool onlyFirstPartUsed(const VPValue *Def);
30
31/// Returns true if only scalar values of \p Def are used by all users.
32bool onlyScalarValuesUsed(const VPValue *Def);
33
34/// Get or create a VPValue that corresponds to the expansion of \p Expr. If \p
35/// Expr is a SCEVConstant or SCEVUnknown, return a VPValue wrapping the live-in
36/// value. Otherwise return a VPExpandSCEVRecipe to expand \p Expr. If \p Plan's
37/// pre-header already contains a recipe expanding \p Expr, return it. If not,
38/// create a new one.
40
41/// Return the SCEV expression for \p V. Returns SCEVCouldNotCompute if no
42/// SCEV expression could be constructed.
43const SCEV *getSCEVExprForVPValue(const VPValue *V,
45 const Loop *L = nullptr);
46
47/// Returns true if \p Addr is an address SCEV that can be passed to
48/// TTI::getAddressComputationCost, i.e. the address SCEV is loop invariant, an
49/// affine AddRec (i.e. induction ), or an add expression of such operands or a
50/// sign-extended AddRec.
51bool isAddressSCEVForCost(const SCEV *Addr, ScalarEvolution &SE, const Loop *L);
52
53/// Returns true if \p VPV is a single scalar, either because it produces the
54/// same value for all lanes or only has its first lane used.
55bool isSingleScalar(const VPValue *VPV);
56
57/// Return true if \p V is a header mask in \p Plan.
58bool isHeaderMask(const VPValue *V, const VPlan &Plan);
59
60/// Checks if \p V is uniform across all VF lanes and UF parts. It is considered
61/// as such if it is either loop invariant (defined outside the vector region)
62/// or its operand is known to be uniform across all VFs and UFs (e.g.
63/// VPDerivedIV or VPCanonicalIVPHI).
65
66/// Returns the header block of the first, top-level loop, or null if none
67/// exist.
69
70/// Get the VF scaling factor applied to the recipe's output, if the recipe has
71/// one.
73
74/// Returns the VPValue representing the uncountable exit comparison used by
75/// AnyOf if the recipes it depends on can be traced back to live-ins and
76/// the addresses (in GEP/PtrAdd form) of any (non-masked) load used in
77/// generating the values for the comparison. The recipes are stored in
78/// \p Recipes, and recipes forming an address for a load are also added to
79/// \p GEPs.
81std::optional<VPValue *>
85
86/// Return a MemoryLocation for \p R with noalias metadata populated from
87/// \p R, if the recipe is supported and std::nullopt otherwise. The pointer of
88/// the location is conservatively set to nullptr.
89std::optional<MemoryLocation> getMemoryLocation(const VPRecipeBase &R);
90
91/// Extracts and returns NoWrap and FastMath flags from the induction binop in
92/// \p ID.
95 return ID.getInductionBinOp()->getFastMathFlags();
96
98 ID.getInductionBinOp()))
99 return VPIRFlags::WrapFlagsTy(OBO->hasNoUnsignedWrap(),
100 OBO->hasNoSignedWrap());
101
103 "Expected int induction");
104 return VPIRFlags::WrapFlagsTy(false, false);
105}
106} // namespace vputils
107
108//===----------------------------------------------------------------------===//
109// Utilities for modifying predecessors and successors of VPlan blocks.
110//===----------------------------------------------------------------------===//
111
112/// Class that provides utilities for VPBlockBases in VPlan.
114public:
115 VPBlockUtils() = delete;
116
117 /// Insert disconnected VPBlockBase \p NewBlock after \p BlockPtr. Add \p
118 /// NewBlock as successor of \p BlockPtr and \p BlockPtr as predecessor of \p
119 /// NewBlock, and propagate \p BlockPtr parent to \p NewBlock. \p BlockPtr's
120 /// successors are moved from \p BlockPtr to \p NewBlock. \p NewBlock must
121 /// have neither successors nor predecessors.
122 static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr) {
123 assert(NewBlock->getSuccessors().empty() &&
124 NewBlock->getPredecessors().empty() &&
125 "Can't insert new block with predecessors or successors.");
126 NewBlock->setParent(BlockPtr->getParent());
127 transferSuccessors(BlockPtr, NewBlock);
128 connectBlocks(BlockPtr, NewBlock);
129 }
130
131 /// Insert disconnected block \p NewBlock before \p Blockptr. First
132 /// disconnects all predecessors of \p BlockPtr and connects them to \p
133 /// NewBlock. Add \p NewBlock as predecessor of \p BlockPtr and \p BlockPtr as
134 /// successor of \p NewBlock.
135 static void insertBlockBefore(VPBlockBase *NewBlock, VPBlockBase *BlockPtr) {
136 assert(NewBlock->getSuccessors().empty() &&
137 NewBlock->getPredecessors().empty() &&
138 "Can't insert new block with predecessors or successors.");
139 NewBlock->setParent(BlockPtr->getParent());
140 for (VPBlockBase *Pred : to_vector(BlockPtr->predecessors())) {
141 Pred->replaceSuccessor(BlockPtr, NewBlock);
142 NewBlock->appendPredecessor(Pred);
143 }
144 BlockPtr->clearPredecessors();
145 connectBlocks(NewBlock, BlockPtr);
146 }
147
148 /// Insert disconnected VPBlockBases \p IfTrue and \p IfFalse after \p
149 /// BlockPtr. Add \p IfTrue and \p IfFalse as succesors of \p BlockPtr and \p
150 /// BlockPtr as predecessor of \p IfTrue and \p IfFalse. Propagate \p BlockPtr
151 /// parent to \p IfTrue and \p IfFalse. \p BlockPtr must have no successors
152 /// and \p IfTrue and \p IfFalse must have neither successors nor
153 /// predecessors.
154 static void insertTwoBlocksAfter(VPBlockBase *IfTrue, VPBlockBase *IfFalse,
155 VPBlockBase *BlockPtr) {
156 assert(IfTrue->getSuccessors().empty() &&
157 "Can't insert IfTrue with successors.");
158 assert(IfFalse->getSuccessors().empty() &&
159 "Can't insert IfFalse with successors.");
160 BlockPtr->setTwoSuccessors(IfTrue, IfFalse);
161 IfTrue->setPredecessors({BlockPtr});
162 IfFalse->setPredecessors({BlockPtr});
163 IfTrue->setParent(BlockPtr->getParent());
164 IfFalse->setParent(BlockPtr->getParent());
165 }
166
167 /// Connect VPBlockBases \p From and \p To bi-directionally. If \p PredIdx is
168 /// -1, append \p From to the predecessors of \p To, otherwise set \p To's
169 /// predecessor at \p PredIdx to \p From. If \p SuccIdx is -1, append \p To to
170 /// the successors of \p From, otherwise set \p From's successor at \p SuccIdx
171 /// to \p To. Both VPBlockBases must have the same parent, which can be null.
172 /// Both VPBlockBases can be already connected to other VPBlockBases.
173 static void connectBlocks(VPBlockBase *From, VPBlockBase *To,
174 unsigned PredIdx = -1u, unsigned SuccIdx = -1u) {
175 assert((From->getParent() == To->getParent()) &&
176 "Can't connect two block with different parents");
177 assert((SuccIdx != -1u || From->getNumSuccessors() < 2) &&
178 "Blocks can't have more than two successors.");
179 if (SuccIdx == -1u)
180 From->appendSuccessor(To);
181 else
182 From->getSuccessors()[SuccIdx] = To;
183
184 if (PredIdx == -1u)
185 To->appendPredecessor(From);
186 else
187 To->getPredecessors()[PredIdx] = From;
188 }
189
190 /// Disconnect VPBlockBases \p From and \p To bi-directionally. Remove \p To
191 /// from the successors of \p From and \p From from the predecessors of \p To.
192 static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To) {
193 assert(To && "Successor to disconnect is null.");
194 From->removeSuccessor(To);
195 To->removePredecessor(From);
196 }
197
198 /// Reassociate all the blocks connected to \p Old so that they now point to
199 /// \p New.
200 static void reassociateBlocks(VPBlockBase *Old, VPBlockBase *New) {
201 for (auto *Pred : to_vector(Old->getPredecessors()))
202 Pred->replaceSuccessor(Old, New);
203 for (auto *Succ : to_vector(Old->getSuccessors()))
204 Succ->replacePredecessor(Old, New);
205 New->setPredecessors(Old->getPredecessors());
206 New->setSuccessors(Old->getSuccessors());
207 Old->clearPredecessors();
208 Old->clearSuccessors();
209 }
210
211 /// Transfer successors from \p Old to \p New. \p New must have no successors.
213 for (auto *Succ : Old->getSuccessors())
214 Succ->replacePredecessor(Old, New);
215 New->setSuccessors(Old->getSuccessors());
216 Old->clearSuccessors();
217 }
218
219 /// Return an iterator range over \p Range which only includes \p BlockTy
220 /// blocks. The accesses are casted to \p BlockTy.
221 template <typename BlockTy, typename T>
222 static auto blocksOnly(const T &Range) {
223 // Create BaseTy with correct const-ness based on BlockTy.
224 using BaseTy = std::conditional_t<std::is_const<BlockTy>::value,
225 const VPBlockBase, VPBlockBase>;
226
227 // We need to first create an iterator range over (const) BlocktTy & instead
228 // of (const) BlockTy * for filter_range to work properly.
229 auto Mapped =
230 map_range(Range, [](BaseTy *Block) -> BaseTy & { return *Block; });
232 Mapped, [](BaseTy &Block) { return isa<BlockTy>(&Block); });
233 return map_range(Filter, [](BaseTy &Block) -> BlockTy * {
234 return cast<BlockTy>(&Block);
235 });
236 }
237
238 /// Inserts \p BlockPtr on the edge between \p From and \p To. That is, update
239 /// \p From's successor to \p To to point to \p BlockPtr and \p To's
240 /// predecessor from \p From to \p BlockPtr. \p From and \p To are added to \p
241 /// BlockPtr's predecessors and successors respectively. There must be a
242 /// single edge between \p From and \p To.
243 static void insertOnEdge(VPBlockBase *From, VPBlockBase *To,
244 VPBlockBase *BlockPtr) {
245 unsigned SuccIdx = From->getIndexForSuccessor(To);
246 unsigned PredIx = To->getIndexForPredecessor(From);
247 VPBlockUtils::connectBlocks(From, BlockPtr, -1, SuccIdx);
248 VPBlockUtils::connectBlocks(BlockPtr, To, PredIx, -1);
249 }
250
251 /// Returns true if \p VPB is a loop header, based on regions or \p VPDT in
252 /// their absence.
253 static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT);
254
255 /// Returns true if \p VPB is a loop latch, using isHeader().
256 static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT);
257};
258
259} // namespace llvm
260
261#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_ABI_FOR_TEST
Definition Compiler.h:218
std::pair< BasicBlock *, unsigned > BlockTy
A pair of (basic block, score).
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
This file contains the declarations of the Vectorization Plan base classes:
A struct for saving information about induction variables.
@ IK_FpInduction
Floating point induction variable.
@ IK_IntInduction
Integer induction variable. Step = C.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Representation for a specific memory location.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
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...
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:3982
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:81
VPRegionBlock * getParent()
Definition VPlan.h:173
iterator_range< VPBlockBase ** > predecessors()
Definition VPlan.h:202
size_t getNumSuccessors() const
Definition VPlan.h:219
unsigned getIndexForSuccessor(const VPBlockBase *Succ) const
Returns the index for Succ in the blocks successor list.
Definition VPlan.h:335
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition VPlan.h:291
unsigned getIndexForPredecessor(const VPBlockBase *Pred) const
Returns the index for Pred in the blocks predecessors list.
Definition VPlan.h:328
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:204
void clearSuccessors()
Remove all the successors of this block.
Definition VPlan.h:310
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
Definition VPlan.h:282
void clearPredecessors()
Remove all the predecessor of this block.
Definition VPlan.h:307
void setParent(VPRegionBlock *P)
Definition VPlan.h:184
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:198
static auto blocksOnly(const T &Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:222
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
Definition VPlanUtils.h:122
static void insertOnEdge(VPBlockBase *From, VPBlockBase *To, VPBlockBase *BlockPtr)
Inserts BlockPtr on the edge between From and To.
Definition VPlanUtils.h:243
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop header, based on regions or VPDT in their absence.
static void insertTwoBlocksAfter(VPBlockBase *IfTrue, VPBlockBase *IfFalse, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBases IfTrue and IfFalse after BlockPtr.
Definition VPlanUtils.h:154
static void connectBlocks(VPBlockBase *From, VPBlockBase *To, unsigned PredIdx=-1u, unsigned SuccIdx=-1u)
Connect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:173
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:192
static void reassociateBlocks(VPBlockBase *Old, VPBlockBase *New)
Reassociate all the blocks connected to Old so that they now point to New.
Definition VPlanUtils.h:200
static void insertBlockBefore(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected block NewBlock before Blockptr.
Definition VPlanUtils.h:135
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
Definition VPlanUtils.h:212
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Class to record and manage LLVM IR flags.
Definition VPlan.h:609
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:387
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:46
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4300
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
bool isSingleScalar(const VPValue *VPV)
Returns true if VPV is a single scalar, either because it produces the same value for all lanes or on...
bool isUniformAcrossVFsAndUFs(VPValue *V)
Checks if V is uniform across all VF lanes and UF parts.
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
VPBasicBlock * getFirstLoopHeader(VPlan &Plan, VPDominatorTree &VPDT)
Returns the header block of the first, top-level loop, or null if none exist.
bool isAddressSCEVForCost(const SCEV *Addr, ScalarEvolution &SE, const Loop *L)
Returns true if Addr is an address SCEV that can be passed to TTI::getAddressComputationCost,...
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
std::optional< MemoryLocation > getMemoryLocation(const VPRecipeBase &R)
Return a MemoryLocation for R with noalias metadata populated from R, if the recipe is supported and ...
bool onlyFirstLaneUsed(const VPValue *Def)
Returns true if only the first lane of Def is used.
VPIRFlags getFlagsFromIndDesc(const InductionDescriptor &ID)
Extracts and returns NoWrap and FastMath flags from the induction binop in ID.
Definition VPlanUtils.h:93
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
const SCEV * getSCEVExprForVPValue(const VPValue *V, PredicatedScalarEvolution &PSE, const Loop *L=nullptr)
Return the SCEV expression for V.
unsigned getVFScaleFactor(VPRecipeBase *R)
Get the VF scaling factor applied to the recipe's output, if the recipe has one.
bool isHeaderMask(const VPValue *V, const VPlan &Plan)
Return true if V is a header mask in Plan.
LLVM_ABI_FOR_TEST std::optional< VPValue * > getRecipesForUncountableExit(VPlan &Plan, SmallVectorImpl< VPRecipeBase * > &Recipes, SmallVectorImpl< VPRecipeBase * > &GEPs)
Returns the VPValue representing the uncountable exit comparison used by AnyOf if the recipes it depe...
This is an optimization pass for GlobalISel generic memory operations.
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
auto map_range(ContainerTy &&C, FuncTy F)
Definition STLExtras.h:364
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
Definition STLExtras.h:550
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559