LLVM 23.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"
11#include "VPlanAnalysis.h"
12#include "VPlanCFG.h"
13#include "VPlanDominatorTree.h"
14#include "VPlanPatternMatch.h"
15#include "llvm/ADT/TypeSwitch.h"
19#include "llvm/IR/Dominators.h"
21
22using namespace llvm;
23using namespace llvm::VPlanPatternMatch;
24using namespace llvm::SCEVPatternMatch;
25
27 return all_of(Def->users(),
28 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
29}
30
32 return all_of(Def->users(),
33 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
34}
35
37 return all_of(Def->users(),
38 [Def](const VPUser *U) { return U->usesScalars(Def); });
39}
40
42 if (auto *E = dyn_cast<SCEVConstant>(Expr))
43 return Plan.getOrAddLiveIn(E->getValue());
44 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
45 // value. Otherwise the value may be defined in a loop and using it directly
46 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
47 // form.
48 auto *U = dyn_cast<SCEVUnknown>(Expr);
49 if (U && !isa<Instruction>(U->getValue()))
50 return Plan.getOrAddLiveIn(U->getValue());
51 auto *Expanded = new VPExpandSCEVRecipe(Expr);
52 VPBasicBlock *EntryVPBB = Plan.getEntry();
53 auto Iter = EntryVPBB->getFirstNonPhi();
54 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
55 ++Iter;
56 EntryVPBB->insert(Expanded, Iter);
57 return Expanded;
58}
59
60bool vputils::isHeaderMask(const VPValue *V, const VPlan &Plan) {
62 return true;
63
64 VPValue *A, *B;
65
66 auto m_CanonicalScalarIVSteps = m_ScalarIVSteps(
69 m_One(), m_Specific(&Plan.getVF()));
70
71 // A wide canonical IV is either an explicit VPWidenCanonicalIVRecipe or a
72 // canonical VPWidenIntOrFpInductionRecipe.
73 auto m_WideCanonicalIV =
75
77 return B == Plan.getTripCount() &&
78 (match(A, m_CanonicalScalarIVSteps) || match(A, m_WideCanonicalIV));
79
80 // For scalar plans, the header mask uses the scalar steps.
81 if (match(V, m_ICmp(m_CanonicalScalarIVSteps,
83 assert(Plan.hasScalarVFOnly() &&
84 "Non-scalar VF using scalar IV steps for header mask?");
85 return true;
86 }
87
88 auto MaskMatch = m_ICmp(m_VPValue(A), m_VPValue(B));
89 if (match(V, m_CombineOr(MaskMatch, m_Reverse(MaskMatch))))
90 return match(A, m_WideCanonicalIV) && B == Plan.getBackedgeTakenCount();
91
92 return match(
95}
96
97/// Returns true if \p R propagates poison from any operand to its result.
101 [](const VPRecipeBase *) { return true; })
102 .Case([](const VPReplicateRecipe *Rep) {
103 // GEP and casts propagate poison from all operands.
104 unsigned Opcode = Rep->getOpcode();
105 return Opcode == Instruction::GetElementPtr ||
106 Instruction::isCast(Opcode);
107 })
108 .Default([](const VPRecipeBase *) { return false; });
109}
110
111/// Returns true if \p V being poison is guaranteed to trigger UB because it
112/// propagates to the address of a memory recipe.
113static bool poisonGuaranteesUB(const VPValue *V) {
116
117 Worklist.push_back(V);
118
119 while (!Worklist.empty()) {
120 const VPValue *Current = Worklist.pop_back_val();
121 if (!Visited.insert(Current).second)
122 continue;
123
124 for (VPUser *U : Current->users()) {
125 // Check if Current is used as an address operand for load/store.
127 if (MemR->getAddr() == Current)
128 return true;
129 continue;
130 }
131 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
132 unsigned Opcode = Rep->getOpcode();
133 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
134 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
135 return true;
136 }
137
138 // Check if poison propagates through this recipe to any of its users.
139 auto *R = cast<VPRecipeBase>(U);
140 for (const VPValue *Op : R->operands()) {
141 if (Op == Current && propagatesPoisonFromRecipeOp(R)) {
142 Worklist.push_back(R->getVPSingleValue());
143 break;
144 }
145 }
146 }
147 }
148
149 return false;
150}
151
153 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
154 // casts to find a root GEP VPInstruction.
155 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
156 unsigned Opcode = PtrVPI->getOpcode();
157 if (Opcode == Instruction::GetElementPtr) {
158 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
159 return PtrVPI->getGEPNoWrapFlags();
160 Ptr = PtrVPI->getOperand(0);
161 continue;
162 }
163 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
164 break;
165 Ptr = PtrVPI->getOperand(0);
166 }
167 return GEPNoWrapFlags::none();
168}
169
172 const Loop *L) {
173 ScalarEvolution &SE = *PSE.getSE();
175 Value *LiveIn = V->getUnderlyingValue();
176 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
177 return SE.getSCEV(LiveIn);
178 return SE.getCouldNotCompute();
179 }
180
181 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
182 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
183 "RegionValue must be canonical IV");
184 if (!L)
185 return SE.getCouldNotCompute();
186 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
188 }
189
190 // Helper to create SCEVs for binary and unary operations.
191 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
192 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
193 -> const SCEV * {
195 for (VPValue *Op : Ops) {
196 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
198 return SE.getCouldNotCompute();
199 SCEVOps.push_back(S);
200 }
201 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
202 };
203
204 VPValue *LHSVal, *RHSVal;
205 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
206 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
207 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
208 });
209 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
210 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
211 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
212 });
213 if (match(V, m_Not(m_VPValue(LHSVal)))) {
214 // not X = xor X, -1 = -1 - X
215 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
216 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
217 });
218 }
219 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
220 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
221 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
222 });
223 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
224 // amount >= the bit width produces poison; do not rewrite it, as
225 // getPowerOfTwo requires the power to be in range.
226 uint64_t ShiftAmt;
227 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
228 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
229 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
230 return SE.getMulExpr(Ops[0],
231 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
232 });
233 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
234 Type *Ty = V->getScalarType();
235 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
236 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
237 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
238 });
239 }
240 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
241 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
242 return SE.getUDivExpr(Ops[0], Ops[1]);
243 });
244 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
245 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
246 return SE.getURemExpr(Ops[0], Ops[1]);
247 });
248 // A SRem with non-negative operands is equivalent to an URem.
249 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
250 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
251 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
252 return SE.getCouldNotCompute();
253 return SE.getURemExpr(Ops[0], Ops[1]);
254 });
255 }
256 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
257 const APInt *Mask;
258 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
259 (*Mask + 1).isPowerOf2())
260 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
261 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
262 });
263 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
264 Type *DestTy = V->getScalarType();
265 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
266 return SE.getTruncateExpr(Ops[0], DestTy);
267 });
268 }
269 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
270 Type *DestTy = V->getScalarType();
271 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
272 return SE.getZeroExtendExpr(Ops[0], DestTy);
273 });
274 }
275 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
276 Type *DestTy = V->getScalarType();
277
278 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
279 // onto the operands before computing the subtraction.
280 VPValue *SubLHS, *SubRHS;
281 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
282 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
283 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
284 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
285 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
287 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
288 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
289 }
290
291 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
292 return SE.getSignExtendExpr(Ops[0], DestTy);
293 });
294 }
295 if (match(V,
297 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
298 return SE.getUMaxExpr(Ops[0], Ops[1]);
299 });
300 if (match(V,
302 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
303 return SE.getSMaxExpr(Ops[0], Ops[1]);
304 });
305 if (match(V,
307 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
308 return SE.getUMinExpr(Ops[0], Ops[1]);
309 });
310 if (match(V,
312 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
313 return SE.getSMinExpr(Ops[0], Ops[1]);
314 });
316 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
317 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
318 // not proof that the input is never INT_MIN, nor that poison reaches
319 // UB. Do not translate it to SCEV's global IsNSW flag.
320 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
321 });
322
324 Type *SourceElementType;
325 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
326 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
327 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
328 });
329 }
330
331 // TODO: Support constructing SCEVs for more recipes as needed.
332 const VPRecipeBase *DefR = V->getDefiningRecipe();
333 const SCEV *Expr =
335 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
336 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
337 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
338 if (!L || isa<SCEVCouldNotCompute>(Step))
339 return SE.getCouldNotCompute();
340 const SCEV *Start =
341 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
342 const SCEV *AddRec =
343 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
344 if (R->getTruncInst())
345 return SE.getTruncateExpr(AddRec, R->getScalarType());
346 return AddRec;
347 })
348 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
349 const SCEV *Start =
350 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
351 if (!L || isa<SCEVCouldNotCompute>(Start))
352 return SE.getCouldNotCompute();
353 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
354 if (isa<SCEVCouldNotCompute>(Step))
355 return SE.getCouldNotCompute();
356 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
357 })
358 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
359 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
360 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
361 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
362 if (any_of(ArrayRef({Start, IV, Scale}),
364 return SE.getCouldNotCompute();
365
366 return SE.getAddExpr(
367 SE.getTruncateOrSignExtend(Start, IV->getType()),
368 SE.getMulExpr(
369 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
370 })
371 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
372 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
373 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
375 return SE.getCouldNotCompute();
376 return SE.getTruncateOrSignExtend(IV, Step->getType());
377 })
378 .Default(
379 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
380
381 return PSE.getPredicatedSCEV(Expr);
382}
383
385 const Loop *L) {
386 // If address is an SCEVAddExpr, we require that all operands must be either
387 // be invariant or a (possibly sign-extend) affine AddRec.
388 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
389 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
390 return SE.isLoopInvariant(Op, L) ||
391 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
392 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
393 });
394 }
395
396 // Otherwise, check if address is loop invariant or an affine add recurrence.
397 return SE.isLoopInvariant(Addr, L) ||
399}
400
401/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
402/// uniform, the result will also be uniform.
403static bool preservesUniformity(unsigned Opcode) {
404 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
405 return true;
406 switch (Opcode) {
407 case Instruction::Freeze:
408 case Instruction::GetElementPtr:
409 case Instruction::ICmp:
410 case Instruction::FCmp:
411 case Instruction::Select:
416 return true;
417 default:
418 return false;
419 }
420}
421
423 // Live-in, symbolic and region-values represent single-scalar values.
425 return true;
426
427 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
428 const VPRegionBlock *RegionOfR = Rep->getRegion();
429 // Don't consider recipes in replicate regions as uniform yet; their first
430 // lane cannot be accessed when executing the replicate region for other
431 // lanes.
432 if (RegionOfR && RegionOfR->isReplicator())
433 return false;
434 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
435 all_of(Rep->operands(), isSingleScalar));
436 }
439 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
440 return preservesUniformity(WidenR->getOpcode()) &&
441 all_of(WidenR->operands(), isSingleScalar);
442 }
443 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
444 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
445 (preservesUniformity(VPI->getOpcode()) &&
446 all_of(VPI->operands(), isSingleScalar));
447 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
448 return !RR->isPartialReduction();
450 VPV))
451 return true;
452 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
453 return Expr->isVectorToScalar();
454
455 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
456 return isa<VPExpandSCEVRecipe>(VPV);
457}
458
460 // Live-ins and region values are uniform.
462 return true;
463
464 const VPRecipeBase *R = V->getDefiningRecipe();
465 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
466 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
467 if (VPBB) {
468 if ((VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
469 if (match(V->getDefiningRecipe(),
471 return false;
472 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
473 }
474 }
475
477 .Case([](const VPDerivedIVRecipe *R) { return true; })
478 .Case([](const VPReplicateRecipe *R) {
479 // Be conservative about side-effects, except for the
480 // known-side-effecting assumes and stores, which we know will be
481 // uniform.
482 return R->isSingleScalar() &&
483 (!R->mayHaveSideEffects() ||
484 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
485 all_of(R->operands(), isUniformAcrossVFsAndUFs);
486 })
487 .Case([](const VPWidenRecipe *R) {
488 return preservesUniformity(R->getOpcode()) &&
489 all_of(R->operands(), isUniformAcrossVFsAndUFs);
490 })
491 .Case([](const VPPhi *) {
492 // Bail out on VPPhi, as we can end up in infinite cycles.
493 return false;
494 })
495 .Case([](const VPInstruction *VPI) {
496 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
499 })
500 .Case([](const VPWidenCastRecipe *R) {
501 // A cast is uniform according to its operand.
502 return isUniformAcrossVFsAndUFs(R->getOperand(0));
503 })
504 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
505 // unless proven otherwise.
506 return false;
507 });
508}
509
511 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
512 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
513 return VPBlockUtils::isHeader(VPB, VPDT);
514 });
515 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
516}
517
519 if (!R)
520 return 1;
521 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
522 return RR->getVFScaleFactor();
523 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
524 return RR->getVFScaleFactor();
525 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
526 return ER->getVFScaleFactor();
527 assert(
528 (!isa<VPInstruction>(R) || cast<VPInstruction>(R)->getOpcode() !=
530 "getting scaling factor of reduction-start-vector not implemented yet");
531 return 1;
532}
533
534bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
535 // Assumes don't alias anything or throw; as long as they're guaranteed to
536 // execute, they're safe to hoist. They should however not be sunk, as it
537 // would destroy information.
539 return Sinking;
540 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
541 return true;
542 // Allocas cannot be hoisted.
543 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
544 return RepR && RepR->getOpcode() == Instruction::Alloca;
545}
546
548 if (VPValue *AliasMask = findIncomingAliasMask(Plan)) {
549 assert(match(AliasMask->getSingleUser(),
550 m_c_BinaryAnd(m_VPValue(), m_Specific(AliasMask))) &&
551 "AliasMask must only be used with the original header mask");
552 return cast<VPSingleDefRecipe>(AliasMask->getSingleUser());
553 }
554
555 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
556 SmallVector<VPValue *> WideCanonicalIVs;
557 auto *WideCanonicalIV =
559 assert(count_if(LoopRegion->getCanonicalIV()->users(),
561 "Must have at most one VPWideCanonicalIVRecipe");
562 if (WideCanonicalIV)
563 WideCanonicalIVs.push_back(WideCanonicalIV);
564
565 // Also include VPWidenIntOrFpInductionRecipes that represent a widened
566 // version of the canonical induction.
567 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
568 for (VPRecipeBase &Phi : HeaderVPBB->phis()) {
570 if (match(&Phi, m_CanonicalWidenIV(WidenIV)))
571 WideCanonicalIVs.push_back(WidenIV);
572 }
573
574 // Walk users of wide canonical IVs and find the single compare of the form
575 // (ICMP_ULE, WideCanonicalIV, backedge-taken-count).
576 VPSingleDefRecipe *HeaderMask = nullptr;
577 for (auto *Wide : WideCanonicalIVs) {
578 for (VPUser *U : Wide->users()) {
579 auto *VPI = dyn_cast<VPInstruction>(U);
580 if (!VPI || !vputils::isHeaderMask(VPI, Plan))
581 continue;
582
583 assert(VPI->getOperand(0) == Wide &&
584 "WidenCanonicalIV must be the first operand of the compare");
585 assert(!HeaderMask && "Multiple header masks found?");
586 HeaderMask = VPI;
587 }
588 }
589
590 for (VPRecipeBase &R : LoopRegion->getEntryBasicBlock()->phis()) {
591 auto *Def = cast<VPSingleDefRecipe>(&R);
592 if (vputils::isHeaderMask(Def, Plan)) {
593 assert(!HeaderMask && "Multiple header masks found?");
594 HeaderMask = Def;
595 }
596 }
597
598 return HeaderMask;
599}
600
603 VPBasicBlock *LastBB) {
604 assert(FirstBB->getParent() == LastBB->getParent() &&
605 "FirstBB and LastBB from different regions");
606#ifndef NDEBUG
607 bool InSingleSuccChain = false;
608 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
609 InSingleSuccChain |= (Succ == LastBB);
610 assert(InSingleSuccChain &&
611 "LastBB unreachable from FirstBB in single-successor chain");
612#endif
613 auto Blocks = to_vector(
615 auto *LastIt = find(Blocks, LastBB);
616 assert(LastIt != Blocks.end() &&
617 "LastBB unreachable from FirstBB in depth-first traversal");
618 Blocks.erase(std::next(LastIt), Blocks.end());
619 return Blocks;
620}
621
623 for (VPRecipeBase &R : *Plan.getVectorPreheader())
625 return cast<VPInstruction>(&R);
626 return nullptr;
627}
628
630 const VPDominatorTree &VPDT) {
631 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
632 if (!VPBB)
633 return false;
634
635 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
636 // VPBB as its entry, i.e., free of predecessors.
637 if (auto *R = VPBB->getParent())
638 return !R->isReplicator() && !VPBB->hasPredecessors();
639
640 // A header dominates its second predecessor (the latch), with the other
641 // predecessor being the preheader
642 return VPB->getPredecessors().size() == 2 &&
643 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
644}
645
647 const VPDominatorTree &VPDT) {
648 // A latch has a header as its last successor, with its other successors
649 // leaving the loop. A preheader OTOH has a header as its first (and only)
650 // successor.
651 return VPB->getNumSuccessors() >= 2 &&
653}
654
655std::pair<VPBasicBlock *, VPBasicBlock *>
657 auto *Header = cast<VPBasicBlock>(
658 Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
659 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
660 return {Header, Latch};
661}
662
666
667std::optional<MemoryLocation>
669 auto *M = dyn_cast<VPIRMetadata>(&R);
670 if (!M)
671 return std::nullopt;
673 // Populate noalias metadata from VPIRMetadata.
674 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
675 Loc.AATags.NoAlias = NoAliasMD;
676 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
677 Loc.AATags.Scope = AliasScopeMD;
678 return Loc;
679}
680
682 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
683 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
684 assert(CanIV && "Expected loop region to have a canonical IV");
685
686 VPSymbolicValue &VFxUF = Plan.getVFxUF();
687
688 // Check if \p Step matches the expected increment step, accounting for
689 // materialization of VFxUF and UF.
690 auto IsIncrementStep = [&](VPValue *Step) -> bool {
691 if (!VFxUF.isMaterialized())
692 return Step == &VFxUF;
693
694 VPSymbolicValue &UF = Plan.getUF();
695 if (!UF.isMaterialized())
696 return Step == &UF ||
697 match(Step, m_c_Mul(m_Specific(&Plan.getUF()),
699
700 // Alias masking: step is number of active lanes of a dependence mask.
701 if (match(Step, m_ZExtOrTruncOrSelf(
703 return true;
704
705 unsigned ConcreteUF = Plan.getConcreteUF();
706 // Fixed VF: step is just the concrete UF.
707 if (match(Step, m_SpecificInt(ConcreteUF)))
708 return true;
709
710 // Scalable VF: step involves VScale.
711 if (ConcreteUF == 1)
713 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF),
715 return true;
716 // mul(VScale, ConcreteUF) may have been simplified to
717 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
718 return isPowerOf2_32(ConcreteUF) &&
720 m_SpecificInt(Log2_32(ConcreteUF))));
721 };
722
723 VPInstruction *Increment = nullptr;
724 for (VPUser *U : CanIV->users()) {
725 VPValue *Step;
726 if (isa<VPInstruction>(U) &&
727 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
728 IsIncrementStep(Step)) {
729 assert(!Increment && "There must be a unique increment");
731 }
732 }
733
734 assert((!VFxUF.isMaterialized() || Increment) &&
735 "After materializing VFxUF, an increment must exist");
736 assert((!Increment ||
737 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
738 "NUW flag in region and increment must match");
739 return Increment;
740}
741
742/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
743/// inserted for predicated reductions or tail folding.
745 VPValue *BackedgeVal = PhiR->getBackedgeValue();
746 if (auto *Res =
748 return Res;
749
750 // Look through selects inserted for tail folding or predicated reductions.
751 VPRecipeBase *SelR =
752 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
753 if (!SelR)
754 return nullptr;
757}
758
761 SmallVector<const VPValue *> WorkList = {V};
762
763 while (!WorkList.empty()) {
764 const VPValue *Cur = WorkList.pop_back_val();
765 if (!Seen.insert(Cur).second)
766 continue;
767
768 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
769 // Skip blends that use V only through a compare by checking if any incoming
770 // value was already visited.
771 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
772 [&](unsigned I) {
773 return Seen.contains(Blend->getIncomingValue(I));
774 }))
775 continue;
776
777 for (VPUser *U : Cur->users()) {
778 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
779 if (InterleaveR->getAddr() == Cur)
780 return true;
781 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
782 // store (operand 1).
785 m_Specific(Cur)))))
786 return true;
788 if (MemR->getAddr() == Cur && MemR->isConsecutive())
789 return true;
790 }
791 }
792
793 // The legacy cost model only supports scalarization loads/stores with phi
794 // addresses, if the phi is directly used as load/store address. Don't
795 // traverse further for Blends.
796 if (Blend)
797 continue;
798
799 // Only traverse further through users that also define a value (and can
800 // thus have their own users walked). Skip when Cur is only used as mask ,
801 // as well as loads: a loaded value does not depend on the load's operand.
802 for (VPUser *U : Cur->users()) {
803 auto *VPI = dyn_cast<VPInstruction>(U);
804 if (VPI && VPI->getMask() == Cur &&
805 none_of(VPI->operandsWithoutMask(),
806 [Cur](VPValue *Op) { return Op == Cur; }))
807 continue;
809 continue;
810 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
811 WorkList.push_back(SDR);
812 }
813 }
814 return false;
815}
816
817/// Try to find a loop-invariant IR value for \p S in the plan's entry block
818/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
819/// if no reusable IR value is found.
820VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
822 return nullptr;
823 VPlan &Plan = Builder.getPlan();
824 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
825 for (Value *V : SE.getSCEVValues(S)) {
826 // Only reuse instructions in the plan's entry block, or, when a
827 // DominatorTree is available, any instruction that dominates it.
828 // Instructions in sibling branches may not dominate the entry block.
829 auto *I = dyn_cast<Instruction>(V);
830 if (!I)
831 return Plan.getOrAddLiveIn(V);
832 if (!SE.DT.dominates(I->getParent(), PH))
833 continue;
834 SmallVector<Instruction *> DropPoisonGeneratingInsts;
835 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
836 continue;
837 for (Instruction *DropI : DropPoisonGeneratingInsts)
839 return Plan.getOrAddLiveIn(V);
840 }
841 return nullptr;
842}
843
845 if (VPValue *V = tryToReuseIRValue(S))
846 return V;
847
848 switch (S->getSCEVType()) {
849 case scConstant:
850 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
851 case scUnknown:
852 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
853 case scVScale:
854 return Builder.createNaryOp(VPInstruction::VScale, {}, S->getType());
855 case scAddExpr:
856 case scMulExpr: {
857 auto *NAry = cast<SCEVNAryExpr>(S);
858 VPIRFlags::WrapFlagsTy WrapFlags(NAry->hasNoUnsignedWrap(),
859 NAry->hasNoSignedWrap());
860
861 // Expanded poiner SCEVAddExpr as a ptradd of the pointer base and the
862 // integer offset, matching SCEVExpander.
863 if (S->getType()->isPointerTy()) {
864 VPValue *Base = tryToExpand(SE.getPointerBase(S));
865 if (!Base)
866 return nullptr;
867 VPValue *Offset = tryToExpand(SE.removePointerBase(S));
868 if (!Offset)
869 return nullptr;
870 GEPNoWrapFlags GEPFlags = WrapFlags.HasNUW
873 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
874 }
875
876 unsigned Opcode =
877 S->getSCEVType() == scAddExpr ? Instruction::Add : Instruction::Mul;
878 // Iterate in reverse so that constants are emitted last.
880 for (const SCEVUse &Op : reverse(NAry->operands())) {
881 VPValue *OpV = tryToExpand(Op);
882 if (!OpV)
883 return nullptr;
884 Ops.push_back(OpV);
885 }
886 VPValue *Result = Ops.front();
887 for (VPValue *Op : drop_begin(Ops))
888 Result = Builder.createOverflowingOp(Opcode, {Result, Op}, WrapFlags, DL);
889 return Result;
890 }
891 case scUDivExpr: {
892 auto *UDiv = cast<SCEVUDivExpr>(S);
893 VPValue *LHS = tryToExpand(UDiv->getLHS());
894 if (!LHS)
895 return nullptr;
896 VPValue *RHS = tryToExpand(UDiv->getRHS());
897 if (!RHS)
898 return nullptr;
899 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
900 VPIRFlags::getDefaultFlags(Instruction::UDiv),
901 DL);
902 }
903 case scTruncate:
904 case scZeroExtend:
905 case scSignExtend: {
906 auto *Cast = cast<SCEVCastExpr>(S);
907 VPValue *Op = tryToExpand(Cast->getOperand());
908 if (!Op)
909 return nullptr;
911 switch (S->getSCEVType()) {
912 case scTruncate:
913 Opcode = Instruction::Trunc;
914 break;
915 case scZeroExtend:
916 Opcode = Instruction::ZExt;
917 break;
918 case scSignExtend:
919 Opcode = Instruction::SExt;
920 break;
921 default:
922 llvm_unreachable("Unhandled cast SCEV");
923 }
924 return Builder.createScalarCast(Opcode, Op, S->getType(), DL);
925 }
926 default:
927 return nullptr;
928 }
929}
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")
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
#define I(x, y, z)
Definition MD5.cpp:57
This file provides utility analysis objects describing memory locations.
static unsigned getScalarSizeInBits(Type *Ty)
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 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
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags noUnsignedWrap()
static GEPNoWrapFlags none()
bool isCast() const
bool isBinaryOp() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1069
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.
static LLVM_ABI void dropPoisonGeneratingAnnotationsAndReinfer(ScalarEvolution &SE, Instruction *I)
Drop poison-generating flags from I, then try re-infer via SCEV.
This class represents an analyzed expression in the program.
static constexpr auto FlagAnyWrap
static constexpr auto FlagNSW
SCEVTypes getSCEVType() const
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getUDivExpr(SCEVUse LHS, SCEVUse RHS)
Get a canonical unsigned division expression, or something simpler if possible.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
LLVM_ABI const SCEV * getAbsExpr(const SCEV *Op, bool IsNSW)
LLVM_ABI const SCEV * getURemExpr(SCEVUse LHS, SCEVUse RHS)
Represents an unsigned remainder expression based on unsigned division.
LLVM_ABI const SCEV * getSMinExpr(SCEVUse LHS, SCEVUse RHS)
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
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 * 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 * getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getUMaxExpr(SCEVUse LHS, SCEVUse 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 * getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
const SCEV * getPowerOfTwo(Type *Ty, unsigned Power)
Return a SCEV for the constant Power of two.
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI const SCEV * getSMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI bool canReuseInstruction(const SCEV *S, Instruction *I, SmallVectorImpl< Instruction * > &DropPoisonGeneratingInsts)
Check whether it is poison-safe to represent the expression S using the instruction I.
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< SCEVUse > IndexExprs)
Returns an expression for a GEP.
LLVM_ABI const SCEV * getUMinExpr(SCEVUse LHS, SCEVUse RHS, bool Sequential=false)
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.
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:46
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4387
iterator end()
Definition VPlan.h:4424
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4475
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:266
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4453
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:94
VPRegionBlock * getParent()
Definition VPlan.h:186
size_t getNumSuccessors() const
Definition VPlan.h:237
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:222
VPlan * getPlan()
Definition VPlan.cpp:211
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:216
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:227
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:211
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
static VPBasicBlock * getPlainCFGMiddleBlock(const VPlan &Plan)
Returns the middle block of Plan in plain CFG form (before regions are formed).
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 auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:312
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...
static SmallVector< VPBasicBlock * > blocksInSingleSuccessorChainBetween(VPBasicBlock *FirstBB, VPBasicBlock *LastBB)
Returns the blocks between FirstBB and LastBB, where FirstBB to LastBB forms a single-sucessor chain.
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition VPlan.h:4175
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:4007
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2483
static VPIRFlags getDefaultFlags(unsigned Opcode)
Returns default flags for Opcode for opcodes that support it, asserts otherwise.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1226
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1315
@ VScale
Returns the value for vscale.
Definition VPlan.h:1348
unsigned getOpcode() const
Definition VPlan.h:1417
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
bool isSingleScalar() const
Returns true if this VPInstruction's operands are single scalars and the result is also a single scal...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:402
A recipe for handling reduction phis.
Definition VPlan.h:2851
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4597
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4673
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4722
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4709
VPValues defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:216
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3385
unsigned getOpcode() const
Definition VPlan.h:3478
VPValue * tryToExpand(const SCEV *S)
Try to expand S into recipes and live-ins using the builder.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4235
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:609
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:385
operand_range operands()
Definition VPlanValue.h:458
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:130
user_range users()
Definition VPlanValue.h:157
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1878
A recipe for handling GEP instructions.
Definition VPlan.h:2206
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2610
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1817
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4745
VPBasicBlock * getEntry()
Definition VPlan.h:4841
VPValue * getTripCount() const
The trip count of the original loop.
Definition VPlan.h:4900
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:4940
VPValue * getBackedgeTakenCount() const
Definition VPlan.h:4927
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:5014
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1053
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:4992
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4846
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:4937
bool hasScalarVFOnly() const
Definition VPlan.h:4982
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4884
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4933
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
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))
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
BinaryOp_match< LHS, RHS, Instruction::UDiv > m_UDiv(const LHS &L, const RHS &R)
auto m_ZExtOrTruncOrSelf(const OpTy &Op)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
CmpClass_match< LHS, RHS, ICmpInst > m_ICmp(CmpPredicate &Pred, const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_commutative_match< Instruction::And, Op0_t, Op1_t > m_c_BinaryAnd(const Op0_t &Op0, const Op1_t &Op1)
Match a binary AND operation.
AllRecipe_match< Opcode, Op0_t, Op1_t > m_Binary(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_match< Opcode, Op0_t > m_Unary(const Op0_t &Op0)
canonical_widen_iv_match m_CanonicalWidenIV()
VPInstruction_match< VPInstruction::ActiveLaneMask, Op0_t, Op1_t, Op2_t > m_ActiveLaneMask(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
auto m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
canonical_iv_match m_CanonicalIV()
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
auto m_DerivedIV(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
auto m_ScalarIVSteps(const Op0_t &Op0, const Op1_t &Op1, const Op2_t &Op2)
VPInstruction_match< VPInstruction::Reverse, Op0_t > m_Reverse(const Op0_t &Op0)
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...
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.
VPValue * findIncomingAliasMask(const VPlan &Plan)
Finds the incoming alias-mask within the vector preheader.
VPSingleDefRecipe * findHeaderMask(VPlan &Plan)
Collect the header mask with the pattern: (ICMP_ULE, WideCanonicalIV, backedge-taken-count) Note: If ...
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
bool isUniformAcrossVFsAndUFs(const VPValue *V)
Checks if V is uniform across all VF lanes and UF parts.
bool isUsedByLoadStoreAddress(const VPValue *V)
Returns true if V is used as part of the address of another load or store.
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
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 drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
@ Offset
Definition DWP.cpp:573
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
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:1739
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:253
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:288
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:1746
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:331
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:279
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:1753
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...
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 >
auto count_if(R &&Range, UnaryPredicate P)
Wrapper function around std::count_if to count the number of times an element satisfying a given pred...
Definition STLExtras.h:2019
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:1772
auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:305
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
@ Default
The result value is 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
SCEVUseT< const SCEV * > SCEVUse
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:287
bool isMaterialized() const
Returns true if this symbolic value has been materialized.
Definition VPlanValue.h:298