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/SetVector.h"
16#include "llvm/ADT/TypeSwitch.h"
25#include "llvm/IR/Dominators.h"
28
29using namespace llvm;
30using namespace llvm::VPlanPatternMatch;
31using namespace llvm::SCEVPatternMatch;
32
34 if (isa<VPBlendRecipe>(U))
35 return true;
36 auto *VPI = dyn_cast<VPInstruction>(U);
37 if (!VPI)
38 return false;
39 unsigned Opcode = VPI->getOpcode();
40 switch (Opcode) {
41 case Instruction::ExtractValue:
42 case Instruction::FCmp:
43 case Instruction::ICmp:
44 case Instruction::Select:
45 case Instruction::Freeze:
47 // TODO: Cover additional opcodes.
48 return true;
50 return Op != VPI->getOperand(0);
51 default:
52 return Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode);
53 }
54}
55
58 Worklist.insert(Def);
59 for (unsigned I = 0; I != Worklist.size(); ++I) {
60 const VPValue *Cur = Worklist[I];
61 for (const VPUser *U : Cur->users()) {
62 if (propagatesFirstLaneUse(U, Cur))
64 else if (!U->usesFirstLaneOnly(Cur))
65 return false;
66 }
67 }
68 return true;
69}
70
72 return all_of(Def->users(),
73 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
74}
75
77 return all_of(Def->users(),
78 [Def](const VPUser *U) { return U->usesScalars(Def); });
79}
80
82 bool ExpandInIR) {
83 if (auto *E = dyn_cast<SCEVConstant>(Expr))
84 return Plan.getOrAddLiveIn(E->getValue());
85 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
86 // value. Otherwise the value may be defined in a loop and using it directly
87 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
88 // form.
89 auto *U = dyn_cast<SCEVUnknown>(Expr);
90 if (U && !isa<Instruction>(U->getValue()))
91 return Plan.getOrAddLiveIn(U->getValue());
92 auto *Expanded = new VPExpandSCEVRecipe(Expr, ExpandInIR);
93 VPBasicBlock *EntryVPBB = Plan.getEntry();
94 auto Iter = EntryVPBB->getFirstNonPhi();
95 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
96 ++Iter;
97 Expanded->insertBefore(Iter);
98 return Expanded;
99}
100
101/// Returns true if \p V being poison is guaranteed to trigger UB because it
102/// propagates to the address of a memory recipe.
103static bool poisonGuaranteesUB(const VPValue *V) {
106
107 auto PropagatesPoisonFromRecipeOp = [](const VPRecipeBase *R) {
109 return false;
110 unsigned Opcode = vputils::getOpcode(R->getVPSingleValue());
111 return Instruction::isCast(Opcode) || Opcode == Instruction::GetElementPtr;
112 };
113
114 Worklist.push_back(V);
115
116 while (!Worklist.empty()) {
117 const VPValue *Current = Worklist.pop_back_val();
118 if (!Visited.insert(Current).second)
119 continue;
120
121 for (VPUser *U : Current->users()) {
122 // Check if Current is used as an address operand for load/store.
123 auto *R = cast<VPRecipeBase>(U);
124 if (auto *MemR = dyn_cast<VPWidenMemoryRecipe>(R)) {
125 if (MemR->getAddr() == Current)
126 return true;
127 continue;
128 }
129 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
130 unsigned Opcode = Rep->getOpcode();
131 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
132 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
133 return true;
134 }
135
136 // Check if poison propagates through this recipe to any of its users.
137 for (const VPValue *Op : R->operands()) {
138 if (Op == Current && PropagatesPoisonFromRecipeOp(R)) {
139 Worklist.push_back(R->getVPSingleValue());
140 break;
141 }
142 }
143 }
144 }
145
146 return false;
147}
148
150 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
151 // casts to find a root GEP VPInstruction.
152 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
153 unsigned Opcode = PtrVPI->getOpcode();
154 if (Opcode == Instruction::GetElementPtr) {
155 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
156 return PtrVPI->getGEPNoWrapFlags();
157 Ptr = PtrVPI->getOperand(0);
158 continue;
159 }
160 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
161 break;
162 Ptr = PtrVPI->getOperand(0);
163 }
164 return GEPNoWrapFlags::none();
165}
166
169 const Loop *L) {
170 ScalarEvolution &SE = *PSE.getSE();
171 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
172 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
173 "RegionValue must be canonical IV");
174 if (!L)
175 return SE.getCouldNotCompute();
176 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
177 L, SCEV::FlagNone);
178 }
179
181 Value *LiveIn = V->getUnderlyingValue();
182 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
183 return SE.getSCEV(LiveIn);
184 return SE.getCouldNotCompute();
185 }
186
187 // Helper to create SCEVs for binary and unary operations.
188 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
189 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
190 -> const SCEV * {
192 for (VPValue *Op : Ops) {
193 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
195 return SE.getCouldNotCompute();
196 SCEVOps.push_back(S);
197 }
198 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
199 };
200
201 VPValue *LHSVal, *RHSVal;
202 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
203 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
204 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
205 });
206 if (match(V, m_BinaryOr(m_VPValue(LHSVal), m_VPValue(RHSVal))))
207 if (cast<VPRecipeWithIRFlags>(V->getDefiningRecipe())->isDisjoint())
208 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
209 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
210 });
211 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
212 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
213 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagNone, 0);
214 });
215 if (match(V, m_Not(m_VPValue(LHSVal)))) {
216 // not X = xor X, -1 = -1 - X
217 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
218 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
219 });
220 }
221 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
222 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
223 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagNone, 0);
224 });
225 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
226 // amount >= the bit width produces poison; do not rewrite it, as
227 // getPowerOfTwo requires the power to be in range.
228 uint64_t ShiftAmt;
229 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
230 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
231 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
232 return SE.getMulExpr(Ops[0],
233 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
234 });
235 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
236 Type *Ty = V->getScalarType();
237 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
238 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
239 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
240 });
241 }
242 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
243 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
244 return SE.getUDivExpr(Ops[0], Ops[1]);
245 });
246 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
247 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
248 return SE.getURemExpr(Ops[0], Ops[1]);
249 });
250 // A SDiv with non-negative operands is equivalent to an UDiv.
251 if (match(V, m_SDiv(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
252 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
253 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
254 return SE.getCouldNotCompute();
255 return SE.getUDivExpr(Ops[0], Ops[1]);
256 });
257 }
258 // A SRem with non-negative operands is equivalent to an URem.
259 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
260 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
261 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
262 return SE.getCouldNotCompute();
263 return SE.getURemExpr(Ops[0], Ops[1]);
264 });
265 }
266 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
267 const APInt *Mask;
268 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
269 (*Mask + 1).isPowerOf2())
270 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
271 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
272 });
273 // SCEV models ptrtoaddr, but not ptrtoint, mirroring createSCEV.
274 if (match(V, m_PtrToAddr(m_VPValue(LHSVal))))
275 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
276 return SE.getPtrToAddrExpr(Ops[0]);
277 });
278 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
279 Type *DestTy = V->getScalarType();
280 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
281 return SE.getTruncateExpr(Ops[0], DestTy);
282 });
283 }
284 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
285 Type *DestTy = V->getScalarType();
286 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
287 return SE.getZeroExtendExpr(Ops[0], DestTy);
288 });
289 }
290 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
291 Type *DestTy = V->getScalarType();
292
293 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
294 // onto the operands before computing the subtraction.
295 VPValue *SubLHS, *SubRHS;
296 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
297 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
298 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
299 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
300 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
302 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
303 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
304 }
305
306 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
307 return SE.getSignExtendExpr(Ops[0], DestTy);
308 });
309 }
310 if (match(V,
312 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
313 return SE.getUMaxExpr(Ops[0], Ops[1]);
314 });
315 if (match(V,
317 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
318 return SE.getSMaxExpr(Ops[0], Ops[1]);
319 });
320 if (match(V,
322 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
323 return SE.getUMinExpr(Ops[0], Ops[1]);
324 });
325 if (match(V,
327 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
328 return SE.getSMinExpr(Ops[0], Ops[1]);
329 });
331 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
332 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
333 // not proof that the input is never INT_MIN, nor that poison reaches
334 // UB. Do not translate it to SCEV's global IsNSW flag.
335 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
336 });
337
339 Type *SourceElementType;
340 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
341 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
342 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
343 });
344 }
345
346 // TODO: Support constructing SCEVs for more recipes as needed.
347 const VPRecipeBase *DefR = V->getDefiningRecipe();
348 const SCEV *Expr =
350 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
351 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
352 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
353 if (!L || isa<SCEVCouldNotCompute>(Step))
354 return SE.getCouldNotCompute();
355 const SCEV *Start =
356 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
357 const SCEV *AddRec =
358 SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
359 if (R->isTruncated())
360 return SE.getTruncateExpr(AddRec, R->getScalarType());
361 return AddRec;
362 })
363 .Case([&SE, &PSE,
364 L](const VPWidenPointerInductionRecipe *R) -> const SCEV * {
365 const SCEV *Start =
366 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
367 if (!L || isa<SCEVCouldNotCompute>(Start))
368 return SE.getCouldNotCompute();
369 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
370 if (isa<SCEVCouldNotCompute>(Step))
371 return SE.getCouldNotCompute();
372 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagNone);
373 })
374 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) -> const SCEV * {
375 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
376 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
377 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
378 if (any_of(ArrayRef({Start, IV, Scale}),
380 return SE.getCouldNotCompute();
381
382 return SE.getAddExpr(
383 SE.getTruncateOrSignExtend(Start, IV->getType()),
384 SE.getMulExpr(
385 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
386 })
387 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
388 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
389 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
391 return SE.getCouldNotCompute();
392 return SE.getTruncateOrSignExtend(IV, Step->getType());
393 })
394 .Default(
395 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
396
397 return PSE.getPredicatedSCEV(Expr);
398}
399
400std::optional<int64_t>
402 PredicatedScalarEvolution &PSE, const Loop *L) {
403 assert(!hasIrregularType(AccessTy, L->getHeader()->getDataLayout()) &&
404 "should not try to widen irregular types");
405 const SCEV *AddrSCEV = getSCEVExprForVPValue(Addr, PSE, L);
406 auto *AddRec = dyn_cast<SCEVAddRecExpr>(AddrSCEV);
407 if (!AddRec)
408 return {};
409
410 return getStrideFromAddRec(AddRec, L, AccessTy, /*Ptr=*/nullptr, PSE);
411}
412
414 const Loop *L) {
415 // If address is an SCEVAddExpr, we require that all operands must be either
416 // be invariant or a (possibly sign-extend) affine AddRec.
417 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
418 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
419 return SE.isLoopInvariant(Op, L) ||
420 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
421 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
422 });
423 }
424
425 // Otherwise, check if address is loop invariant or an affine add recurrence.
426 return SE.isLoopInvariant(Addr, L) ||
428}
429
430unsigned vputils::getOpcode(const VPValue *V) {
434 VPWidenLoadEVLRecipe>([](auto *I) { return I->getOpcode(); })
437 // For recipes that do not directly map to LLVM IR instructions,
438 // assign opcodes after the last VPInstruction opcode (which is also
439 // after the last IR Instruction opcode), based on the VPRecipeID.
440 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
441 })
442 .Default([](auto *) { return 0; });
443}
444
445std::optional<std::pair<bool, unsigned>>
448 return std::make_pair(true, IID);
449 if (unsigned Opcode = vputils::getOpcode(V))
450 return std::make_pair(false, Opcode);
451 return {};
452}
453
454/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
455/// uniform, the result will also be uniform.
456static bool preservesUniformity(unsigned Opcode) {
457 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
458 return true;
459 switch (Opcode) {
460 case Instruction::Freeze:
461 case Instruction::GetElementPtr:
462 case Instruction::ICmp:
463 case Instruction::FCmp:
464 case Instruction::Select:
469 return true;
470 default:
471 return false;
472 }
473}
474
476 // TODO: Handle more opcodes and recipes.
478 return false;
479 unsigned Opcode = getOpcode(V);
480 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
481}
482
484 // Live-in, symbolic and canonical-IV region values are single-scalar.
485 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
486 return RV == RV->getDefiningRegion()->getCanonicalIV();
488 return true;
489
490 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
491 const VPRegionBlock *RegionOfR = Rep->getRegion();
492 // Don't consider recipes in replicate regions as uniform yet; their first
493 // lane cannot be accessed when executing the replicate region for other
494 // lanes.
495 if (RegionOfR && RegionOfR->isReplicator())
496 return false;
497 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
498 all_of(Rep->operands(), isSingleScalar));
499 }
502 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
503 return preservesUniformity(WidenR->getOpcode()) &&
504 all_of(WidenR->operands(), isSingleScalar);
505 }
506 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
507 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
508 (preservesUniformity(VPI->getOpcode()) &&
509 all_of(VPI->operands(), isSingleScalar));
510 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
511 return !RR->isPartialReduction();
514 return true;
515 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
516 return Expr->isVectorToScalar();
517
518 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
519 return isa<VPExpandSCEVRecipe>(VPV);
520}
521
523 const VPValue *V,
524 function_ref<void(VPUser::const_operand_range)> AddToWorklist) {
525 // Live-ins, symbolic and canonical-IV region values are uniform.
526 if (auto *RV = dyn_cast<VPRegionValue>(V))
527 return RV == RV->getDefiningRegion()->getCanonicalIV();
529 return true;
530
531 const VPRecipeBase *R = V->getDefiningRecipe();
532 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
533 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
534 if (VPBB &&
535 (VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
536 if (match(R,
539 return false;
540 AddToWorklist(R->operands());
541 return true;
542 }
543
545 .Case([](const VPDerivedIVRecipe *) { return true; })
546 .Case([&](const VPReplicateRecipe *R) {
547 // Be conservative about side-effects, except for the
548 // known-side-effecting assumes and stores, which we know will be
549 // uniform. Each alloca creates a distinct allocation, so allocas are
550 // never uniform.
551 if (!R->isSingleScalar() || R->getOpcode() == Instruction::Alloca ||
552 (R->mayHaveSideEffects() &&
553 !isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())))
554 return false;
555 AddToWorklist(R->operands());
556 return true;
557 })
558 .Case([&](const VPWidenRecipe *R) {
559 if (!preservesUniformity(R->getOpcode()))
560 return false;
561 AddToWorklist(R->operands());
562 return true;
563 })
564 .Case([](const VPPhi *) {
565 // Bail out on VPPhi, as we can end up in infinite cycles.
566 return false;
567 })
568 .Case([&](const VPInstruction *VPI) {
569 if (!VPI->isSingleScalar() && !VPI->isVectorToScalar() &&
571 return false;
572 AddToWorklist(VPI->operands());
573 return true;
574 })
575 .Case([&](const VPWidenCastRecipe *R) {
576 // A cast is uniform according to its operand.
577 AddToWorklist(R->operands());
578 return true;
579 })
580 .Default([](const VPRecipeBase *) {
581 // A value is considered non-uniform unless proven otherwise.
582 return false;
583 });
584}
585
588 Worklist.insert(V);
589
590 auto AddToWorklist = [&Worklist](VPUser::const_operand_range Operands) {
591 Worklist.insert_range(Operands);
592 };
593
594 // All dependency checks are conjunctive, so each value needs checking once.
595 for (unsigned I = 0; I != Worklist.size(); ++I) {
596 if (!isUniformAcrossVFsAndUFsImpl(Worklist[I], AddToWorklist))
597 return false;
598 }
599 return true;
600}
601
603 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
604 return RepR->doesGeneratePerAllLanes();
605 if (auto *VPI = dyn_cast<VPInstruction>(R))
606 return VPI->doesGeneratePerAllLanes();
607 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
608 return SIVSteps->doesGeneratePerAllLanes();
609 return false;
610}
611
613 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
614 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
615 return VPBlockUtils::isHeader(VPB, VPDT);
616 });
617 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
618}
619
621 if (!R)
622 return 1;
623 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
624 return RR->getVFScaleFactor();
625 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
626 return RR->getVFScaleFactor();
627 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
628 return ER->getVFScaleFactor();
629 assert(
632 "getting scaling factor of reduction-start-vector not implemented yet");
633 return 1;
634}
635
636bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
637 // Assumes don't alias anything or throw; as long as they're guaranteed to
638 // execute, they're safe to hoist. They should however not be sunk, as it
639 // would destroy information.
641 return Sinking;
642 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
643 return true;
644 // Allocas cannot be hoisted.
645 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
646 return RepR && RepR->getOpcode() == Instruction::Alloca;
647}
648
651 VPBasicBlock *LastBB) {
652 assert(FirstBB->getParent() == LastBB->getParent() &&
653 "FirstBB and LastBB from different regions");
654#ifndef NDEBUG
655 bool InSingleSuccChain = false;
656 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
657 InSingleSuccChain |= (Succ == LastBB);
658 assert(InSingleSuccChain &&
659 "LastBB unreachable from FirstBB in single-successor chain");
660#endif
661 auto Blocks = to_vector(
663 auto *LastIt = find(Blocks, LastBB);
664 assert(LastIt != Blocks.end() &&
665 "LastBB unreachable from FirstBB in depth-first traversal");
666 Blocks.erase(std::next(LastIt), Blocks.end());
667 return Blocks;
668}
669
671 for (VPRecipeBase &R : *Plan.getVectorPreheader())
673 return cast<VPInstruction>(&R);
674 return nullptr;
675}
676
678vputils::getEarlyExits(const VPlan &Plan, const VPBlockBase *MiddleVPBB) {
680 for (VPIRBasicBlock *ExitVPBB : Plan.getExitBlocks())
681 for (VPBlockBase *Pred : ExitVPBB->getPredecessors())
682 if (Pred != MiddleVPBB)
683 Exits.emplace_back(cast<VPBasicBlock>(Pred), ExitVPBB);
684 return Exits;
685}
686
689 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
690 Type *ResultTy, VPValue *StartV, VPValue *Step, DebugLoc DL,
691 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
692 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
693 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
694 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
695 VPValue *BaseIV =
696 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
697
698 // Truncate BaseIV and Step to ResultTy.
699 if (ResultTy->isIntegerTy()) {
700 [[maybe_unused]] Type *BaseIVTy = BaseIV->getScalarType();
701 assert(BaseIVTy->isIntegerTy() && "Integral BaseIV type expected");
702 assert(BaseIVTy->getPrimitiveSizeInBits() >=
703 ResultTy->getPrimitiveSizeInBits() &&
704 "BaseIV's type must be at least as large as ResultTy");
705 BaseIV = Builder.createScalarZExtOrTrunc(BaseIV, ResultTy, DL);
706 [[maybe_unused]] Type *StepTy = Step->getScalarType();
707 assert(StepTy->isIntegerTy() && "Integral Step type expected");
708 assert(StepTy->getPrimitiveSizeInBits() >=
709 ResultTy->getPrimitiveSizeInBits() &&
710 "Step's type must be at least as large as ResultTy");
711 auto *VecPreheader =
713 VPBuilder::InsertPointGuard Guard(Builder);
714 Builder.setInsertPoint(VecPreheader);
715 Step = Builder.createScalarZExtOrTrunc(Step, ResultTy, DL);
716 }
717 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
718 &Plan.getVF(), DL);
719}
720
721VPValue *
723 VPlan &Plan, VPBuilder &Builder) {
724 VPValue *StepV = PtrIV->getStepValue();
725 VPIRValue *StartV = Plan.getZero(StepV->getScalarType());
727 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
728 StartV->getScalarType(), StartV, StepV, PtrIV->getDebugLoc(), Builder);
729
730 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
731 PtrIV->getDebugLoc(), "next.gep");
732}
733
735 const VPDominatorTree &VPDT) {
736 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
737 if (!VPBB)
738 return false;
739
740 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
741 // VPBB as its entry, i.e., free of predecessors.
742 if (auto *R = VPBB->getParent())
743 return !R->isReplicator() && !VPBB->hasPredecessors();
744
745 // A header dominates its second predecessor (the latch), with the other
746 // predecessor being the preheader
747 return VPB->getPredecessors().size() == 2 &&
748 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
749}
750
752 const VPDominatorTree &VPDT) {
753 // A latch has a header as its last successor, with its other successors
754 // leaving the loop. A preheader OTOH has a header as its first (and only)
755 // successor.
756 return VPB->getNumSuccessors() >= 2 &&
758}
759
760std::pair<VPBasicBlock *, VPBasicBlock *>
763 Plan.getEntry()->getNumSuccessors() == 1
764 ? Plan.getEntry()->getSingleSuccessor()
765 : Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
766 assert(Header->getNumPredecessors() == 2 &&
767 "Header must have exactly 2 predecessors");
768 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
769 return {Header, Latch};
770}
771
775
777 const VPPhi *PhiR) {
778 if (ID.getKind() == InductionDescriptor::IK_FpInduction)
779 return ID.getInductionBinOp()->getFastMathFlags();
780
781 // The flags only bound the induction values if the increment directly
782 // updates PhiR.
783 VPValue *Inc = PhiR->getOperand(1);
784 if (match(Inc, m_c_Add(m_Specific(PhiR), m_VPValue())))
785 return cast<VPInstruction>(Inc)->getNoWrapFlagsOrNone();
786
787 if (match(Inc, m_Sub(m_Specific(PhiR), m_VPValue()))) {
788 // The step of a sub induction is negated, so NUW cannot be preserved. NSW
789 // can, if the step is not the signed minimum.
790 std::optional<APInt> Step = ID.getConstStepValue();
791 bool NSW = cast<VPInstruction>(Inc)->getNoWrapFlagsOrNone().HasNSW &&
792 Step && !Step->isMinSignedValue();
793 return VPIRFlags::WrapFlagsTy(/*NUW*/ false, NSW);
794 }
795
796 return VPIRFlags::WrapFlagsTy(false, false);
797}
798
799std::optional<MemoryLocation>
801 auto *M = dyn_cast<VPIRMetadata>(&R);
802 if (!M)
803 return std::nullopt;
805 // Populate noalias metadata from VPIRMetadata.
806 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
807 Loc.AATags.NoAlias = NoAliasMD;
808 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
809 Loc.AATags.Scope = AliasScopeMD;
810 return Loc;
811}
812
814 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
815 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
816 assert(CanIV && "Expected loop region to have a canonical IV");
817
818 VPSymbolicValue &VFxUF = Plan.getVFxUF();
819
820 // Check if \p Step matches the expected increment step, accounting for
821 // materialization of VFxUF and UF.
822 auto IsIncrementStep = [&](VPValue *Step) -> bool {
823 if (!VFxUF.isMaterialized())
824 return Step == &VFxUF;
825
826 VPSymbolicValue &UF = Plan.getUF();
827 if (!UF.isMaterialized())
828 return Step == &UF ||
829 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
830
831 // Alias masking: step is number of active lanes of a dependence mask.
832 if (match(Step, m_ZExtOrTruncOrSelf(
834 return true;
835
836 unsigned ConcreteUF = Plan.getConcreteUF();
837 // Fixed VF: step is just the concrete UF.
838 if (match(Step, m_SpecificInt(ConcreteUF)))
839 return true;
840
841 // Scalable VF: step involves VScale.
842 if (ConcreteUF == 1)
843 return match(Step, m_VScale());
844 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
845 return true;
846 // mul(VScale, ConcreteUF) may have been simplified to
847 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
848 return isPowerOf2_32(ConcreteUF) &&
849 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
850 };
851
852 VPInstruction *Increment = nullptr;
853 for (VPUser *U : CanIV->users()) {
854 VPValue *Step;
855 if (isa<VPInstruction>(U) &&
856 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
857 IsIncrementStep(Step)) {
858 assert(!Increment && "There must be a unique increment");
860 }
861 }
862
863 assert((!VFxUF.isMaterialized() || Increment) &&
864 "After materializing VFxUF, an increment must exist");
865 assert((!Increment ||
866 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
867 "NUW flag in region and increment must match");
868 return Increment;
869}
870
871/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
872/// inserted for predicated reductions or tail folding.
874 VPValue *BackedgeVal = PhiR->getBackedgeValue();
875 if (auto *Res =
877 return Res;
878
879 // Look through selects inserted for tail folding or predicated reductions.
881 BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
882 if (!SelR)
883 return nullptr;
885}
886
889 SmallVector<const VPValue *> WorkList = {V};
890
891 while (!WorkList.empty()) {
892 const VPValue *Cur = WorkList.pop_back_val();
893 if (!Seen.insert(Cur).second)
894 continue;
895
896 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
897 // Skip blends that use V only through a compare by checking if any incoming
898 // value was already visited.
899 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
900 [&](unsigned I) {
901 return Seen.contains(Blend->getIncomingValue(I));
902 }))
903 continue;
904
905 for (VPUser *U : Cur->users()) {
906 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
907 if (InterleaveR->getAddr() == Cur)
908 return true;
909 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
910 // store (operand 1).
913 m_Specific(Cur)))))
914 return true;
916 if (MemR->getAddr() == Cur && MemR->isConsecutive())
917 return true;
918 }
919 }
920
921 // The legacy cost model only supports scalarization loads/stores with phi
922 // addresses, if the phi is directly used as load/store address. Don't
923 // traverse further for Blends and first-order recurrence splices.
924 if (Blend ||
925 match(Cur,
927 continue;
928
929 // Only traverse further through users that also define a value (and can
930 // thus have their own users walked). Skip when Cur is only used as mask ,
931 // as well as loads: a loaded value does not depend on the load's operand.
932 for (VPUser *U : Cur->users()) {
933 auto *VPI = dyn_cast<VPInstruction>(U);
934 if (VPI && VPI->getMask() == Cur &&
935 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
936 continue;
938 continue;
939 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
940 WorkList.push_back(SDR);
941 }
942 }
943 return false;
944}
945
946/// Try to find a loop-invariant IR value for \p S in the plan's entry block
947/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
948/// if no reusable IR value is found.
949VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
951 return nullptr;
952 VPlan &Plan = Builder.getPlan();
953 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
954 for (Value *V : SE.getSCEVValues(S)) {
955 // Only reuse instructions in the plan's entry block, or, when a
956 // DominatorTree is available, any instruction that dominates it.
957 // Instructions in sibling branches may not dominate the entry block.
958 auto *I = dyn_cast<Instruction>(V);
959 if (!I)
960 return Plan.getOrAddLiveIn(V);
961 if (!SE.DT.dominates(I->getParent(), PH))
962 continue;
963 Loop *IL = SE.LI.getLoopFor(I->getParent());
964 if (IL && !IL->contains(PH))
965 continue;
966 SmallVector<Instruction *> DropPoisonGeneratingInsts;
967 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
968 continue;
969 for (Instruction *DropI : DropPoisonGeneratingInsts)
971 return Plan.getOrAddLiveIn(V);
972 }
973 return nullptr;
974}
975
976bool VPSCEVExpander::canExpandInIR(const SCEV *S) {
977 return HoistOutOf && !SafeUDivMode && SE.isLoopInvariant(S, HoistOutOf) &&
978 SE.isGuaranteedNotToCauseUB(S);
979}
980
981/// Returns the sums of the operands of \p S invariant in \p L and of the
982/// remaining operands, if there are at least 2 invariant and 1 variant
983/// operands.
984static std::pair<const SCEV *, const SCEV *>
986 if (!L)
987 return {nullptr, nullptr};
988 SmallVector<SCEVUse> InvOps, VarOps;
989 for (SCEVUse Op : S->operands())
990 (SE.isLoopInvariant(Op, L) ? InvOps : VarOps).push_back(Op);
991 if (InvOps.size() < 2 || VarOps.empty())
992 return {nullptr, nullptr};
993 return {SE.getAddExpr(InvOps), SE.getAddExpr(VarOps)};
994}
995
996VPValue *VPSCEVExpander::expandAsPtrAdd(const SCEVNAryExpr *S) {
997 const SCEV *Base = SE.getPointerBase(S);
998 const SCEV *Offset = SE.removePointerBase(S);
999 // If the pointer is invariant in HoistOutOf, use the sum of all invariant
1000 // operands as base, so it is hoisted whole.
1001 if (auto *AddE = dyn_cast<SCEVAddExpr>(S)) {
1002 auto [InvS, VarS] = splitInvariantSum(AddE, HoistOutOf, SE);
1003 if (InvS && InvS->getType()->isPointerTy() && canExpandInIR(InvS))
1004 std::tie(Base, Offset) = std::tie(InvS, VarS);
1005 }
1006 GEPNoWrapFlags GEPFlags = S->hasNoUnsignedWrap()
1008 : GEPNoWrapFlags::none();
1009 VPValue *BaseV = expand(Base);
1010 VPValue *OffsetV = expand(Offset);
1011 return Builder.createNoWrapPtrAdd(BaseV, OffsetV, GEPFlags, DL);
1012}
1013
1014VPValue *VPSCEVExpander::expandAddOps(ArrayRef<const SCEV *> Operands,
1015 VPIRFlags::WrapFlagsTy WrapFlags) {
1016 // Non-constant-negative add operands are expanded negated and subtracted
1017 // from the running result below, instead of being negated and added.
1018 auto UseSubtract = [](const SCEV *Op) { return Op->isNonConstantNegative(); };
1019 // Move the subtracted operands last, matching SCEVExpander's LoopCompare, so
1020 // that they don't start the running result.
1022 stable_sort(SCEVOps, [&](const SCEV *L, const SCEV *R) {
1023 return !UseSubtract(L) && UseSubtract(R);
1024 });
1026 for (const SCEV *Op : SCEVOps) {
1027 // The first operand starts the result, so it is never subtracted.
1028 bool Negate = !Ops.empty() && UseSubtract(Op);
1029 Ops.push_back(expand(Negate ? SE.getNegativeSCEV(Op) : Op));
1030 }
1031 VPValue *Result = Ops.front();
1032 for (auto [Op, OpV] : drop_begin(zip_equal(SCEVOps, Ops))) {
1033 if (UseSubtract(Op)) {
1034 // Result + (-Op) == Result - Op, which saves the multiply for the
1035 // negation. NSW only transfers if negating Op cannot overflow, see
1036 // ScalarEvolution::getMinusSCEV.
1037 bool HasNSW =
1038 WrapFlags.HasNSW && !SE.getSignedRangeMin(Op).isMinSignedValue();
1039 Result = Builder.createOverflowingOp(Instruction::Sub, {Result, OpV},
1040 {/*HasNUW=*/false, HasNSW}, DL);
1041 continue;
1042 }
1043 Result = Builder.createOverflowingOp(Instruction::Add, {Result, OpV},
1044 WrapFlags, DL);
1045 }
1046 return Result;
1047}
1048
1049#ifndef NDEBUG
1050/// Returns true if \p V dominates the insert point of \p Builder.
1051static bool dominatesInsertPoint(const VPValue *V, const VPBuilder &Builder) {
1052 const VPRecipeBase *R = V->getDefiningRecipe();
1053 if (!R)
1054 return true;
1055 VPDominatorTree VPDT(Builder.getPlan());
1056 if (VPRecipeBase *InsertPt = Builder.getRecipeAtInsertPoint())
1057 return VPDT.properlyDominates(R, InsertPt);
1058 return VPDT.dominates(R->getParent(), Builder.getInsertBlock());
1059}
1060#endif
1061
1064 if (VPValue *V = InsertedExpressions.lookup(Key)) {
1065 assert(dominatesInsertPoint(V, Builder) &&
1066 "reused expansion must dominate the insert point");
1067 return V;
1068 }
1069 VPValue *V = expandImpl(S);
1070 InsertedExpressions[Key] = V;
1071 return V;
1072}
1073
1074VPValue *VPSCEVExpander::expandImpl(const SCEV *S) {
1075 if (VPValue *V = tryToReuseIRValue(S))
1076 return V;
1077
1078 if (canExpandInIR(S))
1079 return vputils::getOrCreateVPValueForSCEVExpr(Builder.getPlan(), S,
1080 /*ExpandInIR=*/true);
1081
1082 switch (S->getSCEVType()) {
1083 case scConstant:
1084 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
1085 case scUnknown:
1086 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
1087 case scVScale:
1088 return Builder.createVScale(S->getType(), DL);
1089 case scAddExpr: {
1090 auto *AddE = cast<SCEVAddExpr>(S);
1091 VPIRFlags::WrapFlagsTy WrapFlags(AddE->hasNoUnsignedWrap(),
1092 AddE->hasNoSignedWrap());
1093
1094 // Expand pointer SCEVAddExpr as a ptradd of the pointer base and the
1095 // integer offset, matching SCEVExpander.
1096 if (S->getType()->isPointerTy())
1097 return expandAsPtrAdd(AddE);
1098
1099 // Iterate in reverse so that constants are emitted last.
1100 SmallVector<const SCEV *, 2> SCEVOps(reverse(AddE->operands()));
1101 // Sum the invariant operands separately, so the sum can be hoisted.
1102 auto [InvS, VarS] = splitInvariantSum(AddE, HoistOutOf, SE);
1103 if (InvS && canExpandInIR(InvS))
1104 SCEVOps = {InvS, VarS};
1105 return expandAddOps(SCEVOps, WrapFlags);
1106 }
1107 case scMulExpr: {
1108 auto *MulE = cast<SCEVMulExpr>(S);
1109 VPIRFlags::WrapFlagsTy WrapFlags(MulE->hasNoUnsignedWrap(),
1110 MulE->hasNoSignedWrap());
1112 for (const SCEV *Op : reverse(MulE->operands()))
1113 Ops.push_back(expand(Op));
1114 VPValue *Result = Ops.front();
1115 for (VPValue *OpV : drop_begin(Ops)) {
1116 Result = Builder.createOverflowingOp(Instruction::Mul, {Result, OpV},
1117 WrapFlags, DL);
1118 }
1119 return Result;
1120 }
1121 case scUDivExpr: {
1122 auto *UDiv = cast<SCEVUDivExpr>(S);
1123 VPValue *LHS = expand(UDiv->getLHS());
1124 const SCEV *RHSExpr = UDiv->getRHS();
1125 VPValue *RHS = expand(RHSExpr);
1126 if (SafeUDivMode) {
1127 // Make sure the UDiv's divisor is guaranteed to not be zero/poison, to
1128 // avoid UB.
1129 Type *Ty = UDiv->getType();
1130 bool GuaranteedNotPoison =
1132 if (!GuaranteedNotPoison)
1133 RHS = Builder.createFreeze(RHS, DL);
1134 if (!SE.isKnownNonZero(RHSExpr) || !GuaranteedNotPoison)
1135 RHS = Builder.createScalarIntrinsic(
1136 Intrinsic::umax, {RHS, Builder.getPlan().getConstantInt(Ty, 1)}, Ty,
1137 DL);
1138 }
1139 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
1140 VPIRFlags::getDefaultFlags(Instruction::UDiv),
1141 DL);
1142 }
1143 case scTruncate:
1144 case scZeroExtend:
1145 case scSignExtend:
1146 case scPtrToAddr: {
1147 auto *Cast = cast<SCEVCastExpr>(S);
1148 VPValue *Op = expand(Cast->getOperand());
1149 Instruction::CastOps Opcode;
1150 switch (S->getSCEVType()) {
1151 case scTruncate:
1152 Opcode = Instruction::Trunc;
1153 break;
1154 case scZeroExtend:
1155 Opcode = Instruction::ZExt;
1156 break;
1157 case scSignExtend:
1158 Opcode = Instruction::SExt;
1159 break;
1160 case scPtrToAddr:
1161 Opcode = Instruction::PtrToAddr;
1162 break;
1163 default:
1164 llvm_unreachable("Unhandled cast SCEV");
1165 }
1166
1167 // For ptrtoaddr of an IR value, reuse an existing cast dominating the
1168 // entry if there is one. Otherwise leave it to SCEVExpander, which places
1169 // the cast right after the IR value's definition, so all users can share
1170 // it.
1171 if (Opcode == Instruction::PtrToAddr) {
1172 VPlan &Plan = Builder.getPlan();
1173 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1174 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
1176 IRV->getValue(), S->getType(), PH->getDataLayout(),
1177 [&](const CastInst *CI) {
1178 return SE.DT.dominates(CI->getParent(), PH);
1179 }))
1180 return Plan.getOrAddLiveIn(CI);
1182 }
1183 }
1184
1185 std::optional<VPIRFlags> Flags;
1186 if (Opcode == Instruction::ZExt)
1187 Flags =
1188 VPIRFlags::NonNegFlagsTy(SE.isKnownNonNegative(Cast->getOperand()));
1189
1190 return Builder.createScalarCast(Opcode, Op, S->getType(), DL, Flags);
1191 }
1192 case scUMaxExpr:
1193 case scSMaxExpr:
1194 case scUMinExpr:
1195 case scSMinExpr:
1196 case scSequentialUMinExpr: {
1197 auto *MinMax = cast<SCEVNAryExpr>(S);
1198 Intrinsic::ID IntrinsicID;
1199 switch (S->getSCEVType()) {
1200 case scUMaxExpr:
1201 IntrinsicID = Intrinsic::umax;
1202 break;
1203 case scSMaxExpr:
1204 IntrinsicID = Intrinsic::smax;
1205 break;
1206 case scUMinExpr:
1208 IntrinsicID = Intrinsic::umin;
1209 break;
1210 case scSMinExpr:
1211 IntrinsicID = Intrinsic::smin;
1212 break;
1213 default:
1214 llvm_unreachable("Unexpected min/max SCEV type");
1215 }
1216 // Chain operands in reverse order matching SCEVExpander's expansion of
1217 // min/max expressions. In SafeUDivMode freeze expansion results of operands
1218 // other than the first for sequential UMins, to avoid short-circuiting
1219 // divide-by-0/poison.
1220 bool IsSequential = S->getSCEVType() == scSequentialUMinExpr;
1221 Type *ResultTy = MinMax->getType();
1222 bool PrevSafeMode = SafeUDivMode;
1224 for (const SCEV *SCEVOp : reverse(MinMax->operands())) {
1225 bool MayShortCircuit =
1226 IsSequential && Ops.size() != MinMax->getNumOperands() - 1;
1227 SafeUDivMode = MayShortCircuit || PrevSafeMode;
1228 VPValue *OpV = expand(SCEVOp);
1229 SafeUDivMode = PrevSafeMode;
1230 if (MayShortCircuit)
1231 OpV = Builder.createFreeze(OpV, DL);
1232 Ops.push_back(OpV);
1233 }
1234 VPValue *Result = Ops.front();
1235 for (VPValue *Op : drop_begin(Ops)) {
1236 if (!ResultTy->isPointerTy()) {
1237 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
1238 ResultTy, DL);
1239 continue;
1240 }
1241 // The min/max intrinsics don't support pointer operands, so expand
1242 // pointer-typed min/max as cmp + select, matching SCEVExpander.
1243 VPValue *Cmp = Builder.createICmp(
1244 MinMaxIntrinsic::getPredicate(IntrinsicID), Result, Op, DL);
1245 Result = Builder.createSelect(Cmp, Result, Op, DL);
1246 Function &F = *Builder.getPlan().getIRFunction();
1247 if (MDNode *MD =
1249 cast<VPInstruction>(Result)->setMetadata(LLVMContext::MD_prof, MD);
1250 }
1251 return Result;
1252 }
1253 case scAddRecExpr: {
1254 auto *AR = cast<SCEVAddRecExpr>(S);
1255 VPlan &Plan = Builder.getPlan();
1256 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
1257 assert(SE.DT.dominates(AR->getLoop()->getHeader(), PH) &&
1258 "can only expand AddRecs for loops outside VPlan's scope");
1259
1260 Type *Ty = AR->getType();
1261 if (auto [LCSSAPhi, Diff] = SCEVExpander::findReusableLCSSAPhi(SE, AR, PH);
1262 LCSSAPhi) {
1263 VPValue *DiffV = expand(Diff);
1264 VPValue *BaseV = Plan.getOrAddLiveIn(LCSSAPhi);
1265 if (LCSSAPhi->getType()->isPointerTy()) {
1266 if (Ty->isPointerTy())
1267 return Builder.createPtrAdd(BaseV, DiffV, DL);
1268 BaseV = Builder.createScalarCast(Instruction::PtrToAddr, BaseV, Ty, DL);
1269 }
1270 return Builder.createAdd(BaseV, DiffV, DL);
1271 }
1272
1273 // Mirror SCEVExpander::visitAddRecExpr, but only expand the canonical IV
1274 // {0,+,1} and non-affine AddRecs to IR (which will be created outside the
1275 // scope of VPlan). The AddRec is then scaled and offset using
1276 // VPInstructions.
1277 const Loop *L = AR->getLoop();
1278 auto m_scev_CanonicalIV = // NOLINT
1280 if (!AR->isAffine() || match(AR, m_scev_CanonicalIV))
1282
1283 const SCEV *Step = AR->getStepRecurrence(SE);
1284 // {0,+,F} --> {0,+,1} * F
1285 if (AR->getStart()->isZero()) {
1286 const SCEV *CanIV =
1287 SE.getAddRecExpr(SE.getZero(Ty), SE.getOne(Ty), L, SCEV::FlagNone);
1288 return Builder.createOverflowingOp(
1289 Instruction::Mul, {expand(CanIV), expand(Step)},
1290 {SE.willNotOverflow(Instruction::Mul, /*Signed=*/false, CanIV, Step),
1291 SE.willNotOverflow(Instruction::Mul, /*Signed=*/true, CanIV, Step)},
1292 DL);
1293 }
1294
1295 // {X,+,F} --> X + {0,+,F}
1296 if (Ty->isPointerTy())
1297 return expandAsPtrAdd(AR);
1298 VPValue *Start = expand(AR->getStart());
1299 VPValue *Rest = expand(SE.getAddRecExpr(SE.getZero(Ty), Step, L,
1300 AR->getNoWrapFlags(SCEV::FlagNW)));
1301 return Builder.createAdd(Start, Rest, DL, "",
1302 {AR->hasNoUnsignedWrap(), false});
1303 }
1304 case scCouldNotCompute:
1305 llvm_unreachable("Attempt to expand a SCEVCouldNotCompute");
1306 }
1307 llvm_unreachable("Unknown SCEV kind!");
1308}
1309
1311 // Do remove conditional assume instructions as their conditions may be
1312 // flattened.
1313 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1314 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1316 if (IsConditionalAssume)
1317 return true;
1318
1319 if (R.mayHaveSideEffects())
1320 return false;
1321
1322 // Forbid removing trip-count expressions.
1323 if (isa<VPExpandSCEVRecipe>(R) &&
1324 R.getVPSingleValue() == R.getParent()->getPlan()->getTripCount())
1325 return false;
1326
1327 // Recipe is dead if no user keeps the recipe alive.
1328 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1329}
1330
1332 SmallVector<VPValue *> WorkList;
1334 WorkList.push_back(V);
1335
1336 while (!WorkList.empty()) {
1337 VPValue *Cur = WorkList.pop_back_val();
1338 if (!Seen.insert(Cur).second)
1339 continue;
1340 VPRecipeBase *R = Cur->getDefiningRecipe();
1341 if (!R)
1342 continue;
1343 if (!isDeadRecipe(*R))
1344 continue;
1345 append_range(WorkList, R->operands());
1346 R->eraseFromParent();
1347 }
1348}
1349
1352 for (unsigned I = 0; I != Users.size(); ++I) {
1354 for (VPValue *V : Cur->definedValues())
1355 Users.insert_range(V->users());
1356 }
1357 return Users.takeVector();
1358}
1359
1360/// Returns \p Num / \p Denom as a BranchProbability, clamped so a ratio that is
1361/// neither zero nor one does not round to zero or one. BlockFrequencyInfo also
1362/// keeps a zero-weight edge distinguishable from an unreachable one.
1364 uint64_t Denom) {
1366 if (Num == 0 || Num == Denom)
1367 return P;
1368 return BranchProbability::getRaw(std::clamp(
1369 P.getNumerator(), 1u, BranchProbability::getDenominator() - 1));
1370}
1371
1377
1378/// Returns the probability of each successor edge of \p VPBB, computed via
1379/// BranchProbabilityInfo::getEdgeProbabilitiesFromWeights from the branch
1380/// weights recorded on its terminator, or std::nullopt if not available.
1381static std::optional<SmallVector<BranchProbability>>
1383 // With a single successor the edge is always taken and needs no weights.
1384 if (VPBB->getSingleSuccessor())
1386
1387 SmallVector<uint32_t> Weights;
1389 if (!Term || !extractBranchWeights(Term->getBranchWeights(), Weights) ||
1390 Weights.size() != VPBB->getNumSuccessors())
1391 return std::nullopt;
1393}
1394
1397 using BFIBase = BlockFrequencyInfoImplBase;
1398 assert(!Blocks.empty() && "expected at least the header block");
1399 // Distribute the header's frequency using BFI. Nodes for blocks are numbered
1400 // in reverse post-order. Edges leaving Blocks, i.e. a plain CFG's edges to
1401 // the middle block or to an exit block, exit to a node outside the loop.
1402 BFIBase BFI;
1403 BFIBase::BlockNode Header(0), Outside(Blocks.size());
1404 BFIBase::LoopData &Loop = BFI.Loops.emplace_back(nullptr, Header);
1406 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1407 Nodes[VPBB] = BFIBase::BlockNode(Idx);
1408 BFI.Working.emplace_back(BFIBase::BlockNode(Idx)).Loop = &Loop;
1409 }
1410 BFI.Working.emplace_back(Outside);
1411 BFI.Working[Header.Index].getMass() = BFIBase::BlockMass::getFull();
1412
1413 // Keep track nodes reached via an edge without branch weighs or with
1414 // estimated ones
1415 SmallVector<bool> IsUnknown(Blocks.size()), IsEstimated(Blocks.size());
1416 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1417 BFIBase::BlockNode Node(Idx);
1418 auto Probs = getSuccessorProbabilities(VPBB);
1419 auto *Term = dyn_cast_if_present<VPInstruction>(VPBB->getTerminator());
1420 bool TermIsEstimated = Term && Term->hasEstimatedBranchWeights();
1421 BFIBase::Distribution Dist;
1422 for (auto [SuccIdx, Succ] : enumerate(VPBB->getSuccessors())) {
1423 BFIBase::BlockNode SuccNode = Nodes.lookup_or(Succ, Outside);
1424 if (SuccNode != Header && SuccNode != Outside) {
1425 IsUnknown[SuccNode.Index] |= IsUnknown[Idx] || !Probs;
1426 IsEstimated[SuccNode.Index] |= IsEstimated[Idx] || TermIsEstimated;
1427 }
1428 if (Probs)
1429 BFI.addToDist(Dist, &Loop, Node, SuccNode,
1430 getWeightFromBranchProb((*Probs)[SuccIdx]));
1431 }
1432 if (Probs)
1433 BFI.distributeMass(Node, &Loop, Dist);
1434 }
1435
1436 // Round frequencies up to at least 1, so all edges are reached with a
1437 // non-zero frequency, to distinguish rarely executed blocks from unreachable
1438 // ones. blocks distinguishable from unreachable ones.
1440 Frequencies;
1441 for (auto [Idx, VPBB] : enumerate(Blocks)) {
1442 std::optional<VPExecutionFrequency> &Freq = Frequencies[VPBB];
1443 if (IsUnknown[Idx])
1444 continue;
1445 uint64_t Mass = BFI.Working[Idx].getMass().getMass();
1446 Freq.emplace(BlockFrequency(std::max<uint64_t>(Mass, 1)), IsEstimated[Idx]);
1447 }
1448 return Frequencies;
1449}
1450
1453 const DataLayout &DL) {
1454 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1455 if (!OpcodeOrIID)
1456 return nullptr;
1457
1459 for (VPValue *Op : Operands) {
1460 VPValue *Candidate = Op;
1461 match(Op, m_Broadcast(m_VPValue(Candidate)));
1462 if (!match(Candidate, m_LiveIn()))
1463 return nullptr;
1464 Value *V = Candidate->getUnderlyingValue();
1465 if (!V)
1466 return nullptr;
1467 Ops.push_back(V);
1468 }
1469
1470 VPlan &Plan = *R.getParent()->getPlan();
1471 auto FoldToIRValue = [&]() -> Value * {
1472 InstSimplifyFolder Folder(DL);
1473 if (OpcodeOrIID->first) {
1474 // VPInstructions store the called intrinsic as last operand.
1475 if (isa<VPInstruction>(R))
1476 Ops.pop_back();
1477
1478 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1479 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1480 RFlags ? RFlags->getFastMathFlagsOrNone()
1481 : FastMathFlags());
1482 }
1483 unsigned Opcode = OpcodeOrIID->second;
1484 if (Instruction::isBinaryOp(Opcode))
1485 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1486 Ops[0], Ops[1]);
1487 if (Instruction::isCast(Opcode))
1488 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1489 R.getVPSingleValue()->getScalarType());
1490 switch (Opcode) {
1491 case VPInstruction::Not:
1492 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1494 case Instruction::Select:
1495 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1496 case Instruction::ICmp:
1497 case Instruction::FCmp:
1498 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1499 Ops[1]);
1500 case Instruction::GetElementPtr: {
1501 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1502 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1503 return Folder.FoldGEP(DL, GEP->getSourceElementType(), Ops[0],
1504 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1505 }
1508 return Folder.FoldGEP(DL, IntegerType::getInt8Ty(Plan.getContext()),
1509 Ops[0], Ops[1],
1510 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1511 // An extract of a live-in is an extract of a broadcast, so return the
1512 // broadcasted element.
1513 case Instruction::ExtractElement:
1514 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1515 return Ops[0];
1518 uint64_t Multiplier = 1;
1519 if (Opcode == VPInstruction::WideActiveLaneMask) {
1520 // Optimizing WideALM can only happen after the Plan is unrolled.
1521 if (!Plan.isUnrolled())
1522 return nullptr;
1523
1524 Multiplier = cast<ConstantInt>(Ops[2])->getZExtValue();
1525
1526 // TODO: We can't fold if any users expect require a wide value.
1527 if (Multiplier != 1 &&
1528 !all_of(R.users(), match_fn(m_ExtractVectorForPart())))
1529 return nullptr;
1530
1531 Ops.pop_back();
1532 }
1533
1534 // We rely on the fact that different VPlans are created for the
1535 // fixed-vector and scalable-vector cases.
1536 ElementCount MaxVF =
1538 Multiplier;
1539
1540 Type *I1Ty = IntegerType::getInt1Ty(Plan.getContext());
1541 if (auto *C = dyn_cast_if_present<Constant>(Folder.FoldIntrinsic(
1542 Intrinsic::get_active_lane_mask, Ops,
1543 VectorType::get(I1Ty, MaxVF), {}, Plan.getIRFunction()))) {
1544 // We cannot handle vector constants that are not all-true or all-false,
1545 // because they would not be collapsable to a scalar constant, that
1546 // would be necessary for live-in simplification.
1547 if (C->isOneValue())
1548 return ConstantInt::getTrue(I1Ty);
1549 if (C->isNullValue())
1550 return ConstantInt::getFalse(I1Ty);
1551 }
1552 }
1553 }
1554 return nullptr;
1555 };
1556
1557 if (Value *V = FoldToIRValue())
1558 return Plan.getOrAddLiveIn(V);
1559 return nullptr;
1560}
1561
1563 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1566 vp_depth_first_deep(Plan.getEntry()))) {
1567 for (VPSingleDefRecipe &Def :
1569 if (!isElementwise(&Def))
1570 continue;
1571
1572 // At least one of the ops must be a permutation.
1573 if (none_of(Def.operands(), MatchPerm))
1574 continue;
1575
1576 // All operands must be a single-use permutation or a live in (splat).
1577 if (!all_of(Def.operands(), [&MatchPerm](VPValue *Op) {
1578 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1579 }))
1580 continue;
1581
1582 // Remove the inner permutations.
1583 for (unsigned I = 0, E = Def.getNumOperands(); I != E; ++I)
1584 if (VPValue *X = MatchPerm(Def.getOperand(I)))
1585 Def.setOperand(I, X);
1586
1587 VPSingleDefRecipe *Res = BuildPerm(&Def);
1588 Res->insertAfter(&Def);
1589 Def.replaceUsesWithIf(Res, not_equal_to(Res));
1590 }
1591 }
1592}
1593
1594// Implements the algorithm described in "Simple and Efficient Construction of
1595// Static Single Assignment Form" by Braun et al.
1598 assert(!Defs.empty() && "Defs shouldn't be empty");
1599 assert(
1601 "VPBB isn't reachable from entry");
1602 if (VPValue *Def = Defs.lookup(VPBB))
1603 return Def;
1604 // If the entry block is reached and there's still no def, then Defs is
1605 // missing a definition that covers this path.
1606 assert(VPBB->getNumPredecessors() && "Not all paths have def");
1607
1608 if (VPBlockBase *Pred = VPBB->getSinglePredecessor())
1609 return reconstructSSA(cast<VPBasicBlock>(Pred), Defs);
1610
1611 // Multiple predecessors, create a join.
1612 Type *Ty = Defs.begin()->second->getScalarType();
1613 VPPhi *Phi = VPBuilder(VPBB->getFirstNonPhi())
1614 .createScalarPhi({}, DebugLoc::getUnknown(), "", {}, Ty);
1615 Defs[VPBB] = Phi;
1616 for (auto *Pred : VPBB->predecessors())
1617 Phi->addIncoming(reconstructSSA(cast<VPBasicBlock>(Pred), Defs));
1618
1619 // Fold away trivial phis.
1620 // TODO: Remove phi users which have become trivial too.
1621 if (all_equal(Phi->incoming_values())) {
1622 VPValue *Common = Phi->getIncomingValue(0);
1623 Phi->replaceAllUsesWith(Common);
1624 for (auto &[_, V] : Defs)
1625 if (V == Phi)
1626 V = Common;
1627 Defs[VPBB] = Common;
1628 Phi->eraseFromParent();
1629 return Common;
1630 }
1631
1632 return Phi;
1633}
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:665
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 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.
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 bool dominatesInsertPoint(const VPValue *V, const VPBuilder &Builder)
Returns true if V dominates the insert point of Builder.
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 std::pair< const SCEV *, const SCEV * > splitInvariantSum(const SCEVAddExpr *S, const Loop *L, ScalarEvolution &SE)
Returns the sums of the operands of S invariant in L and of the remaining operands,...
static bool isUniformAcrossVFsAndUFsImpl(const VPValue *V, function_ref< void(VPUser::const_operand_range)> AddToWorklist)
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 ...
Value * RHS
Value * LHS
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)
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
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.
ICmpInst::Predicate getPredicate() const
Returns the comparison predicate underlying the intrinsic.
PointerIntPair - This class implements a pair of a pointer and small integer.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getPredicatedSCEV(const SCEV *Expr)
Returns the rewritten SCEV for Expr in the context of the current SCEV predicate.
This node represents an addition of some number of SCEVs.
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.
ArrayRef< SCEVUse > operands() const
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
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
void insert_range(Range &&R)
Definition SetVector.h:182
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
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.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:346
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:4533
iterator end()
Definition VPlan.h:4574
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:608
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:183
VPBlockBase * getSingleHierarchicalPredecessor()
Definition VPlan.h:269
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:453
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.
A recipe for handling scalar conditional induction PHIs.
Definition VPlan.h:2997
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:4303
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
LLVM_ABI_FOR_TEST bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B) const
Recipe to expand a SCEV expression.
Definition VPlan.h:4127
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2530
VPValue * getStartValue()
Returns the start value of the phi, if one is set.
Definition VPlan.h:2519
A special type of VPBasicBlock that wraps an existing IR basic block.
Definition VPlan.h:4692
Class to record and manage LLVM IR flags.
Definition VPlan.h:683
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:1322
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1423
unsigned getOpcode() const
Definition VPlan.h:1525
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.
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
Definition VPlan.h:3810
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:402
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:547
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:2890
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4764
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4840
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4928
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4884
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:3495
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:4364
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:605
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
iterator_range< const_operand_iterator > const_operand_range
Definition VPlanValue.h:466
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
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:2317
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2399
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1899
A recipe for handling GEP instructions.
Definition VPlan.h:2257
VPValue * getStepValue()
Returns the step value of the induction.
Definition VPlan.h:2597
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2643
A recipe for widened phis.
Definition VPlan.h:2777
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1832
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4951
LLVMContext & getContext() const
Definition VPlan.h:5148
VPBasicBlock * getEntry()
Definition VPlan.h:5043
iterator_range< SmallSetVector< ElementCount, 2 >::iterator > vectorFactors() const
Returns an iterator range over all VFs of the plan.
Definition VPlan.h:5181
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:5146
ArrayRef< VPIRBasicBlock * > getExitBlocks() const
Return an ArrayRef containing VPIRBasicBlocks wrapping the exit blocks of the original scalar loop.
Definition VPlan.h:5109
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:5224
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5250
bool isUnrolled() const
Returns true if the VPlan already has been unrolled, i.e.
Definition VPlan.h:5215
Function * getIRFunction() const
Definition VPlan.h:5156
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1066
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5202
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:5048
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:5143
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:5099
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:5139
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.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
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.
RecipeTy * findSingleUser(VPValue *V, const MatchT &P)
Return the sole user of V matching pattern P, casting it to RecipeTy, or nullptr.
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::Broadcast, Op0_t > m_Broadcast(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
VPInstruction_match< VPInstruction::ExtractVectorForPart, Op_t... > m_ExtractVectorForPart(const Op_t &...Op)
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...
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 by all users.
Intrinsic::ID getIntrinsicID(const Ty *R)
Return the intrinsic ID underlying a call.
Definition VPlanUtils.h:98
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 by all users.
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...
bool propagatesFirstLaneUse(const VPUser *U, const VPValue *Op)
Returns true if checking whether U uses the first lane of Op requires recursively checking Op's users...
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.
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr, bool ExpandInIR=false)
Get or create a VPValue that corresponds to the expansion of Expr.
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:66
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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,...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
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
SCEVUseT< const SCEV * > SCEVUse
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:3965
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3910