LLVM 23.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"
13#include "VPlanPatternMatch.h"
15
16namespace llvm {
17class MemoryLocation;
18class ScalarEvolution;
19class SCEV;
21} // namespace llvm
22
23namespace llvm {
24
25namespace vputils {
26/// Returns true if only the first lane of \p Def is used.
27bool onlyFirstLaneUsed(const VPValue *Def);
28
29/// Returns true if only the first part of \p Def is used.
30bool onlyFirstPartUsed(const VPValue *Def);
31
32/// Returns true if only scalar values of \p Def are used by all users.
33bool onlyScalarValuesUsed(const VPValue *Def);
34
35/// Get or create a VPValue that corresponds to the expansion of \p Expr. If \p
36/// Expr is a SCEVConstant or SCEVUnknown, return a VPValue wrapping the live-in
37/// value. Otherwise return a VPExpandSCEVRecipe to expand \p Expr. If \p Plan's
38/// pre-header already contains a recipe expanding \p Expr, return it. If not,
39/// create a new one.
41
42/// Return the SCEV expression for \p V. Returns SCEVCouldNotCompute if no
43/// SCEV expression could be constructed.
44const SCEV *getSCEVExprForVPValue(const VPValue *V,
46 const Loop *L = nullptr);
47
48/// Returns true if \p Addr is an address SCEV that can be passed to
49/// TTI::getAddressComputationCost, i.e. the address SCEV is loop invariant, an
50/// affine AddRec (i.e. induction ), or an add expression of such operands or a
51/// sign-extended AddRec.
52bool isAddressSCEVForCost(const SCEV *Addr, ScalarEvolution &SE, const Loop *L);
53
54/// Returns true if \p VPV is a single scalar, either because it produces the
55/// same value for all lanes or only has its first lane used.
56bool isSingleScalar(const VPValue *VPV);
57
58/// Return true if \p V is a header mask in \p Plan.
59bool isHeaderMask(const VPValue *V, const VPlan &Plan);
60
61/// Checks if \p V is uniform across all VF lanes and UF parts. It is considered
62/// as such if it is either loop invariant (defined outside the vector region)
63/// or its operands are known to be uniform across all VFs and UFs (e.g.
64/// VPDerivedIV or the canonical IV).
66
67/// Returns the header block of the first, top-level loop, or null if none
68/// exist.
70
71/// Get the VF scaling factor applied to the recipe's output, if the recipe has
72/// one.
74
75/// Return true if we do not know how to (mechanically) hoist or sink \p R.
76/// When sinking, passing \p Sinking = true ensures that assumes aren't sunk.
77bool cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking = false);
78
79/// Returns the VPValue representing the uncountable exit comparison used by
80/// AnyOf if the recipes it depends on can be traced back to live-ins and
81/// the addresses (in GEP/PtrAdd form) of any (non-masked) load used in
82/// generating the values for the comparison. The recipes are stored in
83/// \p Recipes, and recipes forming an address for a load are also added to
84/// \p GEPs.
86std::optional<VPValue *>
89 VPBasicBlock *LatchVPBB);
90
91/// Return a MemoryLocation for \p R with noalias metadata populated from
92/// \p R, if the recipe is supported and std::nullopt otherwise. The pointer of
93/// the location is conservatively set to nullptr.
94std::optional<MemoryLocation> getMemoryLocation(const VPRecipeBase &R);
95
96/// Extracts and returns NoWrap and FastMath flags from the induction binop in
97/// \p ID.
100 return ID.getInductionBinOp()->getFastMathFlags();
101
103 ID.getInductionBinOp()))
104 return VPIRFlags::WrapFlagsTy(OBO->hasNoUnsignedWrap(),
105 OBO->hasNoSignedWrap());
106
108 "Expected int induction");
109 return VPIRFlags::WrapFlagsTy(false, false);
110}
111
112/// Search \p Start's users for a recipe satisfying \p Pred, looking through
113/// recipes with definitions.
114template <typename PredT>
115inline VPRecipeBase *findRecipe(VPValue *Start, PredT Pred) {
116 SetVector<VPValue *> Worklist;
117 Worklist.insert(Start);
118 for (unsigned I = 0; I != Worklist.size(); ++I) {
119 VPValue *Cur = Worklist[I];
120 auto *R = Cur->getDefiningRecipe();
121 if (!R)
122 continue;
123 if (Pred(R))
124 return R;
125 for (VPUser *U : Cur->users()) {
126 for (VPValue *V : cast<VPRecipeBase>(U)->definedValues())
127 Worklist.insert(V);
128 }
129 }
130 return nullptr;
131}
132
133/// If \p V is used by a recipe matching pattern \p P, return it. Otherwise
134/// return nullptr;
135template <typename MatchT>
136static VPRecipeBase *findUserOf(VPValue *V, const MatchT &P) {
137 using namespace llvm::VPlanPatternMatch;
138 auto It = find_if(V->users(), match_fn(P));
139 return It == V->user_end() ? nullptr : cast<VPRecipeBase>(*It);
140}
141
142/// If \p V is used by a VPInstruction with \p Opcode, return it. Otherwise
143/// return nullptr.
144template <unsigned Opcode> static VPInstruction *findUserOf(VPValue *V) {
145 using namespace llvm::VPlanPatternMatch;
147}
148
149template <typename RecipeTy> static RecipeTy *findUserOf(VPValue *V) {
150 using namespace llvm::VPlanPatternMatch;
152}
153
154/// Find the canonical IV increment of \p Plan's vector loop region. Returns
155/// nullptr if not found.
157
158/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
159/// inserted for predicated reductions or tail folding.
161
162/// Collect the header mask with the pattern:
163/// (ICMP_ULE, WideCanonicalIV, backedge-taken-count)
164/// TODO: Introduce explicit recipe for header-mask instead of searching
165/// the header-mask pattern manually.
167
168} // namespace vputils
169
170//===----------------------------------------------------------------------===//
171// Utilities for modifying predecessors and successors of VPlan blocks.
172//===----------------------------------------------------------------------===//
173
174/// Class that provides utilities for VPBlockBases in VPlan.
176public:
177 VPBlockUtils() = delete;
178
179 /// Insert disconnected VPBlockBase \p NewBlock after \p BlockPtr. Add \p
180 /// NewBlock as successor of \p BlockPtr and \p BlockPtr as predecessor of \p
181 /// NewBlock, and propagate \p BlockPtr parent to \p NewBlock. \p BlockPtr's
182 /// successors are moved from \p BlockPtr to \p NewBlock. \p NewBlock must
183 /// have neither successors nor predecessors.
184 static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr) {
185 assert(!NewBlock->hasSuccessors() && !NewBlock->hasPredecessors() &&
186 "Can't insert new block with predecessors or successors.");
187 NewBlock->setParent(BlockPtr->getParent());
188 transferSuccessors(BlockPtr, NewBlock);
189 connectBlocks(BlockPtr, NewBlock);
190 }
191
192 /// Insert disconnected block \p NewBlock before \p Blockptr. First
193 /// disconnects all predecessors of \p BlockPtr and connects them to \p
194 /// NewBlock. Add \p NewBlock as predecessor of \p BlockPtr and \p BlockPtr as
195 /// successor of \p NewBlock.
196 static void insertBlockBefore(VPBlockBase *NewBlock, VPBlockBase *BlockPtr) {
197 assert(!NewBlock->hasSuccessors() && !NewBlock->hasPredecessors() &&
198 "Can't insert new block with predecessors or successors.");
199 NewBlock->setParent(BlockPtr->getParent());
200 for (VPBlockBase *Pred : to_vector(BlockPtr->predecessors())) {
201 Pred->replaceSuccessor(BlockPtr, NewBlock);
202 NewBlock->appendPredecessor(Pred);
203 }
204 BlockPtr->clearPredecessors();
205 connectBlocks(NewBlock, BlockPtr);
206 }
207
208 /// Insert disconnected VPBlockBases \p IfTrue and \p IfFalse after \p
209 /// BlockPtr. Add \p IfTrue and \p IfFalse as succesors of \p BlockPtr and \p
210 /// BlockPtr as predecessor of \p IfTrue and \p IfFalse. Propagate \p BlockPtr
211 /// parent to \p IfTrue and \p IfFalse. \p BlockPtr must have no successors
212 /// and \p IfTrue and \p IfFalse must have neither successors nor
213 /// predecessors.
214 static void insertTwoBlocksAfter(VPBlockBase *IfTrue, VPBlockBase *IfFalse,
215 VPBlockBase *BlockPtr) {
216 assert(!IfTrue->hasSuccessors() && "Can't insert IfTrue with successors.");
217 assert(!IfFalse->hasSuccessors() &&
218 "Can't insert IfFalse with successors.");
219 BlockPtr->setTwoSuccessors(IfTrue, IfFalse);
220 IfTrue->setPredecessors({BlockPtr});
221 IfFalse->setPredecessors({BlockPtr});
222 IfTrue->setParent(BlockPtr->getParent());
223 IfFalse->setParent(BlockPtr->getParent());
224 }
225
226 /// Connect VPBlockBases \p From and \p To bi-directionally. If \p PredIdx is
227 /// -1, append \p From to the predecessors of \p To, otherwise set \p To's
228 /// predecessor at \p PredIdx to \p From. If \p SuccIdx is -1, append \p To to
229 /// the successors of \p From, otherwise set \p From's successor at \p SuccIdx
230 /// to \p To. Both VPBlockBases must have the same parent, which can be null.
231 /// Both VPBlockBases can be already connected to other VPBlockBases.
232 static void connectBlocks(VPBlockBase *From, VPBlockBase *To,
233 unsigned PredIdx = -1u, unsigned SuccIdx = -1u) {
234 assert((From->getParent() == To->getParent()) &&
235 "Can't connect two block with different parents");
236
237 if (SuccIdx == -1u)
238 From->appendSuccessor(To);
239 else
240 From->getSuccessors()[SuccIdx] = To;
241
242 if (PredIdx == -1u)
243 To->appendPredecessor(From);
244 else
245 To->getPredecessors()[PredIdx] = From;
246 }
247
248 /// Disconnect VPBlockBases \p From and \p To bi-directionally. Remove \p To
249 /// from the successors of \p From and \p From from the predecessors of \p To.
250 static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To) {
251 assert(To && "Successor to disconnect is null.");
252 From->removeSuccessor(To);
253 To->removePredecessor(From);
254 }
255
256 /// Reassociate all the blocks connected to \p Old so that they now point to
257 /// \p New.
258 static void reassociateBlocks(VPBlockBase *Old, VPBlockBase *New) {
259 for (auto *Pred : to_vector(Old->getPredecessors()))
260 Pred->replaceSuccessor(Old, New);
261 for (auto *Succ : to_vector(Old->getSuccessors()))
262 Succ->replacePredecessor(Old, New);
263 New->setPredecessors(Old->getPredecessors());
264 New->setSuccessors(Old->getSuccessors());
265 Old->clearPredecessors();
266 Old->clearSuccessors();
267 }
268
269 /// Transfer successors from \p Old to \p New. \p New must have no successors.
271 for (auto *Succ : Old->getSuccessors())
272 Succ->replacePredecessor(Old, New);
273 New->setSuccessors(Old->getSuccessors());
274 Old->clearSuccessors();
275 }
276
277 /// Clone the CFG for all nodes reachable from \p Entry, including cloning
278 /// the blocks and their recipes. Operands of cloned recipes will NOT be
279 /// updated. Remapping of operands must be done separately. Returns a pair
280 /// with the new entry and exiting blocks of the cloned region. If \p Entry
281 /// isn't part of a region, return nullptr for the exiting block.
282 static std::pair<VPBlockBase *, VPBlockBase *> cloneFrom(VPBlockBase *Entry);
283
284 /// Return an iterator range over \p Range which only includes \p BlockTy
285 /// blocks. The accesses are casted to \p BlockTy.
286 template <typename BlockTy, typename T> static auto blocksOnly(T &&Range) {
287 // Create BaseTy with correct const-ness based on BlockTy.
288 using BaseTy = std::conditional_t<std::is_const<BlockTy>::value,
289 const VPBlockBase, VPBlockBase>;
290
291 // We need to first create an iterator range over (const) BlocktTy & instead
292 // of (const) BlockTy * for filter_range to work properly.
293 auto Mapped =
294 map_range(Range, [](BaseTy *Block) -> BaseTy & { return *Block; });
296 Mapped, [](BaseTy &Block) { return isa<BlockTy>(&Block); });
297 return map_range(Filter, [](BaseTy &Block) -> BlockTy * {
298 return cast<BlockTy>(&Block);
299 });
300 }
301
302 /// Returns the blocks between \p FirstBB and \p LastBB, where FirstBB
303 /// to LastBB forms a single-sucessor chain.
306 VPBasicBlock *LastBB);
307
308 /// Inserts \p BlockPtr on the edge between \p From and \p To. That is, update
309 /// \p From's successor to \p To to point to \p BlockPtr and \p To's
310 /// predecessor from \p From to \p BlockPtr. \p From and \p To are added to \p
311 /// BlockPtr's predecessors and successors respectively. There must be a
312 /// single edge between \p From and \p To.
313 static void insertOnEdge(VPBlockBase *From, VPBlockBase *To,
314 VPBlockBase *BlockPtr) {
315 unsigned SuccIdx = From->getIndexForSuccessor(To);
316 unsigned PredIx = To->getIndexForPredecessor(From);
317 VPBlockUtils::connectBlocks(From, BlockPtr, -1, SuccIdx);
318 VPBlockUtils::connectBlocks(BlockPtr, To, PredIx, -1);
319 }
320
321 /// Returns true if \p VPB is a loop header, based on regions or \p VPDT in
322 /// their absence.
323 static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT);
324
325 /// Returns true if \p VPB is a loop latch, using isHeader().
326 static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT);
327};
328
329} // namespace llvm
330
331#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 I(x, y, z)
Definition MD5.cpp:57
#define T
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
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.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4160
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:98
VPRegionBlock * getParent()
Definition VPlan.h:190
iterator_range< VPBlockBase ** > predecessors()
Definition VPlan.h:224
bool hasPredecessors() const
Returns true if this block has any predecessors.
Definition VPlan.h:221
unsigned getIndexForSuccessor(const VPBlockBase *Succ) const
Returns the index for Succ in the blocks successor list.
Definition VPlan.h:354
void setPredecessors(ArrayRef< VPBlockBase * > NewPreds)
Set each VPBasicBlock in NewPreds as predecessor of this VPBlockBase.
Definition VPlan.h:310
unsigned getIndexForPredecessor(const VPBlockBase *Pred) const
Returns the index for Pred in the blocks predecessors list.
Definition VPlan.h:347
bool hasSuccessors() const
Returns true if this block has any successors.
Definition VPlan.h:219
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:226
void clearSuccessors()
Remove all the successors of this block.
Definition VPlan.h:329
void setTwoSuccessors(VPBlockBase *IfTrue, VPBlockBase *IfFalse)
Set two given VPBlockBases IfTrue and IfFalse to be the two successors of this VPBlockBase.
Definition VPlan.h:301
void clearPredecessors()
Remove all the predecessor of this block.
Definition VPlan.h:326
void setParent(VPRegionBlock *P)
Definition VPlan.h:201
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:215
static void insertBlockAfter(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected VPBlockBase NewBlock after BlockPtr.
Definition VPlanUtils.h:184
static void insertOnEdge(VPBlockBase *From, VPBlockBase *To, VPBlockBase *BlockPtr)
Inserts BlockPtr on the edge between From and To.
Definition VPlanUtils.h:313
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:214
static void connectBlocks(VPBlockBase *From, VPBlockBase *To, unsigned PredIdx=-1u, unsigned SuccIdx=-1u)
Connect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:232
static void disconnectBlocks(VPBlockBase *From, VPBlockBase *To)
Disconnect VPBlockBases From and To bi-directionally.
Definition VPlanUtils.h:250
static void reassociateBlocks(VPBlockBase *Old, VPBlockBase *New)
Reassociate all the blocks connected to Old so that they now point to New.
Definition VPlanUtils.h:258
static void insertBlockBefore(VPBlockBase *NewBlock, VPBlockBase *BlockPtr)
Insert disconnected block NewBlock before Blockptr.
Definition VPlanUtils.h:196
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:286
static void transferSuccessors(VPBlockBase *Old, VPBlockBase *New)
Transfer successors from Old to New. New must have no successors.
Definition VPlanUtils.h:270
static SmallVector< VPBasicBlock * > blocksInSingleSuccessorChainBetween(VPBasicBlock *FirstBB, VPBasicBlock *LastBB)
Returns the blocks between FirstBB and LastBB, where FirstBB to LastBB forms a single-sucessor chain.
static std::pair< VPBlockBase *, VPBlockBase * > cloneFrom(VPBlockBase *Entry)
Clone the CFG for all nodes reachable from Entry, including cloning the blocks and their recipes.
Definition VPlan.cpp:693
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Class to record and manage LLVM IR flags.
Definition VPlan.h:688
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1223
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:406
A recipe for handling reduction phis.
Definition VPlan.h:2686
VPSingleDef is a base class for recipes for modeling a sequence of one or more output IR that define ...
Definition VPlan.h:606
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:329
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:49
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:127
user_range users()
Definition VPlanValue.h:155
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4518
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
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.
bool cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking=false)
Return true if we do not know how to (mechanically) hoist or sink R.
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.
VPInstruction * findComputeReductionResult(VPReductionPHIRecipe *PhiR)
Find the ComputeReductionResult recipe for PhiR, looking through selects inserted for predicated redu...
VPInstruction * findCanonicalIVIncrement(VPlan &Plan)
Find the canonical IV increment of Plan's vector loop region.
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:98
VPRecipeBase * findRecipe(VPValue *Start, PredT Pred)
Search Start's users for a recipe satisfying Pred, looking through recipes with definitions.
Definition VPlanUtils.h:115
VPSingleDefRecipe * findHeaderMask(VPlan &Plan)
Collect the header mask with the pattern: (ICMP_ULE, WideCanonicalIV, backedge-taken-count) TODO: Int...
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
static VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
Definition VPlanUtils.h:136
LLVM_ABI_FOR_TEST std::optional< VPValue * > getRecipesForUncountableExit(SmallVectorImpl< VPInstruction * > &Recipes, SmallVectorImpl< VPInstruction * > &GEPs, VPBasicBlock *LatchVPBB)
Returns the VPValue representing the uncountable exit comparison used by AnyOf if the recipes it depe...
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.
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 cast_or_null(const Y &Val)
Definition Casting.h:714
auto map_range(ContainerTy &&C, FuncTy F)
Return a range that applies F to the elements of C.
Definition STLExtras.h:365
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:551
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
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1771