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"
24#include "llvm/IR/Dominators.h"
27
28using namespace llvm;
29using namespace llvm::VPlanPatternMatch;
30using namespace llvm::SCEVPatternMatch;
31
33 return all_of(Def->users(),
34 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
35}
36
38 return all_of(Def->users(),
39 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
40}
41
43 return all_of(Def->users(),
44 [Def](const VPUser *U) { return U->usesScalars(Def); });
45}
46
48 if (auto *E = dyn_cast<SCEVConstant>(Expr))
49 return Plan.getOrAddLiveIn(E->getValue());
50 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
51 // value. Otherwise the value may be defined in a loop and using it directly
52 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
53 // form.
54 auto *U = dyn_cast<SCEVUnknown>(Expr);
55 if (U && !isa<Instruction>(U->getValue()))
56 return Plan.getOrAddLiveIn(U->getValue());
57 auto *Expanded = new VPExpandSCEVRecipe(Expr);
58 VPBasicBlock *EntryVPBB = Plan.getEntry();
59 auto Iter = EntryVPBB->getFirstNonPhi();
60 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
61 ++Iter;
62 EntryVPBB->insert(Expanded, Iter);
63 return Expanded;
64}
65
66/// Returns true if \p V being poison is guaranteed to trigger UB because it
67/// propagates to the address of a memory recipe.
68static bool poisonGuaranteesUB(const VPValue *V) {
71
72 auto PropagatesPoisonFromRecipeOp = [](const VPRecipeBase *R) {
74 return false;
75 unsigned Opcode = vputils::getOpcode(R->getVPSingleValue());
76 return Instruction::isCast(Opcode) || Opcode == Instruction::GetElementPtr;
77 };
78
79 Worklist.push_back(V);
80
81 while (!Worklist.empty()) {
82 const VPValue *Current = Worklist.pop_back_val();
83 if (!Visited.insert(Current).second)
84 continue;
85
86 for (VPUser *U : Current->users()) {
87 // Check if Current is used as an address operand for load/store.
88 auto *R = cast<VPRecipeBase>(U);
89 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(R)) {
90 if (MemR->getAddr() == Current)
91 return true;
92 continue;
93 }
94 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
95 unsigned Opcode = Rep->getOpcode();
96 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
97 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
98 return true;
99 }
100
101 // Check if poison propagates through this recipe to any of its users.
102 for (const VPValue *Op : R->operands()) {
103 if (Op == Current && PropagatesPoisonFromRecipeOp(R)) {
104 Worklist.push_back(R->getVPSingleValue());
105 break;
106 }
107 }
108 }
109 }
110
111 return false;
112}
113
115 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
116 // casts to find a root GEP VPInstruction.
117 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
118 unsigned Opcode = PtrVPI->getOpcode();
119 if (Opcode == Instruction::GetElementPtr) {
120 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
121 return PtrVPI->getGEPNoWrapFlags();
122 Ptr = PtrVPI->getOperand(0);
123 continue;
124 }
125 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
126 break;
127 Ptr = PtrVPI->getOperand(0);
128 }
129 return GEPNoWrapFlags::none();
130}
131
134 const Loop *L) {
135 ScalarEvolution &SE = *PSE.getSE();
136 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
137 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
138 "RegionValue must be canonical IV");
139 if (!L)
140 return SE.getCouldNotCompute();
141 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
143 }
144
146 Value *LiveIn = V->getUnderlyingValue();
147 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
148 return SE.getSCEV(LiveIn);
149 return SE.getCouldNotCompute();
150 }
151
152 // Helper to create SCEVs for binary and unary operations.
153 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
154 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
155 -> const SCEV * {
157 for (VPValue *Op : Ops) {
158 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
160 return SE.getCouldNotCompute();
161 SCEVOps.push_back(S);
162 }
163 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
164 };
165
166 VPValue *LHSVal, *RHSVal;
167 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
168 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
169 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
170 });
171 if (match(V, m_BinaryOr(m_VPValue(LHSVal), m_VPValue(RHSVal))))
172 if (cast<VPRecipeWithIRFlags>(V->getDefiningRecipe())->isDisjoint())
173 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
174 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
175 });
176 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
177 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
178 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
179 });
180 if (match(V, m_Not(m_VPValue(LHSVal)))) {
181 // not X = xor X, -1 = -1 - X
182 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
183 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
184 });
185 }
186 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
187 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
188 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
189 });
190 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
191 // amount >= the bit width produces poison; do not rewrite it, as
192 // getPowerOfTwo requires the power to be in range.
193 uint64_t ShiftAmt;
194 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
195 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
196 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
197 return SE.getMulExpr(Ops[0],
198 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
199 });
200 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
201 Type *Ty = V->getScalarType();
202 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
203 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
204 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
205 });
206 }
207 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
208 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
209 return SE.getUDivExpr(Ops[0], Ops[1]);
210 });
211 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
212 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
213 return SE.getURemExpr(Ops[0], Ops[1]);
214 });
215 // A SDiv with non-negative operands is equivalent to an UDiv.
216 if (match(V, m_SDiv(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
217 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
218 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
219 return SE.getCouldNotCompute();
220 return SE.getUDivExpr(Ops[0], Ops[1]);
221 });
222 }
223 // A SRem with non-negative operands is equivalent to an URem.
224 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
225 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
226 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
227 return SE.getCouldNotCompute();
228 return SE.getURemExpr(Ops[0], Ops[1]);
229 });
230 }
231 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
232 const APInt *Mask;
233 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
234 (*Mask + 1).isPowerOf2())
235 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
236 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
237 });
238 // SCEV models ptrtoaddr, but not ptrtoint, mirroring createSCEV.
239 if (match(V, m_PtrToAddr(m_VPValue(LHSVal))))
240 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
241 return SE.getPtrToAddrExpr(Ops[0]);
242 });
243 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
244 Type *DestTy = V->getScalarType();
245 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
246 return SE.getTruncateExpr(Ops[0], DestTy);
247 });
248 }
249 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
250 Type *DestTy = V->getScalarType();
251 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
252 return SE.getZeroExtendExpr(Ops[0], DestTy);
253 });
254 }
255 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
256 Type *DestTy = V->getScalarType();
257
258 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
259 // onto the operands before computing the subtraction.
260 VPValue *SubLHS, *SubRHS;
261 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
262 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
263 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
264 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
265 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
267 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
268 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
269 }
270
271 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
272 return SE.getSignExtendExpr(Ops[0], DestTy);
273 });
274 }
275 if (match(V,
277 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
278 return SE.getUMaxExpr(Ops[0], Ops[1]);
279 });
280 if (match(V,
282 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
283 return SE.getSMaxExpr(Ops[0], Ops[1]);
284 });
285 if (match(V,
287 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
288 return SE.getUMinExpr(Ops[0], Ops[1]);
289 });
290 if (match(V,
292 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
293 return SE.getSMinExpr(Ops[0], Ops[1]);
294 });
296 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
297 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
298 // not proof that the input is never INT_MIN, nor that poison reaches
299 // UB. Do not translate it to SCEV's global IsNSW flag.
300 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
301 });
302
304 Type *SourceElementType;
305 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
306 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
307 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
308 });
309 }
310
311 // TODO: Support constructing SCEVs for more recipes as needed.
312 const VPRecipeBase *DefR = V->getDefiningRecipe();
313 const SCEV *Expr =
315 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
316 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
317 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
318 if (!L || isa<SCEVCouldNotCompute>(Step))
319 return SE.getCouldNotCompute();
320 const SCEV *Start =
321 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
322 const SCEV *AddRec =
323 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
324 if (R->getTruncInst())
325 return SE.getTruncateExpr(AddRec, R->getScalarType());
326 return AddRec;
327 })
328 .Case([&SE, &PSE,
329 L](const VPWidenPointerInductionRecipe *R) -> const SCEV * {
330 const SCEV *Start =
331 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
332 if (!L || isa<SCEVCouldNotCompute>(Start))
333 return SE.getCouldNotCompute();
334 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
335 if (isa<SCEVCouldNotCompute>(Step))
336 return SE.getCouldNotCompute();
337 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
338 })
339 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) -> const SCEV * {
340 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
341 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
342 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
343 if (any_of(ArrayRef({Start, IV, Scale}),
345 return SE.getCouldNotCompute();
346
347 return SE.getAddExpr(
348 SE.getTruncateOrSignExtend(Start, IV->getType()),
349 SE.getMulExpr(
350 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
351 })
352 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
353 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
354 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
356 return SE.getCouldNotCompute();
357 return SE.getTruncateOrSignExtend(IV, Step->getType());
358 })
359 .Default(
360 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
361
362 return PSE.getPredicatedSCEV(Expr);
363}
364
366 const Loop *L) {
367 // If address is an SCEVAddExpr, we require that all operands must be either
368 // be invariant or a (possibly sign-extend) affine AddRec.
369 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
370 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
371 return SE.isLoopInvariant(Op, L) ||
372 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
373 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
374 });
375 }
376
377 // Otherwise, check if address is loop invariant or an affine add recurrence.
378 return SE.isLoopInvariant(Addr, L) ||
380}
381
382unsigned vputils::getOpcode(const VPValue *V) {
386 VPWidenLoadEVLRecipe>([](auto *I) { return I->getOpcode(); })
387 .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
388 [](auto *I) {
389 // For recipes that do not directly map to LLVM IR instructions,
390 // assign opcodes after the last VPInstruction opcode (which is also
391 // after the last IR Instruction opcode), based on the VPRecipeID.
392 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
393 })
394 .Default([](auto *) { return 0; });
395}
396
397std::optional<std::pair<bool, unsigned>>
400 return std::make_pair(true, IID);
401 if (unsigned Opcode = vputils::getOpcode(V))
402 return std::make_pair(false, Opcode);
403 return {};
404}
405
406/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
407/// uniform, the result will also be uniform.
408static bool preservesUniformity(unsigned Opcode) {
409 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
410 return true;
411 switch (Opcode) {
412 case Instruction::Freeze:
413 case Instruction::GetElementPtr:
414 case Instruction::ICmp:
415 case Instruction::FCmp:
416 case Instruction::Select:
421 return true;
422 default:
423 return false;
424 }
425}
426
428 // TODO: Handle more opcodes and recipes.
430 return false;
431 unsigned Opcode = getOpcode(V);
432 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
433}
434
436 // Live-in, symbolic and canonical-IV region values are single-scalar.
437 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
438 return RV == RV->getDefiningRegion()->getCanonicalIV();
440 return true;
441
442 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
443 const VPRegionBlock *RegionOfR = Rep->getRegion();
444 // Don't consider recipes in replicate regions as uniform yet; their first
445 // lane cannot be accessed when executing the replicate region for other
446 // lanes.
447 if (RegionOfR && RegionOfR->isReplicator())
448 return false;
449 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
450 all_of(Rep->operands(), isSingleScalar));
451 }
454 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
455 return preservesUniformity(WidenR->getOpcode()) &&
456 all_of(WidenR->operands(), isSingleScalar);
457 }
458 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
459 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
460 (preservesUniformity(VPI->getOpcode()) &&
461 all_of(VPI->operands(), isSingleScalar));
462 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
463 return !RR->isPartialReduction();
465 VPV))
466 return true;
467 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
468 return Expr->isVectorToScalar();
469
470 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
471 return isa<VPExpandSCEVRecipe>(VPV);
472}
473
475 // Live-ins, symbolic and canonical-IV region values are uniform.
476 if (auto *RV = dyn_cast<VPRegionValue>(V))
477 return RV == RV->getDefiningRegion()->getCanonicalIV();
479 return true;
480
481 const VPRecipeBase *R = V->getDefiningRecipe();
482 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
483 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
484 if (VPBB &&
485 (VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
486 if (match(R,
489 return false;
490 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
491 }
492
494 .Case([](const VPDerivedIVRecipe *R) { return true; })
495 .Case([](const VPReplicateRecipe *R) {
496 // Be conservative about side-effects, except for the
497 // known-side-effecting assumes and stores, which we know will be
498 // uniform.
499 return R->isSingleScalar() &&
500 (!R->mayHaveSideEffects() ||
501 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
502 all_of(R->operands(), isUniformAcrossVFsAndUFs);
503 })
504 .Case([](const VPWidenRecipe *R) {
505 return preservesUniformity(R->getOpcode()) &&
506 all_of(R->operands(), isUniformAcrossVFsAndUFs);
507 })
508 .Case([](const VPPhi *) {
509 // Bail out on VPPhi, as we can end up in infinite cycles.
510 return false;
511 })
512 .Case([](const VPInstruction *VPI) {
513 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
516 })
517 .Case([](const VPWidenCastRecipe *R) {
518 // A cast is uniform according to its operand.
519 return isUniformAcrossVFsAndUFs(R->getOperand(0));
520 })
521 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
522 // unless proven otherwise.
523 return false;
524 });
525}
526
528 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
529 return RepR->doesGeneratePerAllLanes();
530 if (auto *VPI = dyn_cast<VPInstruction>(R))
531 return VPI->doesGeneratePerAllLanes();
532 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
533 return SIVSteps->doesGeneratePerAllLanes();
534 return false;
535}
536
538 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
539 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
540 return VPBlockUtils::isHeader(VPB, VPDT);
541 });
542 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
543}
544
546 if (!R)
547 return 1;
548 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
549 return RR->getVFScaleFactor();
550 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
551 return RR->getVFScaleFactor();
552 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
553 return ER->getVFScaleFactor();
554 assert(
557 "getting scaling factor of reduction-start-vector not implemented yet");
558 return 1;
559}
560
561bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
562 // Assumes don't alias anything or throw; as long as they're guaranteed to
563 // execute, they're safe to hoist. They should however not be sunk, as it
564 // would destroy information.
566 return Sinking;
567 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
568 return true;
569 // Allocas cannot be hoisted.
570 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
571 return RepR && RepR->getOpcode() == Instruction::Alloca;
572}
573
576 VPBasicBlock *LastBB) {
577 assert(FirstBB->getParent() == LastBB->getParent() &&
578 "FirstBB and LastBB from different regions");
579#ifndef NDEBUG
580 bool InSingleSuccChain = false;
581 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
582 InSingleSuccChain |= (Succ == LastBB);
583 assert(InSingleSuccChain &&
584 "LastBB unreachable from FirstBB in single-successor chain");
585#endif
586 auto Blocks = to_vector(
588 auto *LastIt = find(Blocks, LastBB);
589 assert(LastIt != Blocks.end() &&
590 "LastBB unreachable from FirstBB in depth-first traversal");
591 Blocks.erase(std::next(LastIt), Blocks.end());
592 return Blocks;
593}
594
596 for (VPRecipeBase &R : *Plan.getVectorPreheader())
598 return cast<VPInstruction>(&R);
599 return nullptr;
600}
601
603vputils::getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB) {
605 for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks())
606 for (VPBlockBase *Pred : ExitVPBB->getPredecessors())
607 if (Pred != MiddleVPBB)
608 Exits.emplace_back(cast<VPBasicBlock>(Pred), ExitVPBB);
609 return Exits;
610}
611
614 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
615 Instruction *TruncI, VPValue *StartV, VPValue *Step, DebugLoc DL,
616 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
617 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
618 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
619 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
620 VPSingleDefRecipe *BaseIV =
621 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
622
623 // Truncate base induction if needed.
624 Type *ResultTy = BaseIV->getScalarType();
625 if (TruncI) {
626 Type *TruncTy = TruncI->getType();
627 assert(ResultTy->getScalarSizeInBits() > TruncTy->getScalarSizeInBits() &&
628 "Not truncating.");
629 assert(ResultTy->isIntegerTy() && "Truncation requires an integer type");
630 BaseIV = Builder.createScalarCast(Instruction::Trunc, BaseIV, TruncTy, DL);
631 ResultTy = TruncTy;
632 }
633
634 // Truncate step if needed.
635 Type *StepTy = Step->getScalarType();
636 if (ResultTy != StepTy) {
637 assert(StepTy->getScalarSizeInBits() > ResultTy->getScalarSizeInBits() &&
638 "Not truncating.");
639 assert(StepTy->isIntegerTy() && "Truncation requires an integer type");
640 auto *VecPreheader =
642 VPBuilder::InsertPointGuard Guard(Builder);
643 Builder.setInsertPoint(VecPreheader);
644 Step = Builder.createScalarCast(Instruction::Trunc, Step, ResultTy, DL);
645 }
646 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
647 &Plan.getVF(), DL);
648}
649
650VPValue *
652 VPlan &Plan, VPBuilder &Builder) {
653 const InductionDescriptor &ID = PtrIV->getInductionDescriptor();
654 VPIRValue *StartV = Plan.getZero(ID.getStep()->getType());
655 VPValue *StepV = PtrIV->getOperand(1);
657 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
658 nullptr, StartV, StepV, PtrIV->getDebugLoc(), Builder);
659
660 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
661 PtrIV->getDebugLoc(), "next.gep");
662}
663
665 const VPDominatorTree &VPDT) {
666 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
667 if (!VPBB)
668 return false;
669
670 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
671 // VPBB as its entry, i.e., free of predecessors.
672 if (auto *R = VPBB->getParent())
673 return !R->isReplicator() && !VPBB->hasPredecessors();
674
675 // A header dominates its second predecessor (the latch), with the other
676 // predecessor being the preheader
677 return VPB->getPredecessors().size() == 2 &&
678 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
679}
680
682 const VPDominatorTree &VPDT) {
683 // A latch has a header as its last successor, with its other successors
684 // leaving the loop. A preheader OTOH has a header as its first (and only)
685 // successor.
686 return VPB->getNumSuccessors() >= 2 &&
688}
689
690std::pair<VPBasicBlock *, VPBasicBlock *>
693 Plan.getEntry()->getNumSuccessors() == 1
694 ? Plan.getEntry()->getSingleSuccessor()
695 : Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
696 assert(Header->getNumPredecessors() == 2 &&
697 "Header must have exactly 2 predecessors");
698 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
699 return {Header, Latch};
700}
701
705
706std::optional<MemoryLocation>
708 auto *M = dyn_cast<VPIRMetadata>(&R);
709 if (!M)
710 return std::nullopt;
712 // Populate noalias metadata from VPIRMetadata.
713 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
714 Loc.AATags.NoAlias = NoAliasMD;
715 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
716 Loc.AATags.Scope = AliasScopeMD;
717 return Loc;
718}
719
721 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
722 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
723 assert(CanIV && "Expected loop region to have a canonical IV");
724
725 VPSymbolicValue &VFxUF = Plan.getVFxUF();
726
727 // Check if \p Step matches the expected increment step, accounting for
728 // materialization of VFxUF and UF.
729 auto IsIncrementStep = [&](VPValue *Step) -> bool {
730 if (!VFxUF.isMaterialized())
731 return Step == &VFxUF;
732
733 VPSymbolicValue &UF = Plan.getUF();
734 if (!UF.isMaterialized())
735 return Step == &UF ||
736 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
737
738 // Alias masking: step is number of active lanes of a dependence mask.
739 if (match(Step, m_ZExtOrTruncOrSelf(
741 return true;
742
743 unsigned ConcreteUF = Plan.getConcreteUF();
744 // Fixed VF: step is just the concrete UF.
745 if (match(Step, m_SpecificInt(ConcreteUF)))
746 return true;
747
748 // Scalable VF: step involves VScale.
749 if (ConcreteUF == 1)
750 return match(Step, m_VScale());
751 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
752 return true;
753 // mul(VScale, ConcreteUF) may have been simplified to
754 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
755 return isPowerOf2_32(ConcreteUF) &&
756 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
757 };
758
759 VPInstruction *Increment = nullptr;
760 for (VPUser *U : CanIV->users()) {
761 VPValue *Step;
762 if (isa<VPInstruction>(U) &&
763 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
764 IsIncrementStep(Step)) {
765 assert(!Increment && "There must be a unique increment");
767 }
768 }
769
770 assert((!VFxUF.isMaterialized() || Increment) &&
771 "After materializing VFxUF, an increment must exist");
772 assert((!Increment ||
773 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
774 "NUW flag in region and increment must match");
775 return Increment;
776}
777
778/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
779/// inserted for predicated reductions or tail folding.
781 VPValue *BackedgeVal = PhiR->getBackedgeValue();
782 if (auto *Res =
784 return Res;
785
786 // Look through selects inserted for tail folding or predicated reductions.
787 VPRecipeBase *SelR =
788 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
789 if (!SelR)
790 return nullptr;
793}
794
797 SmallVector<const VPValue *> WorkList = {V};
798
799 while (!WorkList.empty()) {
800 const VPValue *Cur = WorkList.pop_back_val();
801 if (!Seen.insert(Cur).second)
802 continue;
803
804 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
805 // Skip blends that use V only through a compare by checking if any incoming
806 // value was already visited.
807 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
808 [&](unsigned I) {
809 return Seen.contains(Blend->getIncomingValue(I));
810 }))
811 continue;
812
813 for (VPUser *U : Cur->users()) {
814 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
815 if (InterleaveR->getAddr() == Cur)
816 return true;
817 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
818 // store (operand 1).
821 m_Specific(Cur)))))
822 return true;
824 if (MemR->getAddr() == Cur && MemR->isConsecutive())
825 return true;
826 }
827 }
828
829 // The legacy cost model only supports scalarization loads/stores with phi
830 // addresses, if the phi is directly used as load/store address. Don't
831 // traverse further for Blends.
832 if (Blend)
833 continue;
834
835 // Only traverse further through users that also define a value (and can
836 // thus have their own users walked). Skip when Cur is only used as mask ,
837 // as well as loads: a loaded value does not depend on the load's operand.
838 for (VPUser *U : Cur->users()) {
839 auto *VPI = dyn_cast<VPInstruction>(U);
840 if (VPI && VPI->getMask() == Cur &&
841 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
842 continue;
844 continue;
845 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
846 WorkList.push_back(SDR);
847 }
848 }
849 return false;
850}
851
852/// Try to find a loop-invariant IR value for \p S in the plan's entry block
853/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
854/// if no reusable IR value is found.
855VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
857 return nullptr;
858 VPlan &Plan = Builder.getPlan();
859 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
860 for (Value *V : SE.getSCEVValues(S)) {
861 // Only reuse instructions in the plan's entry block, or, when a
862 // DominatorTree is available, any instruction that dominates it.
863 // Instructions in sibling branches may not dominate the entry block.
864 auto *I = dyn_cast<Instruction>(V);
865 if (!I)
866 return Plan.getOrAddLiveIn(V);
867 if (!SE.DT.dominates(I->getParent(), PH))
868 continue;
869 SmallVector<Instruction *> DropPoisonGeneratingInsts;
870 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
871 continue;
872 for (Instruction *DropI : DropPoisonGeneratingInsts)
874 return Plan.getOrAddLiveIn(V);
875 }
876 return nullptr;
877}
878
880 if (VPValue *V = tryToReuseIRValue(S))
881 return V;
882
883 switch (S->getSCEVType()) {
884 case scConstant:
885 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
886 case scUnknown:
887 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
888 case scVScale:
889 return Builder.createVScale(S->getType(), DL);
890 case scAddExpr: {
891 auto *AddE = cast<SCEVAddExpr>(S);
892 VPIRFlags::WrapFlagsTy WrapFlags(AddE->hasNoUnsignedWrap(),
893 AddE->hasNoSignedWrap());
894
895 // Expand pointer SCEVAddExpr as a ptradd of the pointer base and the
896 // integer offset, matching SCEVExpander.
897 if (S->getType()->isPointerTy()) {
898 VPValue *Base = expand(SE.getPointerBase(S));
899 VPValue *Offset = expand(SE.removePointerBase(S));
900 GEPNoWrapFlags GEPFlags = WrapFlags.HasNUW
903 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
904 }
905
906 // Non-constant-negative add operands are expanded negated and subtracted
907 // from the running result below, instead of being negated and added.
908 auto UseSubtract = [](const SCEV *Op) {
909 return Op->isNonConstantNegative();
910 };
911 // Iterate in reverse so that constants are emitted last, and move the
912 // subtracted operands last, matching SCEVExpander's LoopCompare, so that
913 // they don't start the running result.
914 SmallVector<const SCEV *, 2> SCEVOps(reverse(AddE->operands()));
915 stable_sort(SCEVOps, [&](const SCEV *L, const SCEV *R) {
916 return !UseSubtract(L) && UseSubtract(R);
917 });
919 for (const SCEV *Op : SCEVOps) {
920 // The first operand starts the result, so it is never subtracted.
921 bool Negate = !Ops.empty() && UseSubtract(Op);
922 Ops.push_back(expand(Negate ? SE.getNegativeSCEV(Op) : Op));
923 }
924 VPValue *Result = Ops.front();
925 for (auto [Op, OpV] : drop_begin(zip_equal(SCEVOps, Ops))) {
926 if (UseSubtract(Op)) {
927 // Result + (-Op) == Result - Op, which saves the multiply for the
928 // negation. NSW only transfers if negating Op cannot overflow, see
929 // ScalarEvolution::getMinusSCEV.
930 bool HasNSW =
931 WrapFlags.HasNSW && !SE.getSignedRangeMin(Op).isMinSignedValue();
932 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
933 {/*HasNUW=*/false, HasNSW}, DL);
934 continue;
935 }
936 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
937 WrapFlags, DL);
938 }
939 return Result;
940 }
941 case scMulExpr: {
942 auto *MulE = cast<SCEVMulExpr>(S);
943 VPIRFlags::WrapFlagsTy WrapFlags(MulE->hasNoUnsignedWrap(),
944 MulE->hasNoSignedWrap());
946 for (const SCEV *Op : reverse(MulE->operands()))
947 Ops.push_back(expand(Op));
948 VPValue *Result = Ops.front();
949 for (VPValue *OpV : drop_begin(Ops)) {
950 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
951 WrapFlags, DL);
952 }
953 return Result;
954 }
955 case scUDivExpr: {
956 auto *UDiv = cast<SCEVUDivExpr>(S);
957 VPValue *LHS = expand(UDiv->getLHS());
958 const SCEV *RHSExpr = UDiv->getRHS();
959 VPValue *RHS = expand(RHSExpr);
960 if (SafeUDivMode) {
961 // Make sure the UDiv's divisor is guaranteed to not be zero/poison, to
962 // avoid UB.
963 Type *Ty = UDiv->getType();
964 bool GuaranteedNotPoison =
966 if (!GuaranteedNotPoison)
967 RHS = Builder.createFreeze(RHS, DL);
968 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
969 RHS = Builder.createScalarIntrinsic(
970 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
971 DL);
972 }
973 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
974 VPIRFlags::getDefaultFlags(Instruction::UDiv),
975 DL);
976 }
977 case scTruncate:
978 case scZeroExtend:
979 case scSignExtend:
980 case scPtrToAddr: {
981 auto *Cast = cast<SCEVCastExpr>(S);
982 VPValue *Op = expand(Cast->getOperand());
984 switch (S->getSCEVType()) {
985 case scTruncate:
986 Opcode = Instruction::Trunc;
987 break;
988 case scZeroExtend:
989 Opcode = Instruction::ZExt;
990 break;
991 case scSignExtend:
992 Opcode = Instruction::SExt;
993 break;
994 case scPtrToAddr:
995 Opcode = Instruction::PtrToAddr;
996 break;
997 default:
998 llvm_unreachable("Unhandled cast SCEV");
999 }
1000
1001 // When expanding ptrtoaddr, first check if there's an existing ptrtoint we
1002 // can reuse.
1003 if (Opcode == Instruction::PtrToAddr) {
1004 VPlan &Plan = Builder.getPlan();
1005 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1006 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
1008 IRV->getValue(), S->getType(), PH->getDataLayout(),
1009 [&](const CastInst *CI) {
1010 return SE.DT.dominates(CI->getParent(), PH);
1011 }))
1012 return Plan.getOrAddLiveIn(CI);
1013 }
1014 }
1015
1016 std::optional<VPIRFlags> Flags;
1017 if (Opcode == Instruction::ZExt)
1018 Flags =
1019 VPIRFlags::NonNegFlagsTy(SE.isKnownNonNegative(Cast->getOperand()));
1020
1021 return Builder.createScalarCast(Opcode, Op, S->getType(), DL, Flags);
1022 }
1023 case scUMaxExpr:
1024 case scSMaxExpr:
1025 case scUMinExpr:
1026 case scSMinExpr:
1027 case scSequentialUMinExpr: {
1028 auto *MinMax = cast<SCEVNAryExpr>(S);
1029 Intrinsic::ID IntrinsicID;
1030 switch (S->getSCEVType()) {
1031 case scUMaxExpr:
1032 IntrinsicID = Intrinsic::umax;
1033 break;
1034 case scSMaxExpr:
1035 IntrinsicID = Intrinsic::smax;
1036 break;
1037 case scUMinExpr:
1039 IntrinsicID = Intrinsic::umin;
1040 break;
1041 case scSMinExpr:
1042 IntrinsicID = Intrinsic::smin;
1043 break;
1044 default:
1045 llvm_unreachable("Unexpected min/max SCEV type");
1046 }
1047 // Chain operands in reverse order matching SCEVExpander's expansion of
1048 // min/max expressions. In SafeUDivMode freeze expansion results of operands
1049 // other than the first for sequential UMins, to avoid short-circuiting
1050 // divide-by-0/poison.
1051 bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
1052 Type *ResultTy = MinMax->getType();
1053 bool PrevSafeMode = SafeUDivMode;
1055 for (const SCEV *SCEVOp : reverse(MinMax->operands())) {
1056 bool MayShortCircuit =
1057 IsSequential && Ops.size() != MinMax->getNumOperands() - 1;
1058 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1059 VPValue *OpV = expand(SCEVOp);
1060 SafeUDivMode = PrevSafeMode;
1061 if (MayShortCircuit)
1062 OpV = Builder.createFreeze(OpV, DL);
1063 Ops.push_back(OpV);
1064 }
1065 VPValue *Result = Ops.front();
1066 for (VPValue *Op : drop_begin(Ops))
1067 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
1068 ResultTy, DL);
1069 return Result;
1070 }
1071 case scAddRecExpr: {
1072 auto *AR = cast<SCEVAddRecExpr>(S);
1073 VPlan &Plan = Builder.getPlan();
1074 [[maybe_unused]] BasicBlock *PH =
1075 cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1076 assert(SE.DT.dominates(AR->getLoop()->getHeader(), PH) &&
1077 "can only expand AddRecs for loops outside VPlan's scope");
1078
1079 // Try to expand AR by re-using an existing canonical IV in the Plan's
1080 // entry. A canonical IV must be affine and integer typed.
1081 if (!AR->isAffine() || !AR->getType()->isIntegerTy())
1083 auto FoundCanIV =
1084 find_if(Plan.getEntry()->phis(), [&](const VPRecipeBase &R) {
1085 if (!SE.isSCEVable(cast<VPIRPhi>(R).getIRPhi().getType()))
1086 return false;
1087 const SCEV *Candidate = SE.getSCEV(&cast<VPIRPhi>(R).getIRPhi());
1088 return match(Candidate,
1089 m_scev_AffineAddRec(m_scev_Zero(), m_scev_One(),
1090 m_SpecificLoop(AR->getLoop()))) &&
1091 Candidate->getType() == AR->getType();
1092 });
1093 if (FoundCanIV == Plan.getEntry()->phis().end())
1095
1096 // {Start, +, Step} --> Start + IV * Step, since the AddRec is affine.
1097 // Compute Offset = IV * Step.
1098 VPValue *Start = expand(AR->getStart());
1099 Value *CanonicalIV = &cast<VPIRPhi>(FoundCanIV)->getIRPhi();
1101 SE.getMulExpr(SE.getUnknown(CanonicalIV), AR->getStepRecurrence(SE)));
1102
1103 // Compute Start + Offset with nuw from the AddRec.
1104 return Builder.createAdd(Start, Offset, DL, "",
1105 {AR->hasNoUnsignedWrap(), false});
1106 }
1107 case scCouldNotCompute:
1108 llvm_unreachable("Attempt to expand a SCEVCouldNotCompute");
1109 }
1110 llvm_unreachable("Unknown SCEV kind!");
1111}
1112
1114 // Do remove conditional assume instructions as their conditions may be
1115 // flattened.
1116 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1117 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1119 if (IsConditionalAssume)
1120 return true;
1121
1122 if (R.mayHaveSideEffects())
1123 return false;
1124
1125 // Forbid removing trip-count expressions.
1126 if (isa<VPExpandSCEVRecipe>(R) &&
1127 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1128 return false;
1129
1130 // Recipe is dead if no user keeps the recipe alive.
1131 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1132}
1133
1135 SmallVector<VPValue *> WorkList;
1137 WorkList.push_back(V);
1138
1139 while (!WorkList.empty()) {
1140 VPValue *Cur = WorkList.pop_back_val();
1141 if (!Seen.insert(Cur).second)
1142 continue;
1143 VPRecipeBase *R = Cur->getDefiningRecipe();
1144 if (!R)
1145 continue;
1146 if (!isDeadRecipe(*R))
1147 continue;
1148 append_range(WorkList, R->operands());
1149 R->eraseFromParent();
1150 }
1151}
1152
1155 for (unsigned I = 0; I != Users.size(); ++I) {
1157 for (VPValue *V : Cur->definedValues())
1158 Users.insert_range(V->users());
1159 }
1160 return Users.takeVector();
1161}
1162
1163/// Returns \p Num / \p Denom as a BranchProbability, clamped so a ratio that is
1164/// neither zero nor one does not round to zero or one. BlockFrequencyInfo also
1165/// keeps a zero-weight edge distinguishable from an unreachable one.
1167 uint64_t Denom) {
1169 if (Num == 0 || Num == Denom)
1170 return P;
1171 return BranchProbability::getRaw(std::clamp(
1172 P.getNumerator(), 1u, BranchProbability::getDenominator() - 1));
1173}
1174
1179
1180/// Returns the probability of reaching each unique successor of \p VPBB, taken
1181/// from the branch weights recorded on its terminator, or unknown if not
1182/// available. See llvm::getBranchProbability in
1183/// llvm/Transforms/Utils/LoopUtils.h for the IR version.
1186 ArrayRef<VPBlockBase *> Successors = VPBB->getSuccessors();
1187 // With a single successor the edge is always taken and needs no weights.
1188 if (VPBlockBase *Succ = VPBB->getSingleSuccessor())
1190
1191 // Take the branch weights off the terminator. Without usable weights all
1192 // successors have unknown probability; zero the weights, so the accumulation
1193 // below still visits each of them.
1194 SmallVector<uint32_t> Weights;
1196 if (!Term || !extractBranchWeights(Term->getBranchWeights(), Weights) ||
1197 Weights.size() != Successors.size())
1198 Weights.assign(Successors.size(), 0);
1199 uint64_t Total = sum_of(Weights, uint64_t(0));
1200
1201 // Sum the weights of parallel edges to the same successor, so that the
1202 // division below rounds once per successor rather than once per edge.
1204 for (const auto &[Succ, Weight] : zip_equal(Successors, Weights))
1205 WeightPerSuccessor[cast<VPBasicBlock>(Succ)] += Weight;
1206
1207 return map_to_vector<2>(WeightPerSuccessor, [Total](const auto &SuccWeight) {
1208 auto [Succ, Weight] = SuccWeight;
1209 if (Total == 0)
1210 return std::make_pair(Succ, BranchProbability::getUnknown());
1211 return std::make_pair(Succ,
1213 });
1214}
1215
1216/// Returns \p Freq scaled by \p Prob, rounding up to 1 instead of 0 to keep a
1217/// rarely executed block distinguishable from an unreachable one.
1219 BranchProbability Prob) {
1220 BlockFrequency Scaled = Freq * Prob;
1221 if (Scaled == BlockFrequency() && Freq != BlockFrequency() && !Prob.isZero())
1222 return BlockFrequency(1);
1223 return Scaled;
1224}
1225
1228 assert(!Blocks.empty() && "expected at least the header block");
1229 // Push each block's frequency along its outgoing edges. Blocks is a DAG in
1230 // reverse post-order (the loop region's backedge is implicit), so a block's
1231 // frequency is final by the time it is visited.
1233 Frequencies;
1234 Frequencies.reserve(Blocks.size());
1235 // The header (first block) always executes, the others start out unreachable.
1236 Frequencies[Blocks.front()].emplace(BlockFrequency(AlwaysExecutesFreq),
1237 false);
1238 for (VPBasicBlock *VPBB : Blocks.drop_front())
1239 Frequencies[VPBB].emplace(BlockFrequency(), false);
1240
1241 for (VPBasicBlock *VPBB : Blocks) {
1242 std::optional<VPExecutionFrequency> Src = Frequencies.at(VPBB);
1243 auto *Term = dyn_cast_if_present<VPInstruction>(VPBB->getTerminator());
1244 bool TermIsEstimated = Term && Term->hasEstimatedBranchWeights();
1245 for (const auto &[Succ, EdgeProb] : getSuccessorProbabilities(VPBB)) {
1246 std::optional<VPExecutionFrequency> &SuccFreq = Frequencies.at(Succ);
1247 // An unknown edge or predecessor poisons the successor.
1248 if (!Src || EdgeProb.isUnknown() || !SuccFreq) {
1249 SuccFreq = std::nullopt;
1250 continue;
1251 }
1252 // The sum can only exceed AlwaysExecutesFreq by rounding.
1253 BlockFrequency NewFreq =
1255 SuccFreq->Freq + scaleKeepingNonZero(Src->Freq, EdgeProb));
1256 bool NewIsEstimated =
1257 SuccFreq->IsEstimated || Src->IsEstimated || TermIsEstimated;
1258 SuccFreq.emplace(NewFreq, NewIsEstimated);
1259 }
1260 }
1261 return Frequencies;
1262}
1263
1266 const DataLayout &DL) {
1267 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1268 if (!OpcodeOrIID)
1269 return nullptr;
1270
1272 for (VPValue *Op : Operands) {
1273 VPValue *Candidate = Op;
1274 match(Op, m_Broadcast(m_VPValue(Candidate)));
1275 if (!match(Candidate, m_LiveIn()))
1276 return nullptr;
1277 Value *V = Candidate->getUnderlyingValue();
1278 if (!V)
1279 return nullptr;
1280 Ops.push_back(V);
1281 }
1282
1283 VPlan &Plan = *R.getParent()->getPlan();
1284 auto FoldToIRValue = [&]() -> Value * {
1285 InstSimplifyFolder Folder(DL);
1286 if (OpcodeOrIID->first) {
1287 // VPInstructions store the called intrinsic as last operand.
1288 if (isa<VPInstruction>(R))
1289 Ops.pop_back();
1290
1291 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1292 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1293 RFlags ? RFlags->getFastMathFlagsOrNone()
1294 : FastMathFlags());
1295 }
1296 unsigned Opcode = OpcodeOrIID->second;
1297 if (Instruction::isBinaryOp(Opcode))
1298 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1299 Ops[0], Ops[1]);
1300 if (Instruction::isCast(Opcode))
1301 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1302 R.getVPSingleValue()->getScalarType());
1303 switch (Opcode) {
1304 case VPInstruction::Not:
1305 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1307 case Instruction::Select:
1308 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1309 case Instruction::ICmp:
1310 case Instruction::FCmp:
1311 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1312 Ops[1]);
1313 case Instruction::GetElementPtr: {
1314 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1315 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1316 return Folder.FoldGEP(GEP->getSourceElementType(), Ops[0],
1317 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1318 }
1321 return Folder.FoldGEP(IntegerType::getInt8Ty(Plan.getContext()), Ops[0],
1322 Ops[1],
1323 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1324 // An extract of a live-in is an extract of a broadcast, so return the
1325 // broadcasted element.
1326 case Instruction::ExtractElement:
1327 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1328 return Ops[0];
1329 }
1330 return nullptr;
1331 };
1332
1333 if (Value *V = FoldToIRValue())
1334 return Plan.getOrAddLiveIn(V);
1335 return nullptr;
1336}
1337
1339 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1342 vp_depth_first_deep(Plan.getEntry()))) {
1343 for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
1344 auto *Def = dyn_cast<VPSingleDefRecipe>(&R);
1345 if (!Def || !isElementwise(Def))
1346 continue;
1347
1348 // At least one of the ops must be a permutation.
1349 if (none_of(Def->operands(), MatchPerm))
1350 continue;
1351
1352 // All operands must be a single-use permutation or a live in (splat).
1353 if (!all_of(Def->operands(), [&MatchPerm](VPValue *Op) {
1354 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1355 }))
1356 continue;
1357
1358 // Remove the inner permutations.
1359 for (unsigned I = 0, E = Def->getNumOperands(); I != E; ++I)
1360 if (VPValue *X = MatchPerm(Def->getOperand(I)))
1361 Def->setOperand(I, X);
1362
1363 VPSingleDefRecipe *Res = BuildPerm(Def);
1364 Res->insertAfter(Def);
1365 Def->replaceUsesWithIf(
1366 Res, [&Res](VPUser &U, unsigned _) { return &U != Res; });
1367 }
1368 }
1369}
1370
1371// Implements the algorithm described in "Simple and Efficient Construction of
1372// Static Single Assignment Form" by Braun et al.
1375 assert(!Defs.empty() && "Defs shouldn't be empty");
1376 assert(
1378 "VPBB isn't reachable from entry");
1379 if (VPValue *Def = Defs.lookup(VPBB))
1380 return Def;
1381 // If the entry block is reached and there's still no def, then Defs is
1382 // missing a definition that covers this path.
1383 assert(VPBB->getNumPredecessors() && "Not all paths have def");
1384
1385 if (VPBlockBase *Pred = VPBB->getSinglePredecessor())
1386 return reconstructSSA(cast<VPBasicBlock>(Pred), Defs);
1387
1388 // Multiple predecessors, create a join.
1389 Type *Ty = Defs.begin()->second->getScalarType();
1390 VPPhi *Phi = VPBuilder(VPBB, VPBB->getFirstNonPhi())
1391 .createScalarPhi({}, DebugLoc::getUnknown(), "", {}, Ty);
1392 Defs[VPBB] = Phi;
1393 for (auto *Pred : VPBB->predecessors())
1394 Phi->addIncoming(reconstructSSA(cast<VPBasicBlock>(Pred), Defs));
1395
1396 // Fold away trivial phis.
1397 // TODO: Remove phi users which have become trivial too.
1398 if (all_equal(Phi->incoming_values())) {
1399 VPValue *Common = Phi->getIncomingValue(0);
1400 Phi->replaceAllUsesWith(Common);
1401 for (auto &[_, V] : Defs)
1402 if (V == Phi)
1403 V = Common;
1404 Defs[VPBB] = Common;
1405 Phi->eraseFromParent();
1406 return Common;
1407 }
1408
1409 return Phi;
1410}
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:296
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:278
bool empty() const
Definition DenseMap.h:199
iterator begin()
Definition DenseMap.h:165
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Definition DenseMap.h:204
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:630
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:416
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:1053
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...
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:87
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:238
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
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 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
@ 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