LLVM 23.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"
14#include "VPlanPatternMatch.h"
16#include "llvm/ADT/TypeSwitch.h"
19#include "llvm/IR/Instruction.h"
21
22using namespace llvm;
23using namespace VPlanPatternMatch;
24
25#define DEBUG_TYPE "vplan"
26
27Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPBlendRecipe *R) {
28 Type *ResTy = inferScalarType(R->getIncomingValue(0));
29 for (unsigned I = 1, E = R->getNumIncomingValues(); I != E; ++I) {
30 VPValue *Inc = R->getIncomingValue(I);
31 assert(inferScalarType(Inc) == ResTy &&
32 "different types inferred for different incoming values");
33 CachedTypes[Inc] = ResTy;
34 }
35 return ResTy;
36}
37
38Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
39 // Set the result type from the first operand, check if the types for all
40 // other operands match and cache them.
41 auto SetResultTyFromOp = [this, R]() {
42 Type *ResTy = inferScalarType(R->getOperand(0));
43 unsigned NumOperands = R->getNumOperandsWithoutMask();
44 for (unsigned Op = 1; Op != NumOperands; ++Op) {
45 VPValue *OtherV = R->getOperand(Op);
46 assert(inferScalarType(OtherV) == ResTy &&
47 "different types inferred for different operands");
48 CachedTypes[OtherV] = ResTy;
49 }
50 return ResTy;
51 };
52
53 unsigned Opcode = R->getOpcode();
55 return SetResultTyFromOp();
56
57 switch (Opcode) {
58 case Instruction::PHI:
59 for (VPValue *Op : R->operands()) {
60 if (auto *VIR = dyn_cast<VPIRValue>(Op))
61 return VIR->getType();
62 if (auto *Ty = CachedTypes.lookup(Op))
63 return Ty;
64 }
66 case Instruction::ExtractElement:
67 case Instruction::InsertElement:
68 case Instruction::Freeze:
81 return inferScalarType(R->getOperand(0));
82 case Instruction::Select: {
83 Type *ResTy = inferScalarType(R->getOperand(1));
84 VPValue *OtherV = R->getOperand(2);
85 assert(inferScalarType(OtherV) == ResTy &&
86 "different types inferred for different operands");
87 CachedTypes[OtherV] = ResTy;
88 return ResTy;
89 }
90 case Instruction::ICmp:
91 case Instruction::FCmp:
93 assert(inferScalarType(R->getOperand(0)) ==
94 inferScalarType(R->getOperand(1)) &&
95 "different types inferred for different operands");
96 return IntegerType::get(Ctx, 1);
98 return Type::getIntNTy(Ctx, 32);
107 return SetResultTyFromOp();
109 return inferScalarType(R->getOperand(1));
112 // Assume that the maximum possible number of elements in a vector fits
113 // within the index type for the default address space.
114 return DL.getIndexType(Ctx, 0);
117 assert(inferScalarType(R->getOperand(0))->isIntegerTy(1) &&
118 inferScalarType(R->getOperand(1))->isIntegerTy(1) &&
119 "LogicalAnd/Or operands should be bool");
120 return IntegerType::get(Ctx, 1);
122 assert(inferScalarType(R->getOperand(0))->isIntegerTy(1));
123 return IntegerType::get(Ctx, 1);
127 case Instruction::Store:
128 case Instruction::Switch:
129 return Type::getVoidTy(Ctx);
130 case Instruction::Load:
131 return cast<LoadInst>(R->getUnderlyingValue())->getType();
132 case Instruction::Alloca:
133 return cast<AllocaInst>(R->getUnderlyingValue())->getType();
134 case Instruction::Call: {
135 unsigned CallIdx = R->getNumOperandsWithoutMask() - 1;
136 return cast<Function>(R->getOperand(CallIdx)->getLiveInIRValue())
137 ->getReturnType();
138 }
139 case Instruction::GetElementPtr:
140 return inferScalarType(R->getOperand(0));
141 case Instruction::ExtractValue:
142 return cast<ExtractValueInst>(R->getUnderlyingValue())->getType();
143 default:
144 break;
145 }
146 // Type inference not implemented for opcode.
147 LLVM_DEBUG({
148 dbgs() << "LV: Found unhandled opcode for: ";
149 R->getVPSingleValue()->dump();
150 });
151 llvm_unreachable("Unhandled opcode!");
152}
153
154Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenRecipe *R) {
155 unsigned Opcode = R->getOpcode();
156 if (Instruction::isBinaryOp(Opcode) || Instruction::isShift(Opcode) ||
158 Type *ResTy = inferScalarType(R->getOperand(0));
159 assert(ResTy == inferScalarType(R->getOperand(1)) &&
160 "types for both operands must match for binary op");
161 CachedTypes[R->getOperand(1)] = ResTy;
162 return ResTy;
163 }
164
165 switch (Opcode) {
166 case Instruction::ICmp:
167 case Instruction::FCmp:
168 return IntegerType::get(Ctx, 1);
169 case Instruction::FNeg:
170 case Instruction::Freeze:
171 return inferScalarType(R->getOperand(0));
172 case Instruction::ExtractValue: {
173 assert(R->getNumOperands() == 2 && "expected single level extractvalue");
174 auto *StructTy = cast<StructType>(inferScalarType(R->getOperand(0)));
175 return StructTy->getTypeAtIndex(
176 cast<VPConstantInt>(R->getOperand(1))->getZExtValue());
177 }
178 case Instruction::Select: {
179 Type *ResTy = inferScalarType(R->getOperand(1));
180 VPValue *OtherV = R->getOperand(2);
181 assert(inferScalarType(OtherV) == ResTy &&
182 "different types inferred for different operands");
183 CachedTypes[OtherV] = ResTy;
184 return ResTy;
185 }
186 default:
187 break;
188 }
189
190 // Type inference not implemented for opcode.
191 LLVM_DEBUG({
192 dbgs() << "LV: Found unhandled opcode for: ";
193 R->getVPSingleValue()->dump();
194 });
195 llvm_unreachable("Unhandled opcode!");
196}
197
198Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPReplicateRecipe *R) {
199 unsigned Opcode = R->getUnderlyingInstr()->getOpcode();
200
201 if (Instruction::isBinaryOp(Opcode) || Instruction::isShift(Opcode) ||
203 Type *ResTy = inferScalarType(R->getOperand(0));
204 assert(ResTy == inferScalarType(R->getOperand(1)) &&
205 "inferred types for operands of binary op don't match");
206 CachedTypes[R->getOperand(1)] = ResTy;
207 return ResTy;
208 }
209
210 if (Instruction::isCast(Opcode))
211 return R->getUnderlyingInstr()->getType();
212
213 switch (Opcode) {
214 case Instruction::Call: {
215 unsigned CallIdx = R->getNumOperands() - (R->isPredicated() ? 2 : 1);
216 return cast<Function>(R->getOperand(CallIdx)->getLiveInIRValue())
217 ->getReturnType();
218 }
219 case Instruction::Select: {
220 Type *ResTy = inferScalarType(R->getOperand(1));
221 assert(ResTy == inferScalarType(R->getOperand(2)) &&
222 "inferred types for operands of select op don't match");
223 CachedTypes[R->getOperand(2)] = ResTy;
224 return ResTy;
225 }
226 case Instruction::ICmp:
227 case Instruction::FCmp:
228 return IntegerType::get(Ctx, 1);
229 case Instruction::Alloca:
230 case Instruction::ExtractValue:
231 return R->getUnderlyingInstr()->getType();
232 case Instruction::Freeze:
233 case Instruction::FNeg:
234 case Instruction::GetElementPtr:
235 return inferScalarType(R->getOperand(0));
236 case Instruction::Load:
237 return cast<LoadInst>(R->getUnderlyingInstr())->getType();
238 case Instruction::Store:
239 // FIXME: VPReplicateRecipes with store opcodes still define a result
240 // VPValue, so we need to handle them here. Remove the code here once this
241 // is modeled accurately in VPlan.
242 return Type::getVoidTy(Ctx);
243 default:
244 break;
245 }
246 // Type inference not implemented for opcode.
247 LLVM_DEBUG({
248 dbgs() << "LV: Found unhandled opcode for: ";
249 R->getVPSingleValue()->dump();
250 });
251 llvm_unreachable("Unhandled opcode");
252}
253
255 if (Type *CachedTy = CachedTypes.lookup(V))
256 return CachedTy;
257
264 Type *Ty = V->getScalarType();
265 assert(Ty && "Scalar type must be set by recipe construction");
266 return Ty;
267 }
268
269 Type *ResultTy =
270 TypeSwitch<const VPRecipeBase *, Type *>(V->getDefiningRecipe())
271 // VPInstructionWithType must be handled before VPInstruction.
273 [](const auto *R) { return R->getResultType(); })
274 .Case<VPBlendRecipe, VPInstruction, VPWidenRecipe, VPReplicateRecipe>(
275 [this](const auto *R) { return inferScalarTypeForRecipe(R); })
276 .Case([this](const VPReductionRecipe *R) {
277 return inferScalarType(R->getChainOp());
278 })
279 .Case([this](const VPExpressionRecipe *R) {
280 return inferScalarType(R->getOperandOfResultType());
281 });
282
283 assert(ResultTy && "could not infer type for the given VPValue");
284 CachedTypes[V] = ResultTy;
285 return ResultTy;
286}
287
289 VPlan &Plan, DenseSet<VPRecipeBase *> &EphRecipes) {
290 // First, collect seed recipes which are operands of assumes.
294 for (VPRecipeBase &R : *VPBB) {
295 auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
296 if (!RepR || !match(RepR, m_Intrinsic<Intrinsic::assume>()))
297 continue;
298 Worklist.push_back(RepR);
299 EphRecipes.insert(RepR);
300 }
301 }
302
303 // Process operands of candidates in worklist and add them to the set of
304 // ephemeral recipes, if they don't have side-effects and are only used by
305 // other ephemeral recipes.
306 while (!Worklist.empty()) {
307 VPRecipeBase *Cur = Worklist.pop_back_val();
308 for (VPValue *Op : Cur->operands()) {
309 auto *OpR = Op->getDefiningRecipe();
310 if (!OpR || OpR->mayHaveSideEffects() || EphRecipes.contains(OpR))
311 continue;
312 if (any_of(Op->users(), [EphRecipes](VPUser *U) {
313 auto *UR = dyn_cast<VPRecipeBase>(U);
314 return !UR || !EphRecipes.contains(UR);
315 }))
316 continue;
317 EphRecipes.insert(OpR);
318 Worklist.push_back(OpR);
319 }
320 }
321}
322
325
327 const VPRecipeBase *B) {
328 if (A == B)
329 return false;
330
331 auto LocalComesBefore = [](const VPRecipeBase *A, const VPRecipeBase *B) {
332 for (auto &R : *A->getParent()) {
333 if (&R == A)
334 return true;
335 if (&R == B)
336 return false;
337 }
338 llvm_unreachable("recipe not found");
339 };
340 const VPBlockBase *ParentA = A->getParent();
341 const VPBlockBase *ParentB = B->getParent();
342 if (ParentA == ParentB)
343 return LocalComesBefore(A, B);
344
345 return Base::properlyDominates(ParentA, ParentB);
346}
347
351 unsigned OverrideMaxNumRegs) const {
353 for (const auto &[RegClass, MaxUsers] : MaxLocalUsers) {
354 unsigned AvailableRegs = OverrideMaxNumRegs > 0
355 ? OverrideMaxNumRegs
356 : TTI.getNumberOfRegisters(RegClass);
357 if (MaxUsers > AvailableRegs) {
358 // Assume that for each register used past what's available we get one
359 // spill and reload.
360 unsigned Spills = MaxUsers - AvailableRegs;
361 InstructionCost SpillCost =
362 TTI.getRegisterClassSpillCost(RegClass, CostKind) +
363 TTI.getRegisterClassReloadCost(RegClass, CostKind);
364 InstructionCost TotalCost = Spills * SpillCost;
365 LLVM_DEBUG(dbgs() << "LV(REG): Cost of " << TotalCost << " from "
366 << Spills << " spills of "
367 << TTI.getRegisterClassName(RegClass) << "\n");
368 Cost += TotalCost;
369 }
370 }
371 return Cost;
372}
373
376 const SmallPtrSetImpl<const Value *> &ValuesToIgnore) {
377 // Each 'key' in the map opens a new interval. The values
378 // of the map are the index of the 'last seen' usage of the
379 // VPValue that is the key.
381
382 // Maps indices to recipes.
384 // Marks the end of each interval.
385 IntervalMap EndPoint;
386 // Saves the list of VPValues that are used in the loop.
388 // Saves the list of values that are used in the loop but are defined outside
389 // the loop (not including non-recipe values such as arguments and
390 // constants).
391 SmallSetVector<VPValue *, 8> LoopInvariants;
392 if (Plan.getVectorTripCount().getNumUsers() > 0)
393 LoopInvariants.insert(&Plan.getVectorTripCount());
394
395 // We scan the loop in a topological order in order and assign a number to
396 // each recipe. We use RPO to ensure that defs are met before their users. We
397 // assume that each recipe that has in-loop users starts an interval. We
398 // record every time that an in-loop value is used, so we have a list of the
399 // first occurences of each recipe and last occurrence of each VPValue.
400 VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion();
402 LoopRegion);
404 if (!VPBB->getParent())
405 break;
406 for (VPRecipeBase &R : *VPBB) {
407 Idx2Recipe.push_back(&R);
408
409 // Save the end location of each USE.
410 for (VPValue *U : R.operands()) {
411 if (isa<VPRecipeValue>(U)) {
412 // Overwrite previous end points.
413 EndPoint[U] = Idx2Recipe.size();
414 Ends.insert(U);
415 } else if (auto *IRV = dyn_cast<VPIRValue>(U)) {
416 // Ignore non-recipe values such as arguments, constants, etc.
417 // FIXME: Might need some motivation why these values are ignored. If
418 // for example an argument is used inside the loop it will increase
419 // the register pressure (so shouldn't we add it to LoopInvariants).
420 if (!isa<Instruction>(IRV->getValue()))
421 continue;
422 // This recipe is outside the loop, record it and continue.
423 LoopInvariants.insert(U);
424 }
425 // Other types of VPValue are currently not tracked.
426 }
427 }
428 if (VPBB == LoopRegion->getExiting()) {
429 // VPWidenIntOrFpInductionRecipes are used implicitly at the end of the
430 // exiting block, where their increment will get materialized eventually.
431 for (auto &R : LoopRegion->getEntryBasicBlock()->phis()) {
432 if (auto *WideIV = dyn_cast<VPWidenIntOrFpInductionRecipe>(&R)) {
433 EndPoint[WideIV] = Idx2Recipe.size();
434 Ends.insert(WideIV);
435 }
436 }
437 }
438 }
439
440 // Saves the list of intervals that end with the index in 'key'.
441 using VPValueList = SmallVector<VPValue *, 2>;
443
444 // Next, we transpose the EndPoints into a multi map that holds the list of
445 // intervals that *end* at a specific location.
446 for (auto &Interval : EndPoint)
447 TransposeEnds[Interval.second].push_back(Interval.first);
448
449 SmallPtrSet<VPValue *, 8> OpenIntervals;
452
453 LLVM_DEBUG(dbgs() << "LV(REG): Calculating max register usage:\n");
454
455 VPTypeAnalysis TypeInfo(Plan);
456
457 const auto &TTICapture = TTI;
458 auto GetRegUsage = [&TTICapture](Type *Ty, ElementCount VF) -> unsigned {
459 if (Ty->isTokenTy() || !VectorType::isValidElementType(Ty) ||
460 (VF.isScalable() &&
461 !TTICapture.isElementTypeLegalForScalableVector(Ty)))
462 return 0;
463 return TTICapture.getRegUsageForType(VectorType::get(Ty, VF));
464 };
465
466 VPValue *CanIV = LoopRegion->getCanonicalIV();
467 // Note: canonical IVs are retained even if they have no users.
468 if (CanIV->getNumUsers() != 0)
469 OpenIntervals.insert(CanIV);
470
471 // We scan the instructions linearly and record each time that a new interval
472 // starts, by placing it in a set. If we find this value in TransposEnds then
473 // we remove it from the set. The max register usage is the maximum register
474 // usage of the recipes of the set.
475 for (unsigned int Idx = 0, Sz = Idx2Recipe.size(); Idx < Sz; ++Idx) {
476 VPRecipeBase *R = Idx2Recipe[Idx];
477
478 // Remove all of the VPValues that end at this location.
479 VPValueList &List = TransposeEnds[Idx];
480 for (VPValue *ToRemove : List)
481 OpenIntervals.erase(ToRemove);
482
483 // Ignore recipes that are never used within the loop and do not have side
484 // effects.
485 if (none_of(R->definedValues(),
486 [&Ends](VPValue *Def) { return Ends.count(Def); }) &&
487 !R->mayHaveSideEffects())
488 continue;
489
490 // Skip recipes for ignored values.
491 // TODO: Should mark recipes for ephemeral values that cannot be removed
492 // explictly in VPlan.
493 if (isa<VPSingleDefRecipe>(R) &&
494 ValuesToIgnore.contains(
495 cast<VPSingleDefRecipe>(R)->getUnderlyingValue()))
496 continue;
497
498 // For each VF find the maximum usage of registers.
499 for (unsigned J = 0, E = VFs.size(); J < E; ++J) {
500 // Count the number of registers used, per register class, given all open
501 // intervals.
502 // Note that elements in this SmallMapVector will be default constructed
503 // as 0. So we can use "RegUsage[ClassID] += n" in the code below even if
504 // there is no previous entry for ClassID.
506
507 for (auto *VPV : OpenIntervals) {
508 // Skip artificial values or values that weren't present in the original
509 // loop.
510 // TODO: Remove skipping values that weren't present in the original
511 // loop after removing the legacy
512 // LoopVectorizationCostModel::calculateRegisterUsage
514 VPBranchOnMaskRecipe>(VPV) ||
516 continue;
517
518 if (VFs[J].isScalar() ||
523 (cast<VPReductionPHIRecipe>(VPV))->isInLoop())) {
524 unsigned ClassID =
525 TTI.getRegisterClassForType(false, TypeInfo.inferScalarType(VPV));
526 // FIXME: The target might use more than one register for the type
527 // even in the scalar case.
528 RegUsage[ClassID] += 1;
529 } else {
530 // The output from scaled phis and scaled reductions actually has
531 // fewer lanes than the VF.
532 unsigned ScaleFactor =
533 vputils::getVFScaleFactor(VPV->getDefiningRecipe());
534 ElementCount VF = VFs[J];
535 if (ScaleFactor > 1) {
536 VF = VFs[J].divideCoefficientBy(ScaleFactor);
537 LLVM_DEBUG(dbgs() << "LV(REG): Scaled down VF from " << VFs[J]
538 << " to " << VF << " for " << *R << "\n";);
539 }
540
541 Type *ScalarTy = TypeInfo.inferScalarType(VPV);
542 unsigned ClassID = TTI.getRegisterClassForType(true, ScalarTy);
543 RegUsage[ClassID] += GetRegUsage(ScalarTy, VF);
544 }
545 }
546
547 for (const auto &Pair : RegUsage) {
548 auto &Entry = MaxUsages[J][Pair.first];
549 Entry = std::max(Entry, Pair.second);
550 }
551 }
552
553 LLVM_DEBUG(dbgs() << "LV(REG): At #" << Idx << " Interval # "
554 << OpenIntervals.size() << '\n');
555
556 // Add used VPValues defined by the current recipe to the list of open
557 // intervals.
558 for (VPValue *DefV : R->definedValues())
559 if (Ends.contains(DefV))
560 OpenIntervals.insert(DefV);
561 }
562
563 // We also search for instructions that are defined outside the loop, but are
564 // used inside the loop. We need this number separately from the max-interval
565 // usage number because when we unroll, loop-invariant values do not take
566 // more register.
568 for (unsigned Idx = 0, End = VFs.size(); Idx < End; ++Idx) {
569 // Note that elements in this SmallMapVector will be default constructed
570 // as 0. So we can use "Invariant[ClassID] += n" in the code below even if
571 // there is no previous entry for ClassID.
573
574 for (auto *In : LoopInvariants) {
575 // FIXME: The target might use more than one register for the type
576 // even in the scalar case.
577 bool IsScalar = vputils::onlyScalarValuesUsed(In);
578
579 ElementCount VF = IsScalar ? ElementCount::getFixed(1) : VFs[Idx];
580 unsigned ClassID = TTI.getRegisterClassForType(
581 VF.isVector(), TypeInfo.inferScalarType(In));
582 Invariant[ClassID] += GetRegUsage(TypeInfo.inferScalarType(In), VF);
583 }
584
585 LLVM_DEBUG({
586 dbgs() << "LV(REG): VF = " << VFs[Idx] << '\n';
587 dbgs() << "LV(REG): Found max usage: " << MaxUsages[Idx].size()
588 << " item\n";
589 for (const auto &pair : MaxUsages[Idx]) {
590 dbgs() << "LV(REG): RegisterClass: "
591 << TTI.getRegisterClassName(pair.first) << ", " << pair.second
592 << " registers\n";
593 }
594 dbgs() << "LV(REG): Found invariant usage: " << Invariant.size()
595 << " item\n";
596 for (const auto &pair : Invariant) {
597 dbgs() << "LV(REG): RegisterClass: "
598 << TTI.getRegisterClassName(pair.first) << ", " << pair.second
599 << " registers\n";
600 }
601 });
602
603 RU.LoopInvariantRegs = Invariant;
604 RU.MaxLocalUsers = MaxUsages[Idx];
605 RUs[Idx] = RU;
606 }
607
608 return RUs;
609}
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 LLVM_FALLTHROUGH
LLVM_FALLTHROUGH - Mark fallthrough cases in switch statements.
Definition Compiler.h:404
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
#define I(x, y, z)
Definition MD5.cpp:57
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 ...
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:
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
Implements a dense probed hash-table based set.
Definition DenseSet.h:289
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:324
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:309
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:354
size_type size() const
Definition MapVector.h:58
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:151
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:339
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.
TargetCostKind
The kind of cost model.
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
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:286
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:370
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:257
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
Definition Type.cpp:317
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4263
iterator_range< iterator > phis()
Returns an iterator range over the PHI-like recipes in the block.
Definition VPlan.h:4351
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
Definition VPlan.h:2887
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:93
const VPBasicBlock * getEntryBasicBlock() const
Definition VPlan.cpp:216
static auto blocksOnly(T &&Range)
Return an iterator range over Range which only includes BlockTy blocks.
Definition VPlanUtils.h:295
A recipe for generating conditional branches on the bits of a mask.
Definition VPlan.h:3387
A recipe for generating the phi node tracking the current scalar iteration index.
Definition VPlan.h:3944
A recipe for converting the input value IV value to the corresponding value of an IV with different s...
Definition VPlan.h:4038
bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B)
Recipe to expand a SCEV expression.
Definition VPlan.h:3877
A recipe to combine multiple recipes into a single 'expression' recipe, which should be considered a ...
Definition VPlan.h:3432
A pure virtual base class for all recipes modeling header phis, including phis for first order recurr...
Definition VPlan.h:2395
A specialization of VPInstruction augmenting it with a dedicated result type, to be used when the opc...
Definition VPlan.h:1524
This is a concrete Recipe that models a single VPlan-level instruction.
Definition VPlan.h:1227
@ ExtractLastActive
Extracts the last active lane from a set of vectors.
Definition VPlan.h:1325
@ ExtractLane
Extracts a single lane (first operand) from a set of vector operands.
Definition VPlan.h:1316
@ ExitingIVValue
Compute the exiting value of a wide induction after vectorization, that is the value of the last lane...
Definition VPlan.h:1329
@ ResumeForEpilogue
Explicit user for the resume phi of the canonical induction in the main VPlan, used by the epilogue v...
Definition VPlan.h:1319
@ Unpack
Extracts all lanes from its (non-scalable) vector operand.
Definition VPlan.h:1267
@ ReductionStartVector
Start vector for reductions with 3 operands: the original start value, the identity value for the red...
Definition VPlan.h:1312
@ BuildVector
Creates a fixed-width vector containing all operands.
Definition VPlan.h:1262
@ BuildStructVector
Given operands of (the same) struct type, creates a struct of fixed- width vectors each containing a ...
Definition VPlan.h:1259
@ CanonicalIVIncrementForPart
Definition VPlan.h:1243
@ ComputeReductionResult
Reduce the operands to the final reduction result using the operation specified via the operation's V...
Definition VPlan.h:1270
A VPRecipeValue defined by a multi-def recipe, stores a pointer to it.
Definition VPlanValue.h:364
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
Definition VPlan.h:3574
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
Definition VPlan.h:401
A recipe to represent inloop, ordered or partial reduction operations.
Definition VPlan.h:3150
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4473
const VPBlockBase * getEntry() const
Definition VPlan.h:4517
VPRegionValue * getCanonicalIV()
Return the canonical induction variable of the region, null for replicating regions.
Definition VPlan.h:4585
const VPBlockBase * getExiting() const
Definition VPlan.h:4529
VPValues defined by a VPRegionBlock, like the canonical IV.
Definition VPlanValue.h:215
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3304
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Definition VPlan.h:4108
An analysis for type-inference for VPValues.
Type * inferScalarType(const VPValue *V)
Infer the type of V. Returns the scalar type of V.
This class augments VPValue with operands which provide the inverse def-use edges from VPValue's user...
Definition VPlanValue.h:384
operand_range operands()
Definition VPlanValue.h:455
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
unsigned getNumUsers() const
Definition VPlanValue.h:115
A recipe to compute a pointer to the last element of each part of a widened memory access for widened...
Definition VPlan.h:2240
A recipe to compute the pointers for widened memory accesses of SourceElementTy, with the Stride expr...
Definition VPlan.h:2314
A recipe for widening Call instructions using library calls.
Definition VPlan.h:2067
A Recipe for widening the canonical induction variable of the vector loop.
Definition VPlan.h:3988
VPWidenCastRecipe is a recipe to create vector cast instructions.
Definition VPlan.h:1848
A recipe for handling GEP instructions.
Definition VPlan.h:2175
A recipe for widening vector intrinsics.
Definition VPlan.h:1895
A recipe for widened phis.
Definition VPlan.h:2685
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
Definition VPlan.h:1790
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4621
VPSymbolicValue & getVectorTripCount()
The vector trip count.
Definition VPlan.h:4810
LLVM_ABI_FOR_TEST VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
Definition VPlan.cpp:1090
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:212
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:185
#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))
auto m_VPValue()
Match an arbitrary VPValue and ignore it.
VPInstruction_match< VPInstruction::ExtractLastPart, Op0_t > m_ExtractLastPart(const Op0_t &Op0)
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.
InstructionCost Cost
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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:288
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:1745
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:209
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:1752
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
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:559
A MapVector that performs no allocations if smaller than a certain size.
Definition MapVector.h:334
A VPValue representing a live-in from the input IR or a constant.
Definition VPlanValue.h:246
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.
InstructionCost spillCost(const TargetTransformInfo &TTI, TargetTransformInfo::TargetCostKind CostKind, unsigned OverrideMaxNumRegs=0) const
Calculate the estimated cost of any spills due to using more registers than the number available for ...
SmallMapVector< unsigned, unsigned, 4 > LoopInvariantRegs
Holds the number of loop invariant values that are used in the loop.
A symbolic live-in VPValue, used for values like vector trip count, VF, and VFxUF.
Definition VPlanValue.h:286
A recipe for widening load operations with vector-predication intrinsics, using the address to load f...
Definition VPlan.h:3721
A recipe for widening load operations, using the address to load from and an optional mask.
Definition VPlan.h:3672