LLVM 24.0.0git
SLPUtils.cpp
Go to the documentation of this file.
1//===- SLPUtils.cpp - SLP Vectorizer free utility 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#include "SLPUtils.h"
10
11#include "llvm/ADT/STLExtras.h"
12#include "llvm/ADT/Sequence.h"
15#include "llvm/IR/Constants.h"
16#include "llvm/IR/DataLayout.h"
24
25#include <algorithm>
26#include <string>
27#include <type_traits>
28
29using namespace llvm;
30using namespace llvm::PatternMatch;
31
32namespace llvm::slpvectorizer {
33
37
38bool isBinOpIdentityConstant(const Value *V, unsigned Opcode) {
39 const auto *CI = dyn_cast<ConstantInt>(V);
40 return CI && ConstantExpr::getBinOpIdentity(Opcode, CI->getType()) == CI;
41}
42
44 auto *I = dyn_cast<Instruction>(V);
45 // Non-instructions are vector-like only if they are undef.
46 if (!I)
47 return isa<UndefValue>(V);
48 switch (I->getOpcode()) {
49 case Instruction::ExtractValue:
50 case Instruction::InsertValue:
51 return true;
52 case Instruction::ExtractElement:
53 return isa<FixedVectorType>(I->getOperand(0)->getType()) &&
54 isConstant(I->getOperand(1));
55 case Instruction::InsertElement:
56 return isa<FixedVectorType>(I->getOperand(0)->getType()) &&
57 isConstant(I->getOperand(2));
58 default:
59 return false;
60 }
61}
62
63unsigned getNumElements(Type *Ty) {
65 "ScalableVectorType is not supported.");
66 if (isVectorizedTy(Ty))
68 return 1;
69}
70
71unsigned getPartNumElems(unsigned Size, unsigned NumParts) {
72 return std::min<unsigned>(Size, bit_ceil(divideCeil(Size, NumParts)));
73}
74
75unsigned getNumElems(unsigned Size, unsigned PartNumElems, unsigned Part) {
76 return std::min<unsigned>(PartNumElems, Size - Part * PartNumElems);
77}
78
79#if !defined(NDEBUG)
80std::string shortBundleName(ArrayRef<Value *> VL, int Idx) {
81 std::string Result;
82 raw_string_ostream OS(Result);
83 if (Idx >= 0)
84 OS << "Idx: " << Idx << ", ";
85 OS << "n=" << VL.size() << " [" << *VL.front() << ", ..]";
86 return Result;
87}
88#endif
89
91 auto *It = find_if(VL, IsaPred<Instruction>);
92 if (It == VL.end())
93 return false;
96 return true;
97
98 BasicBlock *BB = I0->getParent();
99 for (Value *V : iterator_range(It, VL.end())) {
100 if (isa<PoisonValue>(V))
101 continue;
102 auto *II = dyn_cast<Instruction>(V);
103 if (!II)
104 return false;
105
106 if (BB != II->getParent())
107 return false;
108 }
109 return true;
110}
111
113 // Constant expressions and globals can't be vectorized like normal integer/FP
114 // constants.
115 return all_of(VL, isConstant);
116}
117
119 Value *FirstNonUndef = nullptr;
120 for (Value *V : VL) {
121 if (isa<UndefValue>(V))
122 continue;
123 if (!FirstNonUndef) {
124 FirstNonUndef = V;
125 continue;
126 }
127 if (V != FirstNonUndef)
128 return false;
129 }
130 return FirstNonUndef != nullptr;
131}
132
134 if (LHS == RHS)
135 return RHS;
136 if ((LHS == Intrinsic::fma || LHS == Intrinsic::fmuladd) &&
137 (RHS == Intrinsic::fma || RHS == Intrinsic::fmuladd))
138 return Intrinsic::fma;
140}
141
142bool isCommutative(const Instruction *I, const Value *ValWithUses,
143 bool IsCopyable) {
144 if (auto *Cmp = dyn_cast<CmpInst>(I))
145 return Cmp->isCommutative();
146 if (auto *BO = dyn_cast<BinaryOperator>(I))
147 return BO->isCommutative() ||
148 (BO->getOpcode() == Instruction::Sub && ValWithUses->hasUseList() &&
149 !ValWithUses->hasNUsesOrMore(UsesLimit) &&
150 all_of(
151 ValWithUses->uses(),
152 [&](const Use &U) {
153 // Commutative, if icmp eq/ne sub, 0
154 CmpPredicate Pred;
155 if (match(U.getUser(),
156 m_ICmp(Pred, m_Specific(U.get()), m_Zero())) &&
157 (Pred == ICmpInst::ICMP_EQ || Pred == ICmpInst::ICMP_NE))
158 return true;
159 // Commutative, if abs(sub nsw, true) or abs(sub, false).
160 ConstantInt *Flag;
161 auto *I = dyn_cast<BinaryOperator>(U.get());
162 return match(U.getUser(),
163 m_Intrinsic<Intrinsic::abs>(
164 m_Specific(U.get()), m_ConstantInt(Flag))) &&
165 ((!IsCopyable && I && !I->hasNoSignedWrap()) ||
166 Flag->isOne());
167 })) ||
168 (BO->getOpcode() == Instruction::FSub && ValWithUses->hasUseList() &&
169 !ValWithUses->hasNUsesOrMore(UsesLimit) &&
170 all_of(ValWithUses->uses(), [](const Use &U) {
171 return match(U.getUser(),
172 m_Intrinsic<Intrinsic::fabs>(m_Specific(U.get())));
173 }));
174 return I->isCommutative();
175}
176
177bool isCommutative(const Instruction *I) { return isCommutative(I, I); }
178
179bool isCommutableOperand(const Instruction *I, Value *ValWithUses, unsigned Op,
180 bool IsCopyable) {
181 assert(isCommutative(I, ValWithUses, IsCopyable) &&
182 "The instruction is not commutative.");
183 if (isa<CmpInst>(I))
184 return true;
185 if (auto *BO = dyn_cast<BinaryOperator>(I)) {
186 switch (BO->getOpcode()) {
187 case Instruction::Sub:
188 case Instruction::FSub:
189 return true;
190 default:
191 break;
192 }
193 }
194 return I->isCommutableOperand(Op);
195}
196
199 // IntrinsicInst::isCommutative returns true if swapping the first "two"
200 // arguments to the intrinsic produces the same result.
201 constexpr unsigned IntrinsicNumOperands = 2;
202 return IntrinsicNumOperands;
203 }
204 return I->getNumOperands();
205}
206
207std::optional<unsigned> getElementIndex(const Value *Inst, unsigned Offset) {
208 if (auto Index = getInsertExtractIndex<InsertElementInst>(Inst, Offset))
209 return Index;
211 return Index;
212
213 unsigned Index = Offset;
214
215 const auto *IV = dyn_cast<InsertValueInst>(Inst);
216 if (!IV)
217 return std::nullopt;
218
219 Type *CurrentType = IV->getType();
220 for (unsigned I : IV->indices()) {
221 if (const auto *ST = dyn_cast<StructType>(CurrentType)) {
222 Index *= ST->getNumElements();
223 CurrentType = ST->getElementType(I);
224 } else if (const auto *AT = dyn_cast<ArrayType>(CurrentType)) {
225 Index *= AT->getNumElements();
226 CurrentType = AT->getElementType();
227 } else {
228 return std::nullopt;
229 }
230 Index += I;
231 }
232 return Index;
233}
234
236 auto *It = find_if(VL, IsaPred<Instruction>);
237 if (It == VL.end())
238 return true;
239 Instruction *MainOp = cast<Instruction>(*It);
240 unsigned Opcode = MainOp->getOpcode();
241 bool IsCmpOp = isa<CmpInst>(MainOp);
242 CmpInst::Predicate BasePred = IsCmpOp ? cast<CmpInst>(MainOp)->getPredicate()
244 return all_of(make_range(It, VL.end()), [&](Value *V) {
245 if (auto *CI = dyn_cast<CmpInst>(V))
246 return BasePred == CI->getPredicate();
247 if (auto *I = dyn_cast<Instruction>(V))
248 return I->getOpcode() == Opcode;
249 return isa<PoisonValue>(V);
250 });
251}
252
253std::optional<unsigned> getExtractIndex(const Instruction *E) {
254 unsigned Opcode = E->getOpcode();
255 assert((Opcode == Instruction::ExtractElement ||
256 Opcode == Instruction::ExtractValue) &&
257 "Expected extractelement or extractvalue instruction.");
258 if (Opcode == Instruction::ExtractElement) {
259 auto *CI = dyn_cast<ConstantInt>(E->getOperand(1));
260 if (!CI)
261 return std::nullopt;
262 // Check if the index is out of bound. We can get the source vector from
263 // operand 0.
264 unsigned Idx = CI->getZExtValue();
265 auto *EE = cast<ExtractElementInst>(E);
266 const unsigned VF = getNumElements(EE->getVectorOperandType());
267 if (Idx >= VF)
268 return std::nullopt;
269 return Idx;
270 }
271 auto *EI = cast<ExtractValueInst>(E);
272 if (EI->getNumIndices() != 1)
273 return std::nullopt;
274 return *EI->idx_begin();
275}
276
278 SmallVectorImpl<int> &Mask) {
279 Mask.clear();
280 const unsigned E = Indices.size();
281 Mask.resize(E, PoisonMaskElem);
282 for (unsigned I = 0; I < E; ++I)
283 Mask[Indices[I]] = I;
284}
285
287 assert(!Mask.empty() && "Expected non-empty mask.");
288 SmallVector<Value *> Prev(Scalars.size(),
289 PoisonValue::get(Scalars.front()->getType()));
290 Prev.swap(Scalars);
291 for (unsigned I = 0, E = Prev.size(); I < E; ++I)
292 if (Mask[I] != PoisonMaskElem)
293 Scalars[Mask[I]] = Prev[I];
294}
295
297 assert(!VL.empty() && "Expected non-empty list of values.");
298 Type *Ty = VL.consume_front()->getType();
299 return all_of(VL, [&](Value *V) { return V->getType() == Ty; });
300}
301
302template <typename T>
303std::optional<unsigned> getInsertExtractIndex(const Value *Inst,
304 unsigned Offset) {
305 static_assert(std::is_same_v<T, InsertElementInst> ||
306 std::is_same_v<T, ExtractElementInst>,
307 "unsupported T");
308 const auto *IE = dyn_cast<T>(Inst);
309 if (!IE)
310 return std::nullopt;
311 // InsertElement: result is the vector, index is op 2.
312 // ExtractElement: result is scalar, vector is op 0, index is op 1.
313 constexpr bool IsInsert = std::is_same_v<T, InsertElementInst>;
314 Type *VecTy = IsInsert ? IE->getType() : IE->getOperand(0)->getType();
315 const auto *VT = dyn_cast<FixedVectorType>(VecTy);
316 if (!VT)
317 return std::nullopt;
318 const auto *CI = dyn_cast<ConstantInt>(IE->getOperand(IsInsert ? 2 : 1));
319 if (!CI)
320 return std::nullopt;
321 if (CI->getValue().uge(VT->getNumElements()))
322 return std::nullopt;
323 unsigned Index = Offset;
324 Index *= VT->getNumElements();
325 Index += CI->getZExtValue();
326 return Index;
327}
328
329// Only these two specializations are used; instantiate them here so the
330// definition can stay out of the header.
331template std::optional<unsigned>
333template std::optional<unsigned>
335
337 auto *I = dyn_cast<Instruction>(V);
338 if (!I)
339 return true;
340 return !mayHaveNonDefUseDependency(*I) &&
341 all_of(I->operands(), [I](Value *V) {
342 auto *IO = dyn_cast<Instruction>(V);
343 if (!IO)
344 return true;
345 return isa<PHINode>(IO) || IO->getParent() != I->getParent();
346 });
347}
348
350 auto *I = dyn_cast<Instruction>(V);
351 if (!I)
352 return true;
353 // Limits the number of uses to save compile time.
354 return !I->mayReadOrWriteMemory() && !I->hasNUsesOrMore(UsesLimit) &&
355 all_of(I->users(), [I](User *U) {
356 auto *IU = dyn_cast<Instruction>(U);
357 if (!IU)
358 return true;
359 return IU->getParent() != I->getParent() || isa<PHINode>(IU);
360 });
361}
362
366
371
372void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements,
373 SmallVectorImpl<int> &Mask) {
374 // The ShuffleBuilder implementation use shufflevector to splat an "element".
375 // But the element have different meaning for SLP (scalar) and REVEC
376 // (vector). We need to expand Mask into masks which shufflevector can use
377 // directly.
378 SmallVector<int> NewMask(Mask.size() * VecTyNumElements);
379 for (unsigned I : seq<unsigned>(Mask.size()))
380 for (auto [J, MaskV] : enumerate(MutableArrayRef(NewMask).slice(
381 I * VecTyNumElements, VecTyNumElements)))
382 MaskV = Mask[I] == PoisonMaskElem ? PoisonMaskElem
383 : Mask[I] * VecTyNumElements + J;
384 Mask.swap(NewMask);
385}
386
388 if (VL.empty())
389 return 0;
391 return 0;
392 auto *SV = cast<ShuffleVectorInst>(VL.front());
393 unsigned SVNumElements =
394 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
395 unsigned ShuffleMaskSize = SV->getShuffleMask().size();
396 if (SVNumElements % ShuffleMaskSize != 0)
397 return 0;
398 unsigned GroupSize = SVNumElements / ShuffleMaskSize;
399 if (GroupSize == 0 || (VL.size() % GroupSize) != 0)
400 return 0;
401 unsigned NumGroup = 0;
402 for (size_t I = 0, E = VL.size(); I != E; I += GroupSize) {
403 auto *SV = cast<ShuffleVectorInst>(VL[I]);
404 Value *Src = SV->getOperand(0);
405 ArrayRef<Value *> Group = VL.slice(I, GroupSize);
406 SmallBitVector ExpectedIndex(GroupSize);
407 if (!all_of(Group, [&](Value *V) {
408 auto *SV = cast<ShuffleVectorInst>(V);
409 // From the same source.
410 if (SV->getOperand(0) != Src)
411 return false;
412 int Index;
413 if (!SV->isExtractSubvectorMask(Index))
414 return false;
415 ExpectedIndex.set(Index / ShuffleMaskSize);
416 return true;
417 }))
418 return 0;
419 if (!ExpectedIndex.all())
420 return 0;
421 ++NumGroup;
422 }
423 assert(NumGroup == (VL.size() / GroupSize) && "Unexpected number of groups");
424 return NumGroup;
425}
426
428 assert(getShufflevectorNumGroups(VL) && "Not supported shufflevector usage.");
429 auto *SV = cast<ShuffleVectorInst>(VL.front());
430 unsigned SVNumElements =
431 cast<FixedVectorType>(SV->getOperand(0)->getType())->getNumElements();
432 SmallVector<int> Mask;
433 unsigned AccumulateLength = 0;
434 for (Value *V : VL) {
435 auto *SV = cast<ShuffleVectorInst>(V);
436 for (int M : SV->getShuffleMask())
437 Mask.push_back(M == PoisonMaskElem ? PoisonMaskElem
438 : AccumulateLength + M);
439 AccumulateLength += SVNumElements;
440 }
441 return Mask;
442}
443
445 SmallBitVector UseMask(VF, true);
446 for (auto [Idx, Value] : enumerate(Mask)) {
447 if (Value == PoisonMaskElem) {
448 if (MaskArg == UseMask::UndefsAsMask)
449 UseMask.reset(Idx);
450 continue;
451 }
452 if (MaskArg == UseMask::FirstArg && Value < VF)
453 UseMask.reset(Value);
454 else if (MaskArg == UseMask::SecondArg && Value >= VF)
455 UseMask.reset(Value - VF);
456 }
457 return UseMask;
458}
459
460template <bool IsPoisonOnly>
462 SmallBitVector Res(UseMask.empty() ? 1 : UseMask.size(), true);
463 using T = std::conditional_t<IsPoisonOnly, PoisonValue, UndefValue>;
464 if (isa<T>(V))
465 return Res;
466 auto *VecTy = dyn_cast<FixedVectorType>(V->getType());
467 if (!VecTy)
468 return Res.reset();
469 auto *C = dyn_cast<Constant>(V);
470 if (!C) {
471 if (!UseMask.empty()) {
472 const Value *Base = V;
473 while (auto *II = dyn_cast<InsertElementInst>(Base)) {
474 Base = II->getOperand(0);
475 if (isa<T>(II->getOperand(1)))
476 continue;
477 std::optional<unsigned> Idx = getElementIndex(II);
478 if (!Idx) {
479 Res.reset();
480 return Res;
481 }
482 if (*Idx < UseMask.size() && !UseMask.test(*Idx))
483 Res.reset(*Idx);
484 }
485 // TODO: Add analysis for shuffles here too.
486 if (V == Base) {
487 Res.reset();
488 } else {
489 SmallBitVector SubMask(UseMask.size(), false);
490 Res &= isUndefVector<IsPoisonOnly>(Base, SubMask);
491 }
492 } else {
493 Res.reset();
494 }
495 return Res;
496 }
497 for (unsigned I = 0, E = VecTy->getNumElements(); I != E; ++I) {
498 if (Constant *Elem = C->getAggregateElement(I))
499 if (!isa<T>(Elem) &&
500 (UseMask.empty() || (I < UseMask.size() && !UseMask.test(I))))
501 Res.reset(I);
502 }
503 return Res;
504}
505
507 const SmallBitVector &);
509 const SmallBitVector &);
510
513 const TargetTransformInfo *TTI) {
514 if (!UserInst)
515 return false;
516 unsigned Opcode = UserInst->getOpcode();
517 switch (Opcode) {
518 case Instruction::Load: {
519 LoadInst *LI = cast<LoadInst>(UserInst);
520 return (LI->getPointerOperand() == Scalar);
521 }
522 case Instruction::Store: {
523 StoreInst *SI = cast<StoreInst>(UserInst);
524 return (SI->getPointerOperand() == Scalar);
525 }
526 case Instruction::Call: {
527 CallInst *CI = cast<CallInst>(UserInst);
529 return any_of(enumerate(CI->args()), [&](auto &&Arg) {
530 return isVectorIntrinsicWithScalarOpAtArg(ID, Arg.index(), TTI) &&
531 Arg.value().get() == Scalar;
532 });
533 }
534 default:
535 return false;
536 }
537}
538
546
548 if (LoadInst *LI = dyn_cast<LoadInst>(I))
549 return LI->isSimple();
551 return SI->isSimple();
553 return !MI->isVolatile();
554 return true;
555}
556
557bool isSelectedBaseLoad(Type *ScalarTy, ArrayRef<Value *> PointerOps,
558 const DataLayout &DL, Value *&TrueBase,
559 Value *&FalseBase,
560 SmallVectorImpl<Value *> &Conditions) {
561 TrueBase = nullptr;
562 FalseBase = nullptr;
563 uint64_t ScalarSize = DL.getTypeStoreSize(ScalarTy);
564 Conditions.assign(PointerOps.size(), nullptr);
565 for (auto [Idx, P] : enumerate(PointerOps)) {
566 Value *Base = P;
567 uint64_t Offset = 0;
568 if (auto *GEP = dyn_cast<GetElementPtrInst>(P)) {
569 APInt OffsetAP(DL.getIndexTypeSizeInBits(GEP->getType()), 0);
570 if (!GEP->accumulateConstantOffset(DL, OffsetAP) || OffsetAP.isNegative())
571 return false;
572 Offset = OffsetAP.getZExtValue();
573 Base = GEP->getPointerOperand();
574 }
575 auto *Sel = dyn_cast<SelectInst>(Base);
576 if (!Sel)
577 return false;
578 Value *T = Sel->getTrueValue();
579 Value *F = Sel->getFalseValue();
580 if (!TrueBase) {
581 if (T == F)
582 return false;
583 TrueBase = T;
584 FalseBase = F;
585 } else if (TrueBase != T || FalseBase != F) {
586 return false;
587 }
588 // Lane Idx must be at exactly Base + Idx * sizeof(ScalarTy); codegen reads
589 // contiguously from TrueBase/FalseBase starting at lane 0.
590 if (Offset != static_cast<uint64_t>(Idx) * ScalarSize)
591 return false;
592 Conditions[Idx] = Sel->getCondition();
593 }
594 return TrueBase != nullptr;
595}
596
598 bool ExtendingManyInputs) {
599 if (SubMask.empty())
600 return;
601 assert(
602 (!ExtendingManyInputs || SubMask.size() > Mask.size() ||
603 // Check if input scalars were extended to match the size of other node.
604 (SubMask.size() == Mask.size() && Mask.back() == PoisonMaskElem)) &&
605 "SubMask with many inputs support must be larger than the mask.");
606 if (Mask.empty()) {
607 Mask.append(SubMask.begin(), SubMask.end());
608 return;
609 }
610 SmallVector<int> NewMask(SubMask.size(), PoisonMaskElem);
611 int TermValue = std::min(Mask.size(), SubMask.size());
612 for (int I = 0, E = SubMask.size(); I < E; ++I) {
613 if (SubMask[I] == PoisonMaskElem ||
614 (!ExtendingManyInputs &&
615 (SubMask[I] >= TermValue || Mask[SubMask[I]] >= TermValue)))
616 continue;
617 NewMask[I] = Mask[SubMask[I]];
618 }
619 Mask.swap(NewMask);
620}
621
623 const size_t Sz = Order.size();
624 SmallBitVector UnusedIndices(Sz, /*t=*/true);
625 SmallBitVector MaskedIndices(Sz);
626 for (unsigned I = 0; I < Sz; ++I) {
627 if (Order[I] < Sz)
628 UnusedIndices.reset(Order[I]);
629 else
630 MaskedIndices.set(I);
631 }
632 if (MaskedIndices.none())
633 return;
634 assert(UnusedIndices.count() == MaskedIndices.count() &&
635 "Non-synced masked/available indices.");
636 int Idx = UnusedIndices.find_first();
637 int MIdx = MaskedIndices.find_first();
638 while (MIdx >= 0) {
639 assert(Idx >= 0 && "Indices must be synced.");
640 Order[MIdx] = Idx;
641 Idx = UnusedIndices.find_next(Idx);
642 MIdx = MaskedIndices.find_next(MIdx);
643 }
644}
645
647 unsigned Opcode0, unsigned Opcode1) {
648 unsigned ScalarTyNumElements = getNumElements(ScalarTy);
649 SmallBitVector OpcodeMask(VL.size() * ScalarTyNumElements, false);
650 for (unsigned Lane : seq<unsigned>(VL.size())) {
651 if (isa<PoisonValue>(VL[Lane]))
652 continue;
653 if (cast<Instruction>(VL[Lane])->getOpcode() == Opcode1)
654 OpcodeMask.set(Lane * ScalarTyNumElements,
655 Lane * ScalarTyNumElements + ScalarTyNumElements);
656 }
657 return OpcodeMask;
658}
659
661 assert(none_of(Val, [](Constant *C) { return C->getType()->isVectorTy(); }) &&
662 "Expected scalar constants.");
663 SmallVector<Constant *> NewVal(Val.size() * VF);
664 for (auto [I, V] : enumerate(Val))
665 std::fill_n(NewVal.begin() + I * VF, VF, V);
666 return NewVal;
667}
668
670 switch (Opcode) {
671 case Instruction::UDiv:
672 return Intrinsic::masked_udiv;
673 case Instruction::SDiv:
674 return Intrinsic::masked_sdiv;
675 case Instruction::URem:
676 return Intrinsic::masked_urem;
677 case Instruction::SRem:
678 return Intrinsic::masked_srem;
679 default:
680 llvm_unreachable("Unexpected opcode");
681 }
682}
683
684} // namespace llvm::slpvectorizer
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Hexagon Common GEP
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define T
uint64_t IntrinsicInst * II
#define P(N)
This file contains some templates that are useful if you are working with the STL at all.
Provides some synthesis utilities to produce sequences of values.
static const uint32_t IV[8]
Definition blake3_impl.h:83
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1565
bool isNegative() const
Determine sign of this APInt.
Definition APInt.h:330
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const T & front() const
Get the first element.
Definition ArrayRef.h:144
iterator end() const
Definition ArrayRef.h:130
size_t size() const
Get the array size.
Definition ArrayRef.h:141
iterator begin() const
Definition ArrayRef.h:129
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition ArrayRef.h:185
const T & consume_front()
consume_front() - Returns the first element and drops it from ArrayRef.
Definition ArrayRef.h:156
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
static LLVM_ABI Constant * getBinOpIdentity(unsigned Opcode, Type *Ty, bool AllowRHSConstant=false, bool NSZ=false)
Return the identity constant for a binary opcode.
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
An instruction for reading from memory.
Value * getPointerOperand()
This is the common base class for memset/memcpy/memmove.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
SmallBitVector & set()
int find_next(unsigned Prev) const
Returns the index of the next set bit following the "Prev" bit.
bool all() const
Returns true if all bits are set.
size_type count() const
Returns the number of bits which are set.
SmallBitVector & reset()
bool none() const
Returns true if none of the bits are set.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
void swap(SmallVectorImpl &RHS)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
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.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
bool hasUseList() const
Check if this Value has a use-list.
Definition Value.h:344
LLVM_ABI bool hasNUsesOrMore(unsigned N) const
Return true if this value has N uses or more.
Definition Value.cpp:155
iterator_range< use_iterator > uses()
Definition Value.h:380
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
const ParentTy * getParent() const
Definition ilist_node.h:34
A raw_ostream that writes to an std::string.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
A private "module" namespace for types and utilities used by this pass.
std::optional< unsigned > getExtractIndex(const Instruction *E)
Definition SLPUtils.cpp:253
template SmallBitVector isUndefVector< true >(const Value *, const SmallBitVector &)
bool areAllOperandsNonInsts(Value *V)
Checks if the provided value does not require scheduling.
Definition SLPUtils.cpp:336
std::optional< unsigned > getElementIndex(const Value *Inst, unsigned Offset)
Definition SLPUtils.cpp:207
bool doesInTreeUserNeedToExtract(Value *Scalar, Instruction *UserInst, TargetLibraryInfo *TLI, const TargetTransformInfo *TTI)
Definition SLPUtils.cpp:511
MemoryLocation getLocation(Instruction *I)
Definition SLPUtils.cpp:539
bool isSelectedBaseLoad(Type *ScalarTy, ArrayRef< Value * > PointerOps, const DataLayout &DL, Value *&TrueBase, Value *&FalseBase, SmallVectorImpl< Value * > &Conditions)
Checks if the loads with scalar type ScalarTy and pointer operands PointerOps are each (optionally vi...
Definition SLPUtils.cpp:557
SmallBitVector getAltInstrMask(ArrayRef< Value * > VL, Type *ScalarTy, unsigned Opcode0, unsigned Opcode1)
Definition SLPUtils.cpp:646
SmallBitVector isUndefVector(const Value *V, const SmallBitVector &UseMask)
Checks if the given value is actually an undefined constant vector.
Definition SLPUtils.cpp:461
Intrinsic::ID getMaskedDivRemIntrinsic(unsigned Opcode)
Definition SLPUtils.cpp:669
bool isUsedOutsideBlock(Value *V)
Checks if the provided value does not require scheduling.
Definition SLPUtils.cpp:349
bool doesNotNeedToSchedule(ArrayRef< Value * > VL)
Checks if the specified array of instructions does not require scheduling.
Definition SLPUtils.cpp:367
std::optional< unsigned > getInsertExtractIndex(const Value *Inst, unsigned Offset)
Definition SLPUtils.cpp:303
void reorderScalars(SmallVectorImpl< Value * > &Scalars, ArrayRef< int > Mask)
Reorders the list of scalars in accordance with the given Mask.
Definition SLPUtils.cpp:286
bool allSameType(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:296
bool allSameOpcode(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:235
bool isSplat(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:118
unsigned getNumElements(Type *Ty)
Definition SLPUtils.cpp:63
std::string shortBundleName(ArrayRef< Value * > VL, int Idx)
Print a short descriptor of the instruction bundle suitable for debug output.
Definition SLPUtils.cpp:80
unsigned getPartNumElems(unsigned Size, unsigned NumParts)
Returns power-of-2 number of elements in a single register (part), given the total number of elements...
Definition SLPUtils.cpp:71
bool isCommutableOperand(const Instruction *I, Value *ValWithUses, unsigned Op, bool IsCopyable)
Checks if the operand is commutative.
Definition SLPUtils.cpp:179
void transformScalarShuffleIndiciesToVector(unsigned VecTyNumElements, SmallVectorImpl< int > &Mask)
Definition SLPUtils.cpp:372
SmallVector< int > calculateShufflevectorMask(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:427
SmallBitVector buildUseMask(int VF, ArrayRef< int > Mask, UseMask MaskArg)
Prepares a use bitset for the given mask either for the first argument or for the second.
Definition SLPUtils.cpp:444
bool isCommutative(const Instruction *I, const Value *ValWithUses, bool IsCopyable)
Definition SLPUtils.cpp:142
template SmallBitVector isUndefVector< false >(const Value *, const SmallBitVector &)
unsigned getNumberOfPotentiallyCommutativeOps(Instruction *I)
Definition SLPUtils.cpp:197
bool allConstant(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:112
template std::optional< unsigned > getInsertExtractIndex< InsertElementInst >(const Value *, unsigned)
void inversePermutation(ArrayRef< unsigned > Indices, SmallVectorImpl< int > &Mask)
Compute the inverse permutation Mask of Indices.
Definition SLPUtils.cpp:277
bool allSameBlock(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:90
Intrinsic::ID isEquivalentIntrinsicID(Intrinsic::ID LHS, Intrinsic::ID RHS)
Checks if LHS and RHS are the same intrinsic, or one is llvm.fma and the other is llvm....
Definition SLPUtils.cpp:133
UseMask
Specifies the way the mask should be analyzed for undefs/poisonous elements in the shuffle mask.
Definition SLPUtils.h:230
@ SecondArg
The mask is expected to be for permutation of 2 vectors, check for the mask elements for the second a...
Definition SLPUtils.h:234
@ UndefsAsMask
Consider undef mask elements (-1) as placeholders for future shuffle elements and mark them as ones a...
Definition SLPUtils.h:237
@ FirstArg
The mask is expected to be for permutation of 1-2 vectors, check for the mask elements for the first ...
Definition SLPUtils.h:231
void addMask(SmallVectorImpl< int > &Mask, ArrayRef< int > SubMask, bool ExtendingManyInputs)
Shuffles Mask in accordance with the given SubMask.
Definition SLPUtils.cpp:597
bool isSimple(Instruction *I)
Definition SLPUtils.cpp:547
bool isBinOpIdentityConstant(const Value *V, unsigned Opcode)
Definition SLPUtils.cpp:38
unsigned getShufflevectorNumGroups(ArrayRef< Value * > VL)
Definition SLPUtils.cpp:387
SmallVector< Constant * > replicateMask(ArrayRef< Constant * > Val, unsigned VF)
Replicates the given Val VF times.
Definition SLPUtils.cpp:660
bool isVectorLikeInstWithConstOps(Value *V)
Checks if V is one of vector-like instructions, i.e.
Definition SLPUtils.cpp:43
bool doesNotNeedToBeScheduled(Value *V)
Checks if the specified value does not require scheduling.
Definition SLPUtils.cpp:363
unsigned getNumElems(unsigned Size, unsigned PartNumElems, unsigned Part)
Returns correct remaining number of elements, considering total amount Size, (power-of-2 number) of e...
Definition SLPUtils.cpp:75
constexpr int UsesLimit
Limit of the number of uses for potentially transformed instructions/values, used in checks to avoid ...
Definition SLPUtils.h:42
bool isConstant(Value *V)
Definition SLPUtils.cpp:34
template std::optional< unsigned > getInsertExtractIndex< ExtractElementInst >(const Value *, unsigned)
void fixupOrderingIndices(MutableArrayRef< unsigned > Order)
Order may have elements assigned special value (size) which is out of bounds.
Definition SLPUtils.cpp:622
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
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:1739
LLVM_ABI Intrinsic::ID getVectorIntrinsicIDForCall(const CallInst *CI, const TargetLibraryInfo *TLI)
Returns intrinsic ID for call.
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:2554
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< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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...
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
Definition bit.h:362
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:1746
ElementCount getVectorizedTypeVF(Type *Ty)
Returns the number of vector elements for a vectorized type.
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:1753
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
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
constexpr int PoisonMaskElem
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
constexpr T divideCeil(U Numerator, V Denominator)
Returns the integer ceil(Numerator / Denominator).
Definition MathExtras.h:395
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
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
LLVM_ABI bool mayHaveNonDefUseDependency(const Instruction &I)
Returns true if the result or effects of the given instructions I depend values not reachable through...
constexpr detail::IsaCheckPredicate< Types... > IsaPred
Function object wrapper for the llvm::isa type check.
Definition Casting.h:866