@@ -24,7 +24,7 @@ namespace llvm {
24
24
template <typename T> class ArrayRef ;
25
25
class DemandedBits ;
26
26
class GetElementPtrInst ;
27
- class InterleaveGroup ;
27
+ template < typename InstTy> class InterleaveGroup ;
28
28
class Loop ;
29
29
class ScalarEvolution ;
30
30
class TargetTransformInfo ;
@@ -138,7 +138,7 @@ Instruction *propagateMetadata(Instruction *I, ArrayRef<Value *> VL);
138
138
// / create[*]Mask() utilities which create a shuffle mask (mask that
139
139
// / consists of indices).
140
140
Constant *createBitMaskForGaps (IRBuilder<> &Builder, unsigned VF,
141
- const InterleaveGroup &Group);
141
+ const InterleaveGroup<Instruction> &Group);
142
142
143
143
// / Create a mask with replicated elements.
144
144
// /
@@ -233,9 +233,12 @@ Value *concatenateVectors(IRBuilder<> &Builder, ArrayRef<Value *> Vecs);
233
233
// /
234
234
// / Note: the interleaved load group could have gaps (missing members), but
235
235
// / the interleaved store group doesn't allow gaps.
236
- class InterleaveGroup {
236
+ template < typename InstTy> class InterleaveGroup {
237
237
public:
238
- InterleaveGroup (Instruction *Instr, int Stride, unsigned Align)
238
+ InterleaveGroup (unsigned Factor, bool Reverse, unsigned Align)
239
+ : Factor(Factor), Reverse(Reverse), Align(Align), InsertPos(nullptr ) {}
240
+
241
+ InterleaveGroup (InstTy *Instr, int Stride, unsigned Align)
239
242
: Align(Align), InsertPos(Instr) {
240
243
assert (Align && " The alignment should be non-zero" );
241
244
@@ -256,7 +259,7 @@ class InterleaveGroup {
256
259
// / negative if it is the new leader.
257
260
// /
258
261
// / \returns false if the instruction doesn't belong to the group.
259
- bool insertMember (Instruction *Instr, int Index, unsigned NewAlign) {
262
+ bool insertMember (InstTy *Instr, int Index, unsigned NewAlign) {
260
263
assert (NewAlign && " The new member's alignment should be non-zero" );
261
264
262
265
int Key = Index + SmallestKey;
@@ -288,7 +291,7 @@ class InterleaveGroup {
288
291
// / Get the member with the given index \p Index
289
292
// /
290
293
// / \returns nullptr if contains no such member.
291
- Instruction *getMember (unsigned Index) const {
294
+ InstTy *getMember (unsigned Index) const {
292
295
int Key = SmallestKey + Index;
293
296
auto Member = Members.find (Key);
294
297
if (Member == Members.end ())
@@ -299,29 +302,25 @@ class InterleaveGroup {
299
302
300
303
// / Get the index for the given member. Unlike the key in the member
301
304
// / map, the index starts from 0.
302
- unsigned getIndex (Instruction *Instr) const {
303
- for (auto I : Members)
305
+ unsigned getIndex (const InstTy *Instr) const {
306
+ for (auto I : Members) {
304
307
if (I.second == Instr)
305
308
return I.first - SmallestKey;
309
+ }
306
310
307
311
llvm_unreachable (" InterleaveGroup contains no such member" );
308
312
}
309
313
310
- Instruction *getInsertPos () const { return InsertPos; }
311
- void setInsertPos (Instruction *Inst) { InsertPos = Inst; }
314
+ InstTy *getInsertPos () const { return InsertPos; }
315
+ void setInsertPos (InstTy *Inst) { InsertPos = Inst; }
312
316
313
317
// / Add metadata (e.g. alias info) from the instructions in this group to \p
314
318
// / NewInst.
315
319
// /
316
320
// / FIXME: this function currently does not add noalias metadata a'la
317
321
// / addNewMedata. To do that we need to compute the intersection of the
318
322
// / noalias info from all members.
319
- void addMetadata (Instruction *NewInst) const {
320
- SmallVector<Value *, 4 > VL;
321
- std::transform (Members.begin (), Members.end (), std::back_inserter (VL),
322
- [](std::pair<int , Instruction *> p) { return p.second ; });
323
- propagateMetadata (NewInst, VL);
324
- }
323
+ void addMetadata (InstTy *NewInst) const ;
325
324
326
325
// / Returns true if this Group requires a scalar iteration to handle gaps.
327
326
bool requiresScalarEpilogue () const {
@@ -344,7 +343,7 @@ class InterleaveGroup {
344
343
unsigned Factor; // Interleave Factor.
345
344
bool Reverse;
346
345
unsigned Align;
347
- DenseMap<int , Instruction *> Members;
346
+ DenseMap<int , InstTy *> Members;
348
347
int SmallestKey = 0 ;
349
348
int LargestKey = 0 ;
350
349
@@ -359,7 +358,7 @@ class InterleaveGroup {
359
358
// store i32 %even
360
359
// %odd = add i32 // Def of %odd
361
360
// store i32 %odd // Insert Position
362
- Instruction *InsertPos;
361
+ InstTy *InsertPos;
363
362
};
364
363
365
364
// / Drive the analysis of interleaved memory accesses in the loop.
@@ -390,7 +389,7 @@ class InterleavedAccessInfo {
390
389
// / formation for predicated accesses, we may be able to relax this limitation
391
390
// / in the future once we handle more complicated blocks.
392
391
void reset () {
393
- SmallPtrSet<InterleaveGroup *, 4 > DelSet;
392
+ SmallPtrSet<InterleaveGroup<Instruction> *, 4 > DelSet;
394
393
// Avoid releasing a pointer twice.
395
394
for (auto &I : InterleaveGroupMap)
396
395
DelSet.insert (I.second );
@@ -409,11 +408,16 @@ class InterleavedAccessInfo {
409
408
// / Get the interleave group that \p Instr belongs to.
410
409
// /
411
410
// / \returns nullptr if doesn't have such group.
412
- InterleaveGroup *getInterleaveGroup (Instruction *Instr) const {
413
- auto Group = InterleaveGroupMap.find (Instr);
414
- if (Group == InterleaveGroupMap.end ())
415
- return nullptr ;
416
- return Group->second ;
411
+ InterleaveGroup<Instruction> *
412
+ getInterleaveGroup (const Instruction *Instr) const {
413
+ if (InterleaveGroupMap.count (Instr))
414
+ return InterleaveGroupMap.find (Instr)->second ;
415
+ return nullptr ;
416
+ }
417
+
418
+ iterator_range<SmallPtrSetIterator<llvm::InterleaveGroup<Instruction> *>>
419
+ getInterleaveGroups () {
420
+ return make_range (InterleaveGroups.begin (), InterleaveGroups.end ());
417
421
}
418
422
419
423
// / Returns true if an interleaved group that may access memory
@@ -443,7 +447,9 @@ class InterleavedAccessInfo {
443
447
bool RequiresScalarEpilogue = false ;
444
448
445
449
// / Holds the relationships between the members and the interleave group.
446
- DenseMap<Instruction *, InterleaveGroup *> InterleaveGroupMap;
450
+ DenseMap<Instruction *, InterleaveGroup<Instruction> *> InterleaveGroupMap;
451
+
452
+ SmallPtrSet<InterleaveGroup<Instruction> *, 4 > InterleaveGroups;
447
453
448
454
// / Holds dependences among the memory accesses in the loop. It maps a source
449
455
// / access to a set of dependent sink accesses.
@@ -476,19 +482,23 @@ class InterleavedAccessInfo {
476
482
// / stride \p Stride and alignment \p Align.
477
483
// /
478
484
// / \returns the newly created interleave group.
479
- InterleaveGroup *createInterleaveGroup (Instruction *Instr, int Stride,
480
- unsigned Align) {
481
- assert (!isInterleaved (Instr) && " Already in an interleaved access group" );
482
- InterleaveGroupMap[Instr] = new InterleaveGroup (Instr, Stride, Align);
485
+ InterleaveGroup<Instruction> *
486
+ createInterleaveGroup (Instruction *Instr, int Stride, unsigned Align) {
487
+ assert (!InterleaveGroupMap.count (Instr) &&
488
+ " Already in an interleaved access group" );
489
+ InterleaveGroupMap[Instr] =
490
+ new InterleaveGroup<Instruction>(Instr, Stride, Align);
491
+ InterleaveGroups.insert (InterleaveGroupMap[Instr]);
483
492
return InterleaveGroupMap[Instr];
484
493
}
485
494
486
495
// / Release the group and remove all the relationships.
487
- void releaseGroup (InterleaveGroup *Group) {
496
+ void releaseGroup (InterleaveGroup<Instruction> *Group) {
488
497
for (unsigned i = 0 ; i < Group->getFactor (); i++)
489
498
if (Instruction *Member = Group->getMember (i))
490
499
InterleaveGroupMap.erase (Member);
491
500
501
+ InterleaveGroups.erase (Group);
492
502
delete Group;
493
503
}
494
504
0 commit comments