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
85/// Returns true if \p R propagates poison from any operand to its result.
89 [](const VPRecipeBase *) { return true; })
90 .Case<VPReplicateRecipe>([](const VPReplicateRecipe *Rep) {
91 // GEP and casts propagate poison from all operands.
92 unsigned Opcode = Rep->getOpcode();
93 return Opcode == Instruction::GetElementPtr ||
94 Instruction::isCast(Opcode);
95 })
96 .Default([](const VPRecipeBase *) { return false; });
97}
98
99/// Returns true if \p V being poison is guaranteed to trigger UB because it
100/// propagates to the address of a memory recipe.
101static bool poisonGuaranteesUB(const VPValue *V) {
104
105 Worklist.push_back(V);
106
107 while (!Worklist.empty()) {
108 const VPValue *Current = Worklist.pop_back_val();
109 if (!Visited.insert(Current).second)
110 continue;
111
112 for (VPUser *U : Current->users()) {
113 // Check if Current is used as an address operand for load/store.
114 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(U)) {
115 if (MemR->getAddr() == Current)
116 return true;
117 continue;
118 }
119 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
120 unsigned Opcode = Rep->getOpcode();
121 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
122 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
123 return true;
124 }
125
126 // Check if poison propagates through this recipe to any of its users.
127 auto *R = cast<VPRecipeBase>(U);
128 for (const VPValue *Op : R->operands()) {
129 if (Op == Current && propagatesPoisonFromRecipeOp(R)) {
130 Worklist.push_back(R->getVPSingleValue());
131 break;
132 }
133 }
134 }
135 }
136
137 return false;
138}
139
142 const Loop *L) {
143 ScalarEvolution &SE = *PSE.getSE();
145 Value *LiveIn = V->getUnderlyingValue();
146 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
147 return SE.getSCEV(LiveIn);
148 return SE.getCouldNotCompute();
149 }
150
151 // Helper to create SCEVs for binary and unary operations.
152 auto CreateSCEV =
154 function_ref<const SCEV *(ArrayRef<const SCEV *>)> CreateFn)
155 -> const SCEV * {
157 for (VPValue *Op : Ops) {
158 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
160 return SE.getCouldNotCompute();
161 SCEVOps.push_back(S);
162 }
163 return CreateFn(SCEVOps);
164 };
165
166 VPValue *LHSVal, *RHSVal;
167 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
168 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
169 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
170 });
171 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
172 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
173 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
174 });
175 if (match(V, m_Not(m_VPValue(LHSVal)))) {
176 // not X = xor X, -1 = -1 - X
177 return CreateSCEV({LHSVal}, [&](ArrayRef<const SCEV *> Ops) {
178 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
179 });
180 }
181 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
182 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
183 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
184 return CreateSCEV({LHSVal}, [&](ArrayRef<const SCEV *> Ops) {
185 return SE.getTruncateExpr(Ops[0], DestTy);
186 });
187 }
188 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
189 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
190 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
191 return CreateSCEV({LHSVal}, [&](ArrayRef<const SCEV *> Ops) {
192 return SE.getZeroExtendExpr(Ops[0], DestTy);
193 });
194 }
195 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
196 const VPlan *Plan = V->getDefiningRecipe()->getParent()->getPlan();
197 Type *DestTy = VPTypeAnalysis(*Plan).inferScalarType(V);
198
199 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
200 // onto the operands before computing the subtraction.
201 VPValue *SubLHS, *SubRHS;
202 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
203 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
204 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
205 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
206 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
208 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
209 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
210 }
211
212 return CreateSCEV({LHSVal}, [&](ArrayRef<const SCEV *> Ops) {
213 return SE.getSignExtendExpr(Ops[0], DestTy);
214 });
215 }
216 if (match(V,
218 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
219 return SE.getUMaxExpr(Ops[0], Ops[1]);
220 });
221 if (match(V,
223 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
224 return SE.getSMaxExpr(Ops[0], Ops[1]);
225 });
226 if (match(V,
228 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
229 return SE.getUMinExpr(Ops[0], Ops[1]);
230 });
231 if (match(V,
233 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<const SCEV *> Ops) {
234 return SE.getSMinExpr(Ops[0], Ops[1]);
235 });
236
237 // TODO: Support constructing SCEVs for more recipes as needed.
238 const VPRecipeBase *DefR = V->getDefiningRecipe();
241 [](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
242 .Case<VPCanonicalIVPHIRecipe>([&SE, &PSE,
243 L](const VPCanonicalIVPHIRecipe *R) {
244 if (!L)
245 return SE.getCouldNotCompute();
246 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
247 return SE.getAddRecExpr(Start, SE.getOne(Start->getType()), L,
249 })
250 .Case<VPWidenIntOrFpInductionRecipe>(
251 [&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
252 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
253 if (!L || isa<SCEVCouldNotCompute>(Step))
254 return SE.getCouldNotCompute();
255 const SCEV *Start =
256 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
257 const SCEV *AddRec =
258 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
259 if (R->getTruncInst())
260 return SE.getTruncateExpr(AddRec, R->getScalarType());
261 return AddRec;
262 })
263 .Case<VPDerivedIVRecipe>([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
264 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
265 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
266 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
267 if (any_of(ArrayRef({Start, IV, Scale}), IsaPred<SCEVCouldNotCompute>))
268 return SE.getCouldNotCompute();
269
270 return SE.getAddExpr(SE.getTruncateOrSignExtend(Start, IV->getType()),
272 Scale, IV->getType())));
273 })
274 .Case<VPScalarIVStepsRecipe>([&SE, &PSE,
275 L](const VPScalarIVStepsRecipe *R) {
276 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
277 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
279 !Step->isOne())
280 return SE.getCouldNotCompute();
281 return SE.getMulExpr(SE.getTruncateOrSignExtend(IV, Step->getType()),
282 Step);
283 })
284 .Case<VPReplicateRecipe>([&SE, &PSE, L](const VPReplicateRecipe *R) {
285 if (R->getOpcode() != Instruction::GetElementPtr)
286 return SE.getCouldNotCompute();
287
288 const SCEV *Base = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
290 return SE.getCouldNotCompute();
291
292 SmallVector<const SCEV *> IndexExprs;
293 for (VPValue *Index : drop_begin(R->operands())) {
294 const SCEV *IndexExpr = getSCEVExprForVPValue(Index, PSE, L);
295 if (isa<SCEVCouldNotCompute>(IndexExpr))
296 return SE.getCouldNotCompute();
297 IndexExprs.push_back(IndexExpr);
298 }
299
300 Type *SrcElementTy = cast<GetElementPtrInst>(R->getUnderlyingInstr())
301 ->getSourceElementType();
302 return SE.getGEPExpr(Base, IndexExprs, SrcElementTy);
303 })
304 .Default(
305 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
306
307 return PSE.getPredicatedSCEV(Expr);
308}
309
311 const Loop *L) {
312 // If address is an SCEVAddExpr, we require that all operands must be either
313 // be invariant or a (possibly sign-extend) affine AddRec.
314 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
315 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
316 return SE.isLoopInvariant(Op, L) ||
317 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
318 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
319 });
320 }
321
322 // Otherwise, check if address is loop invariant or an affine add recurrence.
323 return SE.isLoopInvariant(Addr, L) ||
325}
326
327/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
328/// uniform, the result will also be uniform.
329static bool preservesUniformity(unsigned Opcode) {
330 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
331 return true;
332 switch (Opcode) {
333 case Instruction::GetElementPtr:
334 case Instruction::ICmp:
335 case Instruction::FCmp:
336 case Instruction::Select:
340 return true;
341 default:
342 return false;
343 }
344}
345
347 // A live-in must be uniform across the scope of VPlan.
349 return true;
350
351 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
352 const VPRegionBlock *RegionOfR = Rep->getRegion();
353 // Don't consider recipes in replicate regions as uniform yet; their first
354 // lane cannot be accessed when executing the replicate region for other
355 // lanes.
356 if (RegionOfR && RegionOfR->isReplicator())
357 return false;
358 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
359 all_of(Rep->operands(), isSingleScalar));
360 }
363 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
364 return preservesUniformity(WidenR->getOpcode()) &&
365 all_of(WidenR->operands(), isSingleScalar);
366 }
367 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
368 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
369 (preservesUniformity(VPI->getOpcode()) &&
370 all_of(VPI->operands(), isSingleScalar));
371 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
372 return !RR->isPartialReduction();
375 return true;
376 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
377 return Expr->isSingleScalar();
378
379 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
380 return isa<VPExpandSCEVRecipe>(VPV);
381}
382
384 // Live-ins are uniform.
386 return true;
387
388 VPRecipeBase *R = V->getDefiningRecipe();
389 if (R && V->isDefinedOutsideLoopRegions()) {
390 if (match(V->getDefiningRecipe(),
392 return false;
393 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
394 }
395
396 auto *CanonicalIV =
397 R->getParent()->getEnclosingLoopRegion()->getCanonicalIV();
398 // Canonical IV chain is uniform.
399 if (V == CanonicalIV || V == CanonicalIV->getBackedgeValue())
400 return true;
401
403 .Case<VPDerivedIVRecipe>([](const auto *R) { return true; })
404 .Case<VPReplicateRecipe>([](const auto *R) {
405 // Be conservative about side-effects, except for the
406 // known-side-effecting assumes and stores, which we know will be
407 // uniform.
408 return R->isSingleScalar() &&
409 (!R->mayHaveSideEffects() ||
410 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
411 all_of(R->operands(), isUniformAcrossVFsAndUFs);
412 })
413 .Case<VPWidenRecipe>([](const auto *R) {
414 return preservesUniformity(R->getOpcode()) &&
415 all_of(R->operands(), isUniformAcrossVFsAndUFs);
416 })
417 .Case<VPInstruction>([](const auto *VPI) {
418 return (VPI->isScalarCast() &&
419 isUniformAcrossVFsAndUFs(VPI->getOperand(0))) ||
420 (preservesUniformity(VPI->getOpcode()) &&
421 all_of(VPI->operands(), isUniformAcrossVFsAndUFs));
422 })
423 .Case<VPWidenCastRecipe>([](const auto *R) {
424 // A cast is uniform according to its operand.
425 return isUniformAcrossVFsAndUFs(R->getOperand(0));
426 })
427 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
428 // unless proven otherwise.
429 return false;
430 });
431}
432
434 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
435 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
436 return VPBlockUtils::isHeader(VPB, VPDT);
437 });
438 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
439}
440
442 if (!R)
443 return 1;
444 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
445 return RR->getVFScaleFactor();
446 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
447 return RR->getVFScaleFactor();
448 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
449 return ER->getVFScaleFactor();
450 assert(
453 "getting scaling factor of reduction-start-vector not implemented yet");
454 return 1;
455}
456
457std::optional<VPValue *>
461 // Given a VPlan like the following (just including the recipes contributing
462 // to loop control exiting here, not the actual work), we're looking to match
463 // the recipes contributing to the uncountable exit condition comparison
464 // (here, vp<%4>) back to either live-ins or the address nodes for the load
465 // used as part of the uncountable exit comparison so that we can copy them
466 // to a preheader and rotate the address in the loop to the next vector
467 // iteration.
468 //
469 // Currently, the address of the load is restricted to a GEP with 2 operands
470 // and a live-in base address. This constraint may be relaxed later.
471 //
472 // VPlan ' for UF>=1' {
473 // Live-in vp<%0> = VF
474 // Live-in ir<64> = original trip-count
475 //
476 // entry:
477 // Successor(s): preheader, vector.ph
478 //
479 // vector.ph:
480 // Successor(s): vector loop
481 //
482 // <x1> vector loop: {
483 // vector.body:
484 // EMIT vp<%2> = CANONICAL-INDUCTION ir<0>
485 // vp<%3> = SCALAR-STEPS vp<%2>, ir<1>, vp<%0>
486 // CLONE ir<%ee.addr> = getelementptr ir<0>, vp<%3>
487 // WIDEN ir<%ee.load> = load ir<%ee.addr>
488 // WIDEN vp<%4> = icmp eq ir<%ee.load>, ir<0>
489 // EMIT vp<%5> = any-of vp<%4>
490 // EMIT vp<%6> = add vp<%2>, vp<%0>
491 // EMIT vp<%7> = icmp eq vp<%6>, ir<64>
492 // EMIT branch-on-two-conds vp<%5>, vp<%7>
493 // No successors
494 // }
495 // Successor(s): early.exit, middle.block
496 //
497 // middle.block:
498 // Successor(s): preheader
499 //
500 // preheader:
501 // No successors
502 // }
503
504 // Find the uncountable loop exit condition.
505 auto *Region = Plan.getVectorLoopRegion();
506 VPValue *UncountableCondition = nullptr;
507 if (!match(Region->getExitingBasicBlock()->getTerminator(),
508 m_BranchOnTwoConds(m_AnyOf(m_VPValue(UncountableCondition)),
509 m_VPValue())))
510 return std::nullopt;
511
513 Worklist.push_back(UncountableCondition);
514 while (!Worklist.empty()) {
515 VPValue *V = Worklist.pop_back_val();
516
517 // Any value defined outside the loop does not need to be copied.
518 if (V->isDefinedOutsideLoopRegions())
519 continue;
520
521 // FIXME: Remove the single user restriction; it's here because we're
522 // starting with the simplest set of loops we can, and multiple
523 // users means needing to add PHI nodes in the transform.
524 if (V->getNumUsers() > 1)
525 return std::nullopt;
526
527 VPValue *Op1, *Op2;
528 // Walk back through recipes until we find at least one load from memory.
529 if (match(V, m_ICmp(m_VPValue(Op1), m_VPValue(Op2)))) {
530 Worklist.push_back(Op1);
531 Worklist.push_back(Op2);
532 Recipes.push_back(V->getDefiningRecipe());
533 } else if (auto *Load = dyn_cast<VPWidenLoadRecipe>(V)) {
534 // Reject masked loads for the time being; they make the exit condition
535 // more complex.
536 if (Load->isMasked())
537 return std::nullopt;
538
539 VPValue *GEP = Load->getAddr();
541 return std::nullopt;
542
543 Recipes.push_back(Load);
544 Recipes.push_back(GEP->getDefiningRecipe());
545 GEPs.push_back(GEP->getDefiningRecipe());
546 } else
547 return std::nullopt;
548 }
549
550 return UncountableCondition;
551}
552
554 const VPDominatorTree &VPDT) {
555 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
556 if (!VPBB)
557 return false;
558
559 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
560 // VPBB as its entry, i.e., free of predecessors.
561 if (auto *R = VPBB->getParent())
562 return !R->isReplicator() && !VPBB->hasPredecessors();
563
564 // A header dominates its second predecessor (the latch), with the other
565 // predecessor being the preheader
566 return VPB->getPredecessors().size() == 2 &&
567 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
568}
569
571 const VPDominatorTree &VPDT) {
572 // A latch has a header as its second successor, with its other successor
573 // leaving the loop. A preheader OTOH has a header as its first (and only)
574 // successor.
575 return VPB->getNumSuccessors() == 2 &&
576 VPBlockUtils::isHeader(VPB->getSuccessors()[1], VPDT);
577}
578
579std::optional<MemoryLocation>
581 auto *M = dyn_cast<VPIRMetadata>(&R);
582 if (!M)
583 return std::nullopt;
585 // Populate noalias metadata from VPIRMetadata.
586 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
587 Loc.AATags.NoAlias = NoAliasMD;
588 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
589 Loc.AATags.Scope = AliasScopeMD;
590 return Loc;
591}
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 propagatesPoisonFromRecipeOp(const VPRecipeBase *R)
Returns true if R propagates poison from any operand to its result.
static bool preservesUniformity(unsigned Opcode)
Returns true if Opcode preserves uniformity, i.e., if all operands are uniform, the result will also ...
static bool poisonGuaranteesUB(const VPValue *V)
Returns true if V being poison is guaranteed to trigger UB because it propagates to the address of a ...
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.
const SCEV * getMinusOne(Type *Ty)
Return a SCEV for the constant -1 of a specific type.
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.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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:89
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition TypeSwitch.h:98
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:3947
void appendRecipe(VPRecipeBase *Recipe)
Augment the existing recipes of a VPBasicBlock with an additional Recipe as the last recipe.
Definition VPlan.h:4022
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:3533
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition VPlan.h:3701
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:3495
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1130
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:4135
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4203
VPCanonicalIVPHIRecipe * getCanonicalIV()
Returns the canonical induction recipe of the region.
Definition VPlan.h:4233
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:2920
unsigned getOpcode() const
Definition VPlan.h:2990
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:3769
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:229
operand_range operands()
Definition VPlanValue.h:297
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:45
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:119
user_range users()
Definition VPlanValue.h:126
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:1877
A recipe to compute the pointers for widened memory accesses of SourceElementTy.
Definition VPlan.h:1938
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1568
A recipe for handling GEP instructions.
Definition VPlan.h:1814
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2164
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4265
VPBasicBlock * getEntry()
Definition VPlan.h:4354
VPValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4444
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:4412
VPValue * getBackedgeTakenCount() const
Definition VPlan.h:4438
VPIRValue * getOrAddLiveIn(Value *V)
Gets the live-in VPIRValue for V or adds a new live-in (if none exists yet) for V.
Definition VPlan.h:4504
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1022
bool hasScalarVFOnly() const
Definition VPlan.h:4473
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.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
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()
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::BranchOnTwoConds > m_BranchOnTwoConds()
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.
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.
Definition Types.h:26
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