LLVM 24.0.0git
BundleVec.cpp
Go to the documentation of this file.
1//===- BundleVec.cpp - A bundle-forming SLP-style vectorizer pass ---------===//
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
20
21namespace llvm {
22
23namespace sandboxir {
24
25static BundleTy getOperand(BndlRef<Value *> Bndl, unsigned OpIdx) {
27 for (Value *BndlV : Bndl) {
28 auto *BndlI = cast<Instruction>(BndlV);
29 Operands.push_back(BndlI->getOperand(OpIdx));
30 }
31 return Operands;
32}
33
34Value *BundleVec::createVectorInstr(BndlRef<Value *> Bndl,
36 auto CreateVectorInstr = [](BndlRef<Value *> Bndl,
38 assert(all_of(Bndl, [](auto *V) { return isa<Instruction>(V); }) &&
39 "Expect Instructions!");
40 auto &Ctx = Bndl[0]->getContext();
41
42 Type *ScalarTy = VecUtils::getElementType(Utils::getExpectedType(Bndl[0]));
43 auto *VecTy = VecUtils::getWideType(ScalarTy, VecUtils::getNumLanes(Bndl));
44
46 Bndl, cast<Instruction>(Bndl[0])->getParent());
47
48 auto Opcode = cast<Instruction>(Bndl[0])->getOpcode();
49 switch (Opcode) {
50 case Instruction::Opcode::ZExt:
51 case Instruction::Opcode::SExt:
52 case Instruction::Opcode::FPToUI:
53 case Instruction::Opcode::FPToSI:
54 case Instruction::Opcode::FPExt:
55 case Instruction::Opcode::PtrToInt:
56 case Instruction::Opcode::IntToPtr:
57 case Instruction::Opcode::SIToFP:
58 case Instruction::Opcode::UIToFP:
59 case Instruction::Opcode::Trunc:
60 case Instruction::Opcode::FPTrunc:
61 case Instruction::Opcode::BitCast: {
62 assert(Operands.size() == 1u && "Casts are unary!");
63 return CastInst::create(VecTy, Opcode, Operands[0], WhereIt, Ctx,
64 "VCast");
65 }
66 case Instruction::Opcode::FCmp:
67 case Instruction::Opcode::ICmp: {
68 auto Pred = cast<CmpInst>(Bndl[0])->getPredicate();
70 [Pred](auto *SBV) {
71 return cast<CmpInst>(SBV)->getPredicate() == Pred;
72 }) &&
73 "Expected same predicate across bundle.");
74 return CmpInst::create(Pred, Operands[0], Operands[1], WhereIt, Ctx,
75 "VCmp");
76 }
77 case Instruction::Opcode::Select: {
78 return SelectInst::create(Operands[0], Operands[1], Operands[2], WhereIt,
79 Ctx, "Vec");
80 }
81 case Instruction::Opcode::FNeg: {
82 auto *UOp0 = cast<UnaryOperator>(Bndl[0]);
83 auto OpC = UOp0->getOpcode();
85 WhereIt, Ctx, "Vec");
86 }
87 case Instruction::Opcode::Add:
88 case Instruction::Opcode::FAdd:
89 case Instruction::Opcode::Sub:
90 case Instruction::Opcode::FSub:
91 case Instruction::Opcode::Mul:
92 case Instruction::Opcode::FMul:
93 case Instruction::Opcode::UDiv:
94 case Instruction::Opcode::SDiv:
95 case Instruction::Opcode::FDiv:
96 case Instruction::Opcode::URem:
97 case Instruction::Opcode::SRem:
98 case Instruction::Opcode::FRem:
99 case Instruction::Opcode::Shl:
100 case Instruction::Opcode::LShr:
101 case Instruction::Opcode::AShr:
102 case Instruction::Opcode::And:
103 case Instruction::Opcode::Or:
104 case Instruction::Opcode::Xor: {
105 auto *BinOp0 = cast<BinaryOperator>(Bndl[0]);
106 auto *LHS = Operands[0];
107 auto *RHS = Operands[1];
109 BinOp0->getOpcode(), LHS, RHS, BinOp0, WhereIt, Ctx, "Vec");
110 }
111 case Instruction::Opcode::Load: {
112 auto Align = VecUtils::getVecAlignment(Bndl);
113 auto *Ld0 = cast<LoadInst>(Bndl[0]);
114 Value *Ptr = Ld0->getPointerOperand();
115 return LoadInst::create(VecTy, Ptr, Align, WhereIt, Ctx, "VecL");
116 }
117 case Instruction::Opcode::Store: {
118 auto Align = VecUtils::getVecAlignment(Bndl);
119 Value *Val = Operands[0];
120 Value *Ptr = Operands[1];
121 return StoreInst::create(Val, Ptr, Align, WhereIt, Ctx);
122 }
123 case Instruction::Opcode::UncondBr:
124 case Instruction::Opcode::CondBr:
125 case Instruction::Opcode::Ret:
126 case Instruction::Opcode::PHI:
127 case Instruction::Opcode::AddrSpaceCast:
128 case Instruction::Opcode::Call:
129 case Instruction::Opcode::GetElementPtr:
130 llvm_unreachable("Unimplemented");
131 break;
132 default:
133 llvm_unreachable("Unimplemented");
134 break;
135 }
136 llvm_unreachable("Missing switch case!");
137 // TODO: Propagate debug info.
138 };
139
140 auto *NewI = CreateVectorInstr(Bndl, Operands);
141 LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "New instr: " << *NewI << "\n");
142 return NewI;
143}
144
145Value *BundleVec::createShuffle(Value *VecOp, const ShuffleMask &Mask,
146 BasicBlock *UserBB) {
147 BasicBlock::iterator WhereIt =
149 return ShuffleVectorInst::create(VecOp, VecOp, Mask, WhereIt,
150 VecOp->getContext(), "VShuf");
151}
152
153Value *BundleVec::createPack(BndlRef<Value *> ToPack, BasicBlock *UserBB) {
154 BasicBlock::iterator WhereIt =
156
157 Type *ScalarTy = VecUtils::getCommonScalarType(ToPack);
158 unsigned Lanes = VecUtils::getNumLanes(ToPack);
159 Type *VecTy = VecUtils::getWideType(ScalarTy, Lanes);
160
161 // Create a series of pack instructions.
162 Value *LastInsert = PoisonValue::get(VecTy);
163
164 Context &Ctx = ToPack[0]->getContext();
165
166 unsigned InsertIdx = 0;
167 for (Value *Elm : ToPack) {
168 // An element can be either scalar or vector. We need to generate different
169 // IR for each case.
170 if (Elm->getType()->isVectorTy()) {
171 unsigned NumElms =
172 cast<FixedVectorType>(Elm->getType())->getNumElements();
173 for (auto ExtrLane : seq<int>(0, NumElms)) {
174 // We generate extract-insert pairs, for each lane in `Elm`.
175 Constant *ExtrLaneC =
177 // This may return a Constant if Elm is a Constant.
178 auto *ExtrI =
179 ExtractElementInst::create(Elm, ExtrLaneC, WhereIt, Ctx, "VPack");
180 if (!isa<Constant>(ExtrI))
181 WhereIt = std::next(cast<Instruction>(ExtrI)->getIterator());
182 Constant *InsertLaneC =
183 ConstantInt::getSigned(Type::getInt32Ty(Ctx), InsertIdx++);
184 // This may also return a Constant if ExtrI is a Constant.
185 auto *InsertI = InsertElementInst::create(
186 LastInsert, ExtrI, InsertLaneC, WhereIt, Ctx, "VPack");
187 LastInsert = InsertI;
188 if (!isa<Constant>(InsertI))
189 WhereIt = std::next(cast<Instruction>(LastInsert)->getIterator());
190 }
191 } else {
192 Constant *InsertLaneC =
193 ConstantInt::getSigned(Type::getInt32Ty(Ctx), InsertIdx++);
194 // This may be folded into a Constant if LastInsert is a Constant. In
195 // that case we only collect the last constant.
196 LastInsert = InsertElementInst::create(LastInsert, Elm, InsertLaneC,
197 WhereIt, Ctx, "Pack");
198 if (auto *NewI = dyn_cast<Instruction>(LastInsert))
199 WhereIt = std::next(NewI->getIterator());
200 }
201 }
202 return LastInsert;
203}
204
205Action *BundleVec::vectorizeRec(BndlRef<Value *> Bndl,
206 BndlRef<Value *> UserBndl, unsigned Depth,
207 LegalityAnalysis &Legality) {
208 bool StopForDebug = DebugBndlCnt++ >= Opts->sbvec_stop_bndl &&
209 Opts->sbvec_stop_bndl != SBVecStopDisabled;
210 LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "canVectorize() Bundle:\n";
211 VecUtils::dump(Bndl));
212 const auto &LegalityRes = StopForDebug ? Legality.getForcedPackForDebugging()
213 : Legality.canVectorize(Bndl);
214 LLVM_DEBUG(dbgs() << DEBUG_PREFIX << "Legality: " << LegalityRes << "\n");
215
216 if (Dir == SchedDirection::TopDown) {
217 // A non-Widen result means we can't extend the vectorized region into
218 // this bundle, so leave its instructions scalar and don't record an
219 // action for it.
220 if (LegalityRes.getSubclassID() != LegalityResultID::Widen)
221 return nullptr;
222
223 auto ActionPtr =
224 std::make_unique<Action>(&LegalityRes, Bndl, BndlRef<Value *>(), Depth);
225 Action *Action = ActionPtr.get();
226 IMaps->registerVector(Bndl, Action);
227 Actions.push_back(std::move(ActionPtr));
228
229 // Walk down the def-use chain. Each lane in \p Bndl may feed several
230 // users, so we form every compatible user bundle and recurse into each
231 // one.
232 SmallPtrSet<Instruction *, 4> Claimed;
233 for (const auto &NextUserBndl :
234 VecUtils::getNextUserBundles(Bndl, *IMaps, Claimed))
235 vectorizeRec(NextUserBndl, Bndl, Depth + 1, Legality);
236
237 return Action;
238 }
239
240 // Bottom up direction
241 auto ActionPtr =
242 std::make_unique<Action>(&LegalityRes, Bndl, UserBndl, Depth);
244 switch (LegalityRes.getSubclassID()) {
246 auto *I = cast<Instruction>(Bndl[0]);
247 switch (I->getOpcode()) {
248 case Instruction::Opcode::Load:
249 break;
250 case Instruction::Opcode::Store: {
251 // Don't recurse towards the pointer operand.
252 Action *OpA =
253 vectorizeRec(getOperand(Bndl, 0), Bndl, Depth + 1, Legality);
254 Operands.push_back(OpA);
255 break;
256 }
257 default:
258 // Visit all operands.
259 for (auto OpIdx : seq<unsigned>(I->getNumOperands())) {
260 Action *OpA =
261 vectorizeRec(getOperand(Bndl, OpIdx), Bndl, Depth + 1, Legality);
262 Operands.push_back(OpA);
263 }
264 break;
265 }
266 // Update the maps to mark Bndl as "vectorized".
267 IMaps->registerVector(Bndl, ActionPtr.get());
268 break;
269 }
274 break;
275 }
276 // Create actions in post-order.
277 ActionPtr->Operands = std::move(Operands);
278 auto *Action = ActionPtr.get();
279 Actions.push_back(std::move(ActionPtr));
280 return Action;
281}
282
283#ifndef NDEBUG
284void BundleVec::ActionsVector::print(raw_ostream &OS) const {
285 for (auto [Idx, Action] : enumerate(Actions)) {
286 Action->print(OS);
287 OS << "\n";
288 }
289}
290void BundleVec::ActionsVector::dump() const { print(dbgs()); }
291#endif // NDEBUG
292
293void BundleVec::emitUnpacksForExternalUses(BndlRef<Value *> Bndl, Value *Vec) {
294 // Find where we should emit the unpacks.
295 BasicBlock::iterator WhereIt;
296 if (auto *VecI = dyn_cast<Instruction>(Vec)) {
297 WhereIt = std::next(VecI->getIterator());
298 } else {
299 // If Vec is a constant then it should be safe to emit the unpacks at the
300 // top of the block.
301 // Note: Extracts from constants are usually folded to constants.
302 assert(isa<Constant>(Vec) && "Expected constant!");
303 assert(isa<Instruction>(Bndl[0]) &&
304 "A widened Bndl should contain instrs!");
305 BasicBlock *BB = cast<Instruction>(Bndl[0])->getParent();
306 WhereIt =
307 BB->empty()
308 ? BB->begin()
309 : std::next(
310 VecUtils::getLastPHIOrSelf(&*BB->begin())->getIterator());
311 }
312
313 for (auto [Lane, Elm] : VecUtils::enumerateLanes(Bndl)) {
314 // Only redirect the external (non-vectorized) uses to an unpack and leave
315 // the vectorized users untouched. A blanket replaceAllUsesWith() would
316 // also rewrite the operands of users we are going to vectorize but have
317 // not emitted yet (in the top-down direction a user bundle is emitted
318 // after its operand bundle), which would corrupt those operands.
319 auto IsExternal = [this](const Use &U) {
320 return !IMaps->isVectorized(U.getUser());
321 };
322 // Don't emit a dead unpack if all uses are internal to the vector region.
323 if (none_of(Elm->uses(), IsExternal))
324 continue;
325 auto *UnpackV = VecUtils::unpack(Vec, Elm->getType(), Lane, WhereIt);
326 Elm->replaceUsesWithIf(UnpackV, IsExternal);
327 }
328}
329
330Value *BundleVec::emitVectors() {
331 Value *NewVec = nullptr;
332 for (const auto &ActionPtr : Actions) {
333 BndlRef<Value *> Bndl = ActionPtr->Bndl;
334 BndlRef<Value *> UserBndl = ActionPtr->UserBndl;
335 const LegalityResult &LegalityRes = *ActionPtr->LegalityRes;
336 unsigned Depth = ActionPtr->Depth;
337 auto *UserBB = !UserBndl.empty()
338 ? cast<Instruction>(UserBndl.front())->getParent()
339 : cast<Instruction>(Bndl[0])->getParent();
340
341 switch (LegalityRes.getSubclassID()) {
343 auto *I = cast<Instruction>(Bndl[0]);
344 SmallVector<Value *, 2> VecOperands;
345 if (Dir == SchedDirection::BottomUp) {
346 switch (I->getOpcode()) {
347 case Instruction::Opcode::Load:
348 VecOperands.push_back(cast<LoadInst>(I)->getPointerOperand());
349 break;
350 case Instruction::Opcode::Store:
351 VecOperands.push_back(ActionPtr->Operands[0]->Vec);
352 VecOperands.push_back(cast<StoreInst>(I)->getPointerOperand());
353 break;
354 default:
355 for (Action *OpA : ActionPtr->Operands)
356 VecOperands.push_back(OpA->Vec);
357 break;
358 }
359 } else {
360 switch (I->getOpcode()) {
361 case Instruction::Opcode::Load:
362 VecOperands.push_back(cast<LoadInst>(I)->getPointerOperand());
363 break;
364 case Instruction::Opcode::Store: {
365 auto OpBndl = getOperand(Bndl, 0);
366 if (Action *OpA = IMaps->getVectorForOrig(OpBndl[0]))
367 VecOperands.push_back(OpA->Vec);
368 else
369 VecOperands.push_back(createPack(OpBndl, UserBB));
370 VecOperands.push_back(cast<StoreInst>(I)->getPointerOperand());
371 break;
372 }
373 default:
374 for (unsigned OpIdx = 0; OpIdx < I->getNumOperands(); ++OpIdx) {
375 BundleTy OpBndl = getOperand(Bndl, OpIdx);
376 if (Action *OpA = IMaps->getVectorForOrig(OpBndl[0]))
377 VecOperands.push_back(OpA->Vec);
378 else
379 VecOperands.push_back(createPack(OpBndl, UserBB));
380 }
381 break;
382 }
383 }
384 NewVec = createVectorInstr(ActionPtr->Bndl, VecOperands);
385 // Collect any potentially dead scalar instructions, including the
386 // original scalars and pointer operands of loads/stores.
387 if (NewVec != nullptr)
388 DeadInstrMorgue.collectPotentiallyDeadInstrs(Bndl);
389
390 // Emit unpacks for all external uses, if any.
391 emitUnpacksForExternalUses(ActionPtr->Bndl, NewVec);
392 break;
393 }
395 NewVec = cast<DiamondReuse>(LegalityRes).getVector()->Vec;
396 break;
397 }
399 auto *VecOp = cast<DiamondReuseWithShuffle>(LegalityRes).getVector()->Vec;
400 const ShuffleMask &Mask =
401 cast<DiamondReuseWithShuffle>(LegalityRes).getMask();
402 NewVec = createShuffle(VecOp, Mask, UserBB);
403 assert(NewVec->getType() == VecOp->getType() &&
404 "Expected same type! Bad mask ?");
405 break;
406 }
408 const auto &Descr =
409 cast<DiamondReuseMultiInput>(LegalityRes).getCollectDescr();
410 Type *ResTy = VecUtils::getWideType(Bndl[0]->getType(), Bndl.size());
411
412 // TODO: Try to get WhereIt without creating a vector.
413 SmallVector<Value *, 4> DescrInstrs;
414 for (const auto &ElmDescr : Descr.getDescrs()) {
415 auto *V = ElmDescr.needsExtract() ? ElmDescr.getValue()->Vec
416 : ElmDescr.getScalar();
417 if (auto *I = dyn_cast<Instruction>(V))
418 DescrInstrs.push_back(I);
419 }
420 BasicBlock::iterator WhereIt =
421 VecUtils::getInsertPointAfterInstrs(DescrInstrs, UserBB);
422
423 Value *LastV = PoisonValue::get(ResTy);
424 Context &Ctx = LastV->getContext();
425 unsigned Lane = 0;
426 for (const auto &ElmDescr : Descr.getDescrs()) {
427 Value *VecOp = nullptr;
428 Value *ValueToInsert;
429 if (ElmDescr.needsExtract()) {
430 VecOp = ElmDescr.getValue()->Vec;
431 ConstantInt *IdxC =
432 ConstantInt::get(Type::getInt32Ty(Ctx), ElmDescr.getExtractIdx());
433 ValueToInsert = ExtractElementInst::create(
434 VecOp, IdxC, WhereIt, VecOp->getContext(), "VExt");
435 } else {
436 ValueToInsert = ElmDescr.getScalar();
437 }
438 auto NumLanesToInsert = VecUtils::getNumLanes(ValueToInsert);
439 if (NumLanesToInsert == 1) {
440 // If we are inserting a scalar element then we need a single insert.
441 // %VIns = insert %DstVec, %SrcScalar, Lane
442 ConstantInt *LaneC = ConstantInt::get(Type::getInt32Ty(Ctx), Lane);
443 LastV = InsertElementInst::create(LastV, ValueToInsert, LaneC,
444 WhereIt, Ctx, "VIns");
445 } else {
446 // If we are inserting a vector element then we need to extract and
447 // insert each vector element one by one with a chain of extracts and
448 // inserts, for example:
449 // %VExt0 = extract %SrcVec, 0
450 // %VIns0 = insert %DstVec, %Vect0, Lane + 0
451 // %VExt1 = extract %SrcVec, 1
452 // %VIns1 = insert %VIns0, %Vect0, Lane + 1
453 for (unsigned LnCnt = 0; LnCnt != NumLanesToInsert; ++LnCnt) {
454 auto *ExtrIdxC = ConstantInt::get(Type::getInt32Ty(Ctx), LnCnt);
455 auto *ExtrI = ExtractElementInst::create(ValueToInsert, ExtrIdxC,
456 WhereIt, Ctx, "VExt");
457 unsigned InsLane = Lane + LnCnt;
458 auto *InsLaneC = ConstantInt::get(Type::getInt32Ty(Ctx), InsLane);
459 LastV = InsertElementInst::create(LastV, ExtrI, InsLaneC, WhereIt,
460 Ctx, "VIns");
461 }
462 }
463 Lane += NumLanesToInsert;
464 }
465 NewVec = LastV;
466 break;
467 }
469 // If we can't vectorize the seeds then just return.
470 if (Depth == 0)
471 return nullptr;
472 NewVec = createPack(Bndl, UserBB);
473 break;
474 }
475 }
476 if (NewVec != nullptr) {
477 Change = true;
478 ActionPtr->Vec = NewVec;
479 }
480#ifndef NDEBUG
481 if (Opts->sbvec_always_verify) {
482 // This helps find broken IR by constantly verifying the function. Note
483 // that this is very expensive and should only be used for debugging.
484 Instruction *I0 = isa<Instruction>(Bndl[0])
485 ? cast<Instruction>(Bndl[0])
486 : cast<Instruction>(UserBndl[0]);
487 assert(!Utils::verifyFunction(I0->getParent()->getParent(), dbgs()) &&
488 "Broken function!");
489 }
490#endif // NDEBUG
491 }
492 return NewVec;
493}
494
495bool BundleVec::tryVectorize(BndlRef<Value *> Bndl,
496 LegalityAnalysis &Legality) {
497 Change = false;
498 if (LLVM_UNLIKELY(InvocationCnt++ >= Opts->sbvec_stop_at &&
499 Opts->sbvec_stop_at != SBVecStopDisabled))
500 return false;
501 Legality.clear();
502 Actions.clear();
503 DebugBndlCnt = 0;
504 vectorizeRec(Bndl, {}, /*Depth=*/0, Legality);
506 << "Vec: Vectorization Actions:\n";
507 Actions.dump());
508 emitVectors();
509 DeadInstrMorgue.tryEraseDeadInstrs();
510 return Change;
511}
512
514 Opts = &getVectorizeOptions(Rgn.getContext());
515 const auto &SeedSlice = Rgn.getAux();
516 if (SeedSlice.size() < 2)
517 return false;
518 Function &F = *SeedSlice[0]->getParent()->getParent();
519 IMaps = std::make_unique<InstrMaps>();
520 LegalityAnalysis Legality(A.getAA(), A.getScalarEvolution(),
521 F.getParent()->getDataLayout(), A.getTTI(),
522 F.getContext(), *IMaps, Dir);
523
524 // TODO: Refactor to remove the unnecessary copy to SeedSliceVals.
525 SmallVector<Value *> SeedSliceVals(SeedSlice.begin(), SeedSlice.end());
526 // Try to vectorize starting from the seed slice. The returned value
527 // is true if we found vectorizable code and generated some vector
528 // code for it. It does not mean that the code is profitable.
529 return tryVectorize(SeedSliceVals, Legality);
530}
531
532} // namespace sandboxir
533} // namespace llvm
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:348
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
SI Fold Operands
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
static SymbolRef::Type getType(const Symbol *Sym)
Definition TapiFile.cpp:39
#define DEBUG_PREFIX
Definition Debug.h:19
Value * RHS
Value * LHS
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
Definition Value.h:75
static LLVM_ABI Value * createWithCopiedFlags(Instruction::Opcode Op, Value *LHS, Value *RHS, Value *CopyFrom, InsertPosition Pos, Context &Ctx, const Twine &Name="")
An ArrayRef of Values or Instructions that we can print/dump for debugging.
Definition VecUtils.h:39
bool runOnRegion(Region &Rgn, const Analyses &A) final
\Returns true if it modifies R.
static LLVM_ABI Value * create(Type *DestTy, Opcode Op, Value *Operand, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * create(Predicate Pred, Value *S1, Value *S2, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
Definition Constant.cpp:48
static LLVM_ABI ConstantInt * getSigned(IntegerType *Ty, int64_t V)
Return a ConstantInt with the specified value for the specified type.
Definition Constant.cpp:56
static LLVM_ABI Value * create(Value *Vec, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * create(Value *Vec, Value *NewElt, Value *Idx, InsertPosition Pos, Context &Ctx, const Twine &Name="")
LLVM_ABI BBIterator getIterator() const
\Returns a BasicBlock::iterator for this Instruction.
Performs the legality analysis and returns a LegalityResult object.
Definition Legality.h:322
static LLVM_ABI LoadInst * create(Type *Ty, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx, const Twine &Name="")
virtual void print(raw_ostream &OS) const
Definition Pass.h:68
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition Constant.cpp:263
Context & getContext() const
Definition Region.h:169
const SmallVector< Instruction * > & getAux() const
\Returns the auxiliary vector.
Definition Region.h:177
static LLVM_ABI Value * create(Value *Cond, Value *True, Value *False, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI Value * create(Value *V1, Value *V2, Value *Mask, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static LLVM_ABI StoreInst * create(Value *V, Value *Ptr, MaybeAlign Align, InsertPosition Pos, bool IsVolatile, Context &Ctx)
static LLVM_ABI IntegerType * getInt32Ty(Context &Ctx)
Definition Type.cpp:21
static LLVM_ABI Value * createWithCopiedFlags(Instruction::Opcode Op, Value *OpV, Value *CopyFrom, InsertPosition Pos, Context &Ctx, const Twine &Name="")
static Type * getExpectedType(const Value *V)
\Returns the expected type of Value V.
Definition Utils.h:33
static bool verifyFunction(const Function *F, raw_ostream &OS)
Equivalent to llvm::verifyFunction().
Definition Utils.h:132
A SandboxIR Value has users. This is the base class.
Definition Value.h:72
static Type * getCommonScalarType(ArrayRef< Value * > Bndl)
Similar to tryGetCommonScalarType() but will assert that there is a common type.
Definition VecUtils.h:331
static Instruction * getLastPHIOrSelf(Instruction *I)
If I is not a PHI it returns it.
Definition VecUtils.h:290
static unsigned getNumLanes(Type *Ty)
\Returns the number of vector lanes of Ty or 1 if not a vector.
Definition VecUtils.h:134
static Value * unpack(Value *FromVec, Type *ExtrTy, unsigned Lane, BasicBlock::iterator WhereIt)
Emits the necessary instruction sequence to extract element of type ExtrTy at Lane from FromVec.
Definition VecUtils.h:418
static LLVM_DUMP_METHOD void dump(ArrayRef< Value * > Bndl)
Helper dump function for debugging.
Definition VecUtils.cpp:166
static Type * getWideType(Type *ElemTy, unsigned NumElts)
\Returns <NumElts x ElemTy>.
Definition VecUtils.h:157
static auto enumerateLanes(const ValueContainerT &Range)
Helper for creating LaneValueEnumerator ranges.
Definition VecUtils.h:536
static Type * getElementType(Type *Ty)
Returns Ty if scalar or its element type if vector.
Definition VecUtils.h:94
static Align getVecAlignment(AlignRangeT AlignRange, TypeRangeT TypeRange)
Given the alignments of the instructions before vectorization, this returns the alignment of the vect...
Definition VecUtils.h:547
static BasicBlock::iterator getInsertPointAfterInstrs(ArrayRef< Value * > Vals, BasicBlock *BB)
\Returns the BB iterator after the lowest instruction in Vals (skipping instructions not in BB),...
Definition VecUtils.h:302
static LLVM_ABI SmallVector< BundleTy > getNextUserBundles(ArrayRef< Value * > Bndl, const InstrMaps &IMaps, SmallPtrSet< Instruction *, 4 > &Claimed)
For each user of lane 0 in Bndl, try to form a bundle of matching users for all lanes.
Definition VecUtils.cpp:64
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
BndlRef(const T &OneElt) -> BndlRef< T >
LLVM_ABI Function * getParent() const
StringLiteral schedDirectionToStr(SchedDirection Dir)
BasicBlock(llvm::BasicBlock *BB, Context &SBCtx)
Definition BasicBlock.h:75
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
static BundleTy getOperand(BndlRef< Value * > Bndl, unsigned OpIdx)
Definition BundleVec.cpp:25
SmallVector< Value *, 4 > BundleTy
Definition VecUtils.h:82
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
const Value * getPointerOperand(const Value *V)
A helper function that returns the pointer operand of a load, store or GEP instruction.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
constexpr unsigned long SBVecStopDisabled
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:1769
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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
const VectorizeOptions & getVectorizeOptions(const LLVMContext &C)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341