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 && II)

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 (isDeInterleaveMask(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 (SI->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 (C->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

594 F && F == Factor) {

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 && II)

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 (SI && II)

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 (SI->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.