CodeGen: Move function to get subregister indexes to cover a LaneMask
Return the best covering index, and additional needed to complete the
mask. This logically belongs in TargetRegisterInfo, although I ended
up not needing it for why I originally split this out.
GitOrigin-RevId: 1b3d8ddeb9653caef0d208f85564d3f4e6c359f4
diff --git a/include/llvm/CodeGen/TargetRegisterInfo.h b/include/llvm/CodeGen/TargetRegisterInfo.h
index 0e9f89a..3191fff 100644
--- a/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -363,6 +363,15 @@
return SubRegIndexLaneMasks[SubIdx];
}
+ /// Try to find one or more subregister indexes to cover \p LaneMask.
+ ///
+ /// If this is possible, returns true and appends the best matching set of
+ /// indexes to \p Indexes. If this is not possible, returns false.
+ bool getCoveringSubRegIndexes(const MachineRegisterInfo &MRI,
+ const TargetRegisterClass *RC,
+ LaneBitmask LaneMask,
+ SmallVectorImpl<unsigned> &Indexes) const;
+
/// The lane masks returned by getSubRegIndexLaneMask() above can only be
/// used to determine if sub-registers overlap - they can't be used to
/// determine if a set of sub-registers completely cover another
diff --git a/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp
index a6a3149..8ffba4a 100644
--- a/lib/CodeGen/SplitKit.cpp
+++ b/lib/CodeGen/SplitKit.cpp
@@ -557,71 +557,19 @@
// First pass: Try to find a perfectly matching subregister index. If none
// exists find the one covering the most lanemask bits.
- SmallVector<unsigned, 8> PossibleIndexes;
- unsigned BestIdx = 0;
- unsigned BestCover = 0;
const TargetRegisterClass *RC = MRI.getRegClass(FromReg);
assert(RC == MRI.getRegClass(ToReg) && "Should have same reg class");
- for (unsigned Idx = 1, E = TRI.getNumSubRegIndices(); Idx < E; ++Idx) {
- // Is this index even compatible with the given class?
- if (TRI.getSubClassWithSubReg(RC, Idx) != RC)
- continue;
- LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(Idx);
- // Early exit if we found a perfect match.
- if (SubRegMask == LaneMask) {
- BestIdx = Idx;
- break;
- }
- // The index must not cover any lanes outside \p LaneMask.
- if ((SubRegMask & ~LaneMask).any())
- continue;
-
- unsigned PopCount = SubRegMask.getNumLanes();
- PossibleIndexes.push_back(Idx);
- if (PopCount > BestCover) {
- BestCover = PopCount;
- BestIdx = Idx;
- }
- }
+ SmallVector<unsigned, 8> Indexes;
// Abort if we cannot possibly implement the COPY with the given indexes.
- if (BestIdx == 0)
+ if (!TRI.getCoveringSubRegIndexes(MRI, RC, LaneMask, Indexes))
report_fatal_error("Impossible to implement partial COPY");
- SlotIndex Def = buildSingleSubRegCopy(FromReg, ToReg, MBB, InsertBefore,
- BestIdx, DestLI, Late, SlotIndex());
-
- // Greedy heuristic: Keep iterating keeping the best covering subreg index
- // each time.
- LaneBitmask LanesLeft = LaneMask & ~(TRI.getSubRegIndexLaneMask(BestIdx));
- while (LanesLeft.any()) {
- unsigned BestIdx = 0;
- int BestCover = std::numeric_limits<int>::min();
- for (unsigned Idx : PossibleIndexes) {
- LaneBitmask SubRegMask = TRI.getSubRegIndexLaneMask(Idx);
- // Early exit if we found a perfect match.
- if (SubRegMask == LanesLeft) {
- BestIdx = Idx;
- break;
- }
-
- // Try to cover as much of the remaining lanes as possible but
- // as few of the already covered lanes as possible.
- int Cover = (SubRegMask & LanesLeft).getNumLanes()
- - (SubRegMask & ~LanesLeft).getNumLanes();
- if (Cover > BestCover) {
- BestCover = Cover;
- BestIdx = Idx;
- }
- }
-
- if (BestIdx == 0)
- report_fatal_error("Impossible to implement partial COPY");
-
- buildSingleSubRegCopy(FromReg, ToReg, MBB, InsertBefore, BestIdx,
- DestLI, Late, Def);
- LanesLeft &= ~TRI.getSubRegIndexLaneMask(BestIdx);
+ SlotIndex Def;
+ for (unsigned BestIdx : Indexes) {
+ Def = buildSingleSubRegCopy(FromReg, ToReg, MBB, InsertBefore, BestIdx,
+ DestLI, Late, Def);
}
return Def;
diff --git a/lib/CodeGen/TargetRegisterInfo.cpp b/lib/CodeGen/TargetRegisterInfo.cpp
index 5fd7eef..be47e5f 100644
--- a/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/lib/CodeGen/TargetRegisterInfo.cpp
@@ -510,6 +510,77 @@
return getRegSizeInBits(*RC);
}
+bool TargetRegisterInfo::getCoveringSubRegIndexes(
+ const MachineRegisterInfo &MRI, const TargetRegisterClass *RC,
+ LaneBitmask LaneMask, SmallVectorImpl<unsigned> &NeededIndexes) const {
+ SmallVector<unsigned, 8> PossibleIndexes;
+ unsigned BestIdx = 0;
+ unsigned BestCover = 0;
+
+ for (unsigned Idx = 1, E = getNumSubRegIndices(); Idx < E; ++Idx) {
+ // Is this index even compatible with the given class?
+ if (getSubClassWithSubReg(RC, Idx) != RC)
+ continue;
+ LaneBitmask SubRegMask = getSubRegIndexLaneMask(Idx);
+ // Early exit if we found a perfect match.
+ if (SubRegMask == LaneMask) {
+ BestIdx = Idx;
+ break;
+ }
+
+ // The index must not cover any lanes outside \p LaneMask.
+ if ((SubRegMask & ~LaneMask).any())
+ continue;
+
+ unsigned PopCount = SubRegMask.getNumLanes();
+ PossibleIndexes.push_back(Idx);
+ if (PopCount > BestCover) {
+ BestCover = PopCount;
+ BestIdx = Idx;
+ }
+ }
+
+ // Abort if we cannot possibly implement the COPY with the given indexes.
+ if (BestIdx == 0)
+ return 0;
+
+ NeededIndexes.push_back(BestIdx);
+
+ // Greedy heuristic: Keep iterating keeping the best covering subreg index
+ // each time.
+ LaneBitmask LanesLeft = LaneMask & ~getSubRegIndexLaneMask(BestIdx);
+ while (LanesLeft.any()) {
+ unsigned BestIdx = 0;
+ int BestCover = std::numeric_limits<int>::min();
+ for (unsigned Idx : PossibleIndexes) {
+ LaneBitmask SubRegMask = getSubRegIndexLaneMask(Idx);
+ // Early exit if we found a perfect match.
+ if (SubRegMask == LanesLeft) {
+ BestIdx = Idx;
+ break;
+ }
+
+ // Try to cover as much of the remaining lanes as possible but
+ // as few of the already covered lanes as possible.
+ int Cover = (SubRegMask & LanesLeft).getNumLanes() -
+ (SubRegMask & ~LanesLeft).getNumLanes();
+ if (Cover > BestCover) {
+ BestCover = Cover;
+ BestIdx = Idx;
+ }
+ }
+
+ if (BestIdx == 0)
+ return 0; // Impossible to handle
+
+ NeededIndexes.push_back(BestIdx);
+
+ LanesLeft &= ~getSubRegIndexLaneMask(BestIdx);
+ }
+
+ return BestIdx;
+}
+
Register
TargetRegisterInfo::lookThruCopyLike(Register SrcReg,
const MachineRegisterInfo *MRI) const {