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"
27#include "llvm/IR/Dominators.h"
30
31using namespace llvm;
32using namespace llvm::VPlanPatternMatch;
33using namespace llvm::SCEVPatternMatch;
34
36 return all_of(Def->users(),
37 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
38}
39
41 return all_of(Def->users(),
42 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
43}
44
46 return all_of(Def->users(),
47 [Def](const VPUser *U) { return U->usesScalars(Def); });
48}
49
51 if (auto *E = dyn_cast<SCEVConstant>(Expr))
52 return Plan.getOrAddLiveIn(E->getValue());
53 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
54 // value. Otherwise the value may be defined in a loop and using it directly
55 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
56 // form.
57 auto *U = dyn_cast<SCEVUnknown>(Expr);
58 if (U && !isa<Instruction>(U->getValue()))
59 return Plan.getOrAddLiveIn(U->getValue());
60 auto *Expanded = new VPExpandSCEVRecipe(Expr);
61 VPBasicBlock *EntryVPBB = Plan.getEntry();
62 auto Iter = EntryVPBB->getFirstNonPhi();
63 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
64 ++Iter;
65 EntryVPBB->insert(Expanded, Iter);
66 return Expanded;
67}
68
69/// Returns true if \p V being poison is guaranteed to trigger UB because it
70/// propagates to the address of a memory recipe.
71static bool poisonGuaranteesUB(const VPValue *V) {
74
75 auto PropagatesPoisonFromRecipeOp = [](const VPRecipeBase *R) {
77 return false;
78 unsigned Opcode = vputils::getOpcode(R->getVPSingleValue());
79 return Instruction::isCast(Opcode) || Opcode == Instruction::GetElementPtr;
80 };
81
82 Worklist.push_back(V);
83
84 while (!Worklist.empty()) {
85 const VPValue *Current = Worklist.pop_back_val();
86 if (!Visited.insert(Current).second)
87 continue;
88
89 for (VPUser *U : Current->users()) {
90 // Check if Current is used as an address operand for load/store.
91 auto *R = cast<VPRecipeBase>(U);
92 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(R)) {
93 if (MemR->getAddr() == Current)
94 return true;
95 continue;
96 }
97 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
98 unsigned Opcode = Rep->getOpcode();
99 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
100 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
101 return true;
102 }
103
104 // Check if poison propagates through this recipe to any of its users.
105 for (const VPValue *Op : R->operands()) {
106 if (Op == Current && PropagatesPoisonFromRecipeOp(R)) {
107 Worklist.push_back(R->getVPSingleValue());
108 break;
109 }
110 }
111 }
112 }
113
114 return false;
115}
116
118 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
119 // casts to find a root GEP VPInstruction.
120 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
121 unsigned Opcode = PtrVPI->getOpcode();
122 if (Opcode == Instruction::GetElementPtr) {
123 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
124 return PtrVPI->getGEPNoWrapFlags();
125 Ptr = PtrVPI->getOperand(0);
126 continue;
127 }
128 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
129 break;
130 Ptr = PtrVPI->getOperand(0);
131 }
132 return GEPNoWrapFlags::none();
133}
134
137 const Loop *L) {
138 ScalarEvolution &SE = *PSE.getSE();
139 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
140 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
141 "RegionValue must be canonical IV");
142 if (!L)
143 return SE.getCouldNotCompute();
144 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
145 L, SCEV::FlagNone);
146 }
147
149 Value *LiveIn = V->getUnderlyingValue();
150 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
151 return SE.getSCEV(LiveIn);
152 return SE.getCouldNotCompute();
153 }
154
155 // Helper to create SCEVs for binary and unary operations.
156 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
157 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
158 -> const SCEV * {
160 for (VPValue *Op : Ops) {
161 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
163 return SE.getCouldNotCompute();
164 SCEVOps.push_back(S);
165 }
166 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
167 };
168
169 VPValue *LHSVal, *RHSVal;
170 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
171 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
172 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
173 });
174 if (match(V, m_BinaryOr(m_VPValue(LHSVal), m_VPValue(RHSVal))))
175 if (cast<VPRecipeWithIRFlags>(V->getDefiningRecipe())->isDisjoint())
176 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
177 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
178 });
179 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
180 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
181 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagNone, 0);
182 });
183 if (match(V, m_Not(m_VPValue(LHSVal)))) {
184 // not X = xor X, -1 = -1 - X
185 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
186 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
187 });
188 }
189 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
190 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
191 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
192 });
193 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
194 // amount >= the bit width produces poison; do not rewrite it, as
195 // getPowerOfTwo requires the power to be in range.
196 uint64_t ShiftAmt;
197 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
198 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
199 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
200 return SE.getMulExpr(Ops[0],
201 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
202 });
203 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
204 Type *Ty = V->getScalarType();
205 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
206 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
207 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
208 });
209 }
210 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
211 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
212 return SE.getUDivExpr(Ops[0], Ops[1]);
213 });
214 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
215 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
216 return SE.getURemExpr(Ops[0], Ops[1]);
217 });
218 // A SDiv with non-negative operands is equivalent to an UDiv.
219 if (match(V, m_SDiv(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
220 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
221 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
222 return SE.getCouldNotCompute();
223 return SE.getUDivExpr(Ops[0], Ops[1]);
224 });
225 }
226 // A SRem with non-negative operands is equivalent to an URem.
227 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
228 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
229 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
230 return SE.getCouldNotCompute();
231 return SE.getURemExpr(Ops[0], Ops[1]);
232 });
233 }
234 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
235 const APInt *Mask;
236 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
237 (*Mask + 1).isPowerOf2())
238 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
239 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
240 });
241 // SCEV models ptrtoaddr, but not ptrtoint, mirroring createSCEV.
242 if (match(V, m_PtrToAddr(m_VPValue(LHSVal))))
243 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
244 return SE.getPtrToAddrExpr(Ops[0]);
245 });
246 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
247 Type *DestTy = V->getScalarType();
248 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
249 return SE.getTruncateExpr(Ops[0], DestTy);
250 });
251 }
252 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
253 Type *DestTy = V->getScalarType();
254 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
255 return SE.getZeroExtendExpr(Ops[0], DestTy);
256 });
257 }
258 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
259 Type *DestTy = V->getScalarType();
260
261 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
262 // onto the operands before computing the subtraction.
263 VPValue *SubLHS, *SubRHS;
264 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
265 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
266 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
267 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
268 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
270 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
271 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
272 }
273
274 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
275 return SE.getSignExtendExpr(Ops[0], DestTy);
276 });
277 }
278 if (match(V,
280 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
281 return SE.getUMaxExpr(Ops[0], Ops[1]);
282 });
283 if (match(V,
285 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
286 return SE.getSMaxExpr(Ops[0], Ops[1]);
287 });
288 if (match(V,
290 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
291 return SE.getUMinExpr(Ops[0], Ops[1]);
292 });
293 if (match(V,
295 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
296 return SE.getSMinExpr(Ops[0], Ops[1]);
297 });
299 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
300 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
301 // not proof that the input is never INT_MIN, nor that poison reaches
302 // UB. Do not translate it to SCEV's global IsNSW flag.
303 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
304 });
305
307 Type *SourceElementType;
308 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
309 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
310 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
311 });
312 }
313
314 // TODO: Support constructing SCEVs for more recipes as needed.
315 const VPRecipeBase *DefR = V->getDefiningRecipe();
316 const SCEV *Expr =
318 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
319 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
320 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
321 if (!L || isa<SCEVCouldNotCompute>(Step))
322 return SE.getCouldNotCompute();
323 const SCEV *Start =
324 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
325 const SCEV *AddRec =
326 SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
327 if (R->isTruncated())
328 return SE.getTruncateExpr(AddRec, R->getScalarType());
329 return AddRec;
330 })
331 .Case([&SE, &PSE,
332 L](const VPWidenPointerInductionRecipe *R) -> const SCEV * {
333 const SCEV *Start =
334 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
335 if (!L || isa<SCEVCouldNotCompute>(Start))
336 return SE.getCouldNotCompute();
337 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
338 if (isa<SCEVCouldNotCompute>(Step))
339 return SE.getCouldNotCompute();
340 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
341 })
342 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) -> const SCEV * {
343 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
344 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
345 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
346 if (any_of(ArrayRef({Start, IV, Scale}),
348 return SE.getCouldNotCompute();
349
350 return SE.getAddExpr(
351 SE.getTruncateOrSignExtend(Start, IV->getType()),
352 SE.getMulExpr(
353 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
354 })
355 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
356 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
357 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
359 return SE.getCouldNotCompute();
360 return SE.getTruncateOrSignExtend(IV, Step->getType());
361 })
362 .Default(
363 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
364
365 return PSE.getPredicatedSCEV(Expr);
366}
367
368std::optional<int64_t>
370 PredicatedScalarEvolution &PSE, const Loop *L) {
371 assert(!hasIrregularType(AccessTy, L->getHeader()->getDataLayout()) &&
372 "should not try to widen irregular types");
373 const SCEV *AddrSCEV = getSCEVExprForVPValue(Addr, PSE, L);
374 auto *AddRec = dyn_cast<SCEVAddRecExpr>(AddrSCEV);
375 if (!AddRec)
376 return {};
377
378 return getStrideFromAddRec(AddRec, L, AccessTy, /*Ptr=*/nullptr, PSE);
379}
380
382 const Loop *L) {
383 // If address is an SCEVAddExpr, we require that all operands must be either
384 // be invariant or a (possibly sign-extend) affine AddRec.
385 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
386 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
387 return SE.isLoopInvariant(Op, L) ||
388 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
389 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
390 });
391 }
392
393 // Otherwise, check if address is loop invariant or an affine add recurrence.
394 return SE.isLoopInvariant(Addr, L) ||
396}
397
398unsigned vputils::getOpcode(const VPValue *V) {
402 VPWidenLoadEVLRecipe>([](auto *I) { return I->getOpcode(); })
403 .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
404 [](auto *I) {
405 // For recipes that do not directly map to LLVM IR instructions,
406 // assign opcodes after the last VPInstruction opcode (which is also
407 // after the last IR Instruction opcode), based on the VPRecipeID.
408 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
409 })
410 .Default([](auto *) { return 0; });
411}
412
413std::optional<std::pair<bool, unsigned>>
416 return std::make_pair(true, IID);
417 if (unsigned Opcode = vputils::getOpcode(V))
418 return std::make_pair(false, Opcode);
419 return {};
420}
421
422/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
423/// uniform, the result will also be uniform.
424static bool preservesUniformity(unsigned Opcode) {
425 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
426 return true;
427 switch (Opcode) {
428 case Instruction::Freeze:
429 case Instruction::GetElementPtr:
430 case Instruction::ICmp:
431 case Instruction::FCmp:
432 case Instruction::Select:
437 return true;
438 default:
439 return false;
440 }
441}
442
444 // TODO: Handle more opcodes and recipes.
446 return false;
447 unsigned Opcode = getOpcode(V);
448 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
449}
450
452 // Live-in, symbolic and canonical-IV region values are single-scalar.
453 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
454 return RV == RV->getDefiningRegion()->getCanonicalIV();
456 return true;
457
458 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
459 const VPRegionBlock *RegionOfR = Rep->getRegion();
460 // Don't consider recipes in replicate regions as uniform yet; their first
461 // lane cannot be accessed when executing the replicate region for other
462 // lanes.
463 if (RegionOfR && RegionOfR->isReplicator())
464 return false;
465 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
466 all_of(Rep->operands(), isSingleScalar));
467 }
470 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
471 return preservesUniformity(WidenR->getOpcode()) &&
472 all_of(WidenR->operands(), isSingleScalar);
473 }
474 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
475 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
476 (preservesUniformity(VPI->getOpcode()) &&
477 all_of(VPI->operands(), isSingleScalar));
478 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
479 return !RR->isPartialReduction();
481 VPV))
482 return true;
483 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
484 return Expr->isVectorToScalar();
485
486 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
487 return isa<VPExpandSCEVRecipe>(VPV);
488}
489
491 // Live-ins, symbolic and canonical-IV region values are uniform.
492 if (auto *RV = dyn_cast<VPRegionValue>(V))
493 return RV == RV->getDefiningRegion()->getCanonicalIV();
495 return true;
496
497 const VPRecipeBase *R = V->getDefiningRecipe();
498 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
499 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
500 if (VPBB &&
501 (VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
502 if (match(R,
505 return false;
506 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
507 }
508
510 .Case([](const VPDerivedIVRecipe *R) { return true; })
511 .Case([](const VPReplicateRecipe *R) {
512 // Be conservative about side-effects, except for the
513 // known-side-effecting assumes and stores, which we know will be
514 // uniform. Each alloca creates a distinct allocation, so allocas are
515 // never uniform.
516 return R->isSingleScalar() && R->getOpcode() != Instruction::Alloca &&
517 (!R->mayHaveSideEffects() ||
518 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
519 all_of(R->operands(), isUniformAcrossVFsAndUFs);
520 })
521 .Case([](const VPWidenRecipe *R) {
522 return preservesUniformity(R->getOpcode()) &&
523 all_of(R->operands(), isUniformAcrossVFsAndUFs);
524 })
525 .Case([](const VPPhi *) {
526 // Bail out on VPPhi, as we can end up in infinite cycles.
527 return false;
528 })
529 .Case([](const VPInstruction *VPI) {
530 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
533 })
534 .Case([](const VPWidenCastRecipe *R) {
535 // A cast is uniform according to its operand.
536 return isUniformAcrossVFsAndUFs(R->getOperand(0));
537 })
538 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
539 // unless proven otherwise.
540 return false;
541 });
542}
543
545 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
546 return RepR->doesGeneratePerAllLanes();
547 if (auto *VPI = dyn_cast<VPInstruction>(R))
548 return VPI->doesGeneratePerAllLanes();
549 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
550 return SIVSteps->doesGeneratePerAllLanes();
551 return false;
552}
553
555 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
556 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
557 return VPBlockUtils::isHeader(VPB, VPDT);
558 });
559 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
560}
561
563 if (!R)
564 return 1;
565 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
566 return RR->getVFScaleFactor();
567 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
568 return RR->getVFScaleFactor();
569 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
570 return ER->getVFScaleFactor();
571 assert(
574 "getting scaling factor of reduction-start-vector not implemented yet");
575 return 1;
576}
577
578bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
579 // Assumes don't alias anything or throw; as long as they're guaranteed to
580 // execute, they're safe to hoist. They should however not be sunk, as it
581 // would destroy information.
583 return Sinking;
584 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
585 return true;
586 // Allocas cannot be hoisted.
587 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
588 return RepR && RepR->getOpcode() == Instruction::Alloca;
589}
590
593 VPBasicBlock *LastBB) {
594 assert(FirstBB->getParent() == LastBB->getParent() &&
595 "FirstBB and LastBB from different regions");
596#ifndef NDEBUG
597 bool InSingleSuccChain = false;
598 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
599 InSingleSuccChain |= (Succ == LastBB);
600 assert(InSingleSuccChain &&
601 "LastBB unreachable from FirstBB in single-successor chain");
602#endif
603 auto Blocks = to_vector(
605 auto *LastIt = find(Blocks, LastBB);
606 assert(LastIt != Blocks.end() &&
607 "LastBB unreachable from FirstBB in depth-first traversal");
608 Blocks.erase(std::next(LastIt), Blocks.end());
609 return Blocks;
610}
611
613 for (VPRecipeBase &R : *Plan.getVectorPreheader())
615 return cast<VPInstruction>(&R);
616 return nullptr;
617}
618
620vputils::getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB) {
622 for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks())
623 for (VPBlockBase *Pred : ExitVPBB->getPredecessors())
624 if (Pred != MiddleVPBB)
625 Exits.emplace_back(cast<VPBasicBlock>(Pred), ExitVPBB);
626 return Exits;
627}
628
631 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
632 Type *ResultTy, VPValue *StartV, VPValue *Step, DebugLoc DL,
633 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
634 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
635 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
636 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
637 VPValue *BaseIV =
638 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
639
640 // Truncate BaseIV and Step to ResultTy.
641 if (ResultTy->isIntegerTy()) {
642 [[maybe_unused]] Type *BaseIVTy = BaseIV->getScalarType();
643 assert(BaseIVTy->isIntegerTy() && "Integral BaseIV type expected");
644 assert(BaseIVTy->getPrimitiveSizeInBits() >=
645 ResultTy->getPrimitiveSizeInBits() &&
646 "BaseIV's type must be at least as large as ResultTy");
647 BaseIV = Builder.createScalarZExtOrTrunc(BaseIV, ResultTy, DL);
648 [[maybe_unused]] Type *StepTy = Step->getScalarType();
649 assert(StepTy->isIntegerTy() && "Integral Step type expected");
650 assert(StepTy->getPrimitiveSizeInBits() >=
651 ResultTy->getPrimitiveSizeInBits() &&
652 "Step's type must be at least as large as ResultTy");
653 auto *VecPreheader =
655 VPBuilder::InsertPointGuard Guard(Builder);
656 Builder.setInsertPoint(VecPreheader);
657 Step = Builder.createScalarZExtOrTrunc(Step, ResultTy, DL);
658 }
659 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
660 &Plan.getVF(), DL);
661}
662
663VPValue *
665 VPlan &Plan, VPBuilder &Builder) {
666 const InductionDescriptor &ID = PtrIV->getInductionDescriptor();
667 VPIRValue *StartV = Plan.getZero(ID.getStep()->getType());
668 VPValue *StepV = PtrIV->getOperand(1);
670 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
671 StartV->getScalarType(), StartV, StepV, PtrIV->getDebugLoc(), Builder);
672
673 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
674 PtrIV->getDebugLoc(), "next.gep");
675}
676
678 const VPDominatorTree &VPDT) {
679 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
680 if (!VPBB)
681 return false;
682
683 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
684 // VPBB as its entry, i.e., free of predecessors.
685 if (auto *R = VPBB->getParent())
686 return !R->isReplicator() && !VPBB->hasPredecessors();
687
688 // A header dominates its second predecessor (the latch), with the other
689 // predecessor being the preheader
690 return VPB->getPredecessors().size() == 2 &&
691 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
692}
693
695 const VPDominatorTree &VPDT) {
696 // A latch has a header as its last successor, with its other successors
697 // leaving the loop. A preheader OTOH has a header as its first (and only)
698 // successor.
699 return VPB->getNumSuccessors() >= 2 &&
701}
702
703std::pair<VPBasicBlock *, VPBasicBlock *>
706 Plan.getEntry()->getNumSuccessors() == 1
707 ? Plan.getEntry()->getSingleSuccessor()
708 : Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
709 assert(Header->getNumPredecessors() == 2 &&
710 "Header must have exactly 2 predecessors");
711 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
712 return {Header, Latch};
713}
714
718
720 const VPPhi *PhiR) {
721 if (ID.getKind() == InductionDescriptor::IK_FpInduction)
722 return ID.getInductionBinOp()->getFastMathFlags();
723
724 // The flags only bound the induction values if the increment directly
725 // updates PhiR.
726 VPValue *Inc = PhiR->getOperand(1);
727 if (match(Inc, m_c_Add(m_Specific(PhiR), m_VPValue())))
728 return cast<VPInstruction>(Inc)->getNoWrapFlagsOrNone();
729
730 if (match(Inc, m_Sub(m_Specific(PhiR), m_VPValue()))) {
731 // The step of a sub induction is negated, so NUW cannot be preserved. NSW
732 // can, if the step is not the signed minimum.
733 ConstantInt *Step = ID.getConstIntStepValue();
734 bool NSW = cast<VPInstruction>(Inc)->getNoWrapFlagsOrNone().HasNSW &&
735 Step && !Step->isMinValue(/*IsSigned=*/true);
736 return VPIRFlags::WrapFlagsTy(/*NUW*/ false, NSW);
737 }
738
739 return VPIRFlags::WrapFlagsTy(false, false);
740}
741
742std::optional<MemoryLocation>
744 auto *M = dyn_cast<VPIRMetadata>(&R);
745 if (!M)
746 return std::nullopt;
748 // Populate noalias metadata from VPIRMetadata.
749 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
750 Loc.AATags.NoAlias = NoAliasMD;
751 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
752 Loc.AATags.Scope = AliasScopeMD;
753 return Loc;
754}
755
757 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
758 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
759 assert(CanIV && "Expected loop region to have a canonical IV");
760
761 VPSymbolicValue &VFxUF = Plan.getVFxUF();
762
763 // Check if \p Step matches the expected increment step, accounting for
764 // materialization of VFxUF and UF.
765 auto IsIncrementStep = [&](VPValue *Step) -> bool {
766 if (!VFxUF.isMaterialized())
767 return Step == &VFxUF;
768
769 VPSymbolicValue &UF = Plan.getUF();
770 if (!UF.isMaterialized())
771 return Step == &UF ||
772 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
773
774 // Alias masking: step is number of active lanes of a dependence mask.
775 if (match(Step, m_ZExtOrTruncOrSelf(
777 return true;
778
779 unsigned ConcreteUF = Plan.getConcreteUF();
780 // Fixed VF: step is just the concrete UF.
781 if (match(Step, m_SpecificInt(ConcreteUF)))
782 return true;
783
784 // Scalable VF: step involves VScale.
785 if (ConcreteUF == 1)
786 return match(Step, m_VScale());
787 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
788 return true;
789 // mul(VScale, ConcreteUF) may have been simplified to
790 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
791 return isPowerOf2_32(ConcreteUF) &&
792 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
793 };
794
795 VPInstruction *Increment = nullptr;
796 for (VPUser *U : CanIV->users()) {
797 VPValue *Step;
798 if (isa<VPInstruction>(U) &&
799 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
800 IsIncrementStep(Step)) {
801 assert(!Increment && "There must be a unique increment");
803 }
804 }
805
806 assert((!VFxUF.isMaterialized() || Increment) &&
807 "After materializing VFxUF, an increment must exist");
808 assert((!Increment ||
809 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
810 "NUW flag in region and increment must match");
811 return Increment;
812}
813
814/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
815/// inserted for predicated reductions or tail folding.
817 VPValue *BackedgeVal = PhiR->getBackedgeValue();
818 if (auto *Res =
820 return Res;
821
822 // Look through selects inserted for tail folding or predicated reductions.
823 VPRecipeBase *SelR =
824 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
825 if (!SelR)
826 return nullptr;
829}
830
833 SmallVector<const VPValue *> WorkList = {V};
834
835 while (!WorkList.empty()) {
836 const VPValue *Cur = WorkList.pop_back_val();
837 if (!Seen.insert(Cur).second)
838 continue;
839
840 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
841 // Skip blends that use V only through a compare by checking if any incoming
842 // value was already visited.
843 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
844 [&](unsigned I) {
845 return Seen.contains(Blend->getIncomingValue(I));
846 }))
847 continue;
848
849 for (VPUser *U : Cur->users()) {
850 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
851 if (InterleaveR->getAddr() == Cur)
852 return true;
853 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
854 // store (operand 1).
857 m_Specific(Cur)))))
858 return true;
860 if (MemR->getAddr() == Cur && MemR->isConsecutive())
861 return true;
862 }
863 }
864
865 // The legacy cost model only supports scalarization loads/stores with phi
866 // addresses, if the phi is directly used as load/store address. Don't
867 // traverse further for Blends and first-order recurrence splices.
868 if (Blend ||
869 match(Cur,
871 continue;
872
873 // Only traverse further through users that also define a value (and can
874 // thus have their own users walked). Skip when Cur is only used as mask ,
875 // as well as loads: a loaded value does not depend on the load's operand.
876 for (VPUser *U : Cur->users()) {
877 auto *VPI = dyn_cast<VPInstruction>(U);
878 if (VPI && VPI->getMask() == Cur &&
879 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
880 continue;
882 continue;
883 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
884 WorkList.push_back(SDR);
885 }
886 }
887 return false;
888}
889
890/// Try to find a loop-invariant IR value for \p S in the plan's entry block
891/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
892/// if no reusable IR value is found.
893VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
895 return nullptr;
896 VPlan &Plan = Builder.getPlan();
897 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
898 for (Value *V : SE.getSCEVValues(S)) {
899 // Only reuse instructions in the plan's entry block, or, when a
900 // DominatorTree is available, any instruction that dominates it.
901 // Instructions in sibling branches may not dominate the entry block.
902 auto *I = dyn_cast<Instruction>(V);
903 if (!I)
904 return Plan.getOrAddLiveIn(V);
905 if (!SE.DT.dominates(I->getParent(), PH))
906 continue;
907 Loop *IL = SE.LI.getLoopFor(I->getParent());
908 if (IL && !IL->contains(PH))
909 continue;
910 SmallVector<Instruction *> DropPoisonGeneratingInsts;
911 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
912 continue;
913 for (Instruction *DropI : DropPoisonGeneratingInsts)
915 return Plan.getOrAddLiveIn(V);
916 }
917 return nullptr;
918}
919
920VPValue *VPSCEVExpander::expandAsPtrAdd(const SCEVNAryExpr *S) {
921 VPValue *Base = expand(SE.getPointerBase(S));
922 VPValue *Offset = expand(SE.removePointerBase(S));
923 GEPNoWrapFlags GEPFlags = S->hasNoUnsignedWrap()
925 : GEPNoWrapFlags::none();
926 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
927}
928
930 if (VPValue *V = tryToReuseIRValue(S))
931 return V;
932
933 switch (S->getSCEVType()) {
934 case scConstant:
935 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
936 case scUnknown:
937 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
938 case scVScale:
939 return Builder.createVScale(S->getType(), DL);
940 case scAddExpr: {
941 auto *AddE = cast<SCEVAddExpr>(S);
942 VPIRFlags::WrapFlagsTy WrapFlags(AddE->hasNoUnsignedWrap(),
943 AddE->hasNoSignedWrap());
944
945 // Expand pointer SCEVAddExpr as a ptradd of the pointer base and the
946 // integer offset, matching SCEVExpander.
947 if (S->getType()->isPointerTy())
948 return expandAsPtrAdd(AddE);
949
950 // Non-constant-negative add operands are expanded negated and subtracted
951 // from the running result below, instead of being negated and added.
952 auto UseSubtract = [](const SCEV *Op) {
953 return Op->isNonConstantNegative();
954 };
955 // Iterate in reverse so that constants are emitted last, and move the
956 // subtracted operands last, matching SCEVExpander's LoopCompare, so that
957 // they don't start the running result.
958 SmallVector<const SCEV *, 2> SCEVOps(reverse(AddE->operands()));
959 stable_sort(SCEVOps, [&](const SCEV *L, const SCEV *R) {
960 return !UseSubtract(L) && UseSubtract(R);
961 });
963 for (const SCEV *Op : SCEVOps) {
964 // The first operand starts the result, so it is never subtracted.
965 bool Negate = !Ops.empty() && UseSubtract(Op);
966 Ops.push_back(expand(Negate ? SE.getNegativeSCEV(Op) : Op));
967 }
968 VPValue *Result = Ops.front();
969 for (auto [Op, OpV] : drop_begin(zip_equal(SCEVOps, Ops))) {
970 if (UseSubtract(Op)) {
971 // Result + (-Op) == Result - Op, which saves the multiply for the
972 // negation. NSW only transfers if negating Op cannot overflow, see
973 // ScalarEvolution::getMinusSCEV.
974 bool HasNSW =
975 WrapFlags.HasNSW && !SE.getSignedRangeMin(Op).isMinSignedValue();
976 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
977 {/*HasNUW=*/false, HasNSW}, DL);
978 continue;
979 }
980 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
981 WrapFlags, DL);
982 }
983 return Result;
984 }
985 case scMulExpr: {
986 auto *MulE = cast<SCEVMulExpr>(S);
987 VPIRFlags::WrapFlagsTy WrapFlags(MulE->hasNoUnsignedWrap(),
988 MulE->hasNoSignedWrap());
990 for (const SCEV *Op : reverse(MulE->operands()))
991 Ops.push_back(expand(Op));
992 VPValue *Result = Ops.front();
993 for (VPValue *OpV : drop_begin(Ops)) {
994 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
995 WrapFlags, DL);
996 }
997 return Result;
998 }
999 case scUDivExpr: {
1000 auto *UDiv = cast<SCEVUDivExpr>(S);
1001 VPValue *LHS = expand(UDiv->getLHS());
1002 const SCEV *RHSExpr = UDiv->getRHS();
1003 VPValue *RHS = expand(RHSExpr);
1004 if (SafeUDivMode) {
1005 // Make sure the UDiv's divisor is guaranteed to not be zero/poison, to
1006 // avoid UB.
1007 Type *Ty = UDiv->getType();
1008 bool GuaranteedNotPoison =
1010 if (!GuaranteedNotPoison)
1011 RHS = Builder.createFreeze(RHS, DL);
1012 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
1013 RHS = Builder.createScalarIntrinsic(
1014 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
1015 DL);
1016 }
1017 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
1018 VPIRFlags::getDefaultFlags(Instruction::UDiv),
1019 DL);
1020 }
1021 case scTruncate:
1022 case scZeroExtend:
1023 case scSignExtend:
1024 case scPtrToAddr: {
1025 auto *Cast = cast<SCEVCastExpr>(S);
1026 VPValue *Op = expand(Cast->getOperand());
1027 Instruction::CastOps Opcode;
1028 switch (S->getSCEVType()) {
1029 case scTruncate:
1030 Opcode = Instruction::Trunc;
1031 break;
1032 case scZeroExtend:
1033 Opcode = Instruction::ZExt;
1034 break;
1035 case scSignExtend:
1036 Opcode = Instruction::SExt;
1037 break;
1038 case scPtrToAddr:
1039 Opcode = Instruction::PtrToAddr;
1040 break;
1041 default:
1042 llvm_unreachable("Unhandled cast SCEV");
1043 }
1044
1045 // For ptrtoaddr of an IR value, reuse an existing cast dominating the
1046 // entry if there is one. Otherwise leave it to SCEVExpander, which places
1047 // the cast right after the IR value's definition, so all users can share
1048 // it.
1049 if (Opcode == Instruction::PtrToAddr) {
1050 VPlan &Plan = Builder.getPlan();
1051 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1052 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
1054 IRV->getValue(), S->getType(), PH->getDataLayout(),
1055 [&](const CastInst *CI) {
1056 return SE.DT.dominates(CI->getParent(), PH);
1057 }))
1058 return Plan.getOrAddLiveIn(CI);
1060 }
1061 }
1062
1063 std::optional<VPIRFlags> Flags;
1064 if (Opcode == Instruction::ZExt)
1065 Flags =
1066 VPIRFlags::NonNegFlagsTy(SE.isKnownNonNegative(Cast->getOperand()));
1067
1068 return Builder.createScalarCast(Opcode, Op, S->getType(), DL, Flags);
1069 }
1070 case scUMaxExpr:
1071 case scSMaxExpr:
1072 case scUMinExpr:
1073 case scSMinExpr:
1074 case scSequentialUMinExpr: {
1075 auto *MinMax = cast<SCEVNAryExpr>(S);
1076 Intrinsic::ID IntrinsicID;
1077 switch (S->getSCEVType()) {
1078 case scUMaxExpr:
1079 IntrinsicID = Intrinsic::umax;
1080 break;
1081 case scSMaxExpr:
1082 IntrinsicID = Intrinsic::smax;
1083 break;
1084 case scUMinExpr:
1086 IntrinsicID = Intrinsic::umin;
1087 break;
1088 case scSMinExpr:
1089 IntrinsicID = Intrinsic::smin;
1090 break;
1091 default:
1092 llvm_unreachable("Unexpected min/max SCEV type");
1093 }
1094 // Chain operands in reverse order matching SCEVExpander's expansion of
1095 // min/max expressions. In SafeUDivMode freeze expansion results of operands
1096 // other than the first for sequential UMins, to avoid short-circuiting
1097 // divide-by-0/poison.
1098 bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
1099 Type *ResultTy = MinMax->getType();
1100 bool PrevSafeMode = SafeUDivMode;
1102 for (const SCEV *SCEVOp : reverse(MinMax->operands())) {
1103 bool MayShortCircuit =
1104 IsSequential && Ops.size() != MinMax->getNumOperands() - 1;
1105 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1106 VPValue *OpV = expand(SCEVOp);
1107 SafeUDivMode = PrevSafeMode;
1108 if (MayShortCircuit)
1109 OpV = Builder.createFreeze(OpV, DL);
1110 Ops.push_back(OpV);
1111 }
1112 VPValue *Result = Ops.front();
1113 for (VPValue *Op : drop_begin(Ops)) {
1114 if (!ResultTy->isPointerTy()) {
1115 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
1116 ResultTy, DL);
1117 continue;
1118 }
1119 // The min/max intrinsics don't support pointer operands, so expand
1120 // pointer-typed min/max as cmp + select, matching SCEVExpander.
1121 VPValue *Cmp = Builder.createICmp(
1122 MinMaxIntrinsic::getPredicate(IntrinsicID), Result, Op, DL);
1123 Result = Builder.createSelect(Cmp, Result, Op, DL);
1124 Function &F = *Builder.getPlan().getIRFunction();
1125 if (MDNode *MD =
1127 cast<VPInstruction>(Result)->setMetadata(LLVMContext::MD_prof, MD);
1128 }
1129 return Result;
1130 }
1131 case scAddRecExpr: {
1132 auto *AR = cast<SCEVAddRecExpr>(S);
1133 VPlan &Plan = Builder.getPlan();
1134 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1135 assert(SE.DT.dominates(AR->getLoop()->getHeader(), PH) &&
1136 "can only expand AddRecs for loops outside VPlan's scope");
1137
1138 Type *Ty = AR->getType();
1139 if (auto [LCSSAPhi, Diff] = SCEVExpander::findReusableLCSSAPhi(SE, AR, PH);
1140 LCSSAPhi) {
1141 VPValue *DiffV = expand(Diff);
1142 VPValue *BaseV = Plan.getOrAddLiveIn(LCSSAPhi);
1143 if (LCSSAPhi->getType()->isPointerTy()) {
1144 if (Ty->isPointerTy())
1145 return Builder.createPtrAdd(BaseV, DiffV, DL);
1146 BaseV = Builder.createScalarCast(Instruction::PtrToAddr, BaseV, Ty, DL);
1147 }
1148 return Builder.createAdd(BaseV, DiffV, DL);
1149 }
1150
1151 // Mirror SCEVExpander::visitAddRecExpr, but only expand the canonical IV
1152 // {0,+,1} and non-affine AddRecs to IR (which will be created outside the
1153 // scope of VPlan). The AddRec is then scaled and offset using
1154 // VPInstructions.
1155 const Loop *L = AR->getLoop();
1156 auto m_scev_CanonicalIV = // NOLINT
1158 if (!AR->isAffine() || match(AR, m_scev_CanonicalIV))
1160
1161 const SCEV *Step = AR->getStepRecurrence(SE);
1162 // {0,+,F} --> {0,+,1} * F
1163 if (AR->getStart()->isZero()) {
1164 const SCEV *CanIV =
1165 SE.getAddRecExpr(SE.getZero(Ty), SE.getOne(Ty), L, SCEV::FlagNone);
1166 return Builder.createOverflowingOp(
1167 Instruction::Mul, {expand(CanIV), expand(Step)},
1168 {SE.willNotOverflow(Instruction::Mul, /*Signed=*/false, CanIV, Step),
1169 SE.willNotOverflow(Instruction::Mul, /*Signed=*/true, CanIV, Step)},
1170 DL);
1171 }
1172
1173 // {X,+,F} --> X + {0,+,F}
1174 if (Ty->isPointerTy())
1175 return expandAsPtrAdd(AR);
1176 VPValue *Start = expand(AR->getStart());
1177 VPValue *Rest = expand(SE.getAddRecExpr(SE.getZero(Ty), Step, L,
1178 AR->getNoWrapFlags(SCEV::FlagNW)));
1179 return Builder.createAdd(Start, Rest, DL, "",
1180 {AR->hasNoUnsignedWrap(), false});
1181 }
1182 case scCouldNotCompute:
1183 llvm_unreachable("Attempt to expand a SCEVCouldNotCompute");
1184 }
1185 llvm_unreachable("Unknown SCEV kind!");
1186}
1187
1189 // Do remove conditional assume instructions as their conditions may be
1190 // flattened.
1191 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1192 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1194 if (IsConditionalAssume)
1195 return true;
1196
1197 if (R.mayHaveSideEffects())
1198 return false;
1199
1200 // Forbid removing trip-count expressions.
1201 if (isa<VPExpandSCEVRecipe>(R) &&
1202 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1203 return false;
1204
1205 // Recipe is dead if no user keeps the recipe alive.
1206 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1207}
1208
1210 SmallVector<VPValue *> WorkList;
1212 WorkList.push_back(V);
1213
1214 while (!WorkList.empty()) {
1215 VPValue *Cur = WorkList.pop_back_val();
1216 if (!Seen.insert(Cur).second)
1217 continue;
1218 VPRecipeBase *R = Cur->getDefiningRecipe();
1219 if (!R)
1220 continue;
1221 if (!isDeadRecipe(*R))
1222 continue;
1223 append_range(WorkList, R->operands());
1224 R->eraseFromParent();
1225 }
1226}
1227
1230 for (unsigned I = 0; I != Users.size(); ++I) {
1232 for (VPValue *V : Cur->definedValues())
1233 Users.insert_range(V->users());
1234 }
1235 return Users.takeVector();
1236}
1237
1238/// Returns \p Num / \p Denom as a BranchProbability, clamped so a ratio that is
1239/// neither zero nor one does not round to zero or one. BlockFrequencyInfo also
1240/// keeps a zero-weight edge distinguishable from an unreachable one.
1242 uint64_t Denom) {
1244 if (Num == 0 || Num == Denom)
1245 return P;
1246 return BranchProbability::getRaw(std::clamp(
1247 P.getNumerator(), 1u, BranchProbability::getDenominator() - 1));
1248}
1249
1255
1256/// Returns the probability of each successor edge of \p VPBB, computed via
1257/// BranchProbabilityInfo::getEdgeProbabilitiesFromWeights from the branch
1258/// weights recorded on its terminator, or std::nullopt if not available.
1259static std::optional<SmallVector<BranchProbability>>
1261 // With a single successor the edge is always taken and needs no weights.
1262 if (VPBB->getSingleSuccessor())
1264
1265 SmallVector<uint32_t> Weights;
1267 if (!Term || !extractBranchWeights(Term->getBranchWeights(), Weights) ||
1268 Weights.size() != VPBB->getNumSuccessors())
1269 return std::nullopt;
1271}
1272
1275 using BFIBase = BlockFrequencyInfoImplBase;
1276 assert(!Blocks.empty() && "expected at least the header block");
1277 // Distribute the header's frequency using BFI. Nodes for blocks are numbered
1278 // in reverse post-order. Edges leaving Blocks, i.e. a plain CFG's edges to
1279 // the middle block or to an exit block, exit to a node outside the loop.
1280 BFIBase BFI;
1281 BFIBase::BlockNode Header(0), Outside(Blocks.size());
1282 BFIBase::LoopData &Loop = BFI.Loops.emplace_back(nullptr, Header);
1284 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1285 Nodes[VPBB] = BFIBase::BlockNode(Idx);
1286 BFI.Working.emplace_back(BFIBase::BlockNode(Idx)).Loop = &Loop;
1287 }
1288 BFI.Working.emplace_back(Outside);
1289 BFI.Working[Header.Index].getMass() = BFIBase::BlockMass::getFull();
1290
1291 // Keep track nodes reached via an edge without branch weighs or with
1292 // estimated ones
1293 SmallVector<bool> IsUnknown(Blocks.size()), IsEstimated(Blocks.size());
1294 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1295 BFIBase::BlockNode Node(Idx);
1296 auto Probs = getSuccessorProbabilities(VPBB);
1297 auto *Term = dyn_cast_if_present<VPInstruction>(VPBB->getTerminator());
1298 bool TermIsEstimated = Term && Term->hasEstimatedBranchWeights();
1299 BFIBase::Distribution Dist;
1300 for (auto [SuccIdx, Succ] : enumerate(VPBB->getSuccessors())) {
1301 BFIBase::BlockNode SuccNode = Nodes.lookup_or(Succ, Outside);
1302 if (SuccNode != Header && SuccNode != Outside) {
1303 IsUnknown[SuccNode.Index] |= IsUnknown[Idx] || !Probs;
1304 IsEstimated[SuccNode.Index] |= IsEstimated[Idx] || TermIsEstimated;
1305 }
1306 if (Probs)
1307 BFI.addToDist(Dist, &Loop, Node, SuccNode,
1308 getWeightFromBranchProb((*Probs)[SuccIdx]));
1309 }
1310 if (Probs)
1311 BFI.distributeMass(Node, &Loop, Dist);
1312 }
1313
1314 // Round frequencies up to at least 1, so all edges are reached with a
1315 // non-zero frequency, to distinguish rarely executed blocks from unreachable
1316 // ones. blocks distinguishable from unreachable ones.
1318 Frequencies;
1319 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1320 std::optional<VPExecutionFrequency> &Freq = Frequencies[VPBB];
1321 if (IsUnknown[Idx])
1322 continue;
1323 uint64_t Mass = BFI.Working[Idx].getMass().getMass();
1324 Freq.emplace(BlockFrequency(std::max<uint64_t>(Mass, 1)), IsEstimated[Idx]);
1325 }
1326 return Frequencies;
1327}
1328
1331 const DataLayout &DL) {
1332 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1333 if (!OpcodeOrIID)
1334 return nullptr;
1335
1337 for (VPValue *Op : Operands) {
1338 VPValue *Candidate = Op;
1339 match(Op, m_Broadcast(m_VPValue(Candidate)));
1340 if (!match(Candidate, m_LiveIn()))
1341 return nullptr;
1342 Value *V = Candidate->getUnderlyingValue();
1343 if (!V)
1344 return nullptr;
1345 Ops.push_back(V);
1346 }
1347
1348 VPlan &Plan = *R.getParent()->getPlan();
1349 auto FoldToIRValue = [&]() -> Value * {
1350 InstSimplifyFolder Folder(DL);
1351 if (OpcodeOrIID->first) {
1352 // VPInstructions store the called intrinsic as last operand.
1353 if (isa<VPInstruction>(R))
1354 Ops.pop_back();
1355
1356 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1357 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1358 RFlags ? RFlags->getFastMathFlagsOrNone()
1359 : FastMathFlags());
1360 }
1361 unsigned Opcode = OpcodeOrIID->second;
1362 if (Instruction::isBinaryOp(Opcode))
1363 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1364 Ops[0], Ops[1]);
1365 if (Instruction::isCast(Opcode))
1366 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1367 R.getVPSingleValue()->getScalarType());
1368 switch (Opcode) {
1369 case VPInstruction::Not:
1370 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1372 case Instruction::Select:
1373 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1374 case Instruction::ICmp:
1375 case Instruction::FCmp:
1376 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1377 Ops[1]);
1378 case Instruction::GetElementPtr: {
1379 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1380 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1381 return Folder.FoldGEP(DL, GEP->getSourceElementType(), Ops[0],
1382 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1383 }
1386 return Folder.FoldGEP(DL, IntegerType::getInt8Ty(Plan.getContext()),
1387 Ops[0], Ops[1],
1388 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1389 // An extract of a live-in is an extract of a broadcast, so return the
1390 // broadcasted element.
1391 case Instruction::ExtractElement:
1392 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1393 return Ops[0];
1396 uint64_t Multiplier = 1;
1397 if (Opcode == VPInstruction::WideActiveLaneMask) {
1398 // Optimizing WideALM can only happen after the Plan is unrolled.
1399 if (!Plan.isUnrolled())
1400 return nullptr;
1401 Multiplier = cast<ConstantInt>(Ops[2])->getZExtValue();
1402 Ops.pop_back();
1403 }
1404
1405 // We rely on the fact that different VPlans are created for the
1406 // fixed-vector and scalable-vector cases.
1407 ElementCount MaxVF =
1409 Multiplier;
1410
1411 Type *I1Ty = IntegerType::getInt1Ty(Plan.getContext());
1412 if (auto *C = dyn_cast_if_present<Constant>(Folder.FoldIntrinsic(
1413 Intrinsic::get_active_lane_mask, Ops,
1414 VectorType::get(I1Ty, MaxVF), {}, Plan.getIRFunction()))) {
1415 // We cannot handle vector constants that are not all-true or all-false,
1416 // because they would not be collapsable to a scalar constant, that
1417 // would be necessary for live-in simplification.
1418 if (C->isOneValue())
1419 return ConstantInt::getTrue(I1Ty);
1420 if (C->isNullValue())
1421 return ConstantInt::getFalse(I1Ty);
1422 }
1423 }
1424 }
1425 return nullptr;
1426 };
1427
1428 if (Value *V = FoldToIRValue())
1429 return Plan.getOrAddLiveIn(V);
1430 return nullptr;
1431}
1432
1434 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1437 vp_depth_first_deep(Plan.getEntry()))) {
1438 for (VPSingleDefRecipe &Def :
1440 if (!isElementwise(&Def))
1441 continue;
1442
1443 // At least one of the ops must be a permutation.
1444 if (none_of(Def.operands(), MatchPerm))
1445 continue;
1446
1447 // All operands must be a single-use permutation or a live in (splat).
1448 if (!all_of(Def.operands(), [&MatchPerm](VPValue *Op) {
1449 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1450 }))
1451 continue;
1452
1453 // Remove the inner permutations.
1454 for (unsigned I = 0, E = Def.getNumOperands(); I != E; ++I)
1455 if (VPValue *X = MatchPerm(Def.getOperand(I)))
1456 Def.setOperand(I, X);
1457
1458 VPSingleDefRecipe *Res = BuildPerm(&Def);
1459 Res->insertAfter(&Def);
1460 Def.replaceUsesWithIf(Res, not_equal_to(Res));
1461 }
1462 }
1463}
1464
1465// Implements the algorithm described in "Simple and Efficient Construction of
1466// Static Single Assignment Form" by Braun et al.
1469 assert(!Defs.empty() && "Defs shouldn't be empty");
1470 assert(
1472 "VPBB isn't reachable from entry");
1473 if (VPValue *Def = Defs.lookup(VPBB))
1474 return Def;
1475 // If the entry block is reached and there's still no def, then Defs is
1476 // missing a definition that covers this path.
1477 assert(VPBB->getNumPredecessors() && "Not all paths have def");
1478
1479 if (VPBlockBase *Pred = VPBB->getSinglePredecessor())
1480 return reconstructSSA(cast<VPBasicBlock>(Pred), Defs);
1481
1482 // Multiple predecessors, create a join.
1483 Type *Ty = Defs.begin()->second->getScalarType();
1484 VPPhi *Phi = VPBuilder(VPBB, VPBB->getFirstNonPhi())
1485 .createScalarPhi({}, DebugLoc::getUnknown(), "", {}, Ty);
1486 Defs[VPBB] = Phi;
1487 for (auto *Pred : VPBB->predecessors())
1488 Phi->addIncoming(reconstructSSA(cast<VPBasicBlock>(Pred), Defs));
1489
1490 // Fold away trivial phis.
1491 // TODO: Remove phi users which have become trivial too.
1492 if (all_equal(Phi->incoming_values())) {
1493 VPValue *Common = Phi->getIncomingValue(0);
1494 Phi->replaceAllUsesWith(Common);
1495 for (auto &[_, V] : Defs)
1496 if (V == Phi)
1497 V = Common;
1498 Defs[VPBB] = Common;
1499 Phi->eraseFromParent();
1500 return Common;
1501 }
1502
1503 return Phi;
1504}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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 F(x, y, z)
Definition MD5.cpp:54
#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 std::optional< SmallVector< BranchProbability > > getSuccessorProbabilities(const VPBasicBlock *VPBB)
Returns the probability of each successor edge of VPBB, computed via BranchProbabilityInfo::getEdgePr...
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
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.
Base class for BlockFrequencyInfoImpl.
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
static LLVM_ABI SmallVector< BranchProbability > getEdgeProbabilitiesFromWeights(ArrayRef< uint32_t > Weights)
Returns the probabilities of edges with branch weights Weights.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
static constexpr BranchProbability getOne()
static uint32_t getDenominator()
static constexpr BranchProbability getRaw(uint32_t N)
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isMinValue(bool IsSigned) const
This function will return true iff this constant represents the smallest value that may be represente...
Definition Constants.h:250
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
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
bool empty() const
Definition DenseMap.h:716
ValueT lookup_or(const_arg_type_t< KeyT > Val, U &&Default) const
Definition DenseMap.h:803
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:793
iterator begin()
Definition DenseMap.h:682
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_FpInduction
Floating point induction variable.
@ 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
bool contains(const LoopT *L) const
Return true if the specified loop is contained within this loop.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
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.
static ICmpInst::Predicate getPredicate(Intrinsic::ID ID)
Returns the comparison predicate underlying the intrinsic.
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 ...
static LLVM_ABI std::pair< PHINode *, const SCEV * > findReusableLCSSAPhi(ScalarEvolution &SE, SCEVUseT< const SCEVAddRecExpr * > S, const BasicBlock *InsertBB)
Find a phi in the exit block of S's loop, which must dominate InsertBB, such that S can be expanded i...
This node is a base class providing common functionality for n'ary operators.
This class represents an analyzed expression in the program.
static constexpr auto FlagNSW
Type * getType() const
Return the LLVM type of this SCEV expression.
static constexpr auto FlagNone
SCEVTypes getSCEVType() const
static constexpr auto FlagNW
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 const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEVFlags Flags=SCEV::FlagNone, unsigned Depth=0)
Return LHS-RHS.
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.
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 SCEVUse getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEVFlagsPair Flags)
Get an add recurrence expression for the specified loop.
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 SCEVUse getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
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()
LLVM_ABI SCEVUse getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEVFlagsPair Flags={}, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
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 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.
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.
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 TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
Definition Type.cpp:187
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Definition Type.cpp:296
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:4464
iterator end()
Definition VPlan.h:4501
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:228
VPRecipeBase * getTerminator()
If the block has multiple successors, return the branch recipe terminating the block.
Definition VPlan.cpp:607
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4530
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:99
VPRegionBlock * getParent()
Definition VPlan.h:197
iterator_range< VPBlockBase ** > predecessors()
Definition VPlan.h:230
size_t getNumSuccessors() const
Definition VPlan.h:247
size_t getNumPredecessors() const
Definition VPlan.h:248
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:232
VPlan * getPlan()
Definition VPlan.h:201
VPBlockBase * getSinglePredecessor() const
Definition VPlan.h:243
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:183
VPBlockBase * getSingleHierarchicalPredecessor()
Definition VPlan.h:273
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:237
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:221
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:418
static std::pair< VPBasicBlock *, VPBasicBlock * > getPlainCFGHeaderAndLatch(const VPlan &Plan)
Returns the header and latch of the outermost loop of Plan in plain CFG form (before regions are form...
static SmallVector< VPBasicBlock * > blocksInSingleSuccessorChainBetween(VPBasicBlock *FirstBB, VPBasicBlock *LastBB)
Returns the blocks between FirstBB and LastBB, where FirstBB to LastBB forms a single-sucessor chain.
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:572
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4245
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:4077
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2537
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition VPlan.h:2526
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4617
Class to record and manage LLVM IR flags.
Definition VPlan.h:690
static LLVM_ABI_FOR_TEST 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:1315
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1416
unsigned getOpcode() const
Definition VPlan.h:1506
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:405
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:555
void insertAfter(VPRecipeBase *InsertPos)
Insert an unlinked Recipe into a basic block immediately after the specified Recipe.
A recipe for handling reduction phis.
Definition VPlan.h:2897
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4689
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4765
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4853
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4809
VPValues are defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:247
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3447
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:4306
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:613
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:212
bool isMaterialized() const
Returns true if this value has been materialized.
Definition VPlanValue.h:230
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:396
operand_range operands()
Definition VPlanValue.h:472
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:437
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:142
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:123
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:1906
A recipe for handling GEP instructions.
Definition VPlan.h:2264
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition VPlan.h:2621
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2650
A recipe for widened phis.
Definition VPlan.h:2784
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1839
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4876
LLVMContext & getContext() const
Definition VPlan.h:5086
VPBasicBlock * getEntry()
Definition VPlan.h:4972
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
Definition VPlan.h:5119
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5084
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5038
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:5162
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5188
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
Definition VPlan.h:5153
Function * getIRFunction() const
Definition VPlan.h:5094
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1030
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5140
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4977
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:5081
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:5028
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5077
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
static constexpr bool isKnownLT(const FixedOrScalableQuantity &LHS, const FixedOrScalableQuantity &RHS)
Definition TypeSize.h:217
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.
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.
cst_pred_ty< is_one > m_scev_One()
Match an integer 1.
specificloop_ty m_SpecificLoop(const Loop *L)
cst_pred_ty< is_zero > m_scev_Zero()
Match an integer 0.
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 the full mass.
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.
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...
VPScalarIVStepsRecipe * createScalarIVSteps(VPlan &Plan, InductionDescriptor::InductionKind Kind, Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, Type *ResultTy, 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...
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.
VPIRFlags getFlagsForInduction(const InductionDescriptor &ID, const VPPhi *PhiR)
Extracts and returns NoWrap flags from PhiR and fast-math flags from ID.
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.
LLVM_ABI_FOR_TEST 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...
LLVM_ABI_FOR_TEST const SCEV * getSCEVExprForVPValue(const VPValue *V, PredicatedScalarEvolution &PSE, const Loop *L=nullptr)
Return the SCEV expression for V.
unsigned getVFScaleFactor(VPRecipeBase *R)
Get the VF scaling factor applied to the recipe's output, if the recipe has one.
SmallVector< VPUser * > collectUsersRecursively(VPValue *V)
Collect all users of V, looking through recipes that define other values.
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
constexpr auto not_equal_to(T &&Arg)
Functor variant of std::not_equal_to that can be used as a UnaryPredicate in functional algorithms li...
Definition STLExtras.h:2196
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
uint32_t getWeightFromBranchProb(const BranchProbability Prob)
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
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
VPBuilderBase<> VPBuilder
Definition VPlan.h:69
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
LLVM_ABI MDNode * getExplicitlyUnknownBranchWeightsIfProfiled(Function &F, StringRef PassName)
Returns a metadata node containing unknown branch weights if the function has an entry count,...
DWARFExpression::Operation Op
auto max_element(R &&Range)
Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2104
ArrayRef(const T &OneElt) -> ArrayRef< T >
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
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:274
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
Definition VPlan.h:3917
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3864