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"
21#include "llvm/IR/Dominators.h"
23
24using namespace llvm;
25using namespace llvm::VPlanPatternMatch;
26using namespace llvm::SCEVPatternMatch;
27
29 return all_of(Def->users(),
30 [Def](const VPUser *U) { return U->usesFirstLaneOnly(Def); });
31}
32
34 return all_of(Def->users(),
35 [Def](const VPUser *U) { return U->usesFirstPartOnly(Def); });
36}
37
39 return all_of(Def->users(),
40 [Def](const VPUser *U) { return U->usesScalars(Def); });
41}
42
44 if (auto *E = dyn_cast<SCEVConstant>(Expr))
45 return Plan.getOrAddLiveIn(E->getValue());
46 // Skip SCEV expansion if Expr is a SCEVUnknown wrapping a non-instruction
47 // value. Otherwise the value may be defined in a loop and using it directly
48 // will break LCSSA form. The SCEV expansion takes care of preserving LCSSA
49 // form.
50 auto *U = dyn_cast<SCEVUnknown>(Expr);
51 if (U && !isa<Instruction>(U->getValue()))
52 return Plan.getOrAddLiveIn(U->getValue());
53 auto *Expanded = new VPExpandSCEVRecipe(Expr);
54 VPBasicBlock *EntryVPBB = Plan.getEntry();
55 auto Iter = EntryVPBB->getFirstNonPhi();
56 while (Iter != EntryVPBB->end() && isa<VPIRInstruction>(*Iter))
57 ++Iter;
58 EntryVPBB->insert(Expanded, Iter);
59 return Expanded;
60}
61
62/// Returns true if \p R propagates poison from any operand to its result.
66 [](const VPRecipeBase *) { return true; })
67 .Case([](const VPReplicateRecipe *Rep) {
68 // GEP and casts propagate poison from all operands.
69 unsigned Opcode = Rep->getOpcode();
70 return Opcode == Instruction::GetElementPtr ||
71 Instruction::isCast(Opcode);
72 })
73 .Default([](const VPRecipeBase *) { return false; });
74}
75
76/// Returns true if \p V being poison is guaranteed to trigger UB because it
77/// propagates to the address of a memory recipe.
78static bool poisonGuaranteesUB(const VPValue *V) {
81
82 Worklist.push_back(V);
83
84 while (!Worklist.empty()) {
85 const VPValue *Current = Worklist.pop_back_val();
86 if (!Visited.insert(Current).second)
87 continue;
88
89 for (VPUser *U : Current->users()) {
90 // Check if Current is used as an address operand for load/store.
92 if (MemR->getAddr() == Current)
93 return true;
94 continue;
95 }
96 if (auto *Rep = dyn_cast<VPReplicateRecipe>(U)) {
97 unsigned Opcode = Rep->getOpcode();
98 if ((Opcode == Instruction::Load && Rep->getOperand(0) == Current) ||
99 (Opcode == Instruction::Store && Rep->getOperand(1) == Current))
100 return true;
101 }
102
103 // Check if poison propagates through this recipe to any of its users.
104 auto *R = cast<VPRecipeBase>(U);
105 for (const VPValue *Op : R->operands()) {
106 if (Op == Current && propagatesPoisonFromRecipeOp(R)) {
107 Worklist.push_back(R->getVPSingleValue());
108 break;
109 }
110 }
111 }
112 }
113
114 return false;
115}
116
118 // Like IR stripPointerCasts, look through GEPs with all-zero indices and
119 // casts to find a root GEP VPInstruction.
120 while (auto *PtrVPI = dyn_cast<VPInstruction>(Ptr)) {
121 unsigned Opcode = PtrVPI->getOpcode();
122 if (Opcode == Instruction::GetElementPtr) {
123 if (!all_of(drop_begin(PtrVPI->operands()), match_fn(m_ZeroInt())))
124 return PtrVPI->getGEPNoWrapFlags();
125 Ptr = PtrVPI->getOperand(0);
126 continue;
127 }
128 if (Opcode != Instruction::BitCast && Opcode != Instruction::AddrSpaceCast)
129 break;
130 Ptr = PtrVPI->getOperand(0);
131 }
132 return GEPNoWrapFlags::none();
133}
134
137 const Loop *L) {
138 ScalarEvolution &SE = *PSE.getSE();
139 if (auto *RV = dyn_cast<VPRegionValue>(V)) {
140 assert(RV == RV->getDefiningRegion()->getCanonicalIV() &&
141 "RegionValue must be canonical IV");
142 if (!L)
143 return SE.getCouldNotCompute();
144 return SE.getAddRecExpr(SE.getZero(RV->getType()), SE.getOne(RV->getType()),
146 }
147
149 Value *LiveIn = V->getUnderlyingValue();
150 if (LiveIn && SE.isSCEVable(LiveIn->getType()))
151 return SE.getSCEV(LiveIn);
152 return SE.getCouldNotCompute();
153 }
154
155 // Helper to create SCEVs for binary and unary operations.
156 auto CreateSCEV = [&](ArrayRef<VPValue *> Ops,
157 function_ref<const SCEV *(ArrayRef<SCEVUse>)> CreateFn)
158 -> const SCEV * {
160 for (VPValue *Op : Ops) {
161 const SCEV *S = getSCEVExprForVPValue(Op, PSE, L);
163 return SE.getCouldNotCompute();
164 SCEVOps.push_back(S);
165 }
166 return PSE.getPredicatedSCEV(CreateFn(SCEVOps));
167 };
168
169 VPValue *LHSVal, *RHSVal;
170 if (match(V, m_Add(m_VPValue(LHSVal), m_VPValue(RHSVal))))
171 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
172 return SE.getAddExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
173 });
174 if (match(V, m_Sub(m_VPValue(LHSVal), m_VPValue(RHSVal))))
175 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
176 return SE.getMinusSCEV(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
177 });
178 if (match(V, m_Not(m_VPValue(LHSVal)))) {
179 // not X = xor X, -1 = -1 - X
180 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
181 return SE.getMinusSCEV(SE.getMinusOne(Ops[0]->getType()), Ops[0]);
182 });
183 }
184 if (match(V, m_Mul(m_VPValue(LHSVal), m_VPValue(RHSVal))))
185 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
186 return SE.getMulExpr(Ops[0], Ops[1], SCEV::FlagAnyWrap, 0);
187 });
188 // Handle shl by constant: x << c is equivalent to x * (1 << c). A shift
189 // amount >= the bit width produces poison; do not rewrite it, as
190 // getPowerOfTwo requires the power to be in range.
191 uint64_t ShiftAmt;
192 if (match(V, m_Shl(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt))) &&
193 ShiftAmt < LHSVal->getScalarType()->getScalarSizeInBits())
194 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
195 return SE.getMulExpr(Ops[0],
196 SE.getPowerOfTwo(Ops[0]->getType(), ShiftAmt));
197 });
198 if (match(V, m_LShr(m_VPValue(LHSVal), m_ConstantInt(ShiftAmt)))) {
199 Type *Ty = V->getScalarType();
200 if (ShiftAmt < SE.getTypeSizeInBits(Ty))
201 return CreateSCEV(LHSVal, [&](ArrayRef<SCEVUse> Ops) {
202 return SE.getUDivExpr(Ops[0], SE.getPowerOfTwo(Ty, ShiftAmt));
203 });
204 }
205 if (match(V, m_UDiv(m_VPValue(LHSVal), m_VPValue(RHSVal))))
206 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
207 return SE.getUDivExpr(Ops[0], Ops[1]);
208 });
209 if (match(V, m_URem(m_VPValue(LHSVal), m_VPValue(RHSVal))))
210 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
211 return SE.getURemExpr(Ops[0], Ops[1]);
212 });
213 // A SRem with non-negative operands is equivalent to an URem.
214 if (match(V, m_SRem(m_VPValue(LHSVal), m_VPValue(RHSVal)))) {
215 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
216 if (!SE.isKnownNonNegative(Ops[0]) || !SE.isKnownNonNegative(Ops[1]))
217 return SE.getCouldNotCompute();
218 return SE.getURemExpr(Ops[0], Ops[1]);
219 });
220 }
221 // Handle AND with constant mask: x & (2^n - 1) can be represented as x % 2^n.
222 const APInt *Mask;
223 if (match(V, m_c_BinaryAnd(m_VPValue(LHSVal), m_APInt(Mask))) &&
224 (*Mask + 1).isPowerOf2())
225 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
226 return SE.getURemExpr(Ops[0], SE.getConstant(*Mask + 1));
227 });
228 if (match(V, m_Trunc(m_VPValue(LHSVal)))) {
229 Type *DestTy = V->getScalarType();
230 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
231 return SE.getTruncateExpr(Ops[0], DestTy);
232 });
233 }
234 if (match(V, m_ZExt(m_VPValue(LHSVal)))) {
235 Type *DestTy = V->getScalarType();
236 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
237 return SE.getZeroExtendExpr(Ops[0], DestTy);
238 });
239 }
240 if (match(V, m_SExt(m_VPValue(LHSVal)))) {
241 Type *DestTy = V->getScalarType();
242
243 // Mirror SCEV's createSCEV handling for sext(sub nsw): push sign extension
244 // onto the operands before computing the subtraction.
245 VPValue *SubLHS, *SubRHS;
246 auto *SubR = dyn_cast<VPRecipeWithIRFlags>(LHSVal);
247 if (match(LHSVal, m_Sub(m_VPValue(SubLHS), m_VPValue(SubRHS))) && SubR &&
248 SubR->hasNoSignedWrap() && poisonGuaranteesUB(LHSVal)) {
249 const SCEV *V1 = getSCEVExprForVPValue(SubLHS, PSE, L);
250 const SCEV *V2 = getSCEVExprForVPValue(SubRHS, PSE, L);
252 return SE.getMinusSCEV(SE.getSignExtendExpr(V1, DestTy),
253 SE.getSignExtendExpr(V2, DestTy), SCEV::FlagNSW);
254 }
255
256 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
257 return SE.getSignExtendExpr(Ops[0], DestTy);
258 });
259 }
260 if (match(V,
262 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
263 return SE.getUMaxExpr(Ops[0], Ops[1]);
264 });
265 if (match(V,
267 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
268 return SE.getSMaxExpr(Ops[0], Ops[1]);
269 });
270 if (match(V,
272 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
273 return SE.getUMinExpr(Ops[0], Ops[1]);
274 });
275 if (match(V,
277 return CreateSCEV({LHSVal, RHSVal}, [&](ArrayRef<SCEVUse> Ops) {
278 return SE.getSMinExpr(Ops[0], Ops[1]);
279 });
281 return CreateSCEV({LHSVal}, [&](ArrayRef<SCEVUse> Ops) {
282 // is_int_min_poison is local to this intrinsic: poison on INT_MIN is
283 // not proof that the input is never INT_MIN, nor that poison reaches
284 // UB. Do not translate it to SCEV's global IsNSW flag.
285 return SE.getAbsExpr(Ops[0], /*IsNSW=*/false);
286 });
287
289 Type *SourceElementType;
290 if (match(V, m_GetElementPtr(SourceElementType, Ops))) {
291 return CreateSCEV(Ops, [&](ArrayRef<SCEVUse> Ops) {
292 return SE.getGEPExpr(Ops.front(), Ops.drop_front(), SourceElementType);
293 });
294 }
295
296 // TODO: Support constructing SCEVs for more recipes as needed.
297 const VPRecipeBase *DefR = V->getDefiningRecipe();
298 const SCEV *Expr =
300 .Case([](const VPExpandSCEVRecipe *R) { return R->getSCEV(); })
301 .Case([&SE, &PSE, L](const VPWidenIntOrFpInductionRecipe *R) {
302 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
303 if (!L || isa<SCEVCouldNotCompute>(Step))
304 return SE.getCouldNotCompute();
305 const SCEV *Start =
306 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
307 const SCEV *AddRec =
308 SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
309 if (R->getTruncInst())
310 return SE.getTruncateExpr(AddRec, R->getScalarType());
311 return AddRec;
312 })
313 .Case([&SE, &PSE, L](const VPWidenPointerInductionRecipe *R) {
314 const SCEV *Start =
315 getSCEVExprForVPValue(R->getStartValue(), PSE, L);
316 if (!L || isa<SCEVCouldNotCompute>(Start))
317 return SE.getCouldNotCompute();
318 const SCEV *Step = getSCEVExprForVPValue(R->getStepValue(), PSE, L);
319 if (isa<SCEVCouldNotCompute>(Step))
320 return SE.getCouldNotCompute();
321 return SE.getAddRecExpr(Start, Step, L, SCEV::FlagAnyWrap);
322 })
323 .Case([&SE, &PSE, L](const VPDerivedIVRecipe *R) {
324 const SCEV *Start = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
325 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
326 const SCEV *Scale = getSCEVExprForVPValue(R->getOperand(2), PSE, L);
327 if (any_of(ArrayRef({Start, IV, Scale}),
329 return SE.getCouldNotCompute();
330
331 return SE.getAddExpr(
332 SE.getTruncateOrSignExtend(Start, IV->getType()),
333 SE.getMulExpr(
334 IV, SE.getTruncateOrSignExtend(Scale, IV->getType())));
335 })
336 .Case([&SE, &PSE, L](const VPScalarIVStepsRecipe *R) {
337 const SCEV *IV = getSCEVExprForVPValue(R->getOperand(0), PSE, L);
338 const SCEV *Step = getSCEVExprForVPValue(R->getOperand(1), PSE, L);
340 return SE.getCouldNotCompute();
341 return SE.getTruncateOrSignExtend(IV, Step->getType());
342 })
343 .Default(
344 [&SE](const VPRecipeBase *) { return SE.getCouldNotCompute(); });
345
346 return PSE.getPredicatedSCEV(Expr);
347}
348
350 const Loop *L) {
351 // If address is an SCEVAddExpr, we require that all operands must be either
352 // be invariant or a (possibly sign-extend) affine AddRec.
353 if (auto *PtrAdd = dyn_cast<SCEVAddExpr>(Addr)) {
354 return all_of(PtrAdd->operands(), [&SE, L](const SCEV *Op) {
355 return SE.isLoopInvariant(Op, L) ||
356 match(Op, m_scev_SExt(m_scev_AffineAddRec(m_SCEV(), m_SCEV()))) ||
357 match(Op, m_scev_AffineAddRec(m_SCEV(), m_SCEV()));
358 });
359 }
360
361 // Otherwise, check if address is loop invariant or an affine add recurrence.
362 return SE.isLoopInvariant(Addr, L) ||
364}
365
366unsigned vputils::getOpcode(const VPValue *V) {
370 [](auto *I) { return I->getOpcode(); })
371 .Case<VPVectorPointerRecipe, VPPredInstPHIRecipe, VPScalarIVStepsRecipe>(
372 [](auto *I) {
373 // For recipes that do not directly map to LLVM IR instructions,
374 // assign opcodes after the last VPInstruction opcode (which is also
375 // after the last IR Instruction opcode), based on the VPRecipeID.
376 return VPInstruction::OpsEnd + 1 + I->getVPRecipeID();
377 })
378 .Default([](auto *) { return 0; });
379}
380
381std::optional<std::pair<bool, unsigned>>
384 return std::make_pair(true, IID);
385 if (unsigned Opcode = vputils::getOpcode(V))
386 return std::make_pair(false, Opcode);
387 return {};
388}
389
390/// Returns true if \p Opcode preserves uniformity, i.e., if all operands are
391/// uniform, the result will also be uniform.
392static bool preservesUniformity(unsigned Opcode) {
393 if (Instruction::isBinaryOp(Opcode) || Instruction::isCast(Opcode))
394 return true;
395 switch (Opcode) {
396 case Instruction::Freeze:
397 case Instruction::GetElementPtr:
398 case Instruction::ICmp:
399 case Instruction::FCmp:
400 case Instruction::Select:
405 return true;
406 default:
407 return false;
408 }
409}
410
412 // TODO: Handle more opcodes and recipes.
414 return false;
415 unsigned Opcode = getOpcode(V);
416 return Instruction::isUnaryOp(Opcode) || Instruction::isBinaryOp(Opcode);
417}
418
420 // Live-in, symbolic and canonical-IV region values are single-scalar.
421 if (auto *RV = dyn_cast<VPRegionValue>(VPV))
422 return RV == RV->getDefiningRegion()->getCanonicalIV();
424 return true;
425
426 if (auto *Rep = dyn_cast<VPReplicateRecipe>(VPV)) {
427 const VPRegionBlock *RegionOfR = Rep->getRegion();
428 // Don't consider recipes in replicate regions as uniform yet; their first
429 // lane cannot be accessed when executing the replicate region for other
430 // lanes.
431 if (RegionOfR && RegionOfR->isReplicator())
432 return false;
433 return Rep->isSingleScalar() || (preservesUniformity(Rep->getOpcode()) &&
434 all_of(Rep->operands(), isSingleScalar));
435 }
438 if (auto *WidenR = dyn_cast<VPWidenRecipe>(VPV)) {
439 return preservesUniformity(WidenR->getOpcode()) &&
440 all_of(WidenR->operands(), isSingleScalar);
441 }
442 if (auto *VPI = dyn_cast<VPInstruction>(VPV))
443 return VPI->isSingleScalar() || VPI->isVectorToScalar() ||
444 (preservesUniformity(VPI->getOpcode()) &&
445 all_of(VPI->operands(), isSingleScalar));
446 if (auto *RR = dyn_cast<VPReductionRecipe>(VPV))
447 return !RR->isPartialReduction();
449 VPV))
450 return true;
451 if (auto *Expr = dyn_cast<VPExpressionRecipe>(VPV))
452 return Expr->isVectorToScalar();
453
454 // VPExpandSCEVRecipes must be placed in the entry and are always uniform.
455 return isa<VPExpandSCEVRecipe>(VPV);
456}
457
459 // Live-ins, symbolic and canonical-IV region values are uniform.
460 if (auto *RV = dyn_cast<VPRegionValue>(V))
461 return RV == RV->getDefiningRegion()->getCanonicalIV();
463 return true;
464
465 const VPRecipeBase *R = V->getDefiningRecipe();
466 const VPBasicBlock *VPBB = R ? R->getParent() : nullptr;
467 const VPlan *Plan = VPBB ? VPBB->getPlan() : nullptr;
468 if (VPBB) {
469 if ((VPBB == Plan->getVectorPreheader() || VPBB == Plan->getEntry())) {
470 if (match(V->getDefiningRecipe(),
472 return false;
473 return all_of(R->operands(), isUniformAcrossVFsAndUFs);
474 }
475 }
476
478 .Case([](const VPDerivedIVRecipe *R) { return true; })
479 .Case([](const VPReplicateRecipe *R) {
480 // Be conservative about side-effects, except for the
481 // known-side-effecting assumes and stores, which we know will be
482 // uniform.
483 return R->isSingleScalar() &&
484 (!R->mayHaveSideEffects() ||
485 isa<AssumeInst, StoreInst>(R->getUnderlyingInstr())) &&
486 all_of(R->operands(), isUniformAcrossVFsAndUFs);
487 })
488 .Case([](const VPWidenRecipe *R) {
489 return preservesUniformity(R->getOpcode()) &&
490 all_of(R->operands(), isUniformAcrossVFsAndUFs);
491 })
492 .Case([](const VPPhi *) {
493 // Bail out on VPPhi, as we can end up in infinite cycles.
494 return false;
495 })
496 .Case([](const VPInstruction *VPI) {
497 return (VPI->isSingleScalar() || VPI->isVectorToScalar() ||
500 })
501 .Case([](const VPWidenCastRecipe *R) {
502 // A cast is uniform according to its operand.
503 return isUniformAcrossVFsAndUFs(R->getOperand(0));
504 })
505 .Default([](const VPRecipeBase *) { // A value is considered non-uniform
506 // unless proven otherwise.
507 return false;
508 });
509}
510
512 if (auto *RepR = dyn_cast<VPReplicateRecipe>(R))
513 return RepR->doesGeneratePerAllLanes();
514 if (auto *VPI = dyn_cast<VPInstruction>(R))
515 return VPI->doesGeneratePerAllLanes();
516 if (auto *SIVSteps = dyn_cast<VPScalarIVStepsRecipe>(R))
517 return SIVSteps->doesGeneratePerAllLanes();
518 return false;
519}
520
522 auto DepthFirst = vp_depth_first_shallow(Plan.getEntry());
523 auto I = find_if(DepthFirst, [&VPDT](VPBlockBase *VPB) {
524 return VPBlockUtils::isHeader(VPB, VPDT);
525 });
526 return I == DepthFirst.end() ? nullptr : cast<VPBasicBlock>(*I);
527}
528
530 if (!R)
531 return 1;
532 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
533 return RR->getVFScaleFactor();
534 if (auto *RR = dyn_cast<VPReductionRecipe>(R))
535 return RR->getVFScaleFactor();
536 if (auto *ER = dyn_cast<VPExpressionRecipe>(R))
537 return ER->getVFScaleFactor();
538 assert(
541 "getting scaling factor of reduction-start-vector not implemented yet");
542 return 1;
543}
544
545bool vputils::cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking) {
546 // Assumes don't alias anything or throw; as long as they're guaranteed to
547 // execute, they're safe to hoist. They should however not be sunk, as it
548 // would destroy information.
550 return Sinking;
551 if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi())
552 return true;
553 // Allocas cannot be hoisted.
554 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
555 return RepR && RepR->getOpcode() == Instruction::Alloca;
556}
557
560 VPBasicBlock *LastBB) {
561 assert(FirstBB->getParent() == LastBB->getParent() &&
562 "FirstBB and LastBB from different regions");
563#ifndef NDEBUG
564 bool InSingleSuccChain = false;
565 for (VPBlockBase *Succ = FirstBB; Succ; Succ = Succ->getSingleSuccessor())
566 InSingleSuccChain |= (Succ == LastBB);
567 assert(InSingleSuccChain &&
568 "LastBB unreachable from FirstBB in single-successor chain");
569#endif
570 auto Blocks = to_vector(
572 auto *LastIt = find(Blocks, LastBB);
573 assert(LastIt != Blocks.end() &&
574 "LastBB unreachable from FirstBB in depth-first traversal");
575 Blocks.erase(std::next(LastIt), Blocks.end());
576 return Blocks;
577}
578
580 for (VPRecipeBase &R : *Plan.getVectorPreheader())
582 return cast<VPInstruction>(&R);
583 return nullptr;
584}
585
588 Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp,
589 Instruction *TruncI, VPIRValue *StartV, VPValue *Step, DebugLoc DL,
590 VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags) {
591 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
592 VPBasicBlock *HeaderVPBB = LoopRegion->getEntryBasicBlock();
593 VPValue *CanonicalIV = LoopRegion->getCanonicalIV();
594 VPSingleDefRecipe *BaseIV =
595 Builder.createDerivedIV(Kind, FPBinOp, StartV, CanonicalIV, Step, Flags);
596
597 // Truncate base induction if needed.
598 Type *ResultTy = BaseIV->getScalarType();
599 if (TruncI) {
600 Type *TruncTy = TruncI->getType();
601 assert(ResultTy->getScalarSizeInBits() > TruncTy->getScalarSizeInBits() &&
602 "Not truncating.");
603 assert(ResultTy->isIntegerTy() && "Truncation requires an integer type");
604 BaseIV = Builder.createScalarCast(Instruction::Trunc, BaseIV, TruncTy, DL);
605 ResultTy = TruncTy;
606 }
607
608 // Truncate step if needed.
609 Type *StepTy = Step->getScalarType();
610 if (ResultTy != StepTy) {
611 assert(StepTy->getScalarSizeInBits() > ResultTy->getScalarSizeInBits() &&
612 "Not truncating.");
613 assert(StepTy->isIntegerTy() && "Truncation requires an integer type");
614 auto *VecPreheader =
616 VPBuilder::InsertPointGuard Guard(Builder);
617 Builder.setInsertPoint(VecPreheader);
618 Step = Builder.createScalarCast(Instruction::Trunc, Step, ResultTy, DL);
619 }
620 return Builder.createScalarIVSteps(InductionOpcode, FPBinOp, BaseIV, Step,
621 &Plan.getVF(), DL);
622}
623
624VPValue *
626 VPlan &Plan, VPBuilder &Builder) {
628 VPIRValue *StartV = Plan.getZero(ID.getStep()->getType());
629 VPValue *StepV = PtrIV->getOperand(1);
631 Plan, InductionDescriptor::IK_IntInduction, Instruction::Add, nullptr,
632 nullptr, StartV, StepV, PtrIV->getDebugLoc(), Builder);
633
634 return Builder.createPtrAdd(PtrIV->getStartValue(), Steps,
635 PtrIV->getDebugLoc(), "next.gep");
636}
637
639 const VPDominatorTree &VPDT) {
640 auto *VPBB = dyn_cast<VPBasicBlock>(VPB);
641 if (!VPBB)
642 return false;
643
644 // If VPBB is in a region R, VPBB is a loop header if R is a loop region with
645 // VPBB as its entry, i.e., free of predecessors.
646 if (auto *R = VPBB->getParent())
647 return !R->isReplicator() && !VPBB->hasPredecessors();
648
649 // A header dominates its second predecessor (the latch), with the other
650 // predecessor being the preheader
651 return VPB->getPredecessors().size() == 2 &&
652 VPDT.dominates(VPB, VPB->getPredecessors()[1]);
653}
654
656 const VPDominatorTree &VPDT) {
657 // A latch has a header as its last successor, with its other successors
658 // leaving the loop. A preheader OTOH has a header as its first (and only)
659 // successor.
660 return VPB->getNumSuccessors() >= 2 &&
662}
663
664std::pair<VPBasicBlock *, VPBasicBlock *>
666 auto *Header = cast<VPBasicBlock>(
667 Plan.getEntry()->getSuccessors()[1]->getSingleSuccessor());
668 auto *Latch = cast<VPBasicBlock>(Header->getPredecessors()[1]);
669 return {Header, Latch};
670}
671
675
676std::optional<MemoryLocation>
678 auto *M = dyn_cast<VPIRMetadata>(&R);
679 if (!M)
680 return std::nullopt;
682 // Populate noalias metadata from VPIRMetadata.
683 if (MDNode *NoAliasMD = M->getMetadata(LLVMContext::MD_noalias))
684 Loc.AATags.NoAlias = NoAliasMD;
685 if (MDNode *AliasScopeMD = M->getMetadata(LLVMContext::MD_alias_scope))
686 Loc.AATags.Scope = AliasScopeMD;
687 return Loc;
688}
689
691 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
692 VPRegionValue *CanIV = LoopRegion->getCanonicalIV();
693 assert(CanIV && "Expected loop region to have a canonical IV");
694
695 VPSymbolicValue &VFxUF = Plan.getVFxUF();
696
697 // Check if \p Step matches the expected increment step, accounting for
698 // materialization of VFxUF and UF.
699 auto IsIncrementStep = [&](VPValue *Step) -> bool {
700 if (!VFxUF.isMaterialized())
701 return Step == &VFxUF;
702
703 VPSymbolicValue &UF = Plan.getUF();
704 if (!UF.isMaterialized())
705 return Step == &UF ||
706 match(Step, m_c_Mul(m_Specific(&Plan.getUF()), m_VScale()));
707
708 // Alias masking: step is number of active lanes of a dependence mask.
709 if (match(Step, m_ZExtOrTruncOrSelf(
711 return true;
712
713 unsigned ConcreteUF = Plan.getConcreteUF();
714 // Fixed VF: step is just the concrete UF.
715 if (match(Step, m_SpecificInt(ConcreteUF)))
716 return true;
717
718 // Scalable VF: step involves VScale.
719 if (ConcreteUF == 1)
720 return match(Step, m_VScale());
721 if (match(Step, m_c_Mul(m_SpecificInt(ConcreteUF), m_VScale())))
722 return true;
723 // mul(VScale, ConcreteUF) may have been simplified to
724 // shl(VScale, log2(ConcreteUF)) when ConcreteUF is a power of 2.
725 return isPowerOf2_32(ConcreteUF) &&
726 match(Step, m_Shl(m_VScale(), m_SpecificInt(Log2_32(ConcreteUF))));
727 };
728
729 VPInstruction *Increment = nullptr;
730 for (VPUser *U : CanIV->users()) {
731 VPValue *Step;
732 if (isa<VPInstruction>(U) &&
733 match(U, m_c_Add(m_Specific(CanIV), m_VPValue(Step))) &&
734 IsIncrementStep(Step)) {
735 assert(!Increment && "There must be a unique increment");
737 }
738 }
739
740 assert((!VFxUF.isMaterialized() || Increment) &&
741 "After materializing VFxUF, an increment must exist");
742 assert((!Increment ||
743 LoopRegion->hasCanonicalIVNUW() == Increment->hasNoUnsignedWrap()) &&
744 "NUW flag in region and increment must match");
745 return Increment;
746}
747
748/// Find the ComputeReductionResult recipe for \p PhiR, looking through selects
749/// inserted for predicated reductions or tail folding.
751 VPValue *BackedgeVal = PhiR->getBackedgeValue();
752 if (auto *Res =
754 return Res;
755
756 // Look through selects inserted for tail folding or predicated reductions.
757 VPRecipeBase *SelR =
758 findUserOf(BackedgeVal, m_Select(m_VPValue(), m_VPValue(), m_VPValue()));
759 if (!SelR)
760 return nullptr;
763}
764
767 SmallVector<const VPValue *> WorkList = {V};
768
769 while (!WorkList.empty()) {
770 const VPValue *Cur = WorkList.pop_back_val();
771 if (!Seen.insert(Cur).second)
772 continue;
773
774 auto *Blend = dyn_cast<VPBlendRecipe>(Cur);
775 // Skip blends that use V only through a compare by checking if any incoming
776 // value was already visited.
777 if (Blend && none_of(seq<unsigned>(0, Blend->getNumIncomingValues()),
778 [&](unsigned I) {
779 return Seen.contains(Blend->getIncomingValue(I));
780 }))
781 continue;
782
783 for (VPUser *U : Cur->users()) {
784 if (auto *InterleaveR = dyn_cast<VPInterleaveBase>(U))
785 if (InterleaveR->getAddr() == Cur)
786 return true;
787 // Cur is used as the pointer of a (possibly masked) load (operand 0) or
788 // store (operand 1).
791 m_Specific(Cur)))))
792 return true;
794 if (MemR->getAddr() == Cur && MemR->isConsecutive())
795 return true;
796 }
797 }
798
799 // The legacy cost model only supports scalarization loads/stores with phi
800 // addresses, if the phi is directly used as load/store address. Don't
801 // traverse further for Blends.
802 if (Blend)
803 continue;
804
805 // Only traverse further through users that also define a value (and can
806 // thus have their own users walked). Skip when Cur is only used as mask ,
807 // as well as loads: a loaded value does not depend on the load's operand.
808 for (VPUser *U : Cur->users()) {
809 auto *VPI = dyn_cast<VPInstruction>(U);
810 if (VPI && VPI->getMask() == Cur &&
811 none_of(VPI->operandsWithoutMask(), equal_to(Cur)))
812 continue;
814 continue;
815 if (auto *SDR = dyn_cast<VPSingleDefRecipe>(U))
816 WorkList.push_back(SDR);
817 }
818 }
819 return false;
820}
821
822/// Try to find a loop-invariant IR value for \p S in the plan's entry block
823/// that can be reused. Returns the corresponding live-in VPValue, or nullptr
824/// if no reusable IR value is found.
825VPValue *VPSCEVExpander::tryToReuseIRValue(const SCEV *S) {
827 return nullptr;
828 VPlan &Plan = Builder.getPlan();
829 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
830 for (Value *V : SE.getSCEVValues(S)) {
831 // Only reuse instructions in the plan's entry block, or, when a
832 // DominatorTree is available, any instruction that dominates it.
833 // Instructions in sibling branches may not dominate the entry block.
834 auto *I = dyn_cast<Instruction>(V);
835 if (!I)
836 return Plan.getOrAddLiveIn(V);
837 if (!SE.DT.dominates(I->getParent(), PH))
838 continue;
839 SmallVector<Instruction *> DropPoisonGeneratingInsts;
840 if (!SE.canReuseInstruction(S, I, DropPoisonGeneratingInsts))
841 continue;
842 for (Instruction *DropI : DropPoisonGeneratingInsts)
844 return Plan.getOrAddLiveIn(V);
845 }
846 return nullptr;
847}
848
850 if (VPValue *V = tryToReuseIRValue(S))
851 return V;
852
853 switch (S->getSCEVType()) {
854 case scConstant:
855 return Builder.getPlan().getOrAddLiveIn(cast<SCEVConstant>(S)->getValue());
856 case scUnknown:
857 return Builder.getPlan().getOrAddLiveIn(cast<SCEVUnknown>(S)->getValue());
858 case scVScale:
859 return Builder.createVScale(S->getType(), DL);
860 case scAddExpr:
861 case scMulExpr: {
862 auto *NAry = cast<SCEVNAryExpr>(S);
863 VPIRFlags::WrapFlagsTy WrapFlags(NAry->hasNoUnsignedWrap(),
864 NAry->hasNoSignedWrap());
865
866 // Expanded poiner SCEVAddExpr as a ptradd of the pointer base and the
867 // integer offset, matching SCEVExpander.
868 if (S->getType()->isPointerTy()) {
869 VPValue *Base = tryToExpand(SE.getPointerBase(S));
870 if (!Base)
871 return nullptr;
872 VPValue *Offset = tryToExpand(SE.removePointerBase(S));
873 if (!Offset)
874 return nullptr;
875 GEPNoWrapFlags GEPFlags = WrapFlags.HasNUW
878 return Builder.createNoWrapPtrAdd(Base, Offset, GEPFlags, DL);
879 }
880
881 unsigned Opcode =
882 S->getSCEVType() == scAddExpr ? Instruction::Add : Instruction::Mul;
883 // Iterate in reverse so that constants are emitted last.
885 for (const SCEVUse &Op : reverse(NAry->operands())) {
886 VPValue *OpV = tryToExpand(Op);
887 if (!OpV)
888 return nullptr;
889 Ops.push_back(OpV);
890 }
891 VPValue *Result = Ops.front();
892 for (VPValue *Op : drop_begin(Ops))
893 Result = Builder.createOverflowingOp(Opcode, {Result, Op}, WrapFlags, DL);
894 return Result;
895 }
896 case scUDivExpr: {
897 auto *UDiv = cast<SCEVUDivExpr>(S);
898 VPValue *LHS = tryToExpand(UDiv->getLHS());
899 if (!LHS)
900 return nullptr;
901 VPValue *RHS = tryToExpand(UDiv->getRHS());
902 if (!RHS)
903 return nullptr;
904 return Builder.createNaryOp(Instruction::UDiv, {LHS, RHS},
905 VPIRFlags::getDefaultFlags(Instruction::UDiv),
906 DL);
907 }
908 case scTruncate:
909 case scZeroExtend:
910 case scSignExtend:
911 case scPtrToInt:
912 case scPtrToAddr: {
913 auto *Cast = cast<SCEVCastExpr>(S);
914 VPValue *Op = tryToExpand(Cast->getOperand());
915 if (!Op)
916 return nullptr;
918 switch (S->getSCEVType()) {
919 case scTruncate:
920 Opcode = Instruction::Trunc;
921 break;
922 case scZeroExtend:
923 Opcode = Instruction::ZExt;
924 break;
925 case scSignExtend:
926 Opcode = Instruction::SExt;
927 break;
928 case scPtrToInt:
929 Opcode = Instruction::PtrToInt;
930 break;
931 case scPtrToAddr:
932 Opcode = Instruction::PtrToAddr;
933 break;
934 default:
935 llvm_unreachable("Unhandled cast SCEV");
936 }
937
938 // When expanding ptrtoaddr, first check if there's an existing ptrtoint we
939 // can reuse.
940 if (Opcode == Instruction::PtrToAddr) {
941 VPlan &Plan = Builder.getPlan();
942 BasicBlock *PH = cast<VPIRBasicBlock>(Plan.getEntry())->getIRBasicBlock();
943 if (auto *IRV = dyn_cast<VPIRValue>(Op)) {
945 IRV->getValue(), S->getType(), PH->getDataLayout(),
946 [&](const CastInst *CI) {
947 return SE.DT.dominates(CI->getParent(), PH);
948 }))
949 return Plan.getOrAddLiveIn(CI);
950 }
951 }
952
953 return Builder.createScalarCast(Opcode, Op, S->getType(), DL);
954 }
955 case scUMaxExpr:
956 case scSMaxExpr:
957 case scUMinExpr:
958 case scSMinExpr: {
959 auto *MinMax = cast<SCEVMinMaxExpr>(S);
960 Intrinsic::ID IntrinsicID;
961 switch (S->getSCEVType()) {
962 case scUMaxExpr:
963 IntrinsicID = Intrinsic::umax;
964 break;
965 case scSMaxExpr:
966 IntrinsicID = Intrinsic::smax;
967 break;
968 case scUMinExpr:
969 IntrinsicID = Intrinsic::umin;
970 break;
971 case scSMinExpr:
972 IntrinsicID = Intrinsic::smin;
973 break;
974 default:
975 llvm_unreachable("Unexpected min/max SCEV type");
976 }
977 // Chain operands in reverse order matching SCEVExpander's expansion of
978 // min/max expressions.
980 for (const SCEVUse &Op : reverse(MinMax->operands())) {
981 VPValue *OpV = tryToExpand(Op);
982 if (!OpV)
983 return nullptr;
984 Ops.push_back(OpV);
985 }
986 Type *ResultTy = MinMax->getType();
987 VPValue *Result = Ops.front();
988 for (VPValue *Op : drop_begin(Ops))
989 Result = Builder.createScalarIntrinsic(IntrinsicID, {Result, Op},
990 ResultTy, DL);
991 return Result;
992 }
993 default:
994 return nullptr;
995 }
996}
997
999 // Do remove conditional assume instructions as their conditions may be
1000 // flattened.
1001 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
1002 bool IsConditionalAssume = RepR && RepR->isPredicated() &&
1004 if (IsConditionalAssume)
1005 return true;
1006
1007 if (R.mayHaveSideEffects())
1008 return false;
1009
1010 // Recipe is dead if no user keeps the recipe alive.
1011 return all_of(R.definedValues(), [](VPValue *V) { return V->user_empty(); });
1012}
1013
1015 SmallVector<VPValue *> WorkList;
1017 WorkList.push_back(V);
1018
1019 while (!WorkList.empty()) {
1020 VPValue *Cur = WorkList.pop_back_val();
1021 if (!Seen.insert(Cur).second)
1022 continue;
1023 VPRecipeBase *R = Cur->getDefiningRecipe();
1024 if (!R)
1025 continue;
1026 if (!isDeadRecipe(*R))
1027 continue;
1028 append_range(WorkList, R->operands());
1029 R->eraseFromParent();
1030 }
1031}
1032
1035 for (unsigned I = 0; I != Users.size(); ++I) {
1037 for (VPValue *V : Cur->definedValues())
1038 Users.insert_range(V->users());
1039 }
1040 return Users.takeVector();
1041}
1042
1044 ArrayRef<VPValue *> Operands,
1045 const DataLayout &DL) {
1046 auto OpcodeOrIID = getOpcodeOrIntrinsicID(&R);
1047 if (!OpcodeOrIID)
1048 return nullptr;
1049
1051 for (VPValue *Op : Operands) {
1052 VPValue *Candidate = Op;
1053 match(Op, m_Broadcast(m_VPValue(Candidate)));
1054 if (!match(Candidate, m_LiveIn()))
1055 return nullptr;
1056 Value *V = Candidate->getUnderlyingValue();
1057 if (!V)
1058 return nullptr;
1059 Ops.push_back(V);
1060 }
1061
1062 VPlan &Plan = *R.getParent()->getPlan();
1063 auto FoldToIRValue = [&]() -> Value * {
1064 InstSimplifyFolder Folder(DL);
1065 if (OpcodeOrIID->first) {
1066 // VPInstructions store the called intrinsic as last operand.
1067 if (isa<VPInstruction>(R))
1068 Ops.pop_back();
1069
1070 auto *RFlags = dyn_cast<VPRecipeWithIRFlags>(&R);
1071 return Folder.FoldIntrinsic(OpcodeOrIID->second, Ops, R.getScalarType(),
1072 RFlags ? RFlags->getFastMathFlagsOrNone()
1073 : FastMathFlags());
1074 }
1075 unsigned Opcode = OpcodeOrIID->second;
1076 if (Instruction::isBinaryOp(Opcode))
1077 return Folder.FoldBinOp(static_cast<Instruction::BinaryOps>(Opcode),
1078 Ops[0], Ops[1]);
1079 if (Instruction::isCast(Opcode))
1080 return Folder.FoldCast(static_cast<Instruction::CastOps>(Opcode), Ops[0],
1081 R.getVPSingleValue()->getScalarType());
1082 switch (Opcode) {
1083 case VPInstruction::Not:
1084 return Folder.FoldBinOp(Instruction::BinaryOps::Xor, Ops[0],
1086 case Instruction::Select:
1087 return Folder.FoldSelect(Ops[0], Ops[1], Ops[2]);
1088 case Instruction::ICmp:
1089 case Instruction::FCmp:
1090 return Folder.FoldCmp(cast<VPRecipeWithIRFlags>(R).getPredicate(), Ops[0],
1091 Ops[1]);
1092 case Instruction::GetElementPtr: {
1093 auto &RFlags = cast<VPRecipeWithIRFlags>(R);
1094 auto *GEP = cast<GetElementPtrInst>(RFlags.getUnderlyingInstr());
1095 return Folder.FoldGEP(GEP->getSourceElementType(), Ops[0],
1096 drop_begin(Ops), RFlags.getGEPNoWrapFlags());
1097 }
1100 return Folder.FoldGEP(IntegerType::getInt8Ty(Plan.getContext()), Ops[0],
1101 Ops[1],
1102 cast<VPRecipeWithIRFlags>(R).getGEPNoWrapFlags());
1103 // An extract of a live-in is an extract of a broadcast, so return the
1104 // broadcasted element.
1105 case Instruction::ExtractElement:
1106 assert(!Ops[0]->getType()->isVectorTy() && "Live-ins should be scalar");
1107 return Ops[0];
1108 }
1109 return nullptr;
1110 };
1111
1112 if (Value *V = FoldToIRValue())
1113 return Plan.getOrAddLiveIn(V);
1114 return nullptr;
1115}
1116
1118 VPlan &Plan, function_ref<VPValue *(VPValue *Op)> MatchPerm,
1121 vp_depth_first_deep(Plan.getEntry()))) {
1122 for (VPRecipeBase &R : make_early_inc_range(*VPBB)) {
1123 auto *Def = dyn_cast<VPSingleDefRecipe>(&R);
1124 if (!Def || !isElementwise(Def))
1125 continue;
1126
1127 // At least one of the ops must be a permutation.
1128 if (none_of(Def->operands(),
1129 [&MatchPerm](VPValue *Op) { return MatchPerm(Op); }))
1130 continue;
1131
1132 // All operands must be a single-use permutation or a live in (splat).
1133 if (!all_of(Def->operands(), [&MatchPerm](VPValue *Op) {
1134 return (Op->hasOneUse() && MatchPerm(Op)) || match(Op, m_LiveIn());
1135 }))
1136 continue;
1137
1138 // Remove the inner permutations.
1139 for (unsigned I = 0, E = Def->getNumOperands(); I != E; ++I)
1140 if (VPValue *X = MatchPerm(Def->getOperand(I)))
1141 Def->setOperand(I, X);
1142
1143 VPSingleDefRecipe *Res = BuildPerm(Def);
1144 Res->insertAfter(Def);
1145 Def->replaceUsesWithIf(
1146 Res, [&Res](VPUser &U, unsigned _) { return &U != Res; });
1147 }
1148 }
1149}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define X(NUM, ENUM, NAME)
Definition ELF.h:856
Hexagon Common GEP
#define _
iv Induction Variable Users
Definition IVUsers.cpp:48
static constexpr Value * getValue(Ty &ValueOrUse)
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
This file provides a LoopVectorizationPlanner class.
#define I(x, y, z)
Definition MD5.cpp:57
This file provides utility analysis objects describing memory locations.
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 propagatesPoisonFromRecipeOp(const VPRecipeBase *R)
Returns true if R propagates poison from any operand to its result.
static bool preservesUniformity(unsigned Opcode)
Returns true if Opcode preserves uniformity, i.e., if all operands are uniform, the result will also ...
static bool poisonGuaranteesUB(const VPValue *V)
Returns true if V being poison is guaranteed to trigger UB because it propagates to the address of a ...
static const uint32_t IV[8]
Definition blake3_impl.h:83
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this basic block belongs to.
This is the base class for all instructions that perform data casts.
Definition InstrTypes.h:512
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Utility class for floating point operations which can have information about relaxed accuracy require...
Definition Operator.h:202
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
Represents flags for the getelementptr instruction/expression.
static GEPNoWrapFlags noUnsignedWrap()
static GEPNoWrapFlags none()
A struct for saving information about induction variables.
InductionKind
This enum represents the kinds of inductions that we support.
@ IK_IntInduction
Integer induction variable. Step = C.
InstSimplifyFolder - Use InstructionSimplify to fold operations to existing values.
bool isCast() const
bool isBinaryOp() const
bool isUnaryOp() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1069
Representation for a specific memory location.
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
ScalarEvolution * getSE() const
Returns the ScalarEvolution analysis used.
LLVM_ABI const SCEV * getPredicatedSCEV(const SCEV *Expr)
Returns the rewritten SCEV for Expr in the context of the current SCEV predicate.
static LLVM_ABI void dropPoisonGeneratingAnnotationsAndReinfer(ScalarEvolution &SE, Instruction *I)
Drop poison-generating flags from I, then try re-infer via SCEV.
static LLVM_ABI CastInst * findReusableCastForPtrToAddr(Value *PtrOp, Type *Ty, const DataLayout &DL, function_ref< bool(const CastInst *)> Dominates)
Find an existing cast among PtrOp's users that computes the same value as a ptrtoaddr of PtrOp to Ty ...
This class represents an analyzed expression in the program.
static constexpr auto FlagAnyWrap
static constexpr auto FlagNSW
SCEVTypes getSCEVType() const
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
The main scalar evolution driver.
LLVM_ABI const SCEV * getUDivExpr(SCEVUse LHS, SCEVUse RHS)
Get a canonical unsigned division expression, or something simpler if possible.
LLVM_ABI bool isKnownNonNegative(const SCEV *S)
Test if the given expression is known to be non-negative.
LLVM_ABI const SCEV * getAbsExpr(const SCEV *Op, bool IsNSW)
LLVM_ABI const SCEV * getURemExpr(SCEVUse LHS, SCEVUse RHS)
Represents an unsigned remainder expression based on unsigned division.
LLVM_ABI const SCEV * getSMinExpr(SCEVUse LHS, SCEVUse RHS)
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI uint64_t getTypeSizeInBits(Type *Ty) const
Return the size in bits of the specified type, for which isSCEVable must return true.
LLVM_ABI const SCEV * getConstant(ConstantInt *V)
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getMinusSCEV(SCEVUse LHS, SCEVUse RHS, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Return LHS-RHS.
LLVM_ABI const SCEV * getAddRecExpr(SCEVUse Start, SCEVUse Step, const Loop *L, SCEV::NoWrapFlags Flags)
Get an add recurrence expression for the specified loop.
const SCEV * getOne(Type *Ty)
Return a SCEV for the constant 1 of a specific type.
LLVM_ABI bool isLoopInvariant(const SCEV *S, const Loop *L)
Return true if the value of the given SCEV is unchanging in the specified loop.
LLVM_ABI const SCEV * getZeroExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI bool isSCEVable(Type *Ty) const
Test if values of the given type are analyzable within the SCEV framework.
LLVM_ABI const SCEV * getTruncateExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
LLVM_ABI const SCEV * getUMaxExpr(SCEVUse LHS, SCEVUse RHS)
const SCEV * getMinusOne(Type *Ty)
Return a SCEV for the constant -1 of a specific type.
LLVM_ABI const SCEV * getCouldNotCompute()
LLVM_ABI const SCEV * getMulExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical multiply expression, or something simpler if possible.
LLVM_ABI const SCEV * getSignExtendExpr(const SCEV *Op, Type *Ty, unsigned Depth=0)
const SCEV * getPowerOfTwo(Type *Ty, unsigned Power)
Return a SCEV for the constant Power of two.
LLVM_ABI const SCEV * getAddExpr(SmallVectorImpl< SCEVUse > &Ops, SCEV::NoWrapFlags Flags=SCEV::FlagAnyWrap, unsigned Depth=0)
Get a canonical add expression, or something simpler if possible.
LLVM_ABI const SCEV * getSMaxExpr(SCEVUse LHS, SCEVUse RHS)
LLVM_ABI bool canReuseInstruction(const SCEV *S, Instruction *I, SmallVectorImpl< Instruction * > &DropPoisonGeneratingInsts)
Check whether it is poison-safe to represent the expression S using the instruction I.
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< SCEVUse > IndexExprs)
Returns an expression for a GEP.
LLVM_ABI const SCEV * getUMinExpr(SCEVUse LHS, SCEVUse RHS, bool Sequential=false)
LLVM_ABI const SCEV * getTruncateOrSignExtend(const SCEV *V, Type *Ty, unsigned Depth=0)
Return a SCEV corresponding to a conversion of the input value to the specified type.
A vector that has set insertion semantics.
Definition SetVector.h:57
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
Definition TypeSwitch.h:89
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition TypeSwitch.h:98
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isPointerTy() const
True if this is an instance of PointerType.
Definition Type.h:282
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:307
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:368
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:232
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4376
iterator end()
Definition VPlan.h:4413
iterator getFirstNonPhi()
Return the position of the first non-phi node recipe in the block.
Definition VPlan.cpp:266
void insert(VPRecipeBase *Recipe, iterator InsertPt)
Definition VPlan.h:4442
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:94
VPRegionBlock * getParent()
Definition VPlan.h:192
size_t getNumSuccessors() const
Definition VPlan.h:243
const VPBlocksTy & getPredecessors() const
Definition VPlan.h:228
VPlan * getPlan()
Definition VPlan.cpp:211
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:216
VPBlockBase * getSingleHierarchicalPredecessor()
Definition VPlan.h:279
VPBlockBase * getSingleSuccessor() const
Definition VPlan.h:233
const VPBlocksTy & getSuccessors() const
Definition VPlan.h:217
static bool isLatch(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop latch, using isHeader().
static VPBasicBlock * getPlainCFGMiddleBlock(const VPlan &Plan)
Returns the middle block of Plan in plain CFG form (before regions are formed).
static bool isHeader(const VPBlockBase *VPB, const VPDominatorTree &VPDT)
Returns true if VPB is a loop header, based on regions or VPDT in their absence.
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:377
static std::pair< VPBasicBlock *, VPBasicBlock * > getPlainCFGHeaderAndLatch(const VPlan &Plan)
Returns the header and latch of the outermost loop of Plan in plain CFG form (before regions are form...
static SmallVector< VPBasicBlock * > blocksInSingleSuccessorChainBetween(VPBasicBlock *FirstBB, VPBasicBlock *LastBB)
Returns the blocks between FirstBB and LastBB, where FirstBB to LastBB forms a single-sucessor chain.
RAII object that stores the current insertion point and restores it when the object is destroyed.
VPlan-based builder utility analogous to IRBuilder.
ArrayRef< VPRecipeValue * > definedValues()
Returns an ArrayRef of the values defined by the VPDef.
Definition VPlanValue.h:573
A recipe for converting Current into Start + Current * Step.
Definition VPlan.h:4170
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
Recipe to expand a SCEV expression.
Definition VPlan.h:4002
virtual VPValue * getBackedgeValue()
Returns the incoming value from the loop backedge.
Definition VPlan.h:2484
static VPIRFlags getDefaultFlags(unsigned Opcode)
Returns default flags for Opcode for opcodes that support it, asserts otherwise.
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1234
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1323
unsigned getOpcode() const
Definition VPlan.h:1420
bool isVectorToScalar() const
Returns true if this VPInstruction produces a scalar value from a vector, e.g.
bool isSingleScalar() const
Returns true if the recipe produces a single scalar value.
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:411
DebugLoc getDebugLoc() const
Returns the debug location of the recipe.
Definition VPlan.h:561
void insertAfter(VPRecipeBase *InsertPos)
Insert an unlinked Recipe into a basic block immediately after the specified Recipe.
Type * getScalarType() const
Returns the scalar type of this VPRecipeValue.
Definition VPlanValue.h:354
A recipe for handling reduction phis.
Definition VPlan.h:2852
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4601
bool isReplicator() const
An indicator whether this region is to generate multiple replicated instances of output IR correspond...
Definition VPlan.h:4677
bool hasCanonicalIVNUW() const
Indicates if NUW is set for the canonical IV increment, for loop regions.
Definition VPlan.h:4765
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4721
VPValues are defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:252
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3384
unsigned getOpcode() const
Definition VPlan.h:3481
VPValue * tryToExpand(const SCEV *S)
Try to expand S into recipes and live-ins using the builder.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4231
VPSingleDefRecipe is a base class for recipes that model a sequence of one or more output IR that def...
Definition VPlan.h:619
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:217
bool isMaterialized() const
Returns true if this value has been materialized.
Definition VPlanValue.h:235
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:401
operand_range operands()
Definition VPlanValue.h:474
VPValue * getOperand(unsigned N) const
Definition VPlanValue.h:442
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
Type * getScalarType() const
Returns the scalar type of this VPValue, dispatching based on the concrete subclass.
Definition VPlan.cpp:149
VPRecipeBase * getDefiningRecipe()
Returns the recipe defining this VPValue or nullptr if it is not defined by a recipe,...
Definition VPlan.cpp:130
Value * getUnderlyingValue() const
Return the underlying Value attached to this VPValue.
Definition VPlanValue.h:75
user_range users()
Definition VPlanValue.h:157
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1880
A recipe for handling GEP instructions.
Definition VPlan.h:2207
VPIRValue * getStartValue() const
Returns the start value of the induction.
Definition VPlan.h:2559
const InductionDescriptor & getInductionDescriptor() const
Returns the induction descriptor for the recipe.
Definition VPlan.h:2582
A recipe for handling phi nodes of integer and floating-point inductions, producing their vector valu...
Definition VPlan.h:2611
A recipe for widened phis.
Definition VPlan.h:2739
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1819
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4788
LLVMContext & getContext() const
Definition VPlan.h:4991
VPBasicBlock * getEntry()
Definition VPlan.h:4884
VPSymbolicValue & getVFxUF()
Returns VF * UF of the vector loop region.
Definition VPlan.h:4989
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:5063
VPIRValue * getZero(Type *Ty)
Return a VPIRValue wrapping the null value of type Ty.
Definition VPlan.h:5089
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1077
unsigned getConcreteUF() const
Returns the concrete UF of the plan, after unrolling.
Definition VPlan.h:5041
VPBasicBlock * getVectorPreheader() const
Returns the preheader of the vector loop region, if one exists, or null otherwise.
Definition VPlan.h:4889
VPSymbolicValue & getUF()
Returns the UF of the vector loop region.
Definition VPlan.h:4986
VPBasicBlock * getScalarPreheader() const
Return the VPBasicBlock for the preheader of the scalar loop.
Definition VPlan.h:4933
VPSymbolicValue & getVF()
Returns the VF of the vector loop region.
Definition VPlan.h:4982
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:255
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
BinaryOp_match< LHS, RHS, Instruction::Add > m_Add(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::URem > m_URem(const LHS &L, const RHS &R)
ap_match< APInt > m_APInt(const APInt *&Res)
Match a ConstantInt or splatted ConstantVector, binding the specified pointer to the contained APInt.
CastInst_match< OpTy, TruncInst > m_Trunc(const OpTy &Op)
Matches Trunc.
specific_intval< false > m_SpecificInt(const APInt &V)
Match a specific integer value or vector with all elements equal to the value.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
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::LShr > m_LShr(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::SRem > m_SRem(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Mul, true > m_c_Mul(const LHS &L, const RHS &R)
Matches a Mul with LHS and RHS in either order.
BinaryOp_match< LHS, RHS, Instruction::Sub > m_Sub(const LHS &L, const RHS &R)
auto m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
bool match(const SCEV *S, const Pattern &P)
SCEVAffineAddRec_match< Op0_t, Op1_t, match_isa< const Loop > > m_scev_AffineAddRec(const Op0_t &Op0, const Op1_t &Op1)
AllRecipe_commutative_match< Instruction::And, Op0_t, Op1_t > m_c_BinaryAnd(const Op0_t &Op0, const Op1_t &Op1)
Match a binary AND operation.
AllRecipe_match< 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.
VPRecipeBase * findUserOf(VPValue *V, const MatchT &P)
If V is used by a recipe matching pattern P, return it.
VPInstruction_match< VPInstruction::Broadcast, Op0_t > m_Broadcast(const Op0_t &Op0)
match_bind< VPInstruction > m_VPInstruction(VPInstruction *&V)
Match a VPInstruction, capturing if we match.
void pullOutPermutationsImpl(VPlan &Plan, function_ref< VPValue *(VPValue *Op)> Perm, function_ref< VPSingleDefRecipe *(VPSingleDefRecipe *X)> Build)
Template-independent implementation for pullOutPermutations.
bool isSingleScalar(const VPValue *VPV)
Returns true if VPV is a single scalar, either because it produces the same value for all lanes or on...
VPValue * getOrCreateVPValueForSCEVExpr(VPlan &Plan, const SCEV *Expr)
Get or create a VPValue that corresponds to the expansion of Expr.
bool cannotHoistOrSinkRecipe(const VPRecipeBase &R, bool Sinking=false)
Return true if we do not know how to (mechanically) hoist or sink R.
unsigned getOpcode(const VPValue *V)
Return the instruction opcode for the recipe defining V or 0 for unsupported recipes and VPValues not...
VPBasicBlock * getFirstLoopHeader(VPlan &Plan, VPDominatorTree &VPDT)
Returns the header block of the first, top-level loop, or null if none exist.
bool isAddressSCEVForCost(const SCEV *Addr, ScalarEvolution &SE, const Loop *L)
Returns true if Addr is an address SCEV that can be passed to TTI::getAddressComputationCost,...
bool onlyFirstPartUsed(const VPValue *Def)
Returns true if only the first part of Def is used.
Intrinsic::ID getIntrinsicID(const Ty *R)
Return the intrinsic ID underlying a call.
Definition VPlanUtils.h:85
VPInstruction * findComputeReductionResult(VPReductionPHIRecipe *PhiR)
Find the ComputeReductionResult recipe for PhiR, looking through selects inserted for predicated redu...
VPInstruction * findCanonicalIVIncrement(VPlan &Plan)
Find the canonical IV increment of Plan's vector loop region.
std::optional< MemoryLocation > getMemoryLocation(const VPRecipeBase &R)
Return a MemoryLocation for R with noalias metadata populated from R, if the recipe is supported and ...
bool onlyFirstLaneUsed(const VPValue *Def)
Returns true if only the first lane of Def is used.
VPIRValue * tryToFoldLiveIns(VPSingleDefRecipe &R, ArrayRef< VPValue * > Operands, const DataLayout &DL)
Try to fold R using InstSimplifyFolder.
VPValue * findIncomingAliasMask(const VPlan &Plan)
Finds the incoming alias-mask within the vector preheader.
void recursivelyDeleteDeadRecipes(VPValue *V)
Recursively delete V and any of its operands that become dead.
bool doesGeneratePerAllLanes(const VPRecipeBase *R)
Returns true if R produces scalar values for all VF lanes.
bool isDeadRecipe(VPRecipeBase &R)
Returns true if R is dead, i.e.
bool isElementwise(const VPValue *V)
Return true if V is elementwise, i.e. none of the lanes are permuted.
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
bool isUniformAcrossVFsAndUFs(const VPValue *V)
Checks if V is uniform across all VF lanes and UF parts.
bool isUsedByLoadStoreAddress(const VPValue *V)
Returns true if V is used as part of the address of another load or store.
std::optional< std::pair< bool, unsigned > > getOpcodeOrIntrinsicID(const VPValue *V)
Get the instruction opcode or intrinsic ID for the recipe defining V.
VPValue * scalarizeVPWidenPointerInduction(VPWidenPointerInductionRecipe *PtrIV, VPlan &Plan, VPBuilder &Builder)
Scalarize a VPWidenPointerInductionRecipe by replacing it with a PtrAdd (IndStart,...
GEPNoWrapFlags getGEPFlagsForPtr(VPValue *Ptr)
Returns the GEP nowrap flags for Ptr, looking through pointer casts mirroring Value::stripPointerCast...
const SCEV * getSCEVExprForVPValue(const VPValue *V, PredicatedScalarEvolution &PSE, const Loop *L=nullptr)
Return the SCEV expression for V.
unsigned getVFScaleFactor(VPRecipeBase *R)
Get the VF scaling factor applied to the recipe's output, if the recipe has one.
SmallVector< VPUser * > collectUsersRecursively(VPValue *V)
Collect all users of V, looking through recipes that define other values.
VPScalarIVStepsRecipe * createScalarIVSteps(VPlan &Plan, InductionDescriptor::InductionKind Kind, Instruction::BinaryOps InductionOpcode, FPMathOperator *FPBinOp, Instruction *TruncI, VPIRValue *StartV, VPValue *Step, DebugLoc DL, VPBuilder &Builder, const VPIRFlags::WrapFlagsTy &Flags={})
Create a scalar-iv-steps recipe over Plan's canonical IV for an induction of Kind with InductionOpcod...
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
@ Offset
Definition DWP.cpp:578
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr from_range_t from_range
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
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:633
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:2173
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition MathExtras.h:332
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1753
SmallVector< ValueTypeFromRangeType< R >, Size > to_vector(R &&Range)
Given a range of type R, iterate the entire range and return a SmallVector with elements of the vecto...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
@ Default
The result value is uniform if and only if all operands are uniform.
Definition Uniformity.h:20
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866
SCEVUseT< const SCEV * > SCEVUse
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:279