LLVM 22.0.0git
VPlanUtils.cpp
Go to the documentation of this file.
1//===- VPlanUtils.cpp - VPlan-related utilities ---------------------------===//
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 "VPlanUtils.h"
10#include "VPlanAnalysis.h"
11#include "VPlanCFG.h"
12#include "VPlanDominatorTree.h"
13#include "VPlanPatternMatch.h"
14#include "llvm/ADT/TypeSwitch.h"
18
19using namespace llvm;
20using namespace llvm::VPlanPatternMatch;
21using namespace llvm::SCEVPatternMatch;
22
24 return all_of(Def->users(),
25 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
26}
27
29 return all_of(Def->users(),
30 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
31}
32
34 return all_of(Def->users(),
35 [Def](const VPUser *U) { return U->usesScalars(Def); });
36}
37
39 if (auto *E = dyn_cast<SCEVConstant>(Expr))
40 return Plan.getOrAddLiveIn(E->getValue());
41 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
42 // value. Otherwise the value may be defined in a loop and using it directly
43 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
44 // form.
45 auto *U = dyn_cast<SCEVUnknown>(Expr);
46 if (U && !isa<Instruction>(U->getValue()))
47 return Plan.getOrAddLiveIn(U->getValue());
48 auto *Expanded = new VPExpandSCEVRecipe(Expr);
49 Plan.getEntry()->appendRecipe(Expanded);
50 return Expanded;
51}
52
53bool vputils::isHeaderMask(const VPValue *V, const VPlan &Plan) {
55 return true;
56
57 auto IsWideCanonicalIV = [](VPValue *A) {
61 };
62
63 VPValue *A, *B;
64
65 auto m_CanonicalScalarIVSteps =
67 m_One(), m_Specific(&Plan.getVF()));
68
70 return B == Plan.getTripCount() &&
71 (match(A, m_CanonicalScalarIVSteps) || IsWideCanonicalIV(A));
72
73 // For scalar plans, the header mask uses the scalar steps.
74 if (match(V, m_ICmp(m_CanonicalScalarIVSteps,
76 assert(Plan.hasScalarVFOnly() &&
77 "Non-scalar VF using scalar IV steps for header mask?");
78 return true;
79 }
80
81 return match(V, m_ICmp(m_VPValue(A), m_VPValue(B))) && IsWideCanonicalIV(A) &&
82 B == Plan.getBackedgeTakenCount();
83}
84
87 const Loop *L) {
88 ScalarEvolution &SE = *PSE.getSE();
89 if (V->isLiveIn()) {
90 Value *LiveIn = V->getLiveInIRValue();
91 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
92 return SE.getSCEV(LiveIn);
93 return SE.getCouldNotCompute();
94 }
95
96 // Helper to create SCEVs for binary and unary operations.
97 auto CreateSCEV =
99 function_ref<const SCEV *(ArrayRef<const SCEV *>)> CreateFn)
100 -> const SCEV * {
102 for (VPValue *Op : Ops) {
103 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
105 return SE.getCouldNotCompute();
106 SCEVOps.push_back(S);
107 }
108 return CreateFn(SCEVOps);
109 };
110
111 VPValue *LHSVal, *RHSVal;
112 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
113 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
114 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
115 });
116 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
117 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
118 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
119 });
120 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
121 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
122 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
123 return CreateSCEV({LHSVal}, [&](ArrayRef<const SCEV *> Ops) {
124 return SE.getTruncateExpr(Ops[0], DestTy);
125 });
126 }
127 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
128 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
129 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
130 return CreateSCEV({LHSVal}, [&](ArrayRef<const SCEV *> Ops) {
131 return SE.getZeroExtendExpr(Ops[0], DestTy);
132 });
133 }
134 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
135 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
136 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
137 return CreateSCEV({LHSVal}, [&](ArrayRef<const SCEV *> Ops) {
138 return SE.getSignExtendExpr(Ops[0], DestTy);
139 });
140 }
141 if (match(V,
143 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
144 return SE.getUMaxExpr(Ops[0], Ops[1]);
145 });
146 if (match(V,
148 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
149 return SE.getSMaxExpr(Ops[0], Ops[1]);
150 });
151 if (match(V,
153 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
154 return SE.getUMinExpr(Ops[0], Ops[1]);
155 });
156 if (match(V,
158 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
159 return SE.getSMinExpr(Ops[0], Ops[1]);
160 });
161
162 // TODO: Support constructing SCEVs for more recipes as needed.
163 const VPRecipeBase *DefR = V->getDefiningRecipe();
166 [](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
167 .Case<VPCanonicalIVPHIRecipe>([&SE, &PSE,
168 L](const VPCanonicalIVPHIRecipe *R) {
169 if (!L)
170 return SE.getCouldNotCompute();
171 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
172 return SE.getAddRecExpr(Start, SE.getOne(Start->getType()), L,
174 })
175 .Case<VPWidenIntOrFpInductionRecipe>(
176 [&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
177 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
178 if (!L || isa<SCEVCouldNotCompute>(Step))
179 return SE.getCouldNotCompute();
180 const SCEV *Start =
181 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
182 const SCEV *AddRec =
183 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
184 if (R->getTruncInst())
185 return SE.getTruncateExpr(AddRec, R->getScalarType());
186 return AddRec;
187 })
188 .Case<VPDerivedIVRecipe>([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
189 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
190 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
191 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
192 if (any_of(ArrayRef({Start, IV, Scale}), IsaPred<SCEVCouldNotCompute>))
193 return SE.getCouldNotCompute();
194
195 return SE.getAddExpr(SE.getTruncateOrSignExtend(Start, IV->getType()),
197 Scale, IV->getType())));
198 })
199 .Case<VPScalarIVStepsRecipe>([&SE, &PSE,
200 L](const VPScalarIVStepsRecipe *R) {
201 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
202 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
204 !Step->isOne())
205 return SE.getCouldNotCompute();
206 return SE.getMulExpr(SE.getTruncateOrSignExtend(IV, Step->getType()),
207 Step);
208 })
209 .Case<VPReplicateRecipe>([&SE, &PSE, L](const VPReplicateRecipe *R) {
210 if (R->getOpcode() != Instruction::GetElementPtr)
211 return SE.getCouldNotCompute();
212
213 const SCEV *Base = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
215 return SE.getCouldNotCompute();
216
217 SmallVector<const SCEV *> IndexExprs;
218 for (VPValue *Index : drop_begin(R->operands())) {
219 const SCEV *IndexExpr = getSCEVExprForVPValue(Index, PSE, L);
220 if (isa<SCEVCouldNotCompute>(IndexExpr))
221 return SE.getCouldNotCompute();
222 IndexExprs.push_back(IndexExpr);
223 }
224
225 Type *SrcElementTy = cast<GetElementPtrInst>(R->getUnderlyingInstr())
226 ->getSourceElementType();
227 return SE.getGEPExpr(Base, IndexExprs, SrcElementTy);
228 })
229 .Default(
230 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
231
232 return PSE.getPredicatedSCEV(Expr);
233}
234
236 const Loop *L) {
237 // If address is an SCEVAddExpr, we require that all operands must be either
238 // be invariant or a (possibly sign-extend) affine AddRec.
239 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
240 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
241 return SE.isLoopInvariant(Op, L) ||
242 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
243 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
244 });
245 }
246
247 // Otherwise, check if address is loop invariant or an affine add recurrence.
248 return SE.isLoopInvariant(Addr, L) ||
250}
251
252/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
253/// uniform, the result will also be uniform.
254static bool preservesUniformity(unsigned Opcode) {
255 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
256 return true;
257 switch (Opcode) {
258 case Instruction::GetElementPtr:
259 case Instruction::ICmp:
260 case Instruction::FCmp:
261 case Instruction::Select:
265 return true;
266 default:
267 return false;
268 }
269}
270
272 // A live-in must be uniform across the scope of VPlan.
273 if (VPV->isLiveIn())
274 return true;
275
276 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
277 const VPRegionBlock *RegionOfR = Rep->getRegion();
278 // Don't consider recipes in replicate regions as uniform yet; their first
279 // lane cannot be accessed when executing the replicate region for other
280 // lanes.
281 if (RegionOfR && RegionOfR->isReplicator())
282 return false;
283 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
284 all_of(Rep->operands(), isSingleScalar));
285 }
289 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
290 return preservesUniformity(WidenR->getOpcode()) &&
291 all_of(WidenR->operands(), isSingleScalar);
292 }
293 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
294 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
295 (preservesUniformity(VPI->getOpcode()) &&
296 all_of(VPI->operands(), isSingleScalar));
297 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
298 return !RR->isPartialReduction();
301 return true;
302 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
303 return Expr->isSingleScalar();
304
305 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
306 return isa<VPExpandSCEVRecipe>(VPV);
307}
308
310 // Live-ins are uniform.
311 if (V->isLiveIn())
312 return true;
313
314 VPRecipeBase *R = V->getDefiningRecipe();
315 if (R && V->isDefinedOutsideLoopRegions()) {
316 if (match(V->getDefiningRecipe(),
318 return false;
319 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
320 }
321
322 auto *CanonicalIV =
323 R->getParent()->getEnclosingLoopRegion()->getCanonicalIV();
324 // Canonical IV chain is uniform.
325 if (V == CanonicalIV || V == CanonicalIV->getBackedgeValue())
326 return true;
327
329 .Case<VPDerivedIVRecipe>([](const auto *R) { return true; })
330 .Case<VPReplicateRecipe>([](const auto *R) {
331 // Be conservative about side-effects, except for the
332 // known-side-effecting assumes and stores, which we know will be
333 // uniform.
334 return R->isSingleScalar() &&
335 (!R->mayHaveSideEffects() ||
336 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
337 all_of(R->operands(), isUniformAcrossVFsAndUFs);
338 })
339 .Case<VPWidenRecipe>([](const auto *R) {
340 return preservesUniformity(R->getOpcode()) &&
341 all_of(R->operands(), isUniformAcrossVFsAndUFs);
342 })
343 .Case<VPInstruction>([](const auto *VPI) {
344 return (VPI->isScalarCast() &&
345 isUniformAcrossVFsAndUFs(VPI->getOperand(0))) ||
346 (preservesUniformity(VPI->getOpcode()) &&
347 all_of(VPI->operands(), isUniformAcrossVFsAndUFs));
348 })
349 .Case<VPWidenCastRecipe>([](const auto *R) {
350 // A cast is uniform according to its operand.
351 return isUniformAcrossVFsAndUFs(R->getOperand(0));
352 })
353 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
354 // unless proven otherwise.
355 return false;
356 });
357}
358
360 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
361 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
362 return VPBlockUtils::isHeader(VPB, VPDT);
363 });
364 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
365}
366
368 if (!R)
369 return 1;
370 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
371 return RR->getVFScaleFactor();
372 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
373 return RR->getVFScaleFactor();
374 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
375 return ER->getVFScaleFactor();
376 assert(
379 "getting scaling factor of reduction-start-vector not implemented yet");
380 return 1;
381}
382
383std::optional<VPValue *>
387 // Given a VPlan like the following (just including the recipes contributing
388 // to loop control exiting here, not the actual work), we're looking to match
389 // the recipes contributing to the uncountable exit condition comparison
390 // (here, vp<%4>) back to either live-ins or the address nodes for the load
391 // used as part of the uncountable exit comparison so that we can copy them
392 // to a preheader and rotate the address in the loop to the next vector
393 // iteration.
394 //
395 // Currently, the address of the load is restricted to a GEP with 2 operands
396 // and a live-in base address. This constraint may be relaxed later.
397 //
398 // VPlan ' for UF>=1' {
399 // Live-in vp<%0> = VF
400 // Live-in ir<64> = original trip-count
401 //
402 // entry:
403 // Successor(s): preheader, vector.ph
404 //
405 // vector.ph:
406 // Successor(s): vector loop
407 //
408 // <x1> vector loop: {
409 // vector.body:
410 // EMIT vp<%2> = CANONICAL-INDUCTION ir<0>
411 // vp<%3> = SCALAR-STEPS vp<%2>, ir<1>, vp<%0>
412 // CLONE ir<%ee.addr> = getelementptr ir<0>, vp<%3>
413 // WIDEN ir<%ee.load> = load ir<%ee.addr>
414 // WIDEN vp<%4> = icmp eq ir<%ee.load>, ir<0>
415 // EMIT vp<%5> = any-of vp<%4>
416 // EMIT vp<%6> = add vp<%2>, vp<%0>
417 // EMIT vp<%7> = icmp eq vp<%6>, ir<64>
418 // EMIT vp<%8> = or vp<%5>, vp<%7>
419 // EMIT branch-on-cond vp<%8>
420 // No successors
421 // }
422 // Successor(s): middle.block
423 //
424 // middle.block:
425 // Successor(s): preheader
426 //
427 // preheader:
428 // No successors
429 // }
430
431 // Find the uncountable loop exit condition.
432 auto *Region = Plan.getVectorLoopRegion();
433 VPValue *UncountableCondition = nullptr;
434 if (!match(Region->getExitingBasicBlock()->getTerminator(),
436 m_AnyOf(m_VPValue(UncountableCondition)), m_VPValue())))))
437 return std::nullopt;
438
440 Worklist.push_back(UncountableCondition);
441 while (!Worklist.empty()) {
442 VPValue *V = Worklist.pop_back_val();
443
444 // Any value defined outside the loop does not need to be copied.
445 if (V->isDefinedOutsideLoopRegions())
446 continue;
447
448 // FIXME: Remove the single user restriction; it's here because we're
449 // starting with the simplest set of loops we can, and multiple
450 // users means needing to add PHI nodes in the transform.
451 if (V->getNumUsers() > 1)
452 return std::nullopt;
453
454 VPValue *Op1, *Op2;
455 // Walk back through recipes until we find at least one load from memory.
456 if (match(V, m_ICmp(m_VPValue(Op1), m_VPValue(Op2)))) {
457 Worklist.push_back(Op1);
458 Worklist.push_back(Op2);
459 Recipes.push_back(V->getDefiningRecipe());
460 } else if (auto *Load = dyn_cast<VPWidenLoadRecipe>(V)) {
461 // Reject masked loads for the time being; they make the exit condition
462 // more complex.
463 if (Load->isMasked())
464 return std::nullopt;
465
466 VPValue *GEP = Load->getAddr();
468 return std::nullopt;
469
470 Recipes.push_back(Load);
471 Recipes.push_back(GEP->getDefiningRecipe());
472 GEPs.push_back(GEP->getDefiningRecipe());
473 } else
474 return std::nullopt;
475 }
476
477 return UncountableCondition;
478}
479
481 const VPDominatorTree &VPDT) {
482 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
483 if (!VPBB)
484 return false;
485
486 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
487 // VPBB as its entry, i.e., free of predecessors.
488 if (auto *R = VPBB->getParent())
489 return !R->isReplicator() && !VPBB->hasPredecessors();
490
491 // A header dominates its second predecessor (the latch), with the other
492 // predecessor being the preheader
493 return VPB->getPredecessors().size() == 2 &&
494 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
495}
496
498 const VPDominatorTree &VPDT) {
499 // A latch has a header as its second successor, with its other successor
500 // leaving the loop. A preheader OTOH has a header as its first (and only)
501 // successor.
502 return VPB->getNumSuccessors() == 2 &&
503 VPBlockUtils::isHeader(VPB->getSuccessors()[1], VPDT);
504}
505
506std::optional<MemoryLocation>
508 auto *M = dyn_cast<VPIRMetadata>(&R);
509 if (!M)
510 return std::nullopt;
512 // Populate noalias metadata from VPIRMetadata.
513 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
514 Loc.AATags.NoAlias = NoAliasMD;
515 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
516 Loc.AATags.Scope = AliasScopeMD;
517 return Loc;
518}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Hexagon Common GEP
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
#define I(x, y, z)
Definition MD5.cpp:57
This file provides utility analysis objects describing memory locations.
This file implements the TypeSwitch template, which mimics a switch() statement whose cases are type ...
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition VPlanSLP.cpp:247
static bool preservesUniformity(unsigned Opcode)
Returns true if Opcode preserves uniformity, i.e., if all operands are uniform, the result will also ...
static const uint32_t IV[8]
Definition blake3_impl.h:83
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
bool isCast() const
bool isBinaryOp() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1078
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 ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getPredicatedSCEV(const SCEV *Expr)
Returns the rewritten SCEV for Expr in the context of the current SCEV predicate.
This class represents an analyzed expression in the program.
LLVM_ABI bool isOne() const
Return true if the expression is a constant one.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getSMaxExpr(const SCEV *LHS, const SCEV *RHS)
LLVM_ABI const SCEV * getSMinExpr(const SCEV *LHS, const SCEV *RHS)
LLVM_ABI const SCEV * getUMaxExpr(const SCEV *LHS, const SCEV *RHS)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI const SCEV * getAddRecExpr(const SCEV *Start, const SCEV *Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
LLVM_ABI const SCEV * getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getUMinExpr(const SCEV *LHS, const SCEV *RHS, bool Sequential=false)
LLVM_ABI const SCEV * getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getMinusSCEV(const SCEV *LHS, const SCEV *RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getCouldNotCompute()
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< const SCEV * > IndexExprs)
Returns an expression for a GEP.
LLVM_ABI const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< const SCEV * > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI const SCEV * getTruncateOrSignExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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 class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
Definition TypeSwitch.h:88
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition TypeSwitch.h:97
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:3982
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4057
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
Definition VPlan.h:2530
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:81
size_t getNumSuccessors() const
Definition VPlan.h:219
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:204
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:198
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.
Canonical scalar induction phi of the vector loop.
Definition VPlan.h:3565
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition VPlan.h:3732
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:3527
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1125
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:387
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4170
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4238
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the region.
Definition VPlan.h:4268
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:2953
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:3802
An analysis for type-inference for VPValues.
Type * inferScalarType(const VPValue *V)
Infer the type of V. Returns the scalar type of V.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:202
operand_range operands()
Definition VPlanValue.h:270
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:46
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:131
bool isLiveIn() const
Returns true if this VPValue is a live-in, i.e. defined outside the VPlan.
Definition VPlanValue.h:176
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:1915
A recipe to compute the pointers for widened memory accesses of SourceElementTy.
Definition VPlan.h:1976
A recipe for handling GEP instructions.
Definition VPlan.h:1852
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2199
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4300
VPBasicBlock * getEntry()
Definition VPlan.h:4389
VPValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4483
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:4451
VPValue * getBackedgeTakenCount() const
Definition VPlan.h:4477
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1010
VPValue * getOrAddLiveIn(Value *V)
Gets the live-in VPValue for V or adds a new live-in (if none exists yet) for V.
Definition VPlan.h:4543
bool hasScalarVFOnly() const
Definition VPlan.h:4512
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:256
An efficient, type-erasing, non-owning reference to a callable.
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
SCEVAffineAddRec_match< Op0_t, Op1_t, class_match< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
bool match(const SCEV *S, const Pattern &P)
class_match< const SCEV > m_SCEV()
VPInstruction_match< VPInstruction::AnyOf > m_AnyOf()
AllRecipe_commutative_match< Instruction::Or, Op0_t, Op1_t > m_c_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
VPScalarIVSteps_match< Op0_t, Op1_t, Op2_t > m_ScalarIVSteps(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
GEPLikeRecipe_match< Op0_t, Op1_t > m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
VPInstruction_match< VPInstruction::ActiveLaneMask, Op0_t, Op1_t, Op2_t > m_ActiveLaneMask(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
class_match< VPValue > m_VPValue()
Match an arbitrary VPValue and ignore it.
bind_ty< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
VPInstruction_match< VPInstruction::BranchOnCond > m_BranchOnCond()
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.
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 drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1737
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< VPBlockShallowTraversalWrapper< VPBlockBase * > > > vp_depth_first_shallow(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order.
Definition VPlanCFG.h:216
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:1744
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
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
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:1770
@ Default
The result values are uniform if and only if all operands are uniform.
Definition Uniformity.h:20
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
A recipe for widening select instructions.
Definition VPlan.h:1805