LLVM: lib/Transforms/Vectorize/VPlanAnalysis.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
18
19using namespace llvm;
20
21#define DEBUG_TYPE "vplan"
22
23Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPBlendRecipe *R) {
25 for (unsigned I = 1, E = R->getNumIncomingValues(); I != E; ++I) {
26 VPValue *Inc = R->getIncomingValue(I);
28 "different types inferred for different incoming values");
29 CachedTypes[Inc] = ResTy;
30 }
31 return ResTy;
32}
33
34Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPInstruction *R) {
35
36
37 auto SetResultTyFromOp = [this, R]() {
39 for (unsigned Op = 1; Op != R->getNumOperands(); ++Op) {
42 "different types inferred for different operands");
43 CachedTypes[OtherV] = ResTy;
44 }
45 return ResTy;
46 };
47
48 unsigned Opcode = R->getOpcode();
50 return SetResultTyFromOp();
51
52 switch (Opcode) {
53 case Instruction::Select: {
55 VPValue *OtherV = R->getOperand(2);
57 "different types inferred for different operands");
58 CachedTypes[OtherV] = ResTy;
59 return ResTy;
60 }
61 case Instruction::ICmp:
65 "different types inferred for different operands");
68 auto *PhiR = cast(R->getOperand(0));
69 auto *OrigPhi = cast(PhiR->getUnderlyingValue());
70 return OrigPhi->getType();
71 }
80 return SetResultTyFromOp();
83 if (auto *VecTy = dyn_cast(BaseTy))
84 return VecTy->getElementType();
86 }
90 "LogicalAnd operands should be bool");
93
98 default:
99 break;
100 }
101
103 dbgs() << "LV: Found unhandled opcode for: ";
104 R->getVPSingleValue()->dump();
105 });
107}
108
109Type *VPTypeAnalysis::inferScalarTypeForRecipe(const VPWidenRecipe *R) {
110 unsigned Opcode = R->getOpcode();
115 "types for both operands must match for binary op");
116 CachedTypes[R->getOperand(1)] = ResTy;
117 return ResTy;
118 }
119
120 switch (Opcode) {
121 case Instruction::ICmp:
122 case Instruction::FCmp:
124 case Instruction::FNeg:
125 case Instruction::Freeze:
127 default:
128 break;
129 }
130
131
133 dbgs() << "LV: Found unhandled opcode for: ";
134 R->getVPSingleValue()->dump();
135 });
137}
138
140 auto &CI = *cast(R->getUnderlyingInstr());
141 return CI.getType();
142}
143
145 assert((isa<VPWidenLoadRecipe, VPWidenLoadEVLRecipe>(R)) &&
146 "Store recipes should not define any values");
147 return cast(&R->getIngredient())->getType();
148}
149
152 VPValue *OtherV = R->getOperand(2);
154 "different types inferred for different operands");
155 CachedTypes[OtherV] = ResTy;
156 return ResTy;
157}
158
160 unsigned Opcode = R->getUnderlyingInstr()->getOpcode();
161
166 "inferred types for operands of binary op don't match");
167 CachedTypes[R->getOperand(1)] = ResTy;
168 return ResTy;
169 }
170
172 return R->getUnderlyingInstr()->getType();
173
174 switch (Opcode) {
175 case Instruction::Call: {
176 unsigned CallIdx = R->getNumOperands() - (R->isPredicated() ? 2 : 1);
177 return cast(R->getOperand(CallIdx)->getLiveInIRValue())
178 ->getReturnType();
179 }
180 case Instruction::Select: {
183 "inferred types for operands of select op don't match");
184 CachedTypes[R->getOperand(2)] = ResTy;
185 return ResTy;
186 }
187 case Instruction::ICmp:
188 case Instruction::FCmp:
190 case Instruction::Alloca:
191 case Instruction::ExtractValue:
192 return R->getUnderlyingInstr()->getType();
193 case Instruction::Freeze:
194 case Instruction::FNeg:
195 case Instruction::GetElementPtr:
197 case Instruction::Load:
198 return cast(R->getUnderlyingInstr())->getType();
199 case Instruction::Store:
200
201
202
204 default:
205 break;
206 }
207
209 dbgs() << "LV: Found unhandled opcode for: ";
210 R->getVPSingleValue()->dump();
211 });
213}
214
216 if (Type *CachedTy = CachedTypes.lookup(V))
217 return CachedTy;
218
219 if (V->isLiveIn()) {
220 if (auto *IRValue = V->getLiveInIRValue())
221 return IRValue->getType();
222
223
224 return CanonicalIVTy;
225 }
226
227 Type *ResultTy =
233
234
235
236
238 })
239 .Case<VPWidenIntOrFpInductionRecipe, VPDerivedIVRecipe>(
240 [](const auto *R) { return R->getScalarType(); })
246 })
250 [this](const auto *R) { return inferScalarTypeForRecipe(R); })
252 return R->getResultType();
253 })
255
256 return V->getUnderlyingValue()->getType();
257 })
258 .Case(
260 .Case(
263 return R->getSCEV()->getType();
264 })
265 .Case([this](const auto *R) {
267 });
268
269 assert(ResultTy && "could not infer type for the given VPValue");
270 CachedTypes[V] = ResultTy;
271 return ResultTy;
272}
273
276
278 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly(
281 auto *RepR = dyn_cast(&R);
282 if (!RepR || (RepR->getUnderlyingInstr(),
283 PatternMatch::m_IntrinsicIntrinsic::assume()))
284 continue;
286 EphRecipes.insert(RepR);
287 }
288 }
289
290
291
292
293 while (!Worklist.empty()) {
296 auto *OpR = Op->getDefiningRecipe();
297 if (!OpR || OpR->mayHaveSideEffects() || EphRecipes.contains(OpR))
298 continue;
300 auto *UR = dyn_cast(U);
301 return !UR || !EphRecipes.contains(UR);
302 }))
303 continue;
304 EphRecipes.insert(OpR);
306 }
307 }
308}
309
310template void DomTreeBuilder::Calculate<DominatorTreeBase<VPBlockBase, false>>(
312
316 return false;
317
319 for (auto &R : *A->getParent()) {
320 if (&R == A)
321 return true;
322 if (&R == B)
323 return false;
324 }
326 };
329 if (ParentA == ParentB)
330 return LocalComesBefore(A, B);
331
332#ifndef NDEBUG
334 auto *Region = dyn_cast_or_null(R->getParent()->getParent());
337 Region->getNumPredecessors() == 1 && "Expected SESE region!");
338 assert(R->getParent()->size() == 1 &&
339 "A recipe in an original replicator region must be the only "
340 "recipe in its block");
342 }
343 return nullptr;
344 };
346 "No replicate regions expected at this point");
348 "No replicate regions expected at this point");
349#endif
351}
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Generic dominator tree construction - this file provides routines to construct immediate dominator in...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 the Vectorization Plan base classes:
This class represents an Operation in the Expression.
Implements a dense probed hash-table based set.
Core dominator tree base class.
bool properlyDominates(const DomTreeNodeBase< VPBlockBase > *A, const DomTreeNodeBase< VPBlockBase > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
bool isBitwiseLogicOp() const
Return true if this is and/or/xor.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class implements a switch-like dispatch statement for a value of 'T' using dyn_cast functionalit...
TypeSwitch< T, ResultT > & Case(CallableT &&caseFn)
Add a case on the given type.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getIntNTy(LLVMContext &C, unsigned N)
static Type * getVoidTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
A recipe for generating the active lane mask for the vector loop that is used to predicate the vector...
VPBasicBlock serves as the leaf of the Hierarchical Control-Flow Graph.
A recipe for vectorizing a phi-node as a sequence of mask-based select instructions.
VPBlockBase is the building block of the Hierarchical Control-Flow Graph.
Canonical scalar induction phi of the vector loop.
bool properlyDominates(const VPRecipeBase *A, const VPRecipeBase *B)
Returns true if A properly dominates B.
A recipe for generating the phi node for the current index of elements, adjusted in accordance with E...
Recipe to expand a SCEV expression.
This is a concrete Recipe that models a single VPlan-level instruction.
@ ResumePhi
Creates a scalar phi in a leaf VPBB with a single predecessor in VPlan.
@ FirstOrderRecurrenceSplice
@ CanonicalIVIncrementForPart
@ CalculateTripCountMinusVF
VPInterleaveRecipe is a recipe for transforming an interleave group of load or stores into one wide l...
A recipe for forming partial reductions.
VPPredInstPHIRecipe is a recipe for generating the phi nodes needed when control converges back from ...
VPRecipeBase is a base class modeling a sequence of one or more output IR instructions.
A recipe for handling reduction phis.
A recipe to represent inloop reduction operations, performing a reduction on a vector operand into a ...
VPRegionBlock represents a collection of VPBasicBlocks and VPRegionBlocks which form a Single-Entry-S...
const VPBlockBase * getEntry() const
VPReplicateRecipe replicates a given instruction producing multiple scalar copies of the original sca...
A recipe to compute the pointers for widened memory accesses of IndexTy in reverse order.
VPScalarCastRecipe is a recipe to create scalar cast instructions.
A recipe for handling phi nodes of integer and floating-point inductions, producing their scalar valu...
Recipe to generate a scalar PHI.
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...
A recipe to compute the pointers for widened memory accesses of IndexTy.
A recipe for widening Call instructions using library calls.
A Recipe for widening the canonical induction variable of the vector loop.
VPWidenCastRecipe is a recipe to create vector cast instructions.
A recipe for widening operations with vector-predication intrinsics with explicit vector length (EVL)...
A recipe for handling GEP instructions.
A recipe for widening vector intrinsics.
A common base class for widening memory operations.
A recipe for handling phis that are widened in the vector loop.
VPWidenRecipe is a recipe for producing a widened instruction using the opcode and operands of the re...
VPlan models a candidate for vectorization, encoding various decisions take to produce efficient outp...
VPRegionBlock * getVectorLoopRegion()
Returns the VPRegionBlock of the vector loop.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool match(Val *V, const Pattern &P)
This is an optimization pass for GlobalISel generic memory operations.
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...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
void collectEphemeralRecipesForVPlan(VPlan &Plan, DenseSet< VPRecipeBase * > &EphRecipes)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
DWARFExpression::Operation Op
A recipe for handling first-order recurrence phis.
A recipe for widening select instructions.