LLVM 24.0.0git
VPlanAnalysis.cpp
Go to the documentation of this file.
1//===- VPlanAnalysis.cpp - Various Analyses working on VPlan ----*- 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#include "VPlanAnalysis.h"
11#include "VPlan.h"
12#include "VPlanCFG.h"
13#include "VPlanDominatorTree.h"
14#include "VPlanHelpers.h"
15#include "VPlanPatternMatch.h"
16#include "VPlanUtils.h"
21
22using namespace llvm;
23using namespace VPlanPatternMatch;
24
25#define DEBUG_TYPE "vplan"
26
28 VPlan &Plan, DenseSet<VPRecipeBase *> &EphRecipes) {
29 // First, collect seed recipes which are operands of assumes.
35 continue;
36 Worklist.push_back(&RepR);
37 EphRecipes.insert(&RepR);
38 }
39 }
40
41 // Process operands of candidates in worklist and add them to the set of
42 // ephemeral recipes, if they don't have side-effects and are only used by
43 // other ephemeral recipes.
44 while (!Worklist.empty()) {
45 VPRecipeBase *Cur = Worklist.pop_back_val();
46 for (VPValue *Op : Cur->operands()) {
47 auto *OpR = Op->getDefiningRecipe();
48 if (!OpR || OpR->mayHaveSideEffects() || EphRecipes.contains(OpR))
49 continue;
50 if (any_of(Op->users(), [EphRecipes](VPUser *U) {
51 auto *UR = dyn_cast<VPRecipeBase>(U);
52 return !UR || !EphRecipes.contains(UR);
53 }))
54 continue;
55 EphRecipes.insert(OpR);
56 Worklist.push_back(OpR);
57 }
58 }
59}
60
62 const VPRecipeBase *B) const {
63 if (A == B)
64 return false;
65
66 auto LocalComesBefore = [](const VPRecipeBase *A, const VPRecipeBase *B) {
67 for (auto &R : *A->getParent()) {
68 if (&R == A)
69 return true;
70 if (&R == B)
71 return false;
72 }
73 llvm_unreachable("recipe not found");
74 };
75 const VPBlockBase *ParentA = A->getParent();
76 const VPBlockBase *ParentB = B->getParent();
77 if (ParentA == ParentB)
78 return LocalComesBefore(A, B);
79
80 return Base::properlyDominates(ParentA, ParentB);
81}
82
86 unsigned OverrideMaxNumRegs) const {
88 for (const auto &[RegClass, MaxUsers] : MaxLocalUsers) {
89 unsigned AvailableRegs = OverrideMaxNumRegs > 0
90 ? OverrideMaxNumRegs
91 : TTI.getNumberOfRegisters(RegClass);
92 if (MaxUsers > AvailableRegs) {
93 // Assume that for each register used past what's available we get one
94 // spill and reload.
95 unsigned Spills = MaxUsers - AvailableRegs;
96 InstructionCost SpillCost =
97 TTI.getRegisterClassSpillCost(RegClass, CostKind) +
98 TTI.getRegisterClassReloadCost(RegClass, CostKind);
99 InstructionCost TotalCost = Spills * SpillCost;
100 LLVM_DEBUG(dbgs() << "LV(REG): Cost of " << TotalCost << " from "
101 << Spills << " spills of "
102 << TTI.getRegisterClassName(RegClass) << "\n");
103 Cost += TotalCost;
104 }
105 }
106 return Cost;
107}
108
111 const TargetTransformInfo &TTI) {
112 DenseSet<VPRecipeBase *> EphemeralRecipes;
113 collectEphemeralRecipesForVPlan(Plan, EphemeralRecipes);
114
115 // Each 'key' in the map opens a new interval. The values
116 // of the map are the index of the 'last seen' usage of the
117 // VPValue that is the key.
119
120 // Maps indices to recipes.
122 // Marks the end of each interval.
123 IntervalMap EndPoint;
124 // Saves the list of VPValues that are used in the loop.
126 // Saves the list of values that are used in the loop but are defined outside
127 // the loop (not including non-recipe values such as arguments and
128 // constants).
129 SmallSetVector<VPValue *, 8> LoopInvariants;
130 if (!Plan.getVectorTripCount().user_empty())
131 LoopInvariants.insert(&Plan.getVectorTripCount());
132
133 // We scan the loop in a topological order in order and assign a number to
134 // each recipe. We use RPO to ensure that defs are met before their users. We
135 // assume that each recipe that has in-loop users starts an interval. We
136 // record every time that an in-loop value is used, so we have a list of the
137 // first occurences of each recipe and last occurrence of each VPValue.
138 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
140 LoopRegion);
142 if (!VPBB->getParent())
143 break;
144 for (VPRecipeBase &R : *VPBB) {
145 Idx2Recipe.push_back(&R);
146
147 // Save the end location of each USE.
148 for (VPValue *U : R.operands()) {
149 if (isa<VPRecipeValue>(U)) {
150 // Overwrite previous end points.
151 EndPoint[U] = Idx2Recipe.size();
152 Ends.insert(U);
153 } else if (auto *IRV = dyn_cast<VPIRValue>(U)) {
154 // Ignore non-recipe values such as arguments, constants, etc.
155 // FIXME: Might need some motivation why these values are ignored. If
156 // for example an argument is used inside the loop it will increase
157 // the register pressure (so shouldn't we add it to LoopInvariants).
158 if (!isa<Instruction>(IRV->getValue()))
159 continue;
160 // This recipe is outside the loop, record it and continue.
161 LoopInvariants.insert(U);
162 }
163 // Other types of VPValue are currently not tracked.
164 }
165 }
166 if (VPBB == LoopRegion->getExiting()) {
167 // VPWidenIntOrFpInductionRecipes are used implicitly at the end of the
168 // exiting block, where their increment will get materialized eventually.
170 LoopRegion->getEntryBasicBlock()->phis())) {
171 EndPoint[&WideIV] = Idx2Recipe.size();
172 Ends.insert(&WideIV);
173 }
174 }
175 }
176
177 // Saves the list of intervals that end with the index in 'key'.
178 using VPValueList = SmallVector<VPValue *, 2>;
180
181 // Next, we transpose the EndPoints into a multi map that holds the list of
182 // intervals that *end* at a specific location.
183 for (auto &Interval : EndPoint)
184 TransposeEnds[Interval.second].push_back(Interval.first);
185
186 SmallPtrSet<VPValue *, 8> OpenIntervals;
189
190 LLVM_DEBUG(dbgs() << "LV(REG): Calculating max register usage:\n");
191
192 const auto &TTICapture = TTI;
193 auto GetRegUsage = [&TTICapture](Type *Ty, ElementCount VF) -> unsigned {
194 if (Ty->isTokenTy() || !VectorType::isValidElementType(Ty) ||
195 (VF.isScalable() &&
196 !TTICapture.isElementTypeLegalForScalableVector(Ty)))
197 return 0;
198 return TTICapture.getRegUsageForType(VectorType::get(Ty, VF));
199 };
200
201 VPValue *CanIV = LoopRegion->getCanonicalIV();
202 // Note: canonical IVs are retained even if they have no users.
203 if (!CanIV->user_empty())
204 OpenIntervals.insert(CanIV);
205
206 // We scan the instructions linearly and record each time that a new interval
207 // starts, by placing it in a set. If we find this value in TransposEnds then
208 // we remove it from the set. The max register usage is the maximum register
209 // usage of the recipes of the set.
210 for (unsigned int Idx = 0, Sz = Idx2Recipe.size(); Idx < Sz; ++Idx) {
211 VPRecipeBase *R = Idx2Recipe[Idx];
212
213 // Remove all of the VPValues that end at this location.
214 VPValueList &List = TransposeEnds[Idx];
215 for (VPValue *ToRemove : List)
216 OpenIntervals.erase(ToRemove);
217
218 // Ignore recipes that are never used within the loop and do not have side
219 // effects.
220 if (none_of(R->definedValues(),
221 [&Ends](VPValue *Def) { return Ends.count(Def); }) &&
222 !R->mayHaveSideEffects())
223 continue;
224
225 // Skip recipes for ephemeral values, i.e. those only feeding assumes. They
226 // are removed before code generation and must not contribute to the
227 // register pressure of the plan.
228 if (EphemeralRecipes.contains(R))
229 continue;
230
231 // For each VF find the maximum usage of registers.
232 for (unsigned J = 0, E = VFs.size(); J < E; ++J) {
233 // Count the number of registers used, per register class, given all open
234 // intervals.
235 // Note that elements in this SmallMapVector will be default constructed
236 // as 0. So we can use "RegUsage[ClassID] += n" in the code below even if
237 // there is no previous entry for ClassID.
239
240 for (auto *VPV : OpenIntervals) {
241 // Skip artificial values or values that weren't present in the original
242 // loop.
243 // TODO: Remove skipping values that weren't present in the original
244 // loop after removing the legacy
245 // LoopVectorizationCostModel::calculateRegisterUsage
247 VPBranchOnMaskRecipe>(VPV) ||
249 continue;
250
251 if (VFs[J].isScalar() || VPV == CanIV ||
256 (cast<VPReductionPHIRecipe>(VPV))->isInLoop())) {
257 unsigned ClassID =
258 TTI.getRegisterClassForType(false, VPV->getScalarType());
259 // FIXME: The target might use more than one register for the type
260 // even in the scalar case.
261 RegUsage[ClassID] += 1;
262 } else {
263 // The output from scaled phis and scaled reductions actually has
264 // fewer lanes than the VF.
265 unsigned ScaleFactor =
266 vputils::getVFScaleFactor(VPV->getDefiningRecipe());
267 ElementCount VF = VFs[J];
268 if (ScaleFactor > 1) {
269 VF = VFs[J].divideCoefficientBy(ScaleFactor);
270 LLVM_DEBUG(dbgs() << "LV(REG): Scaled down VF from " << VFs[J]
271 << " to " << VF << " for " << *R << "\n";);
272 }
273
274 Type *ScalarTy = VPV->getScalarType();
275 unsigned ClassID = TTI.getRegisterClassForType(true, ScalarTy);
276 RegUsage[ClassID] += GetRegUsage(ScalarTy, VF);
277 }
278 }
279
280 for (const auto &Pair : RegUsage) {
281 auto &Entry = MaxUsages[J][Pair.first];
282 Entry = std::max(Entry, Pair.second);
283 }
284 }
285
286 LLVM_DEBUG(dbgs() << "LV(REG): At #" << Idx << " Interval # "
287 << OpenIntervals.size() << '\n');
288
289 // Add used VPValues defined by the current recipe to the list of open
290 // intervals.
291 for (VPValue *DefV : R->definedValues())
292 if (Ends.contains(DefV))
293 OpenIntervals.insert(DefV);
294 }
295
296 // We also search for instructions that are defined outside the loop, but are
297 // used inside the loop. We need this number separately from the max-interval
298 // usage number because when we unroll, loop-invariant values do not take
299 // more register.
301 for (unsigned Idx = 0, End = VFs.size(); Idx < End; ++Idx) {
302 // Note that elements in this SmallMapVector will be default constructed
303 // as 0. So we can use "Invariant[ClassID] += n" in the code below even if
304 // there is no previous entry for ClassID.
306
307 for (auto *In : LoopInvariants) {
308 // FIXME: The target might use more than one register for the type
309 // even in the scalar case.
310 bool IsScalar = vputils::onlyScalarValuesUsed(In);
311
312 ElementCount VF = IsScalar ? ElementCount::getFixed(1) : VFs[Idx];
313 unsigned ClassID =
314 TTI.getRegisterClassForType(VF.isVector(), In->getScalarType());
315 Invariant[ClassID] += GetRegUsage(In->getScalarType(), VF);
316 }
317
318 LLVM_DEBUG({
319 dbgs() << "LV(REG): VF = " << VFs[Idx] << '\n';
320 dbgs() << "LV(REG): Found max usage: " << MaxUsages[Idx].size()
321 << " item\n";
322 for (const auto &pair : MaxUsages[Idx]) {
323 dbgs() << "LV(REG): RegisterClass: "
324 << TTI.getRegisterClassName(pair.first) << ", " << pair.second
325 << " registers\n";
326 }
327 dbgs() << "LV(REG): Found invariant usage: " << Invariant.size()
328 << " item\n";
329 for (const auto &pair : Invariant) {
330 dbgs() << "LV(REG): RegisterClass: "
331 << TTI.getRegisterClassName(pair.first) << ", " << pair.second
332 << " registers\n";
333 }
334 });
335
336 RU.LoopInvariantRegs = Invariant;
337 RU.MaxLocalUsers = MaxUsages[Idx];
338 RUs[Idx] = RU;
339 }
340
341 return RUs;
342}
343
344//===----------------------------------------------------------------------===//
345// Outer-loop memory safety analysis.
346//===----------------------------------------------------------------------===//
347
348/// Returns the live-in IR value \p Ptr is based on, looking through GEPs, or
349/// nullptr if there is none.
350static const Value *getBaseObject(VPValue *Ptr) {
351 while (auto *VPI = dyn_cast<VPInstruction>(Ptr)) {
352 if (VPI->getOpcode() != Instruction::GetElementPtr)
353 break;
354 Ptr = VPI->getOperand(0);
355 }
356 auto *IRV = dyn_cast<VPIRValue>(Ptr);
357 return IRV ? IRV->getValue() : nullptr;
358}
359
360/// Returns true if \p ObjA and \p ObjB are known and \p AA proves they don't
361/// alias.
362static bool provablyDistinctObjects(AAResults &AA, const Value *ObjA,
363 const Value *ObjB) {
364 return ObjA && ObjB && AA.isNoAlias(ObjA, ObjB);
365}
366
367/// Returns true if a store of \p StoredTy to \p Addr in \p VPBB writes
368/// different locations on each iteration of \p OuterLoop.
370 VPBasicBlock *VPBB,
371 VPBasicBlock *Latch,
372 const VPDominatorTree &VPDT,
374 const Loop *OuterLoop) {
375 // The address cannot repeat if it is an nusw GEP on a live-in base executed
376 // in every iteration, with a single index that does not wrap.
377 auto *GEP = dyn_cast<VPInstruction>(Addr);
378 if (!GEP || GEP->getOpcode() != Instruction::GetElementPtr ||
379 GEP->getNumOperands() != 2 || !isa<VPIRValue>(GEP->getOperand(0)) ||
380 !GEP->getGEPNoWrapFlags().hasNoUnsignedSignedWrap() ||
381 !VPDT.dominates(VPBB, Latch))
382 return false;
383 auto *Idx = dyn_cast<SCEVAddRecExpr>(
384 vputils::getSCEVExprForVPValue(GEP->getOperand(1), PSE, OuterLoop));
385 if (!Idx || !Idx->hasNoUnsignedWrap())
386 return false;
387
388 if (hasIrregularType(StoredTy, Latch->getPlan()->getDataLayout()))
389 return false;
390
391 // Stride != 0 ensures no write-after-write.
392 std::optional<int64_t> Stride =
393 vputils::getConstantStride(Addr, StoredTy, PSE, OuterLoop);
394 return Stride && *Stride != 0;
395}
396
399 AAResults &AA,
400 const VPDominatorTree &VPDT,
401 const Loop *OuterLoop) {
402 SmallVector<const Value *> LoadObjects;
403 SmallVector<const Value *> StoreObjects;
404 auto [Header, Latch] = VPBlockUtils::getPlainCFGHeaderAndLatch(Plan);
405 for (VPBasicBlock *VPBB : vp_rpo_plain_cfg_loop_body(Header)) {
406 for (VPRecipeBase &R : *VPBB) {
407 if (!R.mayReadOrWriteMemory())
408 continue;
409 VPValue *Addr, *StoredVal;
411 LoadObjects.push_back(getBaseObject(Addr));
412 continue;
413 }
414 // Bail out on any other memory accesses or write-after-write conflict in
415 // the outer loop.
417 m_VPValue(Addr))) ||
419 VPBB, Latch, VPDT, PSE,
420 OuterLoop))
421 return false;
422 StoreObjects.push_back(getBaseObject(Addr));
423 }
424 }
425
426 // Stores must access objects not accessed by any other load or store in the
427 // nest.
428 for (auto [I, StoreObj] : enumerate(StoreObjects))
429 for (const Value *Obj : concat<const Value *const>(
430 ArrayRef(StoreObjects).drop_front(I + 1), LoadObjects))
431 if (!provablyDistinctObjects(AA, StoreObj, Obj))
432 return false;
433 return true;
434}
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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")))
Hexagon Common GEP
This file provides a LoopVectorizationPlanner class.
#define I(x, y, z)
Definition MD5.cpp:57
std::pair< uint64_t, uint64_t > Interval
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
static bool provablyDistinctObjects(AAResults &AA, const Value *ObjA, const Value *ObjB)
Returns true if ObjA and ObjB are known and AA proves they don't alias.
static const Value * getBaseObject(VPValue *Ptr)
Returns the live-in IR value Ptr is based on, looking through GEPs, or nullptr if there is none.
static bool writesDisjointLocationsPerIteration(VPValue *Addr, Type *StoredTy, VPBasicBlock *VPBB, VPBasicBlock *Latch, const VPDominatorTree &VPDT, PredicatedScalarEvolution &PSE, const Loop *OuterLoop)
Returns true if a store of StoredTy to Addr in VPBB writes different locations on each iteration of O...
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
This file contains the declarations of different VPlan-related auxiliary helpers.
This file contains the declarations of the Vectorization Plan base classes:
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
bool properlyDominates(const DomTreeNodeBase< VPBlockBase > *A, const DomTreeNodeBase< VPBlockBase > *B) const
constexpr bool isVector() const
One or more elements.
Definition TypeSize.h:321
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
size_type size() const
Definition MapVector.h:58
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
size_type size() const
bool erase(PtrType Ptr)
Remove pointer from the set.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4464
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4552
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:99
VPlan * getPlan()
Definition VPlan.h:201
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:183
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:418
static std::pair< VPBasicBlock *, VPBasicBlock * > getPlainCFGHeaderAndLatch(const VPlan &Plan)
Returns the header and latch of the outermost loop of Plan in plain CFG form (before regions are form...
A recipe for generating conditional branches on the bits of a mask.
Definition VPlan.h:3556
A recipe for generating the phi node tracking the current scalar iteration index.
Definition VPlan.h:4144
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4245
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
LLVM_ABI_FOR_TEST bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B) const
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:405
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4689
const VPBlockBase * getEntry() const
Definition VPlan.h:4733
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4809
const VPBlockBase * getExiting() const
Definition VPlan.h:4745
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3447
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4306
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:396
operand_range operands()
Definition VPlanValue.h:472
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:142
bool user_empty() const
Definition VPlanValue.h:161
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:2324
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2406
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4876
const DataLayout & getDataLayout() const
Definition VPlan.h:5090
VPSymbolicValue & getVectorTripCount()
The vector trip count.
Definition VPlan.h:5074
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1030
LLVM Value Representation.
Definition Value.h:75
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
static LLVM_ABI bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
bool match(Val *V, const Pattern &P)
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > m_ExtractLastPart(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
std::optional< int64_t > getConstantStride(VPValue *Addr, Type *AccessTy, PredicatedScalarEvolution &PSE, const Loop *L)
If the pointer operand Addr of a memory access is an affine AddRec w.r.t.
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
LLVM_ABI_FOR_TEST 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.
This is an optimization pass for GlobalISel generic memory operations.
SmallVector< VPBasicBlock * > vp_rpo_plain_cfg_loop_body(VPBasicBlock *Header)
Returns the VPBasicBlocks forming the loop body of a plain (pre-region) VPlan in reverse post-order s...
Definition VPlanCFG.h:262
InstructionCost Cost
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< df_iterator< VPBlockDeepTraversalWrapper< VPBlockBase * > > > vp_depth_first_deep(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order while traversing t...
Definition VPlanCFG.h:285
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1167
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
void collectEphemeralRecipesForVPlan(VPlan &Plan, DenseSet< VPRecipeBase * > &EphRecipes)
bool hasIrregularType(Type *Ty, const DataLayout &DL)
A helper function that returns true if the given type is irregular.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
SmallVector< VPRegisterUsage, 8 > calculateRegisterUsageForPlan(VPlan &Plan, ArrayRef< ElementCount > VFs, const TargetTransformInfo &TTI)
Estimate the register usage for Plan and vectorization factors in VFs by calculating the highest numb...
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
TargetTransformInfo TTI
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool proveOuterLoopMemorySafety(VPlan &Plan, PredicatedScalarEvolution &PSE, AAResults &AA, const VPDominatorTree &VPDT, const Loop *OuterLoop)
Returns true if the memory accesses in outer loop plain CFG Plan can be vectorized.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:267
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342
A struct that represents some properties of the register usage of a loop.
SmallMapVector< unsigned, unsigned, 4 > MaxLocalUsers
Holds the maximum number of concurrent live intervals in the loop.
InstructionCost spillCost(const TargetTransformInfo &TTI, TargetTransformInfo::TargetCostKind CostKind, unsigned OverrideMaxNumRegs=0) const
Calculate the estimated cost of any spills due to using more registers than the number available for ...
SmallMapVector< unsigned, unsigned, 4 > LoopInvariantRegs
Holds the number of loop invariant values that are used in the loop.