Skip to content

Commit a086c0d

Browse files
committed
[AArch64]: Use PatternMatch to spot (de)interleave accesses
Change-Id: Id7639dcb125a2f642b2fea78ea884b74be1c6b74
1 parent e26c923 commit a086c0d

File tree

11 files changed

+316
-427
lines changed

11 files changed

+316
-427
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@
5656
#include <cstdint>
5757
#include <iterator>
5858
#include <map>
59-
#include <queue>
60-
#include <stack>
6159
#include <string>
6260
#include <utility>
6361
#include <vector>
@@ -3160,7 +3158,6 @@ class TargetLoweringBase {
31603158
/// \p DI is the deinterleave intrinsic.
31613159
/// \p LI is the accompanying load instruction
31623160
virtual bool lowerDeinterleaveIntrinsicToLoad(IntrinsicInst *DI,
3163-
SmallVector<Value *> &LeafNodes,
31643161
LoadInst *LI) const {
31653162
return false;
31663163
}
@@ -3172,7 +3169,6 @@ class TargetLoweringBase {
31723169
/// \p II is the interleave intrinsic.
31733170
/// \p SI is the accompanying store instruction
31743171
virtual bool lowerInterleaveIntrinsicToStore(IntrinsicInst *II,
3175-
SmallVector<Value *> &LeafNodes,
31763172
StoreInst *SI) const {
31773173
return false;
31783174
}

llvm/lib/CodeGen/InterleavedAccessPass.cpp

Lines changed: 6 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@
7070
#include "llvm/Target/TargetMachine.h"
7171
#include "llvm/Transforms/Utils/Local.h"
7272
#include <cassert>
73-
#include <queue>
7473
#include <utility>
7574

7675
using namespace llvm;
@@ -489,57 +488,12 @@ bool InterleavedAccessImpl::lowerDeinterleaveIntrinsic(
489488

490489
LLVM_DEBUG(dbgs() << "IA: Found a deinterleave intrinsic: " << *DI << "\n");
491490

492-
std::stack<IntrinsicInst *> DeinterleaveTreeQueue;
493-
SmallVector<Value *> TempLeafNodes, LeafNodes;
494-
std::map<IntrinsicInst *, bool> mp;
495-
SmallVector<Instruction *> TempDeadInsts;
496-
497-
DeinterleaveTreeQueue.push(DI);
498-
while (!DeinterleaveTreeQueue.empty()) {
499-
auto CurrentDI = DeinterleaveTreeQueue.top();
500-
DeinterleaveTreeQueue.pop();
501-
TempDeadInsts.push_back(CurrentDI);
502-
// iterate over extract users of deinterleave
503-
for (auto UserExtract : CurrentDI->users()) {
504-
Instruction *Extract = dyn_cast<Instruction>(UserExtract);
505-
if (!Extract || Extract->getOpcode() != Instruction::ExtractValue)
506-
continue;
507-
bool IsLeaf = true;
508-
// iterate over deinterleave users of extract
509-
for (auto UserDI : UserExtract->users()) {
510-
IntrinsicInst *Child_DI = dyn_cast<IntrinsicInst>(UserDI);
511-
if (!Child_DI || Child_DI->getIntrinsicID() !=
512-
Intrinsic::experimental_vector_deinterleave2)
513-
continue;
514-
IsLeaf = false;
515-
if (mp.count(Child_DI) == 0) {
516-
DeinterleaveTreeQueue.push(Child_DI);
517-
}
518-
continue;
519-
}
520-
if (IsLeaf) {
521-
TempLeafNodes.push_back(UserExtract);
522-
TempDeadInsts.push_back(Extract);
523-
} else {
524-
TempDeadInsts.push_back(Extract);
525-
}
526-
}
527-
}
528-
// sort the deinterleaved nodes in the order that
529-
// they will be extracted from the target-specific intrinsic.
530-
for (unsigned I = 1; I < TempLeafNodes.size(); I += 2)
531-
LeafNodes.push_back(TempLeafNodes[I]);
532-
533-
for (unsigned I = 0; I < TempLeafNodes.size(); I += 2)
534-
LeafNodes.push_back(TempLeafNodes[I]);
535-
536491
// Try and match this with target specific intrinsics.
537-
if (!TLI->lowerDeinterleaveIntrinsicToLoad(DI, LeafNodes, LI))
492+
if (!TLI->lowerDeinterleaveIntrinsicToLoad(DI, LI))
538493
return false;
539494

540495
// We now have a target-specific load, so delete the old one.
541-
DeadInsts.insert(DeadInsts.end(), TempDeadInsts.rbegin(),
542-
TempDeadInsts.rend());
496+
DeadInsts.push_back(DI);
543497
DeadInsts.push_back(LI);
544498
return true;
545499
}
@@ -555,38 +509,14 @@ bool InterleavedAccessImpl::lowerInterleaveIntrinsic(
555509
return false;
556510

557511
LLVM_DEBUG(dbgs() << "IA: Found an interleave intrinsic: " << *II << "\n");
558-
std::queue<IntrinsicInst *> IeinterleaveTreeQueue;
559-
SmallVector<Value *> TempLeafNodes, LeafNodes;
560-
SmallVector<Instruction *> TempDeadInsts;
561-
562-
IeinterleaveTreeQueue.push(II);
563-
while (!IeinterleaveTreeQueue.empty()) {
564-
auto node = IeinterleaveTreeQueue.front();
565-
TempDeadInsts.push_back(node);
566-
IeinterleaveTreeQueue.pop();
567-
for (unsigned i = 0; i < 2; i++) {
568-
auto op = node->getOperand(i);
569-
if (auto CurrentII = dyn_cast<IntrinsicInst>(op)) {
570-
if (CurrentII->getIntrinsicID() !=
571-
Intrinsic::experimental_vector_interleave2)
572-
continue;
573-
IeinterleaveTreeQueue.push(CurrentII);
574-
continue;
575-
}
576-
TempLeafNodes.push_back(op);
577-
}
578-
}
579-
for (unsigned I = 0; I < TempLeafNodes.size(); I += 2)
580-
LeafNodes.push_back(TempLeafNodes[I]);
581-
for (unsigned I = 1; I < TempLeafNodes.size(); I += 2)
582-
LeafNodes.push_back(TempLeafNodes[I]);
512+
583513
// Try and match this with target specific intrinsics.
584-
if (!TLI->lowerInterleaveIntrinsicToStore(II, LeafNodes, SI))
514+
if (!TLI->lowerInterleaveIntrinsicToStore(II, SI))
585515
return false;
586516

587517
// We now have a target-specific store, so delete the old one.
588518
DeadInsts.push_back(SI);
589-
DeadInsts.insert(DeadInsts.end(), TempDeadInsts.begin(), TempDeadInsts.end());
519+
DeadInsts.push_back(II);
590520
return true;
591521
}
592522

@@ -607,8 +537,7 @@ bool InterleavedAccessImpl::runOnFunction(Function &F) {
607537
// with a factor of 2.
608538
if (II->getIntrinsicID() == Intrinsic::vector_deinterleave2)
609539
Changed |= lowerDeinterleaveIntrinsic(II, DeadInsts);
610-
611-
else if (II->getIntrinsicID() == Intrinsic::vector_interleave2)
540+
if (II->getIntrinsicID() == Intrinsic::vector_interleave2)
612541
Changed |= lowerInterleaveIntrinsic(II, DeadInsts);
613542
}
614543
}

0 commit comments

Comments
 (0)