LLVM 22.0.0git
VPlanAnalysis.cpp
Go to the documentation of this file.
1//===- VPlanAnalysis.cpp - Various Analyses working on VPlan ----*- C++ -*-===//
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 "VPlanAnalysis.h"
10#include "VPlan.h"
11#include "VPlanCFG.h"
12#include "VPlanDominatorTree.h"
14#include "llvm/ADT/TypeSwitch.h"
17#include "llvm/IR/Instruction.h"
19
20using namespace llvm;
21
22#define DEBUG_TYPE "vplan"
23
24VPTypeAnalysis::VPTypeAnalysis(const VPlan &Plan) : Ctx(Plan.getContext()) {
25 if (auto LoopRegion = Plan.getVectorLoopRegion()) {
26 if (const auto *CanIV = dyn_cast<VPCanonicalIVPHIRecipe>(
27 &LoopRegion->getEntryBasicBlock()->front())) {
28 CanonicalIVTy = CanIV->getScalarType();
29 return;
30 }
31 }
32
33 // If there's no canonical IV, retrieve the type from the trip count
34 // expression.
35 auto *TC = Plan.getTripCount();
36 if (TC->isLiveIn()) {
37 CanonicalIVTy = TC->getLiveInIRValue()->getType();
38 return;
39 }
40 CanonicalIVTy = cast<VPExpandSCEVRecipe>(TC)->getSCEV()->getType();
41}
42
43Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPBlendRecipe *R) {
44 Type *ResTy = inferScalarType(R->getIncomingValue(0));
45 for (unsigned I = 1, E = R->getNumIncomingValues(); I != E; ++I) {
46 VPValue *Inc = R->getIncomingValue(I);
47 assert(inferScalarType(Inc) == ResTy &&
48 "different types inferred for different incoming values");
49 CachedTypes[Inc] = ResTy;
50 }
51 return ResTy;
52}
53
54Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
55 // Set the result type from the first operand, check if the types for all
56 // other operands match and cache them.
57 auto SetResultTyFromOp = [this, R]() {
58 Type *ResTy = inferScalarType(R->getOperand(0));
59 for (unsigned Op = 1; Op != R->getNumOperands(); ++Op) {
60 VPValue *OtherV = R->getOperand(Op);
61 assert(inferScalarType(OtherV) == ResTy &&
62 "different types inferred for different operands");
63 CachedTypes[OtherV] = ResTy;
64 }
65 return ResTy;
66 };
67
68 unsigned Opcode = R->getOpcode();
70 return SetResultTyFromOp();
71
72 switch (Opcode) {
73 case Instruction::ExtractElement:
74 case Instruction::Freeze:
77 return inferScalarType(R->getOperand(0));
78 case Instruction::Select: {
79 Type *ResTy = inferScalarType(R->getOperand(1));
80 VPValue *OtherV = R->getOperand(2);
81 assert(inferScalarType(OtherV) == ResTy &&
82 "different types inferred for different operands");
83 CachedTypes[OtherV] = ResTy;
84 return ResTy;
85 }
86 case Instruction::ICmp:
87 case Instruction::FCmp:
89 assert(inferScalarType(R->getOperand(0)) ==
90 inferScalarType(R->getOperand(1)) &&
91 "different types inferred for different operands");
92 return IntegerType::get(Ctx, 1);
94 return inferScalarType(R->getOperand(1));
97 return inferScalarType(R->getOperand(0));
98 }
100 return Type::getIntNTy(Ctx, 32);
101 case Instruction::PHI:
102 // Infer the type of first operand only, as other operands of header phi's
103 // may lead to infinite recursion.
104 return inferScalarType(R->getOperand(0));
112 return SetResultTyFromOp();
114 return inferScalarType(R->getOperand(1));
116 return Type::getIntNTy(Ctx, 64);
119 Type *BaseTy = inferScalarType(R->getOperand(0));
120 if (auto *VecTy = dyn_cast<VectorType>(BaseTy))
121 return VecTy->getElementType();
122 return BaseTy;
123 }
125 assert(inferScalarType(R->getOperand(0))->isIntegerTy(1) &&
126 inferScalarType(R->getOperand(1))->isIntegerTy(1) &&
127 "LogicalAnd operands should be bool");
128 return IntegerType::get(Ctx, 1);
132 // Return the type based on first operand.
133 return inferScalarType(R->getOperand(0));
136 return Type::getVoidTy(Ctx);
137 default:
138 break;
139 }
140 // Type inference not implemented for opcode.
141 LLVM_DEBUG({
142 dbgs() << "LV: Found unhandled opcode for: ";
143 R->getVPSingleValue()->dump();
144 });
145 llvm_unreachable("Unhandled opcode!");
146}
147
148Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenRecipe *R) {
149 unsigned Opcode = R->getOpcode();
150 if (Instruction::isBinaryOp(Opcode) || Instruction::isShift(Opcode) ||
152 Type *ResTy = inferScalarType(R->getOperand(0));
153 assert(ResTy == inferScalarType(R->getOperand(1)) &&
154 "types for both operands must match for binary op");
155 CachedTypes[R->getOperand(1)] = ResTy;
156 return ResTy;
157 }
158
159 switch (Opcode) {
160 case Instruction::ICmp:
161 case Instruction::FCmp:
162 return IntegerType::get(Ctx, 1);
163 case Instruction::FNeg:
164 case Instruction::Freeze:
165 return inferScalarType(R->getOperand(0));
166 case Instruction::ExtractValue: {
167 assert(R->getNumOperands() == 2 && "expected single level extractvalue");
168 auto *StructTy = cast<StructType>(inferScalarType(R->getOperand(0)));
169 auto *CI = cast<ConstantInt>(R->getOperand(1)->getLiveInIRValue());
170 return StructTy->getTypeAtIndex(CI->getZExtValue());
171 }
172 default:
173 break;
174 }
175
176 // Type inference not implemented for opcode.
177 LLVM_DEBUG({
178 dbgs() << "LV: Found unhandled opcode for: ";
179 R->getVPSingleValue()->dump();
180 });
181 llvm_unreachable("Unhandled opcode!");
182}
183
184Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenCallRecipe *R) {
185 auto &CI = *cast<CallInst>(R->getUnderlyingInstr());
186 return CI.getType();
187}
188
189Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenMemoryRecipe *R) {
190 assert((isa<VPWidenLoadRecipe, VPWidenLoadEVLRecipe>(R)) &&
191 "Store recipes should not define any values");
192 return cast<LoadInst>(&R->getIngredient())->getType();
193}
194
195Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenSelectRecipe *R) {
196 Type *ResTy = inferScalarType(R->getOperand(1));
197 VPValue *OtherV = R->getOperand(2);
198 assert(inferScalarType(OtherV) == ResTy &&
199 "different types inferred for different operands");
200 CachedTypes[OtherV] = ResTy;
201 return ResTy;
202}
203
204Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPReplicateRecipe *R) {
205 unsigned Opcode = R->getUnderlyingInstr()->getOpcode();
206
207 if (Instruction::isBinaryOp(Opcode) || Instruction::isShift(Opcode) ||
209 Type *ResTy = inferScalarType(R->getOperand(0));
210 assert(ResTy == inferScalarType(R->getOperand(1)) &&
211 "inferred types for operands of binary op don't match");
212 CachedTypes[R->getOperand(1)] = ResTy;
213 return ResTy;
214 }
215
216 if (Instruction::isCast(Opcode))
217 return R->getUnderlyingInstr()->getType();
218
219 switch (Opcode) {
220 case Instruction::Call: {
221 unsigned CallIdx = R->getNumOperands() - (R->isPredicated() ? 2 : 1);
222 return cast<Function>(R->getOperand(CallIdx)->getLiveInIRValue())
223 ->getReturnType();
224 }
225 case Instruction::Select: {
226 Type *ResTy = inferScalarType(R->getOperand(1));
227 assert(ResTy == inferScalarType(R->getOperand(2)) &&
228 "inferred types for operands of select op don't match");
229 CachedTypes[R->getOperand(2)] = ResTy;
230 return ResTy;
231 }
232 case Instruction::ICmp:
233 case Instruction::FCmp:
234 return IntegerType::get(Ctx, 1);
235 case Instruction::Alloca:
236 case Instruction::ExtractValue:
237 return R->getUnderlyingInstr()->getType();
238 case Instruction::Freeze:
239 case Instruction::FNeg:
240 case Instruction::GetElementPtr:
241 return inferScalarType(R->getOperand(0));
242 case Instruction::Load:
243 return cast<LoadInst>(R->getUnderlyingInstr())->getType();
244 case Instruction::Store:
245 // FIXME: VPReplicateRecipes with store opcodes still define a result
246 // VPValue, so we need to handle them here. Remove the code here once this
247 // is modeled accurately in VPlan.
248 return Type::getVoidTy(Ctx);
249 default:
250 break;
251 }
252 // Type inference not implemented for opcode.
253 LLVM_DEBUG({
254 dbgs() << "LV: Found unhandled opcode for: ";
255 R->getVPSingleValue()->dump();
256 });
257 llvm_unreachable("Unhandled opcode");
258}
259
261 if (Type *CachedTy = CachedTypes.lookup(V))
262 return CachedTy;
263
264 if (V->isLiveIn()) {
265 if (auto *IRValue = V->getLiveInIRValue())
266 return IRValue->getType();
267 // All VPValues without any underlying IR value (like the vector trip count
268 // or the backedge-taken count) have the same type as the canonical IV.
269 return CanonicalIVTy;
270 }
271
272 Type *ResultTy =
273 TypeSwitch<const VPRecipeBase *, Type *>(V->getDefiningRecipe())
277 [this](const auto *R) {
278 // Handle header phi recipes, except VPWidenIntOrFpInduction
279 // which needs special handling due it being possibly truncated.
280 // TODO: consider inferring/caching type of siblings, e.g.,
281 // backedge value, here and in cases below.
282 return inferScalarType(R->getStartValue());
283 })
284 .Case<VPWidenIntOrFpInductionRecipe, VPDerivedIVRecipe>(
285 [](const auto *R) { return R->getScalarType(); })
289 VPPartialReductionRecipe>([this](const VPRecipeBase *R) {
290 return inferScalarType(R->getOperand(0));
291 })
292 // VPInstructionWithType must be handled before VPInstruction.
295 [](const auto *R) { return R->getResultType(); })
298 [this](const auto *R) { return inferScalarTypeForRecipe(R); })
299 .Case<VPInterleaveRecipe>([V](const VPInterleaveRecipe *R) {
300 // TODO: Use info from interleave group.
301 return V->getUnderlyingValue()->getType();
302 })
303 .Case<VPExpandSCEVRecipe>([](const VPExpandSCEVRecipe *R) {
304 return R->getSCEV()->getType();
305 })
306 .Case<VPReductionRecipe>([this](const auto *R) {
307 return inferScalarType(R->getChainOp());
308 })
309 .Case<VPExpressionRecipe>([this](const auto *R) {
310 return inferScalarType(R->getOperandOfResultType());
311 });
312
313 assert(ResultTy && "could not infer type for the given VPValue");
314 CachedTypes[V] = ResultTy;
315 return ResultTy;
316}
317
319 VPlan &Plan, DenseSet<VPRecipeBase *> &EphRecipes) {
320 // First, collect seed recipes which are operands of assumes.
322 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
324 for (VPRecipeBase &R : *VPBB) {
325 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
326 if (!RepR || !match(RepR->getUnderlyingInstr(),
327 PatternMatch::m_Intrinsic<Intrinsic::assume>()))
328 continue;
329 Worklist.push_back(RepR);
330 EphRecipes.insert(RepR);
331 }
332 }
333
334 // Process operands of candidates in worklist and add them to the set of
335 // ephemeral recipes, if they don't have side-effects and are only used by
336 // other ephemeral recipes.
337 while (!Worklist.empty()) {
338 VPRecipeBase *Cur = Worklist.pop_back_val();
339 for (VPValue *Op : Cur->operands()) {
340 auto *OpR = Op->getDefiningRecipe();
341 if (!OpR || OpR->mayHaveSideEffects() || EphRecipes.contains(OpR))
342 continue;
343 if (any_of(Op->users(), [EphRecipes](VPUser *U) {
344 auto *UR = dyn_cast<VPRecipeBase>(U);
345 return !UR || !EphRecipes.contains(UR);
346 }))
347 continue;
348 EphRecipes.insert(OpR);
349 Worklist.push_back(OpR);
350 }
351 }
352}
353
354template void DomTreeBuilder::Calculate<DominatorTreeBase<VPBlockBase, false>>(
356
358 const VPRecipeBase *B) {
359 if (A == B)
360 return false;
361
362 auto LocalComesBefore = [](const VPRecipeBase *A, const VPRecipeBase *B) {
363 for (auto &R : *A->getParent()) {
364 if (&R == A)
365 return true;
366 if (&R == B)
367 return false;
368 }
369 llvm_unreachable("recipe not found");
370 };
371 const VPBlockBase *ParentA = A->getParent();
372 const VPBlockBase *ParentB = B->getParent();
373 if (ParentA == ParentB)
374 return LocalComesBefore(A, B);
375
376#ifndef NDEBUG
377 auto GetReplicateRegion = [](VPRecipeBase *R) -> VPRegionBlock * {
378 auto *Region = dyn_cast_or_null<VPRegionBlock>(R->getParent()->getParent());
379 if (Region && Region->isReplicator()) {
380 assert(Region->getNumSuccessors() == 1 &&
381 Region->getNumPredecessors() == 1 && "Expected SESE region!");
382 assert(R->getParent()->size() == 1 &&
383 "A recipe in an original replicator region must be the only "
384 "recipe in its block");
385 return Region;
386 }
387 return nullptr;
388 };
389 assert(!GetReplicateRegion(const_cast<VPRecipeBase *>(A)) &&
390 "No replicate regions expected at this point");
391 assert(!GetReplicateRegion(const_cast<VPRecipeBase *>(B)) &&
392 "No replicate regions expected at this point");
393#endif
394 return Base::properlyDominates(ParentA, ParentB);
395}
396
397/// Get the VF scaling factor applied to the recipe's output, if the recipe has
398/// one.
399static unsigned getVFScaleFactor(VPRecipeBase *R) {
400 if (auto *RR = dyn_cast<VPReductionPHIRecipe>(R))
401 return RR->getVFScaleFactor();
402 if (auto *RR = dyn_cast<VPPartialReductionRecipe>(R))
403 return RR->getVFScaleFactor();
404 assert(
405 (!isa<VPInstruction>(R) || cast<VPInstruction>(R)->getOpcode() !=
407 "getting scaling factor of reduction-start-vector not implemented yet");
408 return 1;
409}
410
412 unsigned OverrideMaxNumRegs) const {
413 return any_of(MaxLocalUsers, [&TTI, &OverrideMaxNumRegs](auto &LU) {
414 return LU.second > (OverrideMaxNumRegs > 0
415 ? OverrideMaxNumRegs
416 : TTI.getNumberOfRegisters(LU.first));
417 });
418}
419
422 const SmallPtrSetImpl<const Value *> &ValuesToIgnore) {
423 // Each 'key' in the map opens a new interval. The values
424 // of the map are the index of the 'last seen' usage of the
425 // recipe that is the key.
427
428 // Maps indices to recipes.
430 // Marks the end of each interval.
431 IntervalMap EndPoint;
432 // Saves the list of recipe indices that are used in the loop.
434 // Saves the list of values that are used in the loop but are defined outside
435 // the loop (not including non-recipe values such as arguments and
436 // constants).
437 SmallSetVector<VPValue *, 8> LoopInvariants;
438 LoopInvariants.insert(&Plan.getVectorTripCount());
439
440 // We scan the loop in a topological order in order and assign a number to
441 // each recipe. We use RPO to ensure that defs are met before their users. We
442 // assume that each recipe that has in-loop users starts an interval. We
443 // record every time that an in-loop value is used, so we have a list of the
444 // first and last occurrences of each recipe.
445 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
447 LoopRegion);
448 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(RPOT)) {
449 if (!VPBB->getParent())
450 break;
451 for (VPRecipeBase &R : *VPBB) {
452 Idx2Recipe.push_back(&R);
453
454 // Save the end location of each USE.
455 for (VPValue *U : R.operands()) {
456 auto *DefR = U->getDefiningRecipe();
457
458 // Ignore non-recipe values such as arguments, constants, etc.
459 // FIXME: Might need some motivation why these values are ignored. If
460 // for example an argument is used inside the loop it will increase the
461 // register pressure (so shouldn't we add it to LoopInvariants).
462 if (!DefR && (!U->getLiveInIRValue() ||
463 !isa<Instruction>(U->getLiveInIRValue())))
464 continue;
465
466 // If this recipe is outside the loop then record it and continue.
467 if (!DefR) {
468 LoopInvariants.insert(U);
469 continue;
470 }
471
472 // Overwrite previous end points.
473 EndPoint[DefR] = Idx2Recipe.size();
474 Ends.insert(DefR);
475 }
476 }
477 if (VPBB == LoopRegion->getExiting()) {
478 // VPWidenIntOrFpInductionRecipes are used implicitly at the end of the
479 // exiting block, where their increment will get materialized eventually.
480 for (auto &R : LoopRegion->getEntryBasicBlock()->phis()) {
481 if (isa<VPWidenIntOrFpInductionRecipe>(&R)) {
482 EndPoint[&R] = Idx2Recipe.size();
483 Ends.insert(&R);
484 }
485 }
486 }
487 }
488
489 // Saves the list of intervals that end with the index in 'key'.
490 using RecipeList = SmallVector<VPRecipeBase *, 2>;
492
493 // Next, we transpose the EndPoints into a multi map that holds the list of
494 // intervals that *end* at a specific location.
495 for (auto &Interval : EndPoint)
496 TransposeEnds[Interval.second].push_back(Interval.first);
497
498 SmallPtrSet<VPRecipeBase *, 8> OpenIntervals;
501
502 LLVM_DEBUG(dbgs() << "LV(REG): Calculating max register usage:\n");
503
504 VPTypeAnalysis TypeInfo(Plan);
505
506 const auto &TTICapture = TTI;
507 auto GetRegUsage = [&TTICapture](Type *Ty, ElementCount VF) -> unsigned {
508 if (Ty->isTokenTy() || !VectorType::isValidElementType(Ty) ||
509 (VF.isScalable() &&
510 !TTICapture.isElementTypeLegalForScalableVector(Ty)))
511 return 0;
512 return TTICapture.getRegUsageForType(VectorType::get(Ty, VF));
513 };
514
515 // We scan the instructions linearly and record each time that a new interval
516 // starts, by placing it in a set. If we find this value in TransposEnds then
517 // we remove it from the set. The max register usage is the maximum register
518 // usage of the recipes of the set.
519 for (unsigned int Idx = 0, Sz = Idx2Recipe.size(); Idx < Sz; ++Idx) {
520 VPRecipeBase *R = Idx2Recipe[Idx];
521
522 // Remove all of the recipes that end at this location.
523 RecipeList &List = TransposeEnds[Idx];
524 for (VPRecipeBase *ToRemove : List)
525 OpenIntervals.erase(ToRemove);
526
527 // Ignore recipes that are never used within the loop and do not have side
528 // effects.
529 if (!Ends.count(R) && !R->mayHaveSideEffects())
530 continue;
531
532 // Skip recipes for ignored values.
533 // TODO: Should mark recipes for ephemeral values that cannot be removed
534 // explictly in VPlan.
535 if (isa<VPSingleDefRecipe>(R) &&
536 ValuesToIgnore.contains(
537 cast<VPSingleDefRecipe>(R)->getUnderlyingValue()))
538 continue;
539
540 // For each VF find the maximum usage of registers.
541 for (unsigned J = 0, E = VFs.size(); J < E; ++J) {
542 // Count the number of registers used, per register class, given all open
543 // intervals.
544 // Note that elements in this SmallMapVector will be default constructed
545 // as 0. So we can use "RegUsage[ClassID] += n" in the code below even if
546 // there is no previous entry for ClassID.
548
549 for (auto *R : OpenIntervals) {
550 // Skip recipes that weren't present in the original loop.
551 // TODO: Remove after removing the legacy
552 // LoopVectorizationCostModel::calculateRegisterUsage
555 continue;
556
557 if (VFs[J].isScalar() ||
560 (isa<VPInstruction>(R) &&
561 vputils::onlyScalarValuesUsed(cast<VPSingleDefRecipe>(R))) ||
562 (isa<VPReductionPHIRecipe>(R) &&
563 (cast<VPReductionPHIRecipe>(R))->isInLoop())) {
564 unsigned ClassID = TTI.getRegisterClassForType(
565 false, TypeInfo.inferScalarType(R->getVPSingleValue()));
566 // FIXME: The target might use more than one register for the type
567 // even in the scalar case.
568 RegUsage[ClassID] += 1;
569 } else {
570 // The output from scaled phis and scaled reductions actually has
571 // fewer lanes than the VF.
572 unsigned ScaleFactor = getVFScaleFactor(R);
573 ElementCount VF = VFs[J].divideCoefficientBy(ScaleFactor);
574 LLVM_DEBUG(if (VF != VFs[J]) {
575 dbgs() << "LV(REG): Scaled down VF from " << VFs[J] << " to " << VF
576 << " for " << *R << "\n";
577 });
578
579 for (VPValue *DefV : R->definedValues()) {
580 Type *ScalarTy = TypeInfo.inferScalarType(DefV);
581 unsigned ClassID = TTI.getRegisterClassForType(true, ScalarTy);
582 RegUsage[ClassID] += GetRegUsage(ScalarTy, VF);
583 }
584 }
585 }
586
587 for (const auto &Pair : RegUsage) {
588 auto &Entry = MaxUsages[J][Pair.first];
589 Entry = std::max(Entry, Pair.second);
590 }
591 }
592
593 LLVM_DEBUG(dbgs() << "LV(REG): At #" << Idx << " Interval # "
594 << OpenIntervals.size() << '\n');
595
596 // Add the current recipe to the list of open intervals.
597 OpenIntervals.insert(R);
598 }
599
600 // We also search for instructions that are defined outside the loop, but are
601 // used inside the loop. We need this number separately from the max-interval
602 // usage number because when we unroll, loop-invariant values do not take
603 // more register.
605 for (unsigned Idx = 0, End = VFs.size(); Idx < End; ++Idx) {
606 // Note that elements in this SmallMapVector will be default constructed
607 // as 0. So we can use "Invariant[ClassID] += n" in the code below even if
608 // there is no previous entry for ClassID.
610
611 for (auto *In : LoopInvariants) {
612 // FIXME: The target might use more than one register for the type
613 // even in the scalar case.
614 bool IsScalar = vputils::onlyScalarValuesUsed(In);
615
616 ElementCount VF = IsScalar ? ElementCount::getFixed(1) : VFs[Idx];
617 unsigned ClassID = TTI.getRegisterClassForType(
618 VF.isVector(), TypeInfo.inferScalarType(In));
619 Invariant[ClassID] += GetRegUsage(TypeInfo.inferScalarType(In), VF);
620 }
621
622 LLVM_DEBUG({
623 dbgs() << "LV(REG): VF = " << VFs[Idx] << '\n';
624 dbgs() << "LV(REG): Found max usage: " << MaxUsages[Idx].size()
625 << " item\n";
626 for (const auto &pair : MaxUsages[Idx]) {
627 dbgs() << "LV(REG): RegisterClass: "
628 << TTI.getRegisterClassName(pair.first) << ", " << pair.second
629 << " registers\n";
630 }
631 dbgs() << "LV(REG): Found invariant usage: " << Invariant.size()
632 << " item\n";
633 for (const auto &pair : Invariant) {
634 dbgs() << "LV(REG): RegisterClass: "
635 << TTI.getRegisterClassName(pair.first) << ", " << pair.second
636 << " registers\n";
637 }
638 });
639
640 RU.LoopInvariantRegs = Invariant;
641 RU.MaxLocalUsers = MaxUsages[Idx];
642 RUs[Idx] = RU;
643 }
644
645 return RUs;
646}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefAnalysis InstSet & ToRemove
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
bool End
Definition: ELF_riscv.cpp:480
#define I(x, y, z)
Definition: MD5.cpp:58
std::pair< uint64_t, uint64_t > Interval
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
#define LLVM_DEBUG(...)
Definition: Debug.h:119
This pass exposes codegen information to IR-level passes.
This file implements the TypeSwitch template, which mimics a switch() statement whose cases are type ...
static unsigned getVFScaleFactor(VPRecipeBase *R)
Get the VF scaling factor applied to the recipe's output, if the recipe has one.
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
static std::optional< unsigned > getOpcode(ArrayRef< VPValue * > Values)
Returns the opcode of Values or ~0 if they do not all agree.
Definition: VPlanSLP.cpp:247
This file contains the declarations of the Vectorization Plan base classes:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
This class represents an Operation in the Expression.
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
Core dominator tree base class.
bool properlyDominates(const DomTreeNodeBase< VPBlockBase > *A, const DomTreeNodeBase< VPBlockBase > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
constexpr bool isVector() const
One or more elements.
Definition: TypeSize.h:327
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition: TypeSize.h:312
bool isCast() const
Definition: Instruction.h:321
bool isBinaryOp() const
Definition: Instruction.h:317
bool isBitwiseLogicOp() const
Return true if this is and/or/xor.
Definition: Instruction.h:371
bool isShift() const
Definition: Instruction.h:320
bool isUnaryOp() const
Definition: Instruction.h:316
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Definition: Type.cpp:319
size_type size() const
Definition: MapVector.h:56
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:168
size_type size() const
Definition: SmallPtrSet.h:99
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:380
bool erase(PtrType Ptr)
Remove pointer from the set.
Definition: SmallPtrSet.h:418
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:470
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:401
bool contains(ConstPtrType Ptr) const
Definition: SmallPtrSet.h:476
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:356
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
LLVM_ABI unsigned getRegUsageForType(Type *Ty) const
Returns the estimated number of registers required to represent Ty.
LLVM_ABI unsigned getRegisterClassForType(bool Vector, Type *Ty=nullptr) const
LLVM_ABI const char * getRegisterClassName(unsigned ClassID) const
LLVM_ABI unsigned getNumberOfRegisters(unsigned ClassID) const
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
Definition: TypeSwitch.h:87
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition: TypeSwitch.h:96
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:240
bool isTokenTy() const
Return true if this is 'token'.
Definition: Type.h:234
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition: Type.h:352
A recipe for generating the active lane mask for the vector loop that is used to predicate the vector...
Definition: VPlan.h:3352
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition: VPlan.h:3639
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition: VPlan.h:3727
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
Definition: VPlan.h:2374
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition: VPlan.h:81
const VPBasicBlock * getEntryBasicBlock() const
Definition: VPlan.cpp:160
A recipe for generating conditional branches on the bits of a mask.
Definition: VPlan.h:2809
Canonical scalar induction phi of the vector loop.
Definition: VPlan.h:3295
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition: VPlan.h:3460
bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B)
A recipe for generating the phi node for the current index of elements, adjusted in accordance with E...
Definition: VPlan.h:3383
Recipe to expand a SCEV expression.
Definition: VPlan.h:3258
A specialization of VPInstruction augmenting it with a dedicated result type, to be used when the opc...
Definition: VPlan.h:1172
This is a concrete Recipe that models a single VPlan-level instruction.
Definition: VPlan.h:967
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
Definition: VPlan.h:1040
@ ComputeAnyOfResult
Compute the final result of a AnyOf reduction with select(cmp(),x,y), where one of (x,...
Definition: VPlan.h:996
@ ExtractPenultimateElement
Definition: VPlan.h:1006
@ ResumeForEpilogue
Explicit user for the resume phi of the canonical induction in the main VPlan, used by the epilogue v...
Definition: VPlan.h:1043
@ FirstOrderRecurrenceSplice
Definition: VPlan.h:973
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition: VPlan.h:1034
@ BuildVector
Creates a fixed-width vector containing all operands.
Definition: VPlan.h:993
@ BuildStructVector
Given operands of (the same) struct type, creates a struct of fixed- width vectors each containing a ...
Definition: VPlan.h:990
@ CanonicalIVIncrementForPart
Definition: VPlan.h:983
@ ComputeReductionResult
Definition: VPlan.h:998
@ CalculateTripCountMinusVF
Definition: VPlan.h:981
VPInterleaveRecipe is a recipe for transforming an interleave group of load or stores into one wide l...
Definition: VPlan.h:2443
A recipe for forming partial reductions.
Definition: VPlan.h:2628
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
Definition: VPlan.h:2966
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition: VPlan.h:391
A recipe for handling reduction phis.
Definition: VPlan.h:2302
A recipe to represent inloop reduction operations, performing a reduction on a vector operand into a ...
Definition: VPlan.h:2541
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition: VPlan.h:3827
const VPBlockBase * getEntry() const
Definition: VPlan.h:3863
const VPBlockBase * getExiting() const
Definition: VPlan.h:3875
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition: VPlan.h:2731
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition: VPlan.h:3529
An analysis for type-inference for VPValues.
Definition: VPlanAnalysis.h:43
Type * inferScalarType(const VPValue *V)
Infer the type of V. Returns the scalar type of V.
VPTypeAnalysis(const VPlan &Plan)
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition: VPlanValue.h:197
operand_range operands()
Definition: VPlanValue.h:265
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition: VPlan.h:1817
A recipe to compute the pointers for widened memory accesses of IndexTy.
Definition: VPlan.h:1876
A recipe for widening Call instructions using library calls.
Definition: VPlan.h:1613
A Recipe for widening the canonical induction variable of the vector loop.
Definition: VPlan.h:3424
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition: VPlan.h:1467
A recipe for handling GEP instructions.
Definition: VPlan.h:1753
A recipe for widening vector intrinsics.
Definition: VPlan.h:1524
A common base class for widening memory operations.
Definition: VPlan.h:3008
A recipe for widened phis.
Definition: VPlan.h:2224
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition: VPlan.h:1424
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition: VPlan.h:3930
VPValue & getVectorTripCount()
The vector trip count.
Definition: VPlan.h:4119
VPValue * getTripCount() const
The trip count of the original loop.
Definition: VPlan.h:4091
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition: VPlan.cpp:1037
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
static LLVM_ABI bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition: DenseSet.h:169
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:49
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
Definition: VPlanUtils.cpp:27
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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:243
SmallVector< VPRegisterUsage, 8 > calculateRegisterUsageForPlan(VPlan &Plan, ArrayRef< ElementCount > VFs, const TargetTransformInfo &TTI, const SmallPtrSetImpl< const Value * > &ValuesToIgnore)
Estimate the register usage for Plan and vectorization factors in VFs by calculating the highest numb...
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:1751
void collectEphemeralRecipesForVPlan(VPlan &Plan, DenseSet< VPRecipeBase * > &EphRecipes)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
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:548
TargetTransformInfo TTI
DWARFExpression::Operation Op
A MapVector that performs no allocations if smaller than a certain size.
Definition: MapVector.h:249
A recipe for handling first-order recurrence phis.
Definition: VPlan.h:2267
A struct that represents some properties of the register usage of a loop.
Definition: VPlanAnalysis.h:76
SmallMapVector< unsigned, unsigned, 4 > MaxLocalUsers
Holds the maximum number of concurrent live intervals in the loop.
Definition: VPlanAnalysis.h:82
bool exceedsMaxNumRegs(const TargetTransformInfo &TTI, unsigned OverrideMaxNumRegs=0) const
Check if any of the tracked live intervals exceeds the number of available registers for the target.
SmallMapVector< unsigned, unsigned, 4 > LoopInvariantRegs
Holds the number of loop invariant values that are used in the loop.
Definition: VPlanAnalysis.h:79
A recipe for widening select instructions.
Definition: VPlan.h:1707