@@ -24,7 +24,7 @@ namespace llvm {
2424template <typename T> class ArrayRef ;
2525class DemandedBits ;
2626class GetElementPtrInst ;
27- class InterleaveGroup ;
27+ template < typename InstTy> class InterleaveGroup ;
2828class Loop ;
2929class ScalarEvolution ;
3030class TargetTransformInfo ;
@@ -138,7 +138,7 @@ Instruction *propagateMetadata(Instruction *I, ArrayRef<Value *> VL);
138138// / create[*]Mask() utilities which create a shuffle mask (mask that
139139// / consists of indices).
140140Constant *createBitMaskForGaps (IRBuilder<> &Builder, unsigned VF,
141- const InterleaveGroup &Group);
141+ const InterleaveGroup<Instruction> &Group);
142142
143143// / Create a mask with replicated elements.
144144// /
@@ -233,9 +233,12 @@ Value *concatenateVectors(IRBuilder<> &Builder, ArrayRef<Value *> Vecs);
233233// /
234234// / Note: the interleaved load group could have gaps (missing members), but
235235// / the interleaved store group doesn't allow gaps.
236- class InterleaveGroup {
236+ template < typename InstTy> class InterleaveGroup {
237237public:
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)
239242 : Align(Align), InsertPos(Instr) {
240243 assert (Align && " The alignment should be non-zero" );
241244
@@ -256,7 +259,7 @@ class InterleaveGroup {
256259 // / negative if it is the new leader.
257260 // /
258261 // / \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) {
260263 assert (NewAlign && " The new member's alignment should be non-zero" );
261264
262265 int Key = Index + SmallestKey;
@@ -288,7 +291,7 @@ class InterleaveGroup {
288291 // / Get the member with the given index \p Index
289292 // /
290293 // / \returns nullptr if contains no such member.
291- Instruction *getMember (unsigned Index) const {
294+ InstTy *getMember (unsigned Index) const {
292295 int Key = SmallestKey + Index;
293296 auto Member = Members.find (Key);
294297 if (Member == Members.end ())
@@ -299,29 +302,25 @@ class InterleaveGroup {
299302
300303 // / Get the index for the given member. Unlike the key in the member
301304 // / 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) {
304307 if (I.second == Instr)
305308 return I.first - SmallestKey;
309+ }
306310
307311 llvm_unreachable (" InterleaveGroup contains no such member" );
308312 }
309313
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; }
312316
313317 // / Add metadata (e.g. alias info) from the instructions in this group to \p
314318 // / NewInst.
315319 // /
316320 // / FIXME: this function currently does not add noalias metadata a'la
317321 // / addNewMedata. To do that we need to compute the intersection of the
318322 // / 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 ;
325324
326325 // / Returns true if this Group requires a scalar iteration to handle gaps.
327326 bool requiresScalarEpilogue () const {
@@ -344,7 +343,7 @@ class InterleaveGroup {
344343 unsigned Factor; // Interleave Factor.
345344 bool Reverse;
346345 unsigned Align;
347- DenseMap<int , Instruction *> Members;
346+ DenseMap<int , InstTy *> Members;
348347 int SmallestKey = 0 ;
349348 int LargestKey = 0 ;
350349
@@ -359,7 +358,7 @@ class InterleaveGroup {
359358 // store i32 %even
360359 // %odd = add i32 // Def of %odd
361360 // store i32 %odd // Insert Position
362- Instruction *InsertPos;
361+ InstTy *InsertPos;
363362};
364363
365364// / Drive the analysis of interleaved memory accesses in the loop.
@@ -390,7 +389,7 @@ class InterleavedAccessInfo {
390389 // / formation for predicated accesses, we may be able to relax this limitation
391390 // / in the future once we handle more complicated blocks.
392391 void reset () {
393- SmallPtrSet<InterleaveGroup *, 4 > DelSet;
392+ SmallPtrSet<InterleaveGroup<Instruction> *, 4 > DelSet;
394393 // Avoid releasing a pointer twice.
395394 for (auto &I : InterleaveGroupMap)
396395 DelSet.insert (I.second );
@@ -409,11 +408,16 @@ class InterleavedAccessInfo {
409408 // / Get the interleave group that \p Instr belongs to.
410409 // /
411410 // / \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 ());
417421 }
418422
419423 // / Returns true if an interleaved group that may access memory
@@ -443,7 +447,9 @@ class InterleavedAccessInfo {
443447 bool RequiresScalarEpilogue = false ;
444448
445449 // / 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;
447453
448454 // / Holds dependences among the memory accesses in the loop. It maps a source
449455 // / access to a set of dependent sink accesses.
@@ -476,19 +482,23 @@ class InterleavedAccessInfo {
476482 // / stride \p Stride and alignment \p Align.
477483 // /
478484 // / \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]);
483492 return InterleaveGroupMap[Instr];
484493 }
485494
486495 // / Release the group and remove all the relationships.
487- void releaseGroup (InterleaveGroup *Group) {
496+ void releaseGroup (InterleaveGroup<Instruction> *Group) {
488497 for (unsigned i = 0 ; i < Group->getFactor (); i++)
489498 if (Instruction *Member = Group->getMember (i))
490499 InterleaveGroupMap.erase (Member);
491500
501+ InterleaveGroups.erase (Group);
492502 delete Group;
493503 }
494504
0 commit comments