LLVM: lib/CodeGen/InterleavedAccessPass.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
73#include
74#include
75
76using namespace llvm;
77
78#define DEBUG_TYPE "interleaved-access"
79
81 "lower-interleaved-accesses",
82 cl::desc("Enable lowering interleaved accesses to intrinsics"),
84
85namespace {
86
87class InterleavedAccessImpl {
88 friend class InterleavedAccess;
89
90public:
91 InterleavedAccessImpl() = default;
93 : DT(DT), TLI(TLI), MaxFactor(TLI->getMaxSupportedInterleaveFactor()) {}
95
96private:
97 DominatorTree *DT = nullptr;
98 const TargetLowering *TLI = nullptr;
99
100
101 unsigned MaxFactor = 0u;
102
103
104 bool lowerInterleavedLoad(Instruction *Load,
105 SmallSetVector<Instruction *, 32> &DeadInsts);
106
107
108 bool lowerInterleavedStore(Instruction *Store,
109 SmallSetVector<Instruction *, 32> &DeadInsts);
110
111
112
113 bool lowerDeinterleaveIntrinsic(IntrinsicInst *II,
114 SmallSetVector<Instruction *, 32> &DeadInsts);
115
116
117
118 bool lowerInterleaveIntrinsic(IntrinsicInst *II,
119 SmallSetVector<Instruction *, 32> &DeadInsts);
120
121
122
123
124
127
128
129
130
131
132
134 SmallVectorImpl<ShuffleVectorInst *> &Shuffles,
135 Instruction *LI);
136};
137
138class InterleavedAccess : public FunctionPass {
139 InterleavedAccessImpl Impl;
140
141public:
142 static char ID;
143
144 InterleavedAccess() : FunctionPass(ID) {
146 }
147
148 StringRef getPassName() const override { return "Interleaved Access Pass"; }
149
151
152 void getAnalysisUsage(AnalysisUsage &AU) const override {
153 AU.addRequired();
155 }
156};
157
158}
159
163 auto *TLI = TM->getSubtargetImpl(F)->getTargetLowering();
164 InterleavedAccessImpl Impl(DT, TLI);
165 bool Changed = Impl.runOnFunction(F);
166
169
172 return PA;
173}
174
175char InterleavedAccess::ID = 0;
176
177bool InterleavedAccess::runOnFunction(Function &F) {
178 if (skipFunction(F))
179 return false;
180
181 auto *TPC = getAnalysisIfAvailable();
183 return false;
184
185 LLVM_DEBUG(dbgs() << "*** " << getPassName() << ": " << F.getName() << "\n");
186
187 Impl.DT = &getAnalysis().getDomTree();
191
192 return Impl.runOnFunction(F);
193}
194
196 "Lower interleaved memory accesses to target specific intrinsics", false,
197 false)
200 "Lower interleaved memory accesses to target specific intrinsics", false,
202
204 return new InterleavedAccess();
205}
206
207
208
209
210
211
213 unsigned &Index, unsigned MaxFactor,
214 unsigned NumLoadElements) {
215 if (Mask.size() < 2)
216 return false;
217
218
219 for (Factor = 2; Factor <= MaxFactor; Factor++) {
220
221 if (Mask.size() * Factor > NumLoadElements)
222 return false;
224 return true;
225 }
226
227 return false;
228}
229
230
231
232
233
234
235
236
237
238
239
240
242 unsigned MaxFactor) {
244 if (NumElts < 4)
245 return false;
246
247
248 for (Factor = 2; Factor <= MaxFactor; Factor++) {
250 return true;
251 }
252
253 return false;
254}
255
257 switch (II->getIntrinsicID()) {
258 default:
260 case Intrinsic::vp_load:
261 case Intrinsic::masked_load:
262 return II->getOperand(1);
263 case Intrinsic::vp_store:
264 case Intrinsic::masked_store:
265 return II->getOperand(2);
266 }
267}
268
269
270
271
272
273
274static std::pair<Value *, APInt> getMask(Value *WideMask, unsigned Factor,
276
277static std::pair<Value *, APInt> getMask(Value *WideMask, unsigned Factor,
279 return getMask(WideMask, Factor, LeafValueTy->getElementCount());
280}
281
282bool InterleavedAccessImpl::lowerInterleavedLoad(
285 return false;
286
289 if (!LI && )
290 return false;
291
292 if (LI && !LI->isSimple())
293 return false;
294
295
296
297
298
299
302
303
305
306 for (auto *User : Load->users()) {
308 if (Extract && isa(Extract->getIndexOperand())) {
310 continue;
311 }
314 if (!BI->user_empty() &&
316 for (auto *SVI : BI->users())
318 continue;
319 }
320 }
323 return false;
324
326 }
327
328 if (Shuffles.empty() && BinOpShuffles.empty())
329 return false;
330
331 unsigned Factor, Index;
332
333 unsigned NumLoadElements =
335 auto *FirstSVI = Shuffles.size() > 0 ? Shuffles[0] : BinOpShuffles[0];
336
337 if ((FirstSVI->getShuffleMask(), Factor, Index, MaxFactor,
338 NumLoadElements))
339 return false;
340
341
343
345
346
347
348 for (auto *Shuffle : Shuffles) {
349 if (Shuffle->getType() != VecTy)
350 return false;
352 Shuffle->getShuffleMask(), Factor, Index))
353 return false;
354
355 assert(Shuffle->getShuffleMask().size() <= NumLoadElements);
357 }
358 for (auto *Shuffle : BinOpShuffles) {
359 if (Shuffle->getType() != VecTy)
360 return false;
362 Shuffle->getShuffleMask(), Factor, Index))
363 return false;
364
365 assert(Shuffle->getShuffleMask().size() <= NumLoadElements);
366
367 if (cast(Shuffle->getOperand(0))->getOperand(0) == Load)
369 if (cast(Shuffle->getOperand(0))->getOperand(1) == Load)
371 }
372
373
374
375 if (!tryReplaceExtracts(Extracts, Shuffles))
376 return false;
377
378 bool BinOpShuffleChanged =
379 replaceBinOpShuffles(BinOpShuffles.getArrayRef(), Shuffles, Load);
380
383 if (LI) {
384 LLVM_DEBUG(dbgs() << "IA: Found an interleaved load: " << *Load << "\n");
385 } else {
386
388 if (!Mask)
389 return false;
390
391 LLVM_DEBUG(dbgs() << "IA: Found an interleaved vp.load or masked.load: "
392 << *Load << "\n");
393 LLVM_DEBUG(dbgs() << "IA: With nominal factor " << Factor
394 << " and actual factor " << GapMask.popcount() << "\n");
395 }
396
397
398
399 if (!TLI->lowerInterleavedLoad(cast(Load), Mask, Shuffles,
400 Indices, Factor, GapMask))
401
402 return !Extracts.empty() || BinOpShuffleChanged;
403
405
406 DeadInsts.insert(Load);
407 return true;
408}
409
410bool InterleavedAccessImpl::replaceBinOpShuffles(
413 for (auto *SVI : BinOpShuffles) {
418 return Idx < (int)cast(BIOp0Ty)->getNumElements();
419 }));
420
422 auto *NewSVI1 =
424 Mask, SVI->getName(), insertPos);
427 SVI->getName(), insertPos);
429 BI->getOpcode(), NewSVI1, NewSVI2, BI, BI->getName(), insertPos);
430 SVI->replaceAllUsesWith(NewBI);
431 LLVM_DEBUG(dbgs() << " Replaced: " << *BI << "\n And : " << *SVI
432 << "\n With : " << *NewSVI1 << "\n And : "
433 << *NewSVI2 << "\n And : " << *NewBI << "\n");
435 if (NewSVI1->getOperand(0) == Load)
437 if (NewSVI2->getOperand(0) == Load)
439 }
440
441 return !BinOpShuffles.empty();
442}
443
444bool InterleavedAccessImpl::tryReplaceExtracts(
447
448
449 if (Extracts.empty())
450 return true;
451
452
453
455
456 for (auto *Extract : Extracts) {
457
458 auto *IndexOperand = cast(Extract->getIndexOperand());
459 auto Index = IndexOperand->getSExtValue();
460
461
462
463
464 for (auto *Shuffle : Shuffles) {
465
466
467 if (!DT->dominates(Shuffle, Extract))
468 continue;
469
470
471
472
474 Shuffle->getShuffleMask(Indices);
475 for (unsigned I = 0; I < Indices.size(); ++I)
476 if (Indices[I] == Index) {
477 assert(Extract->getOperand(0) == Shuffle->getOperand(0) &&
478 "Vector operations do not match");
479 ReplacementMap[Extract] = std::make_pair(Shuffle, I);
480 break;
481 }
482
483
484 if (ReplacementMap.count(Extract))
485 break;
486 }
487
488
489
490 if (!ReplacementMap.count(Extract))
491 return false;
492 }
493
494
496 for (auto &Replacement : ReplacementMap) {
497 auto *Extract = Replacement.first;
498 auto *Vector = Replacement.second.first;
499 auto Index = Replacement.second.second;
500 Builder.SetInsertPoint(Extract);
501 Extract->replaceAllUsesWith(Builder.CreateExtractElement(Vector, Index));
502 Extract->eraseFromParent();
503 }
504
505 return true;
506}
507
508bool InterleavedAccessImpl::lowerInterleavedStore(
510 Value *StoredValue;
513 if (SI) {
514 if (->isSimple())
515 return false;
516 StoredValue = SI->getValueOperand();
517 } else {
518 assert(II->getIntrinsicID() == Intrinsic::vp_store ||
519 II->getIntrinsicID() == Intrinsic::masked_store);
520 StoredValue = II->getArgOperand(0);
521 }
522
525 return false;
526
527 unsigned NumStoredElements =
529
530 unsigned Factor;
532 return false;
533 assert(NumStoredElements % Factor == 0 &&
534 "number of stored element should be a multiple of Factor");
535
538 if (SI) {
539 LLVM_DEBUG(dbgs() << "IA: Found an interleaved store: " << *Store << "\n");
540 } else {
541
542 unsigned LaneMaskLen = NumStoredElements / Factor;
545 if (!Mask)
546 return false;
547
548 LLVM_DEBUG(dbgs() << "IA: Found an interleaved vp.store or masked.store: "
549 << *Store << "\n");
550 LLVM_DEBUG(dbgs() << "IA: With nominal factor " << Factor
551 << " and actual factor " << GapMask.popcount() << "\n");
552 }
553
554
555
556 if (!TLI->lowerInterleavedStore(Store, Mask, SVI, Factor, GapMask))
557 return false;
558
559
560 DeadInsts.insert(Store);
561 DeadInsts.insert(SVI);
562 return true;
563}
564
565
566
567
568
569
571 unsigned LeafMaskLen, APInt &GapMask) {
573 for (unsigned F = 0U; F < Factor; ++F) {
574 bool AllZero = true;
575 for (unsigned Idx = 0U; Idx < LeafMaskLen; ++Idx) {
577 if (->isZeroValue()) {
578 AllZero = false;
579 break;
580 }
581 }
582
583 if (AllZero)
585 }
586}
587
588static std::pair<Value *, APInt> getMask(Value *WideMask, unsigned Factor,
591
595 Value *RefArg = nullptr;
596
597
598 for (auto [Idx, Arg] : enumerate(IMI->args())) {
600 GapMask.clearBit(Idx);
601 continue;
602 }
603
604 if (!RefArg)
605 RefArg = Arg;
606 else if (RefArg != Arg)
607 return {nullptr, GapMask};
608 }
609
610
611
612
613 return {RefArg ? RefArg : IMI->getArgOperand(0), GapMask};
614 }
615 }
616
617
619 AndOp && AndOp->getOpcode() == Instruction::And) {
620 auto [MaskLHS, GapMaskLHS] =
621 getMask(AndOp->getOperand(0), Factor, LeafValueEC);
622 auto [MaskRHS, GapMaskRHS] =
623 getMask(AndOp->getOperand(1), Factor, LeafValueEC);
624 if (!MaskLHS || !MaskRHS)
625 return {nullptr, GapMask};
626
627
628 return {IRBuilder<>(AndOp).CreateAnd(MaskLHS, MaskRHS),
629 GapMaskLHS & GapMaskRHS};
630 }
631
633 if (auto *Splat = ConstMask->getSplatValue())
634
636
637 if (LeafValueEC.isFixed()) {
638 unsigned LeafMaskLen = LeafValueEC.getFixedValue();
639
640 getGapMask(*ConstMask, Factor, LeafMaskLen, GapMask);
641
643
644
645
646 for (unsigned Idx = 0U; Idx < LeafMaskLen * Factor; ++Idx) {
647 if (!GapMask[Idx % Factor])
648 continue;
649 Constant *C = ConstMask->getAggregateElement(Idx);
650 if (LeafMask[Idx / Factor] && LeafMask[Idx / Factor] != C)
651 return {nullptr, GapMask};
652 LeafMask[Idx / Factor] = C;
653 }
654
656 }
657 }
658
660 Type *Op1Ty = SVI->getOperand(1)->getType();
662 return {nullptr, GapMask};
663
664
665
666
667 unsigned NumSrcElts =
671 NumSrcElts * 2, StartIndexes) &&
672 llvm::all_of(StartIndexes, [](unsigned Start) { return Start == 0; }) &&
673 llvm::all_of(SVI->getShuffleMask(), [&NumSrcElts](int Idx) {
674 return Idx < (int)NumSrcElts;
675 })) {
676 auto *LeafMaskTy =
679 return {Builder.CreateExtractVector(LeafMaskTy, SVI->getOperand(0),
681 GapMask};
682 }
683 }
684
685 return {nullptr, GapMask};
686}
687
688bool InterleavedAccessImpl::lowerDeinterleaveIntrinsic(
691 if (!LoadedVal || !LoadedVal->hasOneUse())
692 return false;
693
696 if (!LI && )
697 return false;
698
700 assert(Factor && "unexpected deinterleave intrinsic");
701
703 if (LI) {
704 if (!LI->isSimple())
705 return false;
706
707 LLVM_DEBUG(dbgs() << "IA: Found a load with deinterleave intrinsic " << *DI
708 << " and factor = " << Factor << "\n");
709 } else {
711 if (II->getIntrinsicID() != Intrinsic::masked_load &&
712 II->getIntrinsicID() != Intrinsic::vp_load)
713 return false;
714
715
716 APInt GapMask(Factor, 0);
717 std::tie(Mask, GapMask) =
719 if (!Mask)
720 return false;
721
722
723
724 if (GapMask.popcount() != Factor)
725 return true;
726
727 LLVM_DEBUG(dbgs() << "IA: Found a vp.load or masked.load with deinterleave"
728 << " intrinsic " << *DI << " and factor = "
729 << Factor << "\n");
730 }
731
732
733 if (!TLI->lowerDeinterleaveIntrinsicToLoad(LoadedVal, Mask, DI))
734 return false;
735
736 DeadInsts.insert(DI);
737
738 DeadInsts.insert(LoadedVal);
739 return true;
740}
741
742bool InterleavedAccessImpl::lowerInterleaveIntrinsic(
745 return false;
747 if (!StoredBy)
748 return false;
751 if ( &&
)
752 return false;
753
756 assert(Factor && "unexpected interleave intrinsic");
757
759 if (II) {
760 if (II->getIntrinsicID() != Intrinsic::masked_store &&
761 II->getIntrinsicID() != Intrinsic::vp_store)
762 return false;
763
764 APInt GapMask(Factor, 0);
765 std::tie(Mask, GapMask) =
768 if (!Mask)
769 return false;
770
771
772 if (GapMask.popcount() != Factor)
773 return true;
774
775 LLVM_DEBUG(dbgs() << "IA: Found a vp.store or masked.store with interleave"
776 << " intrinsic " << *IntII << " and factor = "
777 << Factor << "\n");
778 } else {
779 if (->isSimple())
780 return false;
781
782 LLVM_DEBUG(dbgs() << "IA: Found a store with interleave intrinsic "
783 << *IntII << " and factor = " << Factor << "\n");
784 }
785
786
787 if (!TLI->lowerInterleaveIntrinsicToStore(StoredBy, Mask, InterleaveValues))
788 return false;
789
790
791 DeadInsts.insert(StoredBy);
792 DeadInsts.insert(IntII);
793 return true;
794}
795
796bool InterleavedAccessImpl::runOnFunction(Function &F) {
797
800
806 Changed |= lowerInterleavedLoad(&I, DeadInsts);
807
811 Changed |= lowerInterleavedStore(&I, DeadInsts);
812
815 Changed |= lowerDeinterleaveIntrinsic(II, DeadInsts);
817 Changed |= lowerInterleaveIntrinsic(II, DeadInsts);
818 }
819 }
820
821 for (auto *I : DeadInsts)
822 I->eraseFromParent();
823
825}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines the DenseMap class.
static bool runOnFunction(Function &F, bool PostInlining)
static bool isDeInterleaveMask(ArrayRef< int > Mask, unsigned &Factor, unsigned &Index, unsigned MaxFactor, unsigned NumLoadElements)
Check if the mask is a DE-interleave mask for an interleaved load.
Definition InterleavedAccessPass.cpp:212
static void getGapMask(const Constant &MaskConst, unsigned Factor, unsigned LeafMaskLen, APInt &GapMask)
Definition InterleavedAccessPass.cpp:570
static cl::opt< bool > LowerInterleavedAccesses("lower-interleaved-accesses", cl::desc("Enable lowering interleaved accesses to intrinsics"), cl::init(true), cl::Hidden)
static bool isReInterleaveMask(ShuffleVectorInst *SVI, unsigned &Factor, unsigned MaxFactor)
Check if the mask can be used in an interleaved store.
Definition InterleavedAccessPass.cpp:241
static Value * getMaskOperand(IntrinsicInst *II)
Definition InterleavedAccessPass.cpp:256
static std::pair< Value *, APInt > getMask(Value *WideMask, unsigned Factor, ElementCount LeafValueEC)
Definition InterleavedAccessPass.cpp:588
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
static SymbolRef::Type getType(const Symbol *Sym)
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
Class for arbitrary precision integers.
static APInt getAllOnes(unsigned numBits)
Return an APInt of a specified width with all bits set.
void clearBit(unsigned BitPosition)
Set a given bit to 0.
unsigned getBitWidth() const
Return the number of bits in the APInt.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
InstListType::iterator iterator
Instruction iterators...
BinaryOps getOpcode() const
static BinaryOperator * CreateWithCopiedFlags(BinaryOps Opc, Value *V1, Value *V2, Value *CopyO, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Represents analyses that only rely on functions' control flow.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
static LLVM_ABI Constant * getSplat(ElementCount EC, Constant *Elt)
Return a ConstantVector with the specified constant in each element.
static LLVM_ABI Constant * get(ArrayRef< Constant * > V)
This is an important base class in LLVM.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
static constexpr ElementCount getFixed(ScalarTy MinVal)
FunctionPass class - This class is used to implement most global optimizations.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Definition InterleavedAccessPass.cpp:160
A wrapper class for inspecting calls to intrinsic functions.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
void insert_range(Range &&R)
bool empty() const
Determine if the SetVector is empty or not.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This instruction constructs a fixed permutation of two input vectors.
static LLVM_ABI void getShuffleMask(const Constant *Mask, SmallVectorImpl< int > &Result)
Convert the input shuffle mask operand to a vector of integers.
static LLVM_ABI bool isDeInterleaveMaskOfFactor(ArrayRef< int > Mask, unsigned Factor, unsigned &Index)
Check if the mask is a DE-interleave mask of the given factor Factor like: <Index,...
LLVM_ABI bool isInterleave(unsigned Factor)
Return if this shuffle interleaves its two input vectors together.
static LLVM_ABI bool isInterleaveMask(ArrayRef< int > Mask, unsigned Factor, unsigned NumInputElts, SmallVectorImpl< unsigned > &StartIndexes)
Return true if the mask interleaves one or more input vectors together.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual unsigned getMaxSupportedInterleaveFactor() const
Get the maximum supported factor for interleaved memory accesses.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
virtual const TargetLowering * getTargetLowering() const
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Base class of all SIMD vector types.
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getFixedValue() const
constexpr bool isFixed() const
Returns true if the quantity is not scaled by vscale.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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.
@ C
The default llvm calling convention, compatible with C.
TwoOps_match< ValueOpTy, PointerOpTy, Instruction::Store > m_Store(const ValueOpTy &ValueOp, const PointerOpTy &PointerOp)
Matches StoreInst.
bool match(Val *V, const Pattern &P)
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))
TwoOps_match< V1_t, V2_t, Instruction::ShuffleVector > m_Shuffle(const V1_t &v1, const V2_t &v2)
Matches ShuffleVectorInst independently of mask value.
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
auto m_Undef()
Match an arbitrary undef constant.
MatchFunctor< Val, Pattern > match_fn(const Pattern &P)
A match functor that can be used as a UnaryPredicate in functional algorithms like all_of.
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
initializer< Ty > init(const Ty &Val)
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI void initializeInterleavedAccessPass(PassRegistry &)
LLVM_ABI unsigned getDeinterleaveIntrinsicFactor(Intrinsic::ID ID)
Returns the corresponding factor of llvm.vector.deinterleaveN intrinsics.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI unsigned getInterleaveIntrinsicFactor(Intrinsic::ID ID)
Returns the corresponding factor of llvm.vector.interleaveN intrinsics.
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI FunctionPass * createInterleavedAccessPass()
InterleavedAccess Pass - This pass identifies and matches interleaved memory accesses to target speci...
Definition InterleavedAccessPass.cpp:203
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI VectorType * getDeinterleavedVectorType(IntrinsicInst *DI)
Given a deinterleaveN intrinsic, return the (narrow) vector type of each factor.
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.