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"
13#include "VPlanHelpers.h"
15#include "llvm/ADT/TypeSwitch.h"
18#include "llvm/IR/Instruction.h"
20
21using namespace llvm;
22
23#define DEBUG_TYPE "vplan"
24
26 if (auto LoopRegion = Plan.getVectorLoopRegion()) {
27 if (const auto *CanIV = dyn_cast<VPCanonicalIVPHIRecipe>(
28 &LoopRegion->getEntryBasicBlock()->front())) {
29 CanonicalIVTy = CanIV->getScalarType();
30 return;
31 }
32 }
33
34 // If there's no canonical IV, retrieve the type from the trip count
35 // expression.
36 auto *TC = Plan.getTripCount();
37 if (TC->isLiveIn()) {
38 CanonicalIVTy = TC->getLiveInIRValue()->getType();
39 return;
40 }
41 CanonicalIVTy = cast<VPExpandSCEVRecipe>(TC)->getSCEV()->getType();
42}
43
44Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPBlendRecipe *R) {
45 Type *ResTy = inferScalarType(R->getIncomingValue(0));
46 for (unsigned I = 1, E = R->getNumIncomingValues(); I != E; ++I) {
47 VPValue *Inc = R->getIncomingValue(I);
48 assert(inferScalarType(Inc) == ResTy &&
49 "different types inferred for different incoming values");
50 CachedTypes[Inc] = ResTy;
51 }
52 return ResTy;
53}
54
55Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
56 // Set the result type from the first operand, check if the types for all
57 // other operands match and cache them.
58 auto SetResultTyFromOp = [this, R]() {
59 Type *ResTy = inferScalarType(R->getOperand(0));
60 for (unsigned Op = 1; Op != R->getNumOperands(); ++Op) {
61 VPValue *OtherV = R->getOperand(Op);
62 assert(inferScalarType(OtherV) == ResTy &&
63 "different types inferred for different operands");
64 CachedTypes[OtherV] = ResTy;
65 }
66 return ResTy;
67 };
68
69 unsigned Opcode = R->getOpcode();
71 return SetResultTyFromOp();
72
73 switch (Opcode) {
74 case Instruction::ExtractElement:
75 case Instruction::Freeze:
78 return inferScalarType(R->getOperand(0));
79 case Instruction::Select: {
80 Type *ResTy = inferScalarType(R->getOperand(1));
81 VPValue *OtherV = R->getOperand(2);
82 assert(inferScalarType(OtherV) == ResTy &&
83 "different types inferred for different operands");
84 CachedTypes[OtherV] = ResTy;
85 return ResTy;
86 }
87 case Instruction::ICmp:
88 case Instruction::FCmp:
90 assert(inferScalarType(R->getOperand(0)) ==
91 inferScalarType(R->getOperand(1)) &&
92 "different types inferred for different operands");
93 return IntegerType::get(Ctx, 1);
95 return inferScalarType(R->getOperand(1));
98 return inferScalarType(R->getOperand(0));
99 }
101 return Type::getIntNTy(Ctx, 32);
102 case Instruction::PHI:
103 // Infer the type of first operand only, as other operands of header phi's
104 // may lead to infinite recursion.
105 return inferScalarType(R->getOperand(0));
113 return SetResultTyFromOp();
115 return inferScalarType(R->getOperand(1));
117 return Type::getIntNTy(Ctx, 64);
121 Type *BaseTy = inferScalarType(R->getOperand(0));
122 if (auto *VecTy = dyn_cast<VectorType>(BaseTy))
123 return VecTy->getElementType();
124 return BaseTy;
125 }
127 assert(inferScalarType(R->getOperand(0))->isIntegerTy(1) &&
128 inferScalarType(R->getOperand(1))->isIntegerTy(1) &&
129 "LogicalAnd operands should be bool");
130 return IntegerType::get(Ctx, 1);
134 // Return the type based on first operand.
135 return inferScalarType(R->getOperand(0));
138 return Type::getVoidTy(Ctx);
139 default:
140 break;
141 }
142 // Type inference not implemented for opcode.
143 LLVM_DEBUG({
144 dbgs() << "LV: Found unhandled opcode for: ";
145 R->getVPSingleValue()->dump();
146 });
147 llvm_unreachable("Unhandled opcode!");
148}
149
150Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenRecipe *R) {
151 unsigned Opcode = R->getOpcode();
152 if (Instruction::isBinaryOp(Opcode) || Instruction::isShift(Opcode) ||
154 Type *ResTy = inferScalarType(R->getOperand(0));
155 assert(ResTy == inferScalarType(R->getOperand(1)) &&
156 "types for both operands must match for binary op");
157 CachedTypes[R->getOperand(1)] = ResTy;
158 return ResTy;
159 }
160
161 switch (Opcode) {
162 case Instruction::ICmp:
163 case Instruction::FCmp:
164 return IntegerType::get(Ctx, 1);
165 case Instruction::FNeg:
166 case Instruction::Freeze:
167 return inferScalarType(R->getOperand(0));
168 case Instruction::ExtractValue: {
169 assert(R->getNumOperands() == 2 && "expected single level extractvalue");
170 auto *StructTy = cast<StructType>(inferScalarType(R->getOperand(0)));
171 auto *CI = cast<ConstantInt>(R->getOperand(1)->getLiveInIRValue());
172 return StructTy->getTypeAtIndex(CI->getZExtValue());
173 }
174 default:
175 break;
176 }
177
178 // Type inference not implemented for opcode.
179 LLVM_DEBUG({
180 dbgs() << "LV: Found unhandled opcode for: ";
181 R->getVPSingleValue()->dump();
182 });
183 llvm_unreachable("Unhandled opcode!");
184}
185
186Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenCallRecipe *R) {
187 auto &CI = *cast<CallInst>(R->getUnderlyingInstr());
188 return CI.getType();
189}
190
191Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenMemoryRecipe *R) {
193 "Store recipes should not define any values");
194 return cast<LoadInst>(&R->getIngredient())->getType();
195}
196
197Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenSelectRecipe *R) {
198 Type *ResTy = inferScalarType(R->getOperand(1));
199 VPValue *OtherV = R->getOperand(2);
200 assert(inferScalarType(OtherV) == ResTy &&
201 "different types inferred for different operands");
202 CachedTypes[OtherV] = ResTy;
203 return ResTy;
204}
205
206Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPReplicateRecipe *R) {
207 unsigned Opcode = R->getUnderlyingInstr()->getOpcode();
208
209 if (Instruction::isBinaryOp(Opcode) || Instruction::isShift(Opcode) ||
211 Type *ResTy = inferScalarType(R->getOperand(0));
212 assert(ResTy == inferScalarType(R->getOperand(1)) &&
213 "inferred types for operands of binary op don't match");
214 CachedTypes[R->getOperand(1)] = ResTy;
215 return ResTy;
216 }
217
218 if (Instruction::isCast(Opcode))
219 return R->getUnderlyingInstr()->getType();
220
221 switch (Opcode) {
222 case Instruction::Call: {
223 unsigned CallIdx = R->getNumOperands() - (R->isPredicated() ? 2 : 1);
224 return cast<Function>(R->getOperand(CallIdx)->getLiveInIRValue())
225 ->getReturnType();
226 }
227 case Instruction::Select: {
228 Type *ResTy = inferScalarType(R->getOperand(1));
229 assert(ResTy == inferScalarType(R->getOperand(2)) &&
230 "inferred types for operands of select op don't match");
231 CachedTypes[R->getOperand(2)] = ResTy;
232 return ResTy;
233 }
234 case Instruction::ICmp:
235 case Instruction::FCmp:
236 return IntegerType::get(Ctx, 1);
237 case Instruction::Alloca:
238 case Instruction::ExtractValue:
239 return R->getUnderlyingInstr()->getType();
240 case Instruction::Freeze:
241 case Instruction::FNeg:
242 case Instruction::GetElementPtr:
243 return inferScalarType(R->getOperand(0));
244 case Instruction::Load:
245 return cast<LoadInst>(R->getUnderlyingInstr())->getType();
246 case Instruction::Store:
247 // FIXME: VPReplicateRecipes with store opcodes still define a result
248 // VPValue, so we need to handle them here. Remove the code here once this
249 // is modeled accurately in VPlan.
250 return Type::getVoidTy(Ctx);
251 default:
252 break;
253 }
254 // Type inference not implemented for opcode.
255 LLVM_DEBUG({
256 dbgs() << "LV: Found unhandled opcode for: ";
257 R->getVPSingleValue()->dump();
258 });
259 llvm_unreachable("Unhandled opcode");
260}
261
263 if (Type *CachedTy = CachedTypes.lookup(V))
264 return CachedTy;
265
266 if (V->isLiveIn()) {
267 if (auto *IRValue = V->getLiveInIRValue())
268 return IRValue->getType();
269 // All VPValues without any underlying IR value (like the vector trip count
270 // or the backedge-taken count) have the same type as the canonical IV.
271 return CanonicalIVTy;
272 }
273
274 Type *ResultTy =
275 TypeSwitch<const VPRecipeBase *, Type *>(V->getDefiningRecipe())
279 [this](const auto *R) {
280 // Handle header phi recipes, except VPWidenIntOrFpInduction
281 // which needs special handling due it being possibly truncated.
282 // TODO: consider inferring/caching type of siblings, e.g.,
283 // backedge value, here and in cases below.
284 return inferScalarType(R->getStartValue());
285 })
286 .Case<VPWidenIntOrFpInductionRecipe, VPDerivedIVRecipe>(
287 [](const auto *R) { return R->getScalarType(); })
291 VPPartialReductionRecipe>([this](const VPRecipeBase *R) {
292 return inferScalarType(R->getOperand(0));
293 })
294 // VPInstructionWithType must be handled before VPInstruction.
297 [](const auto *R) { return R->getResultType(); })
300 [this](const auto *R) { return inferScalarTypeForRecipe(R); })
301 .Case<VPInterleaveBase>([V](const auto *R) {
302 // TODO: Use info from interleave group.
303 return V->getUnderlyingValue()->getType();
304 })
305 .Case<VPExpandSCEVRecipe>([](const VPExpandSCEVRecipe *R) {
306 return R->getSCEV()->getType();
307 })
308 .Case<VPReductionRecipe>([this](const auto *R) {
309 return inferScalarType(R->getChainOp());
310 })
311 .Case<VPExpressionRecipe>([this](const auto *R) {
312 return inferScalarType(R->getOperandOfResultType());
313 });
314
315 assert(ResultTy && "could not infer type for the given VPValue");
316 CachedTypes[V] = ResultTy;
317 return ResultTy;
318}
319
321 VPlan &Plan, DenseSet<VPRecipeBase *> &EphRecipes) {
322 // First, collect seed recipes which are operands of assumes.
326 for (VPRecipeBase &R : *VPBB) {
327 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
328 if (!RepR || !match(RepR->getUnderlyingInstr(),
330 continue;
331 Worklist.push_back(RepR);
332 EphRecipes.insert(RepR);
333 }
334 }
335
336 // Process operands of candidates in worklist and add them to the set of
337 // ephemeral recipes, if they don't have side-effects and are only used by
338 // other ephemeral recipes.
339 while (!Worklist.empty()) {
340 VPRecipeBase *Cur = Worklist.pop_back_val();
341 for (VPValue *Op : Cur->operands()) {
342 auto *OpR = Op->getDefiningRecipe();
343 if (!OpR || OpR->mayHaveSideEffects() || EphRecipes.contains(OpR))
344 continue;
345 if (any_of(Op->users(), [EphRecipes](VPUser *U) {
346 auto *UR = dyn_cast<VPRecipeBase>(U);
347 return !UR || !EphRecipes.contains(UR);
348 }))
349 continue;
350 EphRecipes.insert(OpR);
351 Worklist.push_back(OpR);
352 }
353 }
354}
355
358
360 const VPRecipeBase *B) {
361 if (A == B)
362 return false;
363
364 auto LocalComesBefore = [](const VPRecipeBase *A, const VPRecipeBase *B) {
365 for (auto &R : *A->getParent()) {
366 if (&R == A)
367 return true;
368 if (&R == B)
369 return false;
370 }
371 llvm_unreachable("recipe not found");
372 };
373 const VPBlockBase *ParentA = A->getParent();
374 const VPBlockBase *ParentB = B->getParent();
375 if (ParentA == ParentB)
376 return LocalComesBefore(A, B);
377
378#ifndef NDEBUG
379 auto GetReplicateRegion = [](VPRecipeBase *R) -> VPRegionBlock * {
380 auto *Region = dyn_cast_or_null<VPRegionBlock>(R->getParent()->getParent());
381 if (Region && Region->isReplicator()) {
382 assert(Region->getNumSuccessors() == 1 &&
383 Region->getNumPredecessors() == 1 && "Expected SESE region!");
384 assert(R->getParent()->size() == 1 &&
385 "A recipe in an original replicator region must be the only "
386 "recipe in its block");
387 return Region;
388 }
389 return nullptr;
390 };
391 assert(!GetReplicateRegion(const_cast<VPRecipeBase *>(A)) &&
392 "No replicate regions expected at this point");
393 assert(!GetReplicateRegion(const_cast<VPRecipeBase *>(B)) &&
394 "No replicate regions expected at this point");
395#endif
396 return Base::properlyDominates(ParentA, ParentB);
397}
398
400 unsigned OverrideMaxNumRegs) const {
401 return any_of(MaxLocalUsers, [&TTI, &OverrideMaxNumRegs](auto &LU) {
402 return LU.second > (OverrideMaxNumRegs > 0
403 ? OverrideMaxNumRegs
404 : TTI.getNumberOfRegisters(LU.first));
405 });
406}
407
410 const SmallPtrSetImpl<const Value *> &ValuesToIgnore) {
411 // Each 'key' in the map opens a new interval. The values
412 // of the map are the index of the 'last seen' usage of the
413 // VPValue that is the key.
415
416 // Maps indices to recipes.
418 // Marks the end of each interval.
419 IntervalMap EndPoint;
420 // Saves the list of VPValues that are used in the loop.
422 // Saves the list of values that are used in the loop but are defined outside
423 // the loop (not including non-recipe values such as arguments and
424 // constants).
425 SmallSetVector<VPValue *, 8> LoopInvariants;
426 LoopInvariants.insert(&Plan.getVectorTripCount());
427
428 // We scan the loop in a topological order in order and assign a number to
429 // each recipe. We use RPO to ensure that defs are met before their users. We
430 // assume that each recipe that has in-loop users starts an interval. We
431 // record every time that an in-loop value is used, so we have a list of the
432 // first occurences of each recipe and last occurrence of each VPValue.
433 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
435 LoopRegion);
437 if (!VPBB->getParent())
438 break;
439 for (VPRecipeBase &R : *VPBB) {
440 Idx2Recipe.push_back(&R);
441
442 // Save the end location of each USE.
443 for (VPValue *U : R.operands()) {
444 auto *DefR = U->getDefiningRecipe();
445
446 // Ignore non-recipe values such as arguments, constants, etc.
447 // FIXME: Might need some motivation why these values are ignored. If
448 // for example an argument is used inside the loop it will increase the
449 // register pressure (so shouldn't we add it to LoopInvariants).
450 if (!DefR && (!U->getLiveInIRValue() ||
451 !isa<Instruction>(U->getLiveInIRValue())))
452 continue;
453
454 // If this recipe is outside the loop then record it and continue.
455 if (!DefR) {
456 LoopInvariants.insert(U);
457 continue;
458 }
459
460 // Overwrite previous end points.
461 EndPoint[U] = Idx2Recipe.size();
462 Ends.insert(U);
463 }
464 }
465 if (VPBB == LoopRegion->getExiting()) {
466 // VPWidenIntOrFpInductionRecipes are used implicitly at the end of the
467 // exiting block, where their increment will get materialized eventually.
468 for (auto &R : LoopRegion->getEntryBasicBlock()->phis()) {
469 if (auto *WideIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R)) {
470 EndPoint[WideIV] = Idx2Recipe.size();
471 Ends.insert(WideIV);
472 }
473 }
474 }
475 }
476
477 // Saves the list of intervals that end with the index in 'key'.
478 using VPValueList = SmallVector<VPValue *, 2>;
480
481 // Next, we transpose the EndPoints into a multi map that holds the list of
482 // intervals that *end* at a specific location.
483 for (auto &Interval : EndPoint)
484 TransposeEnds[Interval.second].push_back(Interval.first);
485
486 SmallPtrSet<VPValue *, 8> OpenIntervals;
489
490 LLVM_DEBUG(dbgs() << "LV(REG): Calculating max register usage:\n");
491
492 VPTypeAnalysis TypeInfo(Plan);
493
494 const auto &TTICapture = TTI;
495 auto GetRegUsage = [&TTICapture](Type *Ty, ElementCount VF) -> unsigned {
496 if (Ty->isTokenTy() || !VectorType::isValidElementType(Ty) ||
497 (VF.isScalable() &&
498 !TTICapture.isElementTypeLegalForScalableVector(Ty)))
499 return 0;
500 return TTICapture.getRegUsageForType(VectorType::get(Ty, VF));
501 };
502
503 // We scan the instructions linearly and record each time that a new interval
504 // starts, by placing it in a set. If we find this value in TransposEnds then
505 // we remove it from the set. The max register usage is the maximum register
506 // usage of the recipes of the set.
507 for (unsigned int Idx = 0, Sz = Idx2Recipe.size(); Idx < Sz; ++Idx) {
508 VPRecipeBase *R = Idx2Recipe[Idx];
509
510 // Remove all of the VPValues that end at this location.
511 VPValueList &List = TransposeEnds[Idx];
512 for (VPValue *ToRemove : List)
513 OpenIntervals.erase(ToRemove);
514
515 // Ignore recipes that are never used within the loop and do not have side
516 // effects.
517 if (none_of(R->definedValues(),
518 [&Ends](VPValue *Def) { return Ends.count(Def); }) &&
519 !R->mayHaveSideEffects())
520 continue;
521
522 // Skip recipes for ignored values.
523 // TODO: Should mark recipes for ephemeral values that cannot be removed
524 // explictly in VPlan.
525 if (isa<VPSingleDefRecipe>(R) &&
526 ValuesToIgnore.contains(
527 cast<VPSingleDefRecipe>(R)->getUnderlyingValue()))
528 continue;
529
530 // For each VF find the maximum usage of registers.
531 for (unsigned J = 0, E = VFs.size(); J < E; ++J) {
532 // Count the number of registers used, per register class, given all open
533 // intervals.
534 // Note that elements in this SmallMapVector will be default constructed
535 // as 0. So we can use "RegUsage[ClassID] += n" in the code below even if
536 // there is no previous entry for ClassID.
538
539 for (auto *VPV : OpenIntervals) {
540 // Skip values that weren't present in the original loop.
541 // TODO: Remove after removing the legacy
542 // LoopVectorizationCostModel::calculateRegisterUsage
545 continue;
546
547 if (VFs[J].isScalar() ||
552 (cast<VPReductionPHIRecipe>(VPV))->isInLoop())) {
553 unsigned ClassID =
554 TTI.getRegisterClassForType(false, TypeInfo.inferScalarType(VPV));
555 // FIXME: The target might use more than one register for the type
556 // even in the scalar case.
557 RegUsage[ClassID] += 1;
558 } else {
559 // The output from scaled phis and scaled reductions actually has
560 // fewer lanes than the VF.
561 unsigned ScaleFactor =
562 vputils::getVFScaleFactor(VPV->getDefiningRecipe());
563 ElementCount VF = VFs[J].divideCoefficientBy(ScaleFactor);
564 LLVM_DEBUG(if (VF != VFs[J]) {
565 dbgs() << "LV(REG): Scaled down VF from " << VFs[J] << " to " << VF
566 << " for " << *R << "\n";
567 });
568
569 Type *ScalarTy = TypeInfo.inferScalarType(VPV);
570 unsigned ClassID = TTI.getRegisterClassForType(true, ScalarTy);
571 RegUsage[ClassID] += GetRegUsage(ScalarTy, VF);
572 }
573 }
574
575 for (const auto &Pair : RegUsage) {
576 auto &Entry = MaxUsages[J][Pair.first];
577 Entry = std::max(Entry, Pair.second);
578 }
579 }
580
581 LLVM_DEBUG(dbgs() << "LV(REG): At #" << Idx << " Interval # "
582 << OpenIntervals.size() << '\n');
583
584 // Add used VPValues defined by the current recipe to the list of open
585 // intervals.
586 for (VPValue *DefV : R->definedValues())
587 if (Ends.contains(DefV))
588 OpenIntervals.insert(DefV);
589 }
590
591 // We also search for instructions that are defined outside the loop, but are
592 // used inside the loop. We need this number separately from the max-interval
593 // usage number because when we unroll, loop-invariant values do not take
594 // more register.
596 for (unsigned Idx = 0, End = VFs.size(); Idx < End; ++Idx) {
597 // Note that elements in this SmallMapVector will be default constructed
598 // as 0. So we can use "Invariant[ClassID] += n" in the code below even if
599 // there is no previous entry for ClassID.
601
602 for (auto *In : LoopInvariants) {
603 // FIXME: The target might use more than one register for the type
604 // even in the scalar case.
605 bool IsScalar = vputils::onlyScalarValuesUsed(In);
606
607 ElementCount VF = IsScalar ? ElementCount::getFixed(1) : VFs[Idx];
608 unsigned ClassID = TTI.getRegisterClassForType(
609 VF.isVector(), TypeInfo.inferScalarType(In));
610 Invariant[ClassID] += GetRegUsage(TypeInfo.inferScalarType(In), VF);
611 }
612
613 LLVM_DEBUG({
614 dbgs() << "LV(REG): VF = " << VFs[Idx] << '\n';
615 dbgs() << "LV(REG): Found max usage: " << MaxUsages[Idx].size()
616 << " item\n";
617 for (const auto &pair : MaxUsages[Idx]) {
618 dbgs() << "LV(REG): RegisterClass: "
619 << TTI.getRegisterClassName(pair.first) << ", " << pair.second
620 << " registers\n";
621 }
622 dbgs() << "LV(REG): Found invariant usage: " << Invariant.size()
623 << " item\n";
624 for (const auto &pair : Invariant) {
625 dbgs() << "LV(REG): RegisterClass: "
626 << TTI.getRegisterClassName(pair.first) << ", " << pair.second
627 << " registers\n";
628 }
629 });
630
631 RU.LoopInvariantRegs = Invariant;
632 RU.MaxLocalUsers = MaxUsages[Idx];
633 RUs[Idx] = RU;
634 }
635
636 return RUs;
637}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
ReachingDefInfo InstSet & ToRemove
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#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:114
This pass exposes codegen information to IR-level passes.
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.
This file contains the declarations of different VPlan-related auxiliary helpers.
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
Implements a dense probed hash-table based set.
Definition DenseSet.h:279
Core dominator tree base class.
bool properlyDominates(const DomTreeNodeBase< VPBlockBase > *A, const DomTreeNodeBase< VPBlockBase > *B) const
constexpr bool isVector() const
One or more elements.
Definition TypeSize.h:325
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:310
bool isCast() const
bool isBinaryOp() const
bool isBitwiseLogicOp() const
Return true if this is and/or/xor.
bool isShift() const
bool isUnaryOp() const
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:150
size_type size() const
Definition SmallPtrSet.h:99
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:338
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 pass provides access to the codegen interfaces that are needed for IR-level transformations.
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
Definition TypeSwitch.h:88
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
Definition TypeSwitch.h:97
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:281
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:240
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:301
A recipe for generating the active lane mask for the vector loop that is used to predicate the vector...
Definition VPlan.h:3492
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:3779
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:3867
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
Definition VPlan.h:2397
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:80
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:170
static auto blocksOnly(const T &Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:232
A recipe for generating conditional branches on the bits of a mask.
Definition VPlan.h:2928
Canonical scalar induction phi of the vector loop.
Definition VPlan.h:3435
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition VPlan.h:3600
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:3523
Recipe to expand a SCEV expression.
Definition VPlan.h:3398
A specialization of VPInstruction augmenting it with a dedicated result type, to be used when the opc...
Definition VPlan.h:1182
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:975
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
Definition VPlan.h:1054
@ ComputeAnyOfResult
Compute the final result of a AnyOf reduction with select(cmp(),x,y), where one of (x,...
Definition VPlan.h:1008
@ ResumeForEpilogue
Explicit user for the resume phi of the canonical induction in the main VPlan, used by the epilogue v...
Definition VPlan.h:1057
@ FirstOrderRecurrenceSplice
Definition VPlan.h:981
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1048
@ BuildVector
Creates a fixed-width vector containing all operands.
Definition VPlan.h:1005
@ BuildStructVector
Given operands of (the same) struct type, creates a struct of fixed- width vectors each containing a ...
Definition VPlan.h:1002
@ CanonicalIVIncrementForPart
Definition VPlan.h:995
@ CalculateTripCountMinusVF
Definition VPlan.h:993
A recipe for forming partial reductions.
Definition VPlan.h:2747
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
Definition VPlan.h:3106
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:386
A recipe for handling reduction phis.
Definition VPlan.h:2325
A recipe to represent inloop reduction operations, performing a reduction on a vector operand into a ...
Definition VPlan.h:2660
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:3967
const VPBlockBase * getEntry() const
Definition VPlan.h:4003
const VPBlockBase * getExiting() const
Definition VPlan.h:4015
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:2850
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:3669
An analysis for type-inference for VPValues.
LLVMContext & getContext()
Return the LLVMContext used by the analysis.
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:199
operand_range operands()
Definition VPlanValue.h:267
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:1836
A recipe to compute the pointers for widened memory accesses of IndexTy.
Definition VPlan.h:1895
A recipe for widening Call instructions using library calls.
Definition VPlan.h:1624
A Recipe for widening the canonical induction variable of the vector loop.
Definition VPlan.h:3564
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1477
A recipe for handling GEP instructions.
Definition VPlan.h:1764
A recipe for widening vector intrinsics.
Definition VPlan.h:1535
A common base class for widening memory operations.
Definition VPlan.h:3148
A recipe for widened phis.
Definition VPlan.h:2248
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1434
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4083
VPValue & getVectorTripCount()
The vector trip count.
Definition VPlan.h:4273
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1049
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:202
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:175
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool match(Val *V, const Pattern &P)
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
bool onlyScalarValuesUsed(const VPValue *Def)
Returns true if only scalar values of Def are used by all users.
unsigned getVFScaleFactor(VPRecipeBase *R)
Get the VF scaling factor applied to the recipe's output, if the recipe has one.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:644
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...
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:754
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:1732
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 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:1739
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
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:560
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:257
A recipe for handling first-order recurrence phis.
Definition VPlan.h:2290
A struct that represents some properties of the register usage of a loop.
SmallMapVector< unsigned, unsigned, 4 > MaxLocalUsers
Holds the maximum number of concurrent live intervals in the loop.
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.
A recipe for widening select instructions.
Definition VPlan.h:1718