LLVM 24.0.0git
VPlanHelpers.h
Go to the documentation of this file.
1//===- VPlanHelpers.h - VPlan-related auxiliary helpers -------------------===//
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/// \file
10/// This file contains the declarations of different VPlan-related auxiliary
11/// helpers.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_TRANSFORMS_VECTORIZE_VPLANHELPERS_H
16#define LLVM_TRANSFORMS_VECTORIZE_VPLANHELPERS_H
17
18#include "VPlanAnalysis.h"
19#include "VPlanDominatorTree.h"
20#include "llvm/ADT/DenseMap.h"
25#include "llvm/IR/DebugLoc.h"
28
29namespace llvm {
30
31class AssumptionCache;
32class BasicBlock;
33class DominatorTree;
34class Function;
35class IRBuilderBase;
36class LoopInfo;
37class Type;
39class VPBasicBlock;
40class VPRegionBlock;
41class VPlan;
42class VPSlotTracker;
43class Value;
44struct VectorizeOptions;
45
46namespace Intrinsic {
47typedef unsigned ID;
48}
49
50/// Returns a calculation for the total number of elements for a given \p VF.
51/// For fixed width vectors this value is a constant, whereas for scalable
52/// vectors it is an expression determined at runtime.
54
55/// A range of powers-of-2 vectorization factors with fixed start and
56/// adjustable end. The range includes start and excludes end, e.g.,:
57/// [1, 16) = {1, 2, 4, 8}
58struct VFRange {
59 // A power of 2.
61
62 // A power of 2. If End <= Start range is empty.
64
65 bool isEmpty() const {
66 return End.getKnownMinValue() <= Start.getKnownMinValue();
67 }
68
70 : Start(Start), End(End) {
71 assert(Start.isScalable() == End.isScalable() &&
72 "Both Start and End should have the same scalable flag");
73 assert(Start.isPowerOf2() && "Expected Start to be a power of 2");
74 assert(End.isPowerOf2() && "Expected End to be a power of 2");
75 }
76
77 /// Iterator to iterate over vectorization factors in a VFRange.
79 : public iterator_facade_base<iterator, std::forward_iterator_tag,
80 ElementCount> {
81 ElementCount VF;
82
83 public:
84 iterator(ElementCount VF) : VF(VF) {}
85
86 bool operator==(const iterator &Other) const { return VF == Other.VF; }
87
88 ElementCount operator*() const { return VF; }
89
91 VF *= 2;
92 return *this;
93 }
94 };
95
98 assert(End.isPowerOf2());
99 return iterator(End);
100 }
101};
102
103/// In what follows, the term "input IR" refers to code that is fed into the
104/// vectorizer whereas the term "output IR" refers to code that is generated by
105/// the vectorizer.
106
107/// VPLane provides a way to access lanes in both fixed width and scalable
108/// vectors, where for the latter the lane index sometimes needs calculating
109/// as a runtime expression.
110class VPLane {
111public:
112 /// Kind describes how to interpret Lane.
113 enum class Kind : uint8_t {
114 /// For First, Lane is the index into the first N elements of a
115 /// fixed-vector <N x <ElTy>> or a scalable vector <vscale x N x <ElTy>>.
117 /// For ScalableLast, Lane is the offset from the start of the last
118 /// N-element subvector in a scalable vector <vscale x N x <ElTy>>. For
119 /// example, a Lane of 0 corresponds to lane `(vscale - 1) * N`, a Lane of
120 /// 1 corresponds to `((vscale - 1) * N) + 1`, etc.
122 };
123
124private:
125 /// in [0..VF)
126 unsigned Lane;
127
128 /// Indicates how the Lane should be interpreted, as described above.
129 Kind LaneKind = Kind::First;
130
131public:
132 VPLane(unsigned Lane) : Lane(Lane) {}
133 VPLane(unsigned Lane, Kind LaneKind) : Lane(Lane), LaneKind(LaneKind) {}
134
136
137 static VPLane getLaneFromEnd(const ElementCount &VF, unsigned Offset) {
138 assert(Offset > 0 && Offset <= VF.getKnownMinValue() &&
139 "trying to extract with invalid offset");
140 unsigned LaneOffset = VF.getKnownMinValue() - Offset;
141 Kind LaneKind;
142 if (VF.isScalable())
143 // In this case 'LaneOffset' refers to the offset from the start of the
144 // last subvector with VF.getKnownMinValue() elements.
146 else
147 LaneKind = VPLane::Kind::First;
148 return VPLane(LaneOffset, LaneKind);
149 }
150
152 return getLaneFromEnd(VF, 1);
153 }
154
155 /// Returns a compile-time known value for the lane index and asserts if the
156 /// lane can only be calculated at runtime.
157 unsigned getKnownLane() const {
158 assert(LaneKind == Kind::First &&
159 "can only get known lane from the beginning");
160 return Lane;
161 }
162
163 /// Returns an expression describing the lane index that can be used at
164 /// runtime.
165 Value *getAsRuntimeExpr(IRBuilderBase &Builder, const ElementCount &VF) const;
166
167 /// Returns the Kind of lane offset.
168 Kind getKind() const { return LaneKind; }
169
170 /// Returns true if this is the first lane of the whole vector.
171 bool isFirstLane() const { return Lane == 0 && LaneKind == Kind::First; }
172
173 /// Maps the lane to a cache index based on \p VF.
174 unsigned mapToCacheIndex(const ElementCount &VF) const {
175 switch (LaneKind) {
177 assert(VF.isScalable() && Lane < VF.getKnownMinValue() &&
178 "ScalableLast can only be used with scalable VFs");
179 return VF.getKnownMinValue() + Lane;
180 default:
181 assert(Lane < VF.getKnownMinValue() &&
182 "Cannot extract lane larger than VF");
183 return Lane;
184 }
185 }
186};
187
188/// VPTransformState holds information passed down when "executing" a VPlan,
189/// needed for generating the output IR.
195 /// Target Transform Info.
197
198 /// The chosen Vectorization Factor of the loop being vectorized.
200
201 struct DataState {
202 // Each value from the original loop, when vectorized, is represented by a
203 // vector value in the map.
205
208
209 /// Get the generated vector Value for a given VPValue \p Def if
210 /// \p NeedsSingleScalar is false, otherwise return the generated scalar.
211 /// \See set.
212 Value *get(const VPValue *Def, bool NeedsSingleScalar = false);
213
214 /// Get the generated Value for a given VPValue and given Part and Lane.
215 Value *get(const VPValue *Def, const VPLane &Lane);
216
217 bool hasVectorValue(const VPValue *Def) {
218 return Data.VPV2Vector.contains(Def);
219 }
220
221 bool hasScalarValue(const VPValue *Def, VPLane Lane) {
222 auto I = Data.VPV2Scalars.find(Def);
223 if (I == Data.VPV2Scalars.end())
224 return false;
225 unsigned CacheIdx = Lane.mapToCacheIndex(VF);
226 return CacheIdx < I->second.size() && I->second[CacheIdx];
227 }
228
229 /// Set the generated vector Value for a given VPValue, if \p
230 /// IsScalar is false. If \p IsScalar is true, set the scalar in lane 0.
231 void set(const VPValue *Def, Value *V, bool IsScalar = false) {
232 if (IsScalar) {
233 set(Def, V, VPLane(0));
234 return;
235 }
236 assert((VF.isScalar() || isVectorizedTy(V->getType())) &&
237 "scalar values must be stored as (0, 0)");
238 Data.VPV2Vector[Def] = V;
239 }
240
241 /// Set the generated scalar \p V for \p Def and the given \p Lane.
242 void set(const VPValue *Def, Value *V, const VPLane &Lane) {
243 auto &Scalars = Data.VPV2Scalars[Def];
244 unsigned CacheIdx = Lane.mapToCacheIndex(VF);
245 if (Scalars.size() <= CacheIdx)
246 Scalars.resize(CacheIdx + 1);
247 assert(!Scalars[CacheIdx] && "should overwrite existing value");
248 Scalars[CacheIdx] = V;
249 }
250
251 /// Set the debug location in the builder using the debug location \p DL.
253
254 /// Add the backedge (latch) incoming value to the canonical, reduction and
255 /// first-order recurrence phis in all loop headers state's plan, after
256 /// the loop body has been generated.
257 void fixupHeaderPhis();
258
259 /// Hold state information used when constructing the CFG of the output IR,
260 /// traversing the VPBasicBlocks and generating corresponding IR BasicBlocks.
261 struct CFGState {
262 /// The previous VPBasicBlock visited. Initially set to null.
264
265 /// The previous IR BasicBlock created or used. Initially set to the new
266 /// header BasicBlock.
267 BasicBlock *PrevBB = nullptr;
268
269 /// The last IR BasicBlock in the output IR. Set to the exit block of the
270 /// vector loop.
271 BasicBlock *ExitBB = nullptr;
272
273 /// A mapping of each VPBasicBlock to the corresponding BasicBlock. In case
274 /// of replication, maps the BasicBlock of the last replica created.
276
277 /// Updater for the DominatorTree.
279
281 : DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy) {}
283
284 /// Hold a pointer to LoopInfo to register new basic blocks in the loop.
286
287 /// Hold a pointer to AssumptionCache to register new assumptions after
288 /// replicating assume calls.
290
291 /// Hold a reference to the IRBuilder used to generate output IR code.
293
294 /// Pointer to the VPlan code is generated for.
296
297 /// The parent loop object for the current scope, or nullptr.
299
300 /// VPlan-based dominator tree.
302};
303
304/// Struct to hold various analysis needed for cost computations.
306 const VectorizeOptions &Opts;
315 const Loop *L;
316
317 /// Number of predicated stores in the VPlan, computed on demand.
318 std::optional<unsigned> NumPredStores;
319
320 VPCostContext(const TargetLibraryInfo &TLI, const VPlan &Plan,
322 bool ReusePrintingSlotTracker = false);
323
324 /// Return the cost for \p UI with \p VF using the legacy cost model as
325 /// fallback until computing the cost of all recipes migrates to VPlan.
327
328 /// Return true if the cost for \p UI shouldn't be computed, e.g. because it
329 /// has already been pre-computed.
330 bool skipCostComputation(Instruction *UI, bool IsVector) const;
331
332 /// Mark the widening decision for \p I at \p VF as invalidated since a VPlan
333 /// transform replaced the original recipe.
335
336 /// \returns how much the cost of a block executing with recorded frequency
337 /// \p Freq should be divided by.
338 uint64_t getCostDivisor(std::optional<VPExecutionFrequency> Freq) const;
339
340 /// Returns true if \p I is known to be scalarized at \p VF.
342
343 /// Returns true if the vector loop body of \p Plan is known to execute at
344 /// most once at \p VF, i.e. its trip count is a constant not greater than
345 /// \p VF. Currently ignores UF.
346 static bool executesAtMostOnce(const VPlan &Plan, ElementCount VF);
347
348 /// Forwards to LoopVectorizationCostModel::isMaskRequired.
349 bool isMaskRequired(Instruction *I) const;
350
351 /// Returns the OperandInfo for \p V, if it is a live-in.
353
354 /// Estimate the overhead of scalarizing a recipe with result type \p ResultTy
355 /// and \p Operands with \p VF. This is a convenience wrapper for the
356 /// type-based getScalarizationOverhead API. \p VIC provides context about
357 /// whether the scalarization is for a load/store operation. If \p
358 /// AlwaysIncludeReplicatingR is true, always compute the cost of scalarizing
359 /// replicating operands.
363 bool AlwaysIncludeReplicatingR = false);
364
365 /// Returns true if an artificially high cost for emulated masked memrefs
366 /// should be used.
368
369 /// Returns true if \p ID is a pseudo intrinsic that is dropped via
370 /// scalarization rather than widened.
371 static bool isFreeScalarIntrinsic(Intrinsic::ID ID);
372
373#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
374 /// Return a VPSlotTracker to re-use for printing, lazily constructing it on
375 /// first use. Returns nullptr if slot-tracker re-use was not requested at
376 /// construction.
378
379private:
380 /// VPlan to build the printing VPSlotTracker for, or nullptr if slot-tracker
381 /// re-use was not requested.
382 const VPlan *PlanForSlotTracker = nullptr;
383
384 /// SlotTracker to re-use when printing, lazily constructed by getSlotTracker.
385 std::unique_ptr<VPSlotTracker> SlotTracker;
386#endif
387};
388
389/// This class can be used to assign names to VPValues. For VPValues without
390/// underlying value, assign consecutive numbers and use those as names (wrapped
391/// in vp<>). Otherwise, use the name from the underlying value (wrapped in
392/// ir<>), appending a .V version number if there are multiple uses of the same
393/// name. Allows querying names for VPValues for printing, similar to the
394/// ModuleSlotTracker for IR values.
396 /// Keep track of versioned names assigned to VPValues with underlying IR
397 /// values.
399 /// Keep track of the next number to use to version the base name.
400 StringMap<unsigned> BaseName2Version;
401
402 /// Number to assign to the next VPValue without underlying value.
403 unsigned NextSlot = 0;
404
405 /// Lazily created ModuleSlotTracker, used only when unnamed IR instructions
406 /// require slot tracking.
407 std::unique_ptr<ModuleSlotTracker> MST;
408
409 /// Cached metadata kind names from the Module's LLVMContext.
411
412 /// Cached Function pointer for printing names and metadata.
413 const Function *F = nullptr;
414
415 void assignName(const VPValue *V);
416 LLVM_ABI_FOR_TEST void assignNames(const VPlan &Plan);
417 void assignNames(const VPBasicBlock *VPBB);
418 std::string getName(const Value *V);
419
420 /// Lazily create the ModuleSlotTracker.
421 ModuleSlotTracker &getOrCreateMST();
422
423public:
424 VPSlotTracker(const VPlan *Plan = nullptr) {
425 if (Plan) {
426 if (auto *ScalarHeader = Plan->getScalarHeader()) {
427 const BasicBlock *ScalarHeaderIRBB = ScalarHeader->getIRBasicBlock();
428 F = ScalarHeaderIRBB->getParent();
429 }
430 assignNames(*Plan);
431 }
432 }
433
434 /// Returns the name assigned to \p V, if there is one, otherwise try to
435 /// construct one from the underlying value, if there's one; else return
436 /// <badref>.
437 std::string getOrCreateName(const VPValue *V) const;
438
439 /// Returns the cached metadata kind names.
441 const Module *M = getModule();
442 if (MDNames.empty() && M)
443 M->getContext().getMDKindNames(MDNames);
444 return MDNames;
445 }
446
447 /// Print a reference to metadata node \p N to \p O.
449
450 /// Returns the module the plan operates on, if any.
451 const Module *getModule() const { return F ? F->getParent() : nullptr; }
452};
453
454#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
455/// VPlanPrinter prints a given VPlan to a given output stream. The printing is
456/// indented and follows the dot format.
458 raw_ostream &OS;
459 const VPlan &Plan;
460 unsigned Depth = 0;
461 unsigned TabWidth = 2;
462 std::string Indent;
463 unsigned BID = 0;
465
466 VPSlotTracker SlotTracker;
467
468 /// Handle indentation.
469 void bumpIndent(int b) { Indent = std::string((Depth += b) * TabWidth, ' '); }
470
471 /// Print a given \p Block of the Plan.
472 void dumpBlock(const VPBlockBase *Block);
473
474 /// Print the information related to the CFG edges going out of a given
475 /// \p Block, followed by printing the successor blocks themselves.
476 void dumpEdges(const VPBlockBase *Block);
477
478 /// Print a given \p BasicBlock, including its VPRecipes, followed by printing
479 /// its successor blocks.
480 void dumpBasicBlock(const VPBasicBlock *BasicBlock);
481
482 /// Print a given \p Region of the Plan.
483 void dumpRegion(const VPRegionBlock *Region);
484
485 unsigned getOrCreateBID(const VPBlockBase *Block) {
486 return BlockID.count(Block) ? BlockID[Block] : BlockID[Block] = BID++;
487 }
488
489 Twine getUID(const VPBlockBase *Block);
490
491 /// Print the information related to a CFG edge between two VPBlockBases.
492 void drawEdge(const VPBlockBase *From, const VPBlockBase *To, bool Hidden,
493 const Twine &Label);
494
495public:
497 : OS(O), Plan(P), SlotTracker(&P) {}
498
499 LLVM_DUMP_METHOD void dump();
500};
501#endif
502
503/// Check if a constant \p CI can be safely treated as having been extended
504/// from a narrower type with the given extension kind.
505bool canConstantBeExtended(const APInt *C, Type *NarrowType,
507} // end namespace llvm
508
509#endif // LLVM_TRANSFORMS_VECTORIZE_VPLAN_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:690
#define LLVM_ABI_FOR_TEST
Definition Compiler.h:216
This file defines the DenseMap class.
Flatten the CFG
This file defines an InstructionCost class that is used when calculating the cost of an instruction,...
#define I(x, y, z)
Definition MD5.cpp:57
#define P(N)
SI Fold Operands
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This pass exposes codegen information to IR-level passes.
This file implements dominator tree analysis for a single level of a VPlan's H-CFG.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
const Function * getParent() const
Return the enclosing method, or null if none.
Definition BasicBlock.h:213
A debug info location.
Definition DebugLoc.h:126
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
Common base class shared among various IRBuilders.
Definition IRBuilder.h:111
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LoopVectorizationCostModel - estimates the expected speedups due to vectorization.
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
Metadata node.
Definition Metadata.h:1081
Manage lifetime of a slot tracker for printing IR.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
An interface layer with SCEV used to manage how we see SCEV expressions for values in the context of ...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:129
Provides information about what library functions are available for the current target.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
llvm::VectorInstrContext VectorInstrContext
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
Iterator to iterate over vectorization factors in a VFRange.
ElementCount operator*() const
iterator(ElementCount VF)
bool operator==(const iterator &Other) const
Holds state needed to make cost decisions before computing costs per-VF, including the maximum VFs.
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
Definition VPlan.h:4465
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Definition VPlan.h:96
Template specialization of the standard LLVM dominator tree utility for VPBlockBases.
In what follows, the term "input IR" refers to code that is fed into the vectorizer whereas the term ...
static VPLane getLastLaneForVF(const ElementCount &VF)
Value * getAsRuntimeExpr(IRBuilderBase &Builder, const ElementCount &VF) const
Returns an expression describing the lane index that can be used at runtime.
Definition VPlan.cpp:81
VPLane(unsigned Lane, Kind LaneKind)
Kind getKind() const
Returns the Kind of lane offset.
static VPLane getLaneFromEnd(const ElementCount &VF, unsigned Offset)
bool isFirstLane() const
Returns true if this is the first lane of the whole vector.
VPLane(unsigned Lane)
unsigned getKnownLane() const
Returns a compile-time known value for the lane index and asserts if the lane can only be calculated ...
static VPLane getFirstLane()
Kind
Kind describes how to interpret Lane.
@ ScalableLast
For ScalableLast, Lane is the offset from the start of the last N-element subvector in a scalable vec...
@ First
For First, Lane is the index into the first N elements of a fixed-vector <N x <ElTy>> or a scalable v...
unsigned mapToCacheIndex(const ElementCount &VF) const
Maps the lane to a cache index based on VF.
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
Definition VPlan.h:4696
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
Definition VPlan.h:3428
This class can be used to assign names to VPValues.
ArrayRef< StringRef > getMDNames()
Returns the cached metadata kind names.
std::string getOrCreateName(const VPValue *V) const
Returns the name assigned to V, if there is one, otherwise try to construct one from the underlying v...
Definition VPlan.cpp:1622
const Module * getModule() const
Returns the module the plan operates on, if any.
void printMetadataAsOperand(raw_ostream &O, const MDNode *N)
Print a reference to metadata node N to O.
Definition VPlan.cpp:1618
VPSlotTracker(const VPlan *Plan=nullptr)
This is the base class of the VPlan Def/Use graph, used for modeling the data flow into,...
Definition VPlanValue.h:50
VPlanPrinter(raw_ostream &O, const VPlan &P)
LLVM_DUMP_METHOD void dump()
Definition VPlan.cpp:1334
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
Definition VPlan.h:4883
VPIRBasicBlock * getScalarHeader() const
Return the VPIRBasicBlock wrapping the header of the scalar loop.
Definition VPlan.h:5037
LLVM Value Representation.
Definition Value.h:75
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:169
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition iterator.h:80
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This namespace contains an enum with a value for every intrinsic/builtin function known by LLVM.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
Value * getRuntimeVF(IRBuilderBase &B, Type *Ty, ElementCount VF)
Return the runtime value for VF.
bool isVectorizedTy(Type *Ty)
Returns true if Ty is a vector type or a struct of vector types where all vector types share the same...
bool canConstantBeExtended(const APInt *C, Type *NarrowType, TTI::PartialReductionExtendKind ExtKind)
Check if a constant CI can be safely treated as having been extended from a narrower type with the gi...
Definition VPlan.cpp:1828
@ Other
Any other memory.
Definition ModRef.h:68
#define N
iterator end()
const ElementCount Start
ElementCount End
iterator begin()
bool isEmpty() const
VFRange(const ElementCount &Start, const ElementCount &End)
LLVMContext & LLVMCtx
const VFSelectionContext & Config
uint64_t getCostDivisor(std::optional< VPExecutionFrequency > Freq) const
Definition VPlan.cpp:1941
LoopVectorizationCostModel & CM
TargetTransformInfo::OperandValueInfo getOperandInfo(VPValue *V) const
Returns the OperandInfo for V, if it is a live-in.
Definition VPlan.cpp:1839
VPCostContext(const TargetLibraryInfo &TLI, const VPlan &Plan, LoopVectorizationCostModel &CM, VFSelectionContext &Config, bool ReusePrintingSlotTracker=false)
static bool isFreeScalarIntrinsic(Intrinsic::ID ID)
Returns true if ID is a pseudo intrinsic that is dropped via scalarization rather than widened.
Definition VPlan.cpp:1932
bool skipCostComputation(Instruction *UI, bool IsVector) const
Return true if the cost for UI shouldn't be computed, e.g.
InstructionCost getLegacyCost(Instruction *UI, ElementCount VF) const
Return the cost for UI with VF using the legacy cost model as fallback until computing the cost of al...
bool isMaskRequired(Instruction *I) const
Forwards to LoopVectorizationCostModel::isMaskRequired.
void invalidateWideningDecision(Instruction *I, ElementCount VF)
Mark the widening decision for I at VF as invalidated since a VPlan transform replaced the original r...
PredicatedScalarEvolution & PSE
bool willBeScalarized(Instruction *I, ElementCount VF) const
Returns true if I is known to be scalarized at VF.
static bool executesAtMostOnce(const VPlan &Plan, ElementCount VF)
Returns true if the vector loop body of Plan is known to execute at most once at VF,...
std::optional< unsigned > NumPredStores
Number of predicated stores in the VPlan, computed on demand.
InstructionCost getScalarizationOverhead(Type *ResultTy, ArrayRef< const VPValue * > Operands, ElementCount VF, TTI::VectorInstrContext VIC=TTI::VectorInstrContext::None, bool AlwaysIncludeReplicatingR=false)
Estimate the overhead of scalarizing a recipe with result type ResultTy and Operands with VF.
Definition VPlan.cpp:1856
TargetTransformInfo::TargetCostKind CostKind
VPSlotTracker * getSlotTracker()
Return a VPSlotTracker to re-use for printing, lazily constructing it on first use.
Definition VPlan.cpp:1847
const TargetLibraryInfo & TLI
const TargetTransformInfo & TTI
SmallPtrSet< Instruction *, 8 > SkipCostComputation
bool useEmulatedMaskMemRefHack(const VPReplicateRecipe *R, ElementCount VF)
Returns true if an artificially high cost for emulated masked memrefs should be used.
Definition VPlan.cpp:1894
const VectorizeOptions & Opts
BasicBlock * PrevBB
The previous IR BasicBlock created or used.
VPBasicBlock * PrevVPBB
The previous VPBasicBlock visited. Initially set to null.
BasicBlock * ExitBB
The last IR BasicBlock in the output IR.
SmallDenseMap< const VPBasicBlock *, BasicBlock * > VPBB2IRBB
A mapping of each VPBasicBlock to the corresponding BasicBlock.
DomTreeUpdater DTU
Updater for the DominatorTree.
DenseMap< const VPValue *, SmallVector< Value *, 4 > > VPV2Scalars
DenseMap< const VPValue *, Value * > VPV2Vector
LoopInfo * LI
Hold a pointer to LoopInfo to register new basic blocks in the loop.
void fixupHeaderPhis()
Add the backedge (latch) incoming value to the canonical, reduction and first-order recurrence phis i...
Definition VPlan.cpp:331
struct llvm::VPTransformState::DataState Data
void set(const VPValue *Def, Value *V, const VPLane &Lane)
Set the generated scalar V for Def and the given Lane.
IRBuilderBase & Builder
Hold a reference to the IRBuilder used to generate output IR code.
bool hasScalarValue(const VPValue *Def, VPLane Lane)
Value * get(const VPValue *Def, bool NeedsSingleScalar=false)
Get the generated vector Value for a given VPValue Def if NeedsSingleScalar is false,...
Definition VPlan.cpp:270
const TargetTransformInfo * TTI
Target Transform Info.
VPTransformState(const TargetTransformInfo *TTI, ElementCount VF, LoopInfo *LI, DominatorTree *DT, AssumptionCache *AC, IRBuilderBase &Builder, VPlan *Plan, Loop *CurrentParentLoop)
Definition VPlan.cpp:235
VPlan * Plan
Pointer to the VPlan code is generated for.
void set(const VPValue *Def, Value *V, bool IsScalar=false)
Set the generated vector Value for a given VPValue, if IsScalar is false.
bool hasVectorValue(const VPValue *Def)
VPDominatorTree VPDT
VPlan-based dominator tree.
ElementCount VF
The chosen Vectorization Factor of the loop being vectorized.
AssumptionCache * AC
Hold a pointer to AssumptionCache to register new assumptions after replicating assume calls.
void setDebugLocFrom(DebugLoc DL)
Set the debug location in the builder using the debug location DL.
Definition VPlan.cpp:309
Loop * CurrentParentLoop
The parent loop object for the current scope, or nullptr.