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 || match(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

315 if (A == B)

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.