LLVM 24.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/MapVector.h"
16#include "llvm/ADT/SetVector.h"
18#include "llvm/ADT/TypeSwitch.h"
25#include "llvm/IR/Dominators.h"
28
29using namespace llvm;
30using namespace llvm::VPlanPatternMatch;
31using namespace llvm::SCEVPatternMatch;
32
34 return all_of(Def->users(),
35 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
36}
37
39 return all_of(Def->users(),
40 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
41}
42
44 return all_of(Def->users(),
45 [Def](const VPUser *U) { return U->usesScalars(Def); });
46}
47
49 if (auto *E = dyn_cast<SCEVConstant>(Expr))
50 return Plan.getOrAddLiveIn(E->getValue());
51 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
52 // value. Otherwise the value may be defined in a loop and using it directly
53 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
54 // form.
55 auto *U = dyn_cast<SCEVUnknown>(Expr);
56 if (U && !isa<Instruction>(U->getValue()))
57 return Plan.getOrAddLiveIn(U->getValue());
58 auto *Expanded = new VPExpandSCEVRecipe(Expr);
59 VPBasicBlock *EntryVPBB = Plan.getEntry();
60 auto Iter = EntryVPBB->getFirstNonPhi();
61 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
62 ++Iter;
63 EntryVPBB->insert(Expanded, Iter);
64 return Expanded;
65}
66
67/// Returns true if \p V being poison is guaranteed to trigger UB because it
68/// propagates to the address of a memory recipe.
69static bool poisonGuaranteesUB(const VPValue *V) {
72
73 auto PropagatesPoisonFromRecipeOp = [](const VPRecipeBase *R) {
75 return false;
76 unsigned Opcode = vputils::getOpcode(R->getVPSingleValue());
77 return Instruction::isCast(Opcode) || Opcode == Instruction::GetElementPtr;
78 };
79
80 Worklist.push_back(V);
81
82 while (!Worklist.empty()) {
83 const VPValue *Current = Worklist.pop_back_val();
84 if (!Visited.insert(Current).second)
85 continue;
86
87 for (VPUser *U : Current->users()) {
88 // Check if Current is used as an address operand for load/store.
89 auto *R = cast<VPRecipeBase>(U);
90 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(R)) {
91 if (MemR->getAddr() == Current)
92 return true;
93 continue;
94 }
95 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
96 unsigned Opcode = Rep->getOpcode();
97 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
98 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
99 return true;
100 }
101
102 // Check if poison propagates through this recipe to any of its users.
103 for (const VPValue *Op : R->operands()) {
104 if (Op == Current && PropagatesPoisonFromRecipeOp(R)) {
105 Worklist.push_back(R->getVPSingleValue());
106 break;
107 }
108 }
109 }
110 }
111
112 return false;
113}
114
116 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
117 // casts to find a root GEP VPInstruction.
118 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
119 unsigned Opcode = PtrVPI->getOpcode();
120 if (Opcode == Instruction::GetElementPtr) {
121 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
122 return PtrVPI->getGEPNoWrapFlags();
123 Ptr = PtrVPI->getOperand(0);
124 continue;
125 }
126 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
127 break;
128 Ptr = PtrVPI->getOperand(0);
129 }
130 return GEPNoWrapFlags::none();
131}
132
135 const Loop *L) {
136 ScalarEvolution &SE = *PSE.getSE();
137 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
138 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
139 "RegionValue must be canonical IV");
140 if (!L)
141 return SE.getCouldNotCompute();
142 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
144 }
145
147 Value *LiveIn = V->getUnderlyingValue();
148 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
149 return SE.getSCEV(LiveIn);
150 return SE.getCouldNotCompute();
151 }
152
153 // Helper to create SCEVs for binary and unary operations.
154 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
155 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
156 -> const SCEV * {
158 for (VPValue *Op : Ops) {
159 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
161 return SE.getCouldNotCompute();
162 SCEVOps.push_back(S);
163 }
164 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
165 };
166
167 VPValue *LHSVal, *RHSVal;
168 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
169 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
170 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
171 });
172 if (match(V, m_BinaryOr(m_VPValue(LHSVal), m_VPValue(RHSVal))))
173 if (cast<VPRecipeWithIRFlags>(V->getDefiningRecipe())->isDisjoint())
174 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
175 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
176 });
177 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
178 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
179 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
180 });
181 if (match(V, m_Not(m_VPValue(LHSVal)))) {
182 // not X = xor X, -1 = -1 - X
183 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
184 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
185 });
186 }
187 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
188 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
189 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
190 });
191 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
192 // amount >= the bit width produces poison; do not rewrite it, as
193 // getPowerOfTwo requires the power to be in range.
194 uint64_t ShiftAmt;
195 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
196 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
197 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
198 return SE.getMulExpr(Ops[0],
199 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
200 });
201 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
202 Type *Ty = V->getScalarType();
203 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
204 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
205 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
206 });
207 }
208 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
209 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
210 return SE.getUDivExpr(Ops[0], Ops[1]);
211 });
212 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
213 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
214 return SE.getURemExpr(Ops[0], Ops[1]);
215 });
216 // A SDiv with non-negative operands is equivalent to an UDiv.
217 if (match(V, m_SDiv(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
218 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
219 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
220 return SE.getCouldNotCompute();
221 return SE.getUDivExpr(Ops[0], Ops[1]);
222 });
223 }
224 // A SRem with non-negative operands is equivalent to an URem.
225 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
226 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
227 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
228 return SE.getCouldNotCompute();
229 return SE.getURemExpr(Ops[0], Ops[1]);
230 });
231 }
232 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
233 const APInt *Mask;
234 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
235 (*Mask + 1).isPowerOf2())
236 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
237 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
238 });
239 // SCEV models ptrtoaddr, but not ptrtoint, mirroring createSCEV.
240 if (match(V, m_PtrToAddr(m_VPValue(LHSVal))))
241 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
242 return SE.getPtrToAddrExpr(Ops[0]);
243 });
244 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
245 Type *DestTy = V->getScalarType();
246 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
247 return SE.getTruncateExpr(Ops[0], DestTy);
248 });
249 }
250 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
251 Type *DestTy = V->getScalarType();
252 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
253 return SE.getZeroExtendExpr(Ops[0], DestTy);
254 });
255 }
256 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
257 Type *DestTy = V->getScalarType();
258
259 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
260 // onto the operands before computing the subtraction.
261 VPValue *SubLHS, *SubRHS;
262 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
263 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
264 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
265 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
266 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
268 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
269 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
270 }
271
272 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
273 return SE.getSignExtendExpr(Ops[0], DestTy);
274 });
275 }
276 if (match(V,
278 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
279 return SE.getUMaxExpr(Ops[0], Ops[1]);
280 });
281 if (match(V,
283 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
284 return SE.getSMaxExpr(Ops[0], Ops[1]);
285 });
286 if (match(V,
288 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
289 return SE.getUMinExpr(Ops[0], Ops[1]);
290 });
291 if (match(V,
293 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
294 return SE.getSMinExpr(Ops[0], Ops[1]);
295 });
297 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
298 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
299 // not proof that the input is never INT_MIN, nor that poison reaches
300 // UB. Do not translate it to SCEV's global IsNSW flag.
301 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
302 });
303
305 Type *SourceElementType;
306 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
307 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
308 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
309 });
310 }
311
312 // TODO: Support constructing SCEVs for more recipes as needed.
313 const VPRecipeBase *DefR = V->getDefiningRecipe();
314 const SCEV *Expr =
316 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
317 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
318 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
319 if (!L || isa<SCEVCouldNotCompute>(Step))
320 return SE.getCouldNotCompute();
321 const SCEV *Start =
322 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
323 const SCEV *AddRec =
324 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
325 if (R->getTruncInst())
326 return SE.getTruncateExpr(AddRec, R->getScalarType());
327 return AddRec;
328 })
329 .Case([&SE, &PSE,
330 L](const VPWidenPointerInductionRecipe *R) -> const SCEV * {
331 const SCEV *Start =
332 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
333 if (!L || isa<SCEVCouldNotCompute>(Start))
334 return SE.getCouldNotCompute();
335 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
336 if (isa<SCEVCouldNotCompute>(Step))
337 return SE.getCouldNotCompute();
338 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
339 })
340 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) -> const SCEV * {
341 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
342 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
343 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
344 if (any_of(ArrayRef({Start, IV, Scale}),
346 return SE.getCouldNotCompute();
347
348 return SE.getAddExpr(
349 SE.getTruncateOrSignExtend(Start, IV->getType()),
350 SE.getMulExpr(
351 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
352 })
353 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
354 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
355 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
357 return SE.getCouldNotCompute();
358 return SE.getTruncateOrSignExtend(IV, Step->getType());
359 })
360 .Default(
361 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
362
363 return PSE.getPredicatedSCEV(Expr);
364}
365
366std::optional<int64_t>
368 PredicatedScalarEvolution &PSE, const Loop *L) {
369 assert(!hasIrregularType(AccessTy, L->getHeader()->getDataLayout()) &&
370 "should not try to widen irregular types");
371 const SCEV *AddrSCEV = getSCEVExprForVPValue(Addr, PSE, L);
372 auto *AddRec = dyn_cast<SCEVAddRecExpr>(AddrSCEV);
373 if (!AddRec)
374 return {};
375
376 return getStrideFromAddRec(AddRec, L, AccessTy, /*Ptr=*/nullptr, PSE);
377}
378
380 const Loop *L) {
381 // If address is an SCEVAddExpr, we require that all operands must be either
382 // be invariant or a (possibly sign-extend) affine AddRec.
383 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
384 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
385 return SE.isLoopInvariant(Op, L) ||
386 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
387 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
388 });
389 }
390
391 // Otherwise, check if address is loop invariant or an affine add recurrence.
392 return SE.isLoopInvariant(Addr, L) ||
394}
395
396unsigned vputils::getOpcode(const VPValue *V) {
400 VPWidenLoadEVLRecipe>([](auto *I) { return I->getOpcode(); })
401 .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
402 [](auto *I) {
403 // For recipes that do not directly map to LLVM IR instructions,
404 // assign opcodes after the last VPInstruction opcode (which is also
405 // after the last IR Instruction opcode), based on the VPRecipeID.
406 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
407 })
408 .Default([](auto *) { return 0; });
409}
410
411std::optional<std::pair<bool, unsigned>>
414 return std::make_pair(true, IID);
415 if (unsigned Opcode = vputils::getOpcode(V))
416 return std::make_pair(false, Opcode);
417 return {};
418}
419
420/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
421/// uniform, the result will also be uniform.
422static bool preservesUniformity(unsigned Opcode) {
423 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
424 return true;
425 switch (Opcode) {
426 case Instruction::Freeze:
427 case Instruction::GetElementPtr:
428 case Instruction::ICmp:
429 case Instruction::FCmp:
430 case Instruction::Select:
435 return true;
436 default:
437 return false;
438 }
439}
440
442 // TODO: Handle more opcodes and recipes.
444 return false;
445 unsigned Opcode = getOpcode(V);
446 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
447}
448
450 // Live-in, symbolic and canonical-IV region values are single-scalar.
451 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
452 return RV == RV->getDefiningRegion()->getCanonicalIV();
454 return true;
455
456 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
457 const VPRegionBlock *RegionOfR = Rep->getRegion();
458 // Don't consider recipes in replicate regions as uniform yet; their first
459 // lane cannot be accessed when executing the replicate region for other
460 // lanes.
461 if (RegionOfR && RegionOfR->isReplicator())
462 return false;
463 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
464 all_of(Rep->operands(), isSingleScalar));
465 }
468 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
469 return preservesUniformity(WidenR->getOpcode()) &&
470 all_of(WidenR->operands(), isSingleScalar);
471 }
472 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
473 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
474 (preservesUniformity(VPI->getOpcode()) &&
475 all_of(VPI->operands(), isSingleScalar));
476 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
477 return !RR->isPartialReduction();
479 VPV))
480 return true;
481 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
482 return Expr->isVectorToScalar();
483
484 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
485 return isa<VPExpandSCEVRecipe>(VPV);
486}
487
489 // Live-ins, symbolic and canonical-IV region values are uniform.
490 if (auto *RV = dyn_cast<VPRegionValue>(V))
491 return RV == RV->getDefiningRegion()->getCanonicalIV();
493 return true;
494
495 const VPRecipeBase *R = V->getDefiningRecipe();
496 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
497 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
498 if (VPBB &&
499 (VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
500 if (match(R,
503 return false;
504 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
505 }
506
508 .Case([](const VPDerivedIVRecipe *R) { return true; })
509 .Case([](const VPReplicateRecipe *R) {
510 // Be conservative about side-effects, except for the
511 // known-side-effecting assumes and stores, which we know will be
512 // uniform.
513 return R->isSingleScalar() &&
514 (!R->mayHaveSideEffects() ||
515 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
516 all_of(R->operands(), isUniformAcrossVFsAndUFs);
517 })
518 .Case([](const VPWidenRecipe *R) {
519 return preservesUniformity(R->getOpcode()) &&
520 all_of(R->operands(), isUniformAcrossVFsAndUFs);
521 })
522 .Case([](const VPPhi *) {
523 // Bail out on VPPhi, as we can end up in infinite cycles.
524 return false;
525 })
526 .Case([](const VPInstruction *VPI) {
527 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
530 })
531 .Case([](const VPWidenCastRecipe *R) {
532 // A cast is uniform according to its operand.
533 return isUniformAcrossVFsAndUFs(R->getOperand(0));
534 })
535 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
536 // unless proven otherwise.
537 return false;
538 });
539}
540
542 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
543 return RepR->doesGeneratePerAllLanes();
544 if (auto *VPI = dyn_cast<VPInstruction>(R))
545 return VPI->doesGeneratePerAllLanes();
546 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
547 return SIVSteps->doesGeneratePerAllLanes();
548 return false;
549}
550
552 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
553 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
554 return VPBlockUtils::isHeader(VPB, VPDT);
555 });
556 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
557}
558
560 if (!R)
561 return 1;
562 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
563 return RR->getVFScaleFactor();
564 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
565 return RR->getVFScaleFactor();
566 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
567 return ER->getVFScaleFactor();
568 assert(
571 "getting scaling factor of reduction-start-vector not implemented yet");
572 return 1;
573}
574
575bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
576 // Assumes don't alias anything or throw; as long as they're guaranteed to
577 // execute, they're safe to hoist. They should however not be sunk, as it
578 // would destroy information.
580 return Sinking;
581 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
582 return true;
583 // Allocas cannot be hoisted.
584 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
585 return RepR && RepR->getOpcode() == Instruction::Alloca;
586}
587
590 VPBasicBlock *LastBB) {
591 assert(FirstBB->getParent() == LastBB->getParent() &&
592 "FirstBB and LastBB from different regions");
593#ifndef NDEBUG
594 bool InSingleSuccChain = false;
595 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
596 InSingleSuccChain |= (Succ == LastBB);
597 assert(InSingleSuccChain &&
598 "LastBB unreachable from FirstBB in single-successor chain");
599#endif
600 auto Blocks = to_vector(
602 auto *LastIt = find(Blocks, LastBB);
603 assert(LastIt != Blocks.end() &&
604 "LastBB unreachable from FirstBB in depth-first traversal");
605 Blocks.erase(std::next(LastIt), Blocks.end());
606 return Blocks;
607}
608
610 for (VPRecipeBase &R : *Plan.getVectorPreheader())
612 return cast<VPInstruction>(&R);
613 return nullptr;
614}
615
617vputils::getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB) {
619 for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks())
620 for (VPBlockBase *Pred : ExitVPBB->getPredecessors())
621 if (Pred != MiddleVPBB)
622 Exits.emplace_back(cast<VPBasicBlock>(Pred), ExitVPBB);
623 return Exits;
624}
625
628 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
629 Instruction *TruncI, VPValue *StartV, VPValue *Step, DebugLoc DL,
630 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
631 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
632 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
633 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
634 VPSingleDefRecipe *BaseIV =
635 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
636
637 // Truncate base induction if needed.
638 Type *ResultTy = BaseIV->getScalarType();
639 if (TruncI) {
640 Type *TruncTy = TruncI->getType();
641 assert(ResultTy->getScalarSizeInBits() > TruncTy->getScalarSizeInBits() &&
642 "Not truncating.");
643 assert(ResultTy->isIntegerTy() && "Truncation requires an integer type");
644 BaseIV = Builder.createScalarCast(Instruction::Trunc, BaseIV, TruncTy, DL);
645 ResultTy = TruncTy;
646 }
647
648 // Truncate step if needed.
649 Type *StepTy = Step->getScalarType();
650 if (ResultTy != StepTy) {
651 assert(StepTy->getScalarSizeInBits() > ResultTy->getScalarSizeInBits() &&
652 "Not truncating.");
653 assert(StepTy->isIntegerTy() && "Truncation requires an integer type");
654 auto *VecPreheader =
656 VPBuilder::InsertPointGuard Guard(Builder);
657 Builder.setInsertPoint(VecPreheader);
658 Step = Builder.createScalarCast(Instruction::Trunc, Step, ResultTy, DL);
659 }
660 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
661 &Plan.getVF(), DL);
662}
663
664VPValue *
666 VPlan &Plan, VPBuilder &Builder) {
667 const InductionDescriptor &ID = PtrIV->getInductionDescriptor();
668 VPIRValue *StartV = Plan.getZero(ID.getStep()->getType());
669 VPValue *StepV = PtrIV->getOperand(1);
671 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
672 nullptr, StartV, StepV, PtrIV->getDebugLoc(), Builder);
673
674 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
675 PtrIV->getDebugLoc(), "next.gep");
676}
677
679 const VPDominatorTree &VPDT) {
680 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
681 if (!VPBB)
682 return false;
683
684 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
685 // VPBB as its entry, i.e., free of predecessors.
686 if (auto *R = VPBB->getParent())
687 return !R->isReplicator() && !VPBB->hasPredecessors();
688
689 // A header dominates its second predecessor (the latch), with the other
690 // predecessor being the preheader
691 return VPB->getPredecessors().size() == 2 &&
692 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
693}
694
696 const VPDominatorTree &VPDT) {
697 // A latch has a header as its last successor, with its other successors
698 // leaving the loop. A preheader OTOH has a header as its first (and only)
699 // successor.
700 return VPB->getNumSuccessors() >= 2 &&
702}
703
704std::pair<VPBasicBlock *, VPBasicBlock *>
707 Plan.getEntry()->getNumSuccessors() == 1
708 ? Plan.getEntry()->getSingleSuccessor()
709 : Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
710 assert(Header->getNumPredecessors() == 2 &&
711 "Header must have exactly 2 predecessors");
712 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
713 return {Header, Latch};
714}
715
719
720std::optional<MemoryLocation>
722 auto *M = dyn_cast<VPIRMetadata>(&R);
723 if (!M)
724 return std::nullopt;
726 // Populate noalias metadata from VPIRMetadata.
727 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
728 Loc.AATags.NoAlias = NoAliasMD;
729 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
730 Loc.AATags.Scope = AliasScopeMD;
731 return Loc;
732}
733
735 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
736 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
737 assert(CanIV && "Expected loop region to have a canonical IV");
738
739 VPSymbolicValue &VFxUF = Plan.getVFxUF();
740
741 // Check if \p Step matches the expected increment step, accounting for
742 // materialization of VFxUF and UF.
743 auto IsIncrementStep = [&](VPValue *Step) -> bool {
744 if (!VFxUF.isMaterialized())
745 return Step == &VFxUF;
746
747 VPSymbolicValue &UF = Plan.getUF();
748 if (!UF.isMaterialized())
749 return Step == &UF ||
750 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
751
752 // Alias masking: step is number of active lanes of a dependence mask.
753 if (match(Step, m_ZExtOrTruncOrSelf(
755 return true;
756
757 unsigned ConcreteUF = Plan.getConcreteUF();
758 // Fixed VF: step is just the concrete UF.
759 if (match(Step, m_SpecificInt(ConcreteUF)))
760 return true;
761
762 // Scalable VF: step involves VScale.
763 if (ConcreteUF == 1)
764 return match(Step, m_VScale());
765 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
766 return true;
767 // mul(VScale, ConcreteUF) may have been simplified to
768 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
769 return isPowerOf2_32(ConcreteUF) &&
770 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
771 };
772
773 VPInstruction *Increment = nullptr;
774 for (VPUser *U : CanIV->users()) {
775 VPValue *Step;
776 if (isa<VPInstruction>(U) &&
777 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
778 IsIncrementStep(Step)) {
779 assert(!Increment && "There must be a unique increment");
781 }
782 }
783
784 assert((!VFxUF.isMaterialized() || Increment) &&
785 "After materializing VFxUF, an increment must exist");
786 assert((!Increment ||
787 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
788 "NUW flag in region and increment must match");
789 return Increment;
790}
791
792/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
793/// inserted for predicated reductions or tail folding.
795 VPValue *BackedgeVal = PhiR->getBackedgeValue();
796 if (auto *Res =
798 return Res;
799
800 // Look through selects inserted for tail folding or predicated reductions.
801 VPRecipeBase *SelR =
802 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
803 if (!SelR)
804 return nullptr;
807}
808
811 SmallVector<const VPValue *> WorkList = {V};
812
813 while (!WorkList.empty()) {
814 const VPValue *Cur = WorkList.pop_back_val();
815 if (!Seen.insert(Cur).second)
816 continue;
817
818 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
819 // Skip blends that use V only through a compare by checking if any incoming
820 // value was already visited.
821 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
822 [&](unsigned I) {
823 return Seen.contains(Blend->getIncomingValue(I));
824 }))
825 continue;
826
827 for (VPUser *U : Cur->users()) {
828 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
829 if (InterleaveR->getAddr() == Cur)
830 return true;
831 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
832 // store (operand 1).
835 m_Specific(Cur)))))
836 return true;
838 if (MemR->getAddr() == Cur && MemR->isConsecutive())
839 return true;
840 }
841 }
842
843 // The legacy cost model only supports scalarization loads/stores with phi
844 // addresses, if the phi is directly used as load/store address. Don't
845 // traverse further for Blends.
846 if (Blend)
847 continue;
848
849 // Only traverse further through users that also define a value (and can
850 // thus have their own users walked). Skip when Cur is only used as mask ,
851 // as well as loads: a loaded value does not depend on the load's operand.
852 for (VPUser *U : Cur->users()) {
853 auto *VPI = dyn_cast<VPInstruction>(U);
854 if (VPI && VPI->getMask() == Cur &&
855 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
856 continue;
858 continue;
859 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
860 WorkList.push_back(SDR);
861 }
862 }
863 return false;
864}
865
866/// Try to find a loop-invariant IR value for \p S in the plan's entry block
867/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
868/// if no reusable IR value is found.
869VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
871 return nullptr;
872 VPlan &Plan = Builder.getPlan();
873 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
874 for (Value *V : SE.getSCEVValues(S)) {
875 // Only reuse instructions in the plan's entry block, or, when a
876 // DominatorTree is available, any instruction that dominates it.
877 // Instructions in sibling branches may not dominate the entry block.
878 auto *I = dyn_cast<Instruction>(V);
879 if (!I)
880 return Plan.getOrAddLiveIn(V);
881 if (!SE.DT.dominates(I->getParent(), PH))
882 continue;
883 SmallVector<Instruction *> DropPoisonGeneratingInsts;
884 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
885 continue;
886 for (Instruction *DropI : DropPoisonGeneratingInsts)
888 return Plan.getOrAddLiveIn(V);
889 }
890 return nullptr;
891}
892
894 if (VPValue *V = tryToReuseIRValue(S))
895 return V;
896
897 switch (S->getSCEVType()) {
898 case scConstant:
899 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
900 case scUnknown:
901 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
902 case scVScale:
903 return Builder.createVScale(S->getType(), DL);
904 case scAddExpr: {
905 auto *AddE = cast<SCEVAddExpr>(S);
906 VPIRFlags::WrapFlagsTy WrapFlags(AddE->hasNoUnsignedWrap(),
907 AddE->hasNoSignedWrap());
908
909 // Expand pointer SCEVAddExpr as a ptradd of the pointer base and the
910 // integer offset, matching SCEVExpander.
911 if (S->getType()->isPointerTy()) {
912 VPValue *Base = expand(SE.getPointerBase(S));
913 VPValue *Offset = expand(SE.removePointerBase(S));
914 GEPNoWrapFlags GEPFlags = WrapFlags.HasNUW
917 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
918 }
919
920 // Non-constant-negative add operands are expanded negated and subtracted
921 // from the running result below, instead of being negated and added.
922 auto UseSubtract = [](const SCEV *Op) {
923 return Op->isNonConstantNegative();
924 };
925 // Iterate in reverse so that constants are emitted last, and move the
926 // subtracted operands last, matching SCEVExpander's LoopCompare, so that
927 // they don't start the running result.
928 SmallVector<const SCEV *, 2> SCEVOps(reverse(AddE->operands()));
929 stable_sort(SCEVOps, [&](const SCEV *L, const SCEV *R) {
930 return !UseSubtract(L) && UseSubtract(R);
931 });
933 for (const SCEV *Op : SCEVOps) {
934 // The first operand starts the result, so it is never subtracted.
935 bool Negate = !Ops.empty() && UseSubtract(Op);
936 Ops.push_back(expand(Negate ? SE.getNegativeSCEV(Op) : Op));
937 }
938 VPValue *Result = Ops.front();
939 for (auto [Op, OpV] : drop_begin(zip_equal(SCEVOps, Ops))) {
940 if (UseSubtract(Op)) {
941 // Result + (-Op) == Result - Op, which saves the multiply for the
942 // negation. NSW only transfers if negating Op cannot overflow, see
943 // ScalarEvolution::getMinusSCEV.
944 bool HasNSW =
945 WrapFlags.HasNSW && !SE.getSignedRangeMin(Op).isMinSignedValue();
946 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
947 {/*HasNUW=*/false, HasNSW}, DL);
948 continue;
949 }
950 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
951 WrapFlags, DL);
952 }
953 return Result;
954 }
955 case scMulExpr: {
956 auto *MulE = cast<SCEVMulExpr>(S);
957 VPIRFlags::WrapFlagsTy WrapFlags(MulE->hasNoUnsignedWrap(),
958 MulE->hasNoSignedWrap());
960 for (const SCEV *Op : reverse(MulE->operands()))
961 Ops.push_back(expand(Op));
962 VPValue *Result = Ops.front();
963 for (VPValue *OpV : drop_begin(Ops)) {
964 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
965 WrapFlags, DL);
966 }
967 return Result;
968 }
969 case scUDivExpr: {
970 auto *UDiv = cast<SCEVUDivExpr>(S);
971 VPValue *LHS = expand(UDiv->getLHS());
972 const SCEV *RHSExpr = UDiv->getRHS();
973 VPValue *RHS = expand(RHSExpr);
974 if (SafeUDivMode) {
975 // Make sure the UDiv's divisor is guaranteed to not be zero/poison, to
976 // avoid UB.
977 Type *Ty = UDiv->getType();
978 bool GuaranteedNotPoison =
980 if (!GuaranteedNotPoison)
981 RHS = Builder.createFreeze(RHS, DL);
982 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
983 RHS = Builder.createScalarIntrinsic(
984 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
985 DL);
986 }
987 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
988 VPIRFlags::getDefaultFlags(Instruction::UDiv),
989 DL);
990 }
991 case scTruncate:
992 case scZeroExtend:
993 case scSignExtend:
994 case scPtrToAddr: {
995 auto *Cast = cast<SCEVCastExpr>(S);
996 VPValue *Op = expand(Cast->getOperand());
998 switch (S->getSCEVType()) {
999 case scTruncate:
1000 Opcode = Instruction::Trunc;
1001 break;
1002 case scZeroExtend:
1003 Opcode = Instruction::ZExt;
1004 break;
1005 case scSignExtend:
1006 Opcode = Instruction::SExt;
1007 break;
1008 case scPtrToAddr:
1009 Opcode = Instruction::PtrToAddr;
1010 break;
1011 default:
1012 llvm_unreachable("Unhandled cast SCEV");
1013 }
1014
1015 // When expanding ptrtoaddr, first check if there's an existing ptrtoint we
1016 // can reuse.
1017 if (Opcode == Instruction::PtrToAddr) {
1018 VPlan &Plan = Builder.getPlan();
1019 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1020 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
1022 IRV->getValue(), S->getType(), PH->getDataLayout(),
1023 [&](const CastInst *CI) {
1024 return SE.DT.dominates(CI->getParent(), PH);
1025 }))
1026 return Plan.getOrAddLiveIn(CI);
1027 }
1028 }
1029
1030 std::optional<VPIRFlags> Flags;
1031 if (Opcode == Instruction::ZExt)
1032 Flags =
1033 VPIRFlags::NonNegFlagsTy(SE.isKnownNonNegative(Cast->getOperand()));
1034
1035 return Builder.createScalarCast(Opcode, Op, S->getType(), DL, Flags);
1036 }
1037 case scUMaxExpr:
1038 case scSMaxExpr:
1039 case scUMinExpr:
1040 case scSMinExpr:
1041 case scSequentialUMinExpr: {
1042 auto *MinMax = cast<SCEVNAryExpr>(S);
1043 Intrinsic::ID IntrinsicID;
1044 switch (S->getSCEVType()) {
1045 case scUMaxExpr:
1046 IntrinsicID = Intrinsic::umax;
1047 break;
1048 case scSMaxExpr:
1049 IntrinsicID = Intrinsic::smax;
1050 break;
1051 case scUMinExpr:
1053 IntrinsicID = Intrinsic::umin;
1054 break;
1055 case scSMinExpr:
1056 IntrinsicID = Intrinsic::smin;
1057 break;
1058 default:
1059 llvm_unreachable("Unexpected min/max SCEV type");
1060 }
1061 // Chain operands in reverse order matching SCEVExpander's expansion of
1062 // min/max expressions. In SafeUDivMode freeze expansion results of operands
1063 // other than the first for sequential UMins, to avoid short-circuiting
1064 // divide-by-0/poison.
1065 bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
1066 Type *ResultTy = MinMax->getType();
1067 bool PrevSafeMode = SafeUDivMode;
1069 for (const SCEV *SCEVOp : reverse(MinMax->operands())) {
1070 bool MayShortCircuit =
1071 IsSequential && Ops.size() != MinMax->getNumOperands() - 1;
1072 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1073 VPValue *OpV = expand(SCEVOp);
1074 SafeUDivMode = PrevSafeMode;
1075 if (MayShortCircuit)
1076 OpV = Builder.createFreeze(OpV, DL);
1077 Ops.push_back(OpV);
1078 }
1079 VPValue *Result = Ops.front();
1080 for (VPValue *Op : drop_begin(Ops))
1081 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
1082 ResultTy, DL);
1083 return Result;
1084 }
1085 case scAddRecExpr: {
1086 auto *AR = cast<SCEVAddRecExpr>(S);
1087 VPlan &Plan = Builder.getPlan();
1088 [[maybe_unused]] BasicBlock *PH =
1089 cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1090 assert(SE.DT.dominates(AR->getLoop()->getHeader(), PH) &&
1091 "can only expand AddRecs for loops outside VPlan's scope");
1092
1093 // Try to expand AR by re-using an existing canonical IV in the Plan's
1094 // entry. A canonical IV must be affine and integer typed.
1095 if (!AR->isAffine() || !AR->getType()->isIntegerTy())
1097 auto FoundCanIV =
1098 find_if(Plan.getEntry()->phis(), [&](const VPRecipeBase &R) {
1099 if (!SE.isSCEVable(cast<VPIRPhi>(R).getIRPhi().getType()))
1100 return false;
1101 const SCEV *Candidate = SE.getSCEV(&cast<VPIRPhi>(R).getIRPhi());
1102 return match(Candidate,
1103 m_scev_AffineAddRec(m_scev_Zero(), m_scev_One(),
1104 m_SpecificLoop(AR->getLoop()))) &&
1105 Candidate->getType() == AR->getType();
1106 });
1107 if (FoundCanIV == Plan.getEntry()->phis().end())
1109
1110 // {Start, +, Step} --> Start + IV * Step, since the AddRec is affine.
1111 // Compute Offset = IV * Step.
1112 VPValue *Start = expand(AR->getStart());
1113 Value *CanonicalIV = &cast<VPIRPhi>(FoundCanIV)->getIRPhi();
1115 SE.getMulExpr(SE.getUnknown(CanonicalIV), AR->getStepRecurrence(SE)));
1116
1117 // Compute Start + Offset with nuw from the AddRec.
1118 return Builder.createAdd(Start, Offset, DL, "",
1119 {AR->hasNoUnsignedWrap(), false});
1120 }
1121 case scCouldNotCompute:
1122 llvm_unreachable("Attempt to expand a SCEVCouldNotCompute");
1123 }
1124 llvm_unreachable("Unknown SCEV kind!");
1125}
1126
1128 // Do remove conditional assume instructions as their conditions may be
1129 // flattened.
1130 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1131 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1133 if (IsConditionalAssume)
1134 return true;
1135
1136 if (R.mayHaveSideEffects())
1137 return false;
1138
1139 // Forbid removing trip-count expressions.
1140 if (isa<VPExpandSCEVRecipe>(R) &&
1141 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1142 return false;
1143
1144 // Recipe is dead if no user keeps the recipe alive.
1145 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1146}
1147
1149 SmallVector<VPValue *> WorkList;
1151 WorkList.push_back(V);
1152
1153 while (!WorkList.empty()) {
1154 VPValue *Cur = WorkList.pop_back_val();
1155 if (!Seen.insert(Cur).second)
1156 continue;
1157 VPRecipeBase *R = Cur->getDefiningRecipe();
1158 if (!R)
1159 continue;
1160 if (!isDeadRecipe(*R))
1161 continue;
1162 append_range(WorkList, R->operands());
1163 R->eraseFromParent();
1164 }
1165}
1166
1169 for (unsigned I = 0; I != Users.size(); ++I) {
1171 for (VPValue *V : Cur->definedValues())
1172 Users.insert_range(V->users());
1173 }
1174 return Users.takeVector();
1175}
1176
1177/// Returns \p Num / \p Denom as a BranchProbability, clamped so a ratio that is
1178/// neither zero nor one does not round to zero or one. BlockFrequencyInfo also
1179/// keeps a zero-weight edge distinguishable from an unreachable one.
1181 uint64_t Denom) {
1183 if (Num == 0 || Num == Denom)
1184 return P;
1185 return BranchProbability::getRaw(std::clamp(
1186 P.getNumerator(), 1u, BranchProbability::getDenominator() - 1));
1187}
1188
1193
1194/// Returns the probability of reaching each unique successor of \p VPBB, taken
1195/// from the branch weights recorded on its terminator, or unknown if not
1196/// available. See llvm::getBranchProbability in
1197/// llvm/Transforms/Utils/LoopUtils.h for the IR version.
1200 ArrayRef<VPBlockBase *> Successors = VPBB->getSuccessors();
1201 // With a single successor the edge is always taken and needs no weights.
1202 if (VPBlockBase *Succ = VPBB->getSingleSuccessor())
1204
1205 // Take the branch weights off the terminator. Without usable weights all
1206 // successors have unknown probability; zero the weights, so the accumulation
1207 // below still visits each of them.
1208 SmallVector<uint32_t> Weights;
1210 if (!Term || !extractBranchWeights(Term->getBranchWeights(), Weights) ||
1211 Weights.size() != Successors.size())
1212 Weights.assign(Successors.size(), 0);
1213 uint64_t Total = sum_of(Weights, uint64_t(0));
1214
1215 // Sum the weights of parallel edges to the same successor, so that the
1216 // division below rounds once per successor rather than once per edge.
1218 for (const auto &[Succ, Weight] : zip_equal(Successors, Weights))
1219 WeightPerSuccessor[cast<VPBasicBlock>(Succ)] += Weight;
1220
1221 return map_to_vector<2>(WeightPerSuccessor, [Total](const auto &SuccWeight) {
1222 auto [Succ, Weight] = SuccWeight;
1223 if (Total == 0)
1224 return std::make_pair(Succ, BranchProbability::getUnknown());
1225 return std::make_pair(Succ,
1227 });
1228}
1229
1230/// Returns \p Freq scaled by \p Prob, rounding up to 1 instead of 0 to keep a
1231/// rarely executed block distinguishable from an unreachable one.
1233 BranchProbability Prob) {
1234 BlockFrequency Scaled = Freq * Prob;
1235 if (Scaled == BlockFrequency() && Freq != BlockFrequency() && !Prob.isZero())
1236 return BlockFrequency(1);
1237 return Scaled;
1238}
1239
1242 assert(!Blocks.empty() && "expected at least the header block");
1243 // Push each block's frequency along its outgoing edges. Blocks is in reverse
1244 // post-order and forms a DAG with the backedge from the latch (the last
1245 // block) ignored, so a block's frequency is final by the time it is visited.
1247 Frequencies;
1248 Frequencies.reserve(Blocks.size());
1249 // The header (first block) always executes, the others start out unreachable.
1250 Frequencies[Blocks.front()].emplace(BlockFrequency(AlwaysExecutesFreq),
1251 false);
1252 for (VPBasicBlock *VPBB : Blocks.drop_front())
1253 Frequencies[VPBB].emplace(BlockFrequency(), false);
1254
1255 for (VPBasicBlock *VPBB : Blocks) {
1256 std::optional<VPExecutionFrequency> Src = Frequencies.at(VPBB);
1257 auto *Term = dyn_cast_if_present<VPInstruction>(VPBB->getTerminator());
1258 bool TermIsEstimated = Term && Term->hasEstimatedBranchWeights();
1259 for (const auto &[Succ, EdgeProb] : getSuccessorProbabilities(VPBB)) {
1260 // Ignore the backedge to the header (already treated as always
1261 // executing).
1262 if (Succ == Blocks.front())
1263 continue;
1264 // Ignore edges leaving Blocks, i.e. a plain CFG's edges to the middle
1265 // block or to an exit block.
1266 auto It = Frequencies.find(Succ);
1267 if (It == Frequencies.end())
1268 continue;
1269 std::optional<VPExecutionFrequency> &SuccFreq = It->second;
1270 // An unknown edge or predecessor poisons the successor.
1271 if (!Src || EdgeProb.isUnknown() || !SuccFreq) {
1272 SuccFreq = std::nullopt;
1273 continue;
1274 }
1275 // The sum can only exceed AlwaysExecutesFreq by rounding.
1276 BlockFrequency NewFreq =
1278 SuccFreq->Freq + scaleKeepingNonZero(Src->Freq, EdgeProb));
1279 bool NewIsEstimated =
1280 SuccFreq->IsEstimated || Src->IsEstimated || TermIsEstimated;
1281 SuccFreq.emplace(NewFreq, NewIsEstimated);
1282 }
1283 }
1284 return Frequencies;
1285}
1286
1289 const DataLayout &DL) {
1290 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1291 if (!OpcodeOrIID)
1292 return nullptr;
1293
1295 for (VPValue *Op : Operands) {
1296 VPValue *Candidate = Op;
1297 match(Op, m_Broadcast(m_VPValue(Candidate)));
1298 if (!match(Candidate, m_LiveIn()))
1299 return nullptr;
1300 Value *V = Candidate->getUnderlyingValue();
1301 if (!V)
1302 return nullptr;
1303 Ops.push_back(V);
1304 }
1305
1306 VPlan &Plan = *R.getParent()->getPlan();
1307 auto FoldToIRValue = [&]() -> Value * {
1308 InstSimplifyFolder Folder(DL);
1309 if (OpcodeOrIID->first) {
1310 // VPInstructions store the called intrinsic as last operand.
1311 if (isa<VPInstruction>(R))
1312 Ops.pop_back();
1313
1314 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1315 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1316 RFlags ? RFlags->getFastMathFlagsOrNone()
1317 : FastMathFlags());
1318 }
1319 unsigned Opcode = OpcodeOrIID->second;
1320 if (Instruction::isBinaryOp(Opcode))
1321 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1322 Ops[0], Ops[1]);
1323 if (Instruction::isCast(Opcode))
1324 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1325 R.getVPSingleValue()->getScalarType());
1326 switch (Opcode) {
1327 case VPInstruction::Not:
1328 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1330 case Instruction::Select:
1331 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1332 case Instruction::ICmp:
1333 case Instruction::FCmp:
1334 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1335 Ops[1]);
1336 case Instruction::GetElementPtr: {
1337 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1338 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1339 return Folder.FoldGEP(GEP->getSourceElementType(), Ops[0],
1340 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1341 }
1344 return Folder.FoldGEP(IntegerType::getInt8Ty(Plan.getContext()), Ops[0],
1345 Ops[1],
1346 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1347 // An extract of a live-in is an extract of a broadcast, so return the
1348 // broadcasted element.
1349 case Instruction::ExtractElement:
1350 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1351 return Ops[0];
1352 }
1353 return nullptr;
1354 };
1355
1356 if (Value *V = FoldToIRValue())
1357 return Plan.getOrAddLiveIn(V);
1358 return nullptr;
1359}
1360
1362 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1365 vp_depth_first_deep(Plan.getEntry()))) {
1366 for (VPSingleDefRecipe &Def :
1368 if (!isElementwise(&Def))
1369 continue;
1370
1371 // At least one of the ops must be a permutation.
1372 if (none_of(Def.operands(), MatchPerm))
1373 continue;
1374
1375 // All operands must be a single-use permutation or a live in (splat).
1376 if (!all_of(Def.operands(), [&MatchPerm](VPValue *Op) {
1377 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1378 }))
1379 continue;
1380
1381 // Remove the inner permutations.
1382 for (unsigned I = 0, E = Def.getNumOperands(); I != E; ++I)
1383 if (VPValue *X = MatchPerm(Def.getOperand(I)))
1384 Def.setOperand(I, X);
1385
1386 VPSingleDefRecipe *Res = BuildPerm(&Def);
1387 Res->insertAfter(&Def);
1388 Def.replaceUsesWithIf(
1389 Res, [&Res](VPUser &U, unsigned _) { return &U != Res; });
1390 }
1391 }
1392}
1393
1394// Implements the algorithm described in "Simple and Efficient Construction of
1395// Static Single Assignment Form" by Braun et al.
1398 assert(!Defs.empty() && "Defs shouldn't be empty");
1399 assert(
1401 "VPBB isn't reachable from entry");
1402 if (VPValue *Def = Defs.lookup(VPBB))
1403 return Def;
1404 // If the entry block is reached and there's still no def, then Defs is
1405 // missing a definition that covers this path.
1406 assert(VPBB->getNumPredecessors() && "Not all paths have def");
1407
1408 if (VPBlockBase *Pred = VPBB->getSinglePredecessor())
1409 return reconstructSSA(cast<VPBasicBlock>(Pred), Defs);
1410
1411 // Multiple predecessors, create a join.
1412 Type *Ty = Defs.begin()->second->getScalarType();
1413 VPPhi *Phi = VPBuilder(VPBB, VPBB->getFirstNonPhi())
1414 .createScalarPhi({}, DebugLoc::getUnknown(), "", {}, Ty);
1415 Defs[VPBB] = Phi;
1416 for (auto *Pred : VPBB->predecessors())
1417 Phi->addIncoming(reconstructSSA(cast<VPBasicBlock>(Pred), Defs));
1418
1419 // Fold away trivial phis.
1420 // TODO: Remove phi users which have become trivial too.
1421 if (all_equal(Phi->incoming_values())) {
1422 VPValue *Common = Phi->getIncomingValue(0);
1423 Phi->replaceAllUsesWith(Common);
1424 for (auto &[_, V] : Defs)
1425 if (V == Phi)
1426 V = Common;
1427 Defs[VPBB] = Common;
1428 Phi->eraseFromParent();
1429 return Common;
1430 }
1431
1432 return Phi;
1433}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
@ Scaled
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
Hexagon Common GEP
#define _
iv Induction Variable Users
Definition IVUsers.cpp:48
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 implements a map that provides insertion order iteration.
This file provides utility analysis objects describing memory locations.
#define P(N)
This file contains the declarations for profiling metadata utility functions.
SI Fold Operands
This file implements a set that has insertion order iteration characteristics.
This file defines less commonly used SmallVector utilities.
static unsigned getScalarSizeInBits(Type *Ty)
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
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 BranchProbability getBranchProbabilityKeepingPartial(uint64_t Num, uint64_t Denom)
Returns Num / Denom as a BranchProbability, clamped so a ratio that is neither zero nor one does not ...
static BlockFrequency scaleKeepingNonZero(BlockFrequency Freq, BranchProbability Prob)
Returns Freq scaled by Prob, rounding up to 1 instead of 0 to keep a rarely executed block distinguis...
static bool preservesUniformity(unsigned Opcode)
Returns true if Opcode preserves uniformity, i.e., if all operands are uniform, the result will also ...
static SmallVector< std::pair< const VPBasicBlock *, BranchProbability >, 2 > getSuccessorProbabilities(const VPBasicBlock *VPBB)
Returns the probability of reaching each unique successor of VPBB, taken from the branch weights reco...
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
ArrayRef< T > drop_front(size_t N=1) const
Drop the first N elements of the array.
Definition ArrayRef.h:194
const T & front() const
Get the first element.
Definition ArrayRef.h:144
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
static constexpr BranchProbability getOne()
static uint32_t getDenominator()
static constexpr BranchProbability getUnknown()
static constexpr BranchProbability getRaw(uint32_t N)
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
static DebugLoc getUnknown()
Definition DebugLoc.h:153
ValueT & at(const_arg_type_t< KeyT > Val)
Return the entry for the specified key, or abort if no such entry exists.
Definition DenseMap.h:303
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:285
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:258
bool empty() const
Definition DenseMap.h:206
iterator begin()
Definition DenseMap.h:172
iterator end()
Definition DenseMap.h:176
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Definition DenseMap.h:211
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.
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition Operator.h:202
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags noUnsignedWrap()
static GEPNoWrapFlags none()
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
@ IK_IntInduction
Integer induction variable. Step = C.
InstSimplifyFolder - Use InstructionSimplify to fold operations to existing values.
bool isCast() const
bool isBinaryOp() const
bool isUnaryOp() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1081
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.
static LLVM_ABI CastInst * findReusableCastForPtrToAddr(Value *PtrOp, Type *Ty, const DataLayout &DL, function_ref< bool(const CastInst *)> Dominates)
Find an existing cast among PtrOp's users that computes the same value as a ptrtoaddr of PtrOp to Ty ...
This class represents an analyzed expression in the program.
static constexpr auto FlagAnyWrap
static constexpr auto FlagNSW
Type * getType() const
Return the LLVM type of this SCEV expression.
SCEVTypes getSCEVType() const
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 * getZeroExtendExpr(SCEVUse Op, Type *Ty, unsigned Depth=0)
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.
static LLVM_ABI bool isGuaranteedNotToBePoison(const SCEV *Op)
Returns true if Op is guaranteed to not be poison.
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 * getTruncateExpr(SCEVUse 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 * getSignExtendExpr(SCEVUse 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()
const SCEV * getPowerOfTwo(Type *Ty, unsigned Power)
Return a SCEV for the constant Power of two.
LLVM_ABI const SCEV * getPtrToAddrExpr(const SCEV *Op)
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 SCEVUse getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlags Flags={}, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
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.
LLVM_ABI SCEVUse getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEVFlags Flags)
Get an add recurrence expression for the specified loop.
LLVM_ABI SCEVUse getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlags Flags={}, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
A vector that has set insertion semantics.
Definition SetVector.h:57
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 assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
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:277
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4418
iterator end()
Definition VPlan.h:4455
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4506
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:233
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:610
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4484
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:95
VPRegionBlock * getParent()
Definition VPlan.h:193
iterator_range< VPBlockBase ** > predecessors()
Definition VPlan.h:226
size_t getNumSuccessors() const
Definition VPlan.h:243
size_t getNumPredecessors() const
Definition VPlan.h:244
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:228
VPlan * getPlan()
Definition VPlan.h:197
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:239
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:188
VPBlockBase * getSingleHierarchicalPredecessor()
Definition VPlan.h:279
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:233
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:217
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:431
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.
RAII object that stores the current insertion point and restores it when the object is destroyed.
VPlan-based builder utility analogous to IRBuilder.
VPPhi * createScalarPhi(ArrayRef< VPValue * > IncomingValues, DebugLoc DL=DebugLoc::getUnknown(), const Twine &Name="", std::optional< VPIRFlags > Flags=std::nullopt, Type *ResultTy=nullptr)
Create a phi with IncomingValues, using the default flags for the result type, unless Flags is set.
ArrayRef< VPRecipeValue * > definedValues()
Returns an ArrayRef of the values defined by the VPDef.
Definition VPlanValue.h:574
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4199
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:4031
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2493
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition VPlan.h:2482
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4571
static VPIRFlags getDefaultFlags(unsigned Opcode, Type *ResultTy=nullptr)
Returns default flags for Opcode and scalar ResultTy for opcodes that support it, asserts otherwise.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1305
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1402
unsigned getOpcode() const
Definition VPlan.h:1491
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
bool isSingleScalar() const
Returns true if the recipe produces a single scalar value.
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:411
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:561
void insertAfter(VPRecipeBase *InsertPos)
Insert an unlinked Recipe into a basic block immediately after the specified Recipe.
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
Definition VPlanValue.h:354
A recipe for handling reduction phis.
Definition VPlan.h:2864
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4643
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4719
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4807
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4763
VPValues are defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:252
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3401
VPValue * expand(const SCEV *S)
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:4260
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:619
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:217
bool isMaterialized() const
Returns true if this value has been materialized.
Definition VPlanValue.h:235
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:401
operand_range operands()
Definition VPlanValue.h:474
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:442
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:147
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:128
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
Definition VPlanValue.h:75
user_range users()
Definition VPlanValue.h:157
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1889
A recipe for handling GEP instructions.
Definition VPlan.h:2216
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition VPlan.h:2586
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2615
A recipe for widened phis.
Definition VPlan.h:2751
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1823
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4830
LLVMContext & getContext() const
Definition VPlan.h:5040
VPBasicBlock * getEntry()
Definition VPlan.h:4926
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5038
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:4992
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:5112
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5138
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1033
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5090
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4931
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:5035
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4982
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5031
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
An efficient, type-erasing, non-owning reference to a callable.
IteratorT end() const
#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.
CastOperator_match< OpTy, Instruction::PtrToAddr > m_PtrToAddr(const OpTy &Op)
Matches PtrToAddr.
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.
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)
auto m_VScale()
Matches a call to llvm.vscale().
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.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
BinaryOp_match< LHS, RHS, Instruction::SDiv > m_SDiv(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(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< Instruction::Or, Op0_t, Op1_t > m_BinaryOr(const Op0_t &Op0, const Op1_t &Op1)
Match a binary OR 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)
auto m_GetElementPtr(const Op0_t &Op0, const Op1_t &Op1)
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractVectorForPart, Op0_t, Op1_t > m_ExtractVectorForPart(const Op0_t &Op0, const Op1_t &Op1)
VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
VPInstruction_match< VPInstruction::Broadcast, Op0_t > m_Broadcast(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
void pullOutPermutationsImpl(VPlan &Plan, function_ref< VPValue *(VPValue *Op)> Perm, function_ref< VPSingleDefRecipe *(VPSingleDefRecipe *X)> Build)
Template-independent implementation for pullOutPermutations.
BranchProbability getExecutionProbability(BlockFrequency Freq)
Returns Freq as a BranchProbability, relative to AlwaysExecutesFreq.
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.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
std::optional< int64_t > getConstantStride(VPValue *Addr, Type *AccessTy, PredicatedScalarEvolution &PSE, const Loop *L)
If the pointer operand Addr of a memory access is an affine AddRec w.r.t.
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,...
LLVM_ABI_FOR_TEST VPValue * reconstructSSA(VPBasicBlock *VPBB, DenseMap< VPBasicBlock *, VPValue * > &Defs)
Insert phis to reconstruct SSA for a single value starting from VPBB.
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
Intrinsic::ID getIntrinsicID(const Ty *R)
Return the intrinsic ID underlying a call.
Definition VPlanUtils.h:94
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.
VPIRValue * tryToFoldLiveIns(VPSingleDefRecipe &R, ArrayRef< VPValue * > Operands, const DataLayout &DL)
Try to fold R using InstSimplifyFolder.
SmallVector< std::pair< VPBasicBlock *, VPIRBasicBlock * > > getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB)
Returns the (early exiting block, exit block) pairs of Plan, i.e.
VPValue * findIncomingAliasMask(const VPlan &Plan)
Finds the incoming alias-mask within the vector preheader.
constexpr uint64_t AlwaysExecutesFreq
Denominator of the frequencies computed by computeExecutionFrequencies, i.e.
Definition VPlanUtils.h:245
DenseMap< const VPBasicBlock *, std::optional< VPExecutionFrequency > > computeExecutionFrequencies(ArrayRef< VPBasicBlock * > Blocks)
Computes for each block in Blocks, which must be in reverse post-order, the frequency with which it e...
void recursivelyDeleteDeadRecipes(VPValue *V)
Recursively delete V and any of its operands that become dead.
bool doesGeneratePerAllLanes(const VPRecipeBase *R)
Returns true if R produces scalar values for all VF lanes.
bool isDeadRecipe(VPRecipeBase &R)
Returns true if R is dead, i.e.
bool isElementwise(const VPValue *V)
Return true if V is elementwise, i.e. none of the lanes are permuted.
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.
std::optional< std::pair< bool, unsigned > > getOpcodeOrIntrinsicID(const VPValue *V)
Get the instruction opcode or intrinsic ID for the recipe defining V.
VPValue * scalarizeVPWidenPointerInduction(VPWidenPointerInductionRecipe *PtrIV, VPlan &Plan, VPBuilder &Builder)
Scalarize a VPWidenPointerInductionRecipe by replacing it with a PtrAdd (IndStart,...
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.
SmallVector< VPUser * > collectUsersRecursively(VPValue *V)
Collect all users of V, looking through recipes that define other values.
VPScalarIVStepsRecipe * createScalarIVSteps(VPlan &Plan, InductionDescriptor::InductionKind Kind, Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, Instruction *TruncI, VPValue *StartV, VPValue *Step, DebugLoc DL, VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags={})
Create a scalar-iv-steps recipe over Plan's canonical IV for an induction of Kind with InductionOpcod...
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
@ Offset
Definition DWP.cpp:577
void stable_sort(R &&Range)
Definition STLExtras.h:2132
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:1781
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:1755
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:856
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto map_to_vector(ContainerTy &&C, FuncTy &&F)
Map a range to a SmallVector with element types deduced from the mapping.
constexpr from_range_t from_range
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:732
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
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:250
iterator_range< df_iterator< VPBlockDeepTraversalWrapper< VPBlockBase * > > > vp_depth_first_deep(VPBlockBase *G)
Returns an iterator range to traverse the graph starting at G in depth-first order while traversing t...
Definition VPlanCFG.h:285
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
Definition STLExtras.h:2189
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
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:326
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool hasIrregularType(Type *Ty, const DataLayout &DL)
A helper function that returns true if the given type is irregular.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1769
SmallVector< 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 sum_of(R &&Range, E Init=E{0})
Returns the sum of all values in Range with Init initial value.
Definition STLExtras.h:1733
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
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:1788
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
Definition STLExtras.h:2182
LLVM_ABI std::optional< int64_t > getStrideFromAddRec(const SCEVAddRecExpr *AR, const Loop *Lp, Type *AccessTy, Value *Ptr, PredicatedScalarEvolution &PSE)
If AR is an affine AddRec for Lp with a constant step, return the step in units of AccessTy's allocat...
@ 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
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:342
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:279
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
Definition VPlan.h:3871
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3818