[llvm] r296905 - RegisterCoalescer: Simplify subrange splitting code; NFC
Matthias Braun via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 3 11:05:35 PST 2017
Author: matze
Date: Fri Mar 3 13:05:34 2017
New Revision: 296905
URL: http://llvm.org/viewvc/llvm-project?rev=296905&view=rev
Log:
RegisterCoalescer: Simplify subrange splitting code; NFC
- Use slightly better variable names / compute in a more direct way.
Modified:
llvm/trunk/include/llvm/CodeGen/LiveInterval.h
llvm/trunk/lib/CodeGen/LiveInterval.cpp
llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp
llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
Modified: llvm/trunk/include/llvm/CodeGen/LiveInterval.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/LiveInterval.h?rev=296905&r1=296904&r2=296905&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/LiveInterval.h (original)
+++ llvm/trunk/include/llvm/CodeGen/LiveInterval.h Fri Mar 3 13:05:34 2017
@@ -227,15 +227,22 @@ namespace llvm {
LiveRange(const LiveRange &Other, BumpPtrAllocator &Allocator) {
assert(Other.segmentSet == nullptr &&
"Copying of LiveRanges with active SegmentSets is not supported");
+ assign(Other, Allocator);
+ }
+
+ /// Copies values numbers and live segments from \p Other into this range.
+ void assign(const LiveRange &Other, BumpPtrAllocator &Allocator) {
+ if (this == &Other)
+ return;
+ assert(Other.segmentSet == nullptr &&
+ "Copying of LiveRanges with active SegmentSets is not supported");
// Duplicate valnos.
- for (const VNInfo *VNI : Other.valnos) {
+ for (const VNInfo *VNI : Other.valnos)
createValueCopy(VNI, Allocator);
- }
// Now we can copy segments and remap their valnos.
- for (const Segment &S : Other.segments) {
+ for (const Segment &S : Other.segments)
segments.push_back(Segment(S.start, S.end, valnos[S.valno->id]));
- }
}
/// advanceTo - Advance the specified iterator to point to the Segment
@@ -767,6 +774,19 @@ namespace llvm {
const MachineRegisterInfo &MRI,
const SlotIndexes &Indexes) const;
+ /// Refines the subranges to support \p LaneMask. This may only be called
+ /// for LI.hasSubrange()==true. Subregister ranges are split or created
+ /// until \p LaneMask can be matched exactly. \p Mod is executed on the
+ /// matching subranges.
+ ///
+ /// Example:
+ /// Given an interval with subranges with lanemasks L0F00, L00F0 and
+ /// L000F, refining for mask L0018. Will split the L00F0 lane into
+ /// L00E0 and L0010 and the L000F lane into L0007 and L0008. The Mod
+ /// function will be applied to the L0010 and L0008 subranges.
+ void refineSubRanges(BumpPtrAllocator &Allocator, LaneBitmask LaneMask,
+ std::function<void(LiveInterval::SubRange&)> Mod);
+
bool operator<(const LiveInterval& other) const {
const SlotIndex &thisIndex = beginIndex();
const SlotIndex &otherIndex = other.beginIndex();
Modified: llvm/trunk/lib/CodeGen/LiveInterval.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveInterval.cpp?rev=296905&r1=296904&r2=296905&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveInterval.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveInterval.cpp Fri Mar 3 13:05:34 2017
@@ -863,6 +863,37 @@ void LiveInterval::clearSubRanges() {
SubRanges = nullptr;
}
+void LiveInterval::refineSubRanges(BumpPtrAllocator &Allocator,
+ LaneBitmask LaneMask, std::function<void(LiveInterval::SubRange&)> Apply) {
+
+ LaneBitmask ToApply = LaneMask;
+ for (SubRange &SR : subranges()) {
+ LaneBitmask SRMask = SR.LaneMask;
+ LaneBitmask Matching = SRMask & LaneMask;
+ if (Matching.none())
+ continue;
+
+ SubRange *MatchingRange;
+ if (SRMask == Matching) {
+ // The subrange fits (it does not cover bits outside \p LaneMask).
+ MatchingRange = &SR;
+ } else {
+ // We have to split the subrange into a matching and non-matching part.
+ // Reduce lanemask of existing lane to non-matching part.
+ SR.LaneMask = SRMask & ~Matching;
+ // Create a new subrange for the matching part
+ MatchingRange = createSubRangeFrom(Allocator, Matching, SR);
+ }
+ Apply(*MatchingRange);
+ ToApply &= ~Matching;
+ }
+ // Create a new subrange if there are uncovered bits left.
+ if (ToApply.any()) {
+ SubRange *NewRange = createSubRange(Allocator, ToApply);
+ Apply(*NewRange);
+ }
+}
+
unsigned LiveInterval::getSize() const {
unsigned Sum = 0;
for (const Segment &S : segments)
Modified: llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp?rev=296905&r1=296904&r2=296905&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp (original)
+++ llvm/trunk/lib/CodeGen/LiveRangeCalc.cpp Fri Mar 3 13:05:34 2017
@@ -75,34 +75,11 @@ void LiveRangeCalc::calculate(LiveInterv
LI.createSubRangeFrom(*Alloc, ClassMask, LI);
}
- LaneBitmask Mask = SubMask;
- for (LiveInterval::SubRange &S : LI.subranges()) {
- // A Mask for subregs common to the existing subrange and current def.
- LaneBitmask Common = S.LaneMask & Mask;
- if (Common.none())
- continue;
- LiveInterval::SubRange *CommonRange;
- // A Mask for subregs covered by the subrange but not the current def.
- LaneBitmask RM = S.LaneMask & ~Mask;
- if (RM.any()) {
- // Split the subrange S into two parts: one covered by the current
- // def (CommonRange), and the one not affected by it (updated S).
- S.LaneMask = RM;
- CommonRange = LI.createSubRangeFrom(*Alloc, Common, S);
- } else {
- assert(Common == S.LaneMask);
- CommonRange = &S;
- }
+ LI.refineSubRanges(*Alloc, SubMask,
+ [&MO, this](LiveInterval::SubRange &SR) {
if (MO.isDef())
- createDeadDef(*Indexes, *Alloc, *CommonRange, MO);
- Mask &= ~Common;
- }
- // Create a new SubRange for subregs we did not cover yet.
- if (Mask.any()) {
- LiveInterval::SubRange *NewRange = LI.createSubRange(*Alloc, Mask);
- if (MO.isDef())
- createDeadDef(*Indexes, *Alloc, *NewRange, MO);
- }
+ createDeadDef(*Indexes, *Alloc, SR, MO);
+ });
}
// Create the def in the main liverange. We do not have to do this if
Modified: llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp?rev=296905&r1=296904&r2=296905&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp (original)
+++ llvm/trunk/lib/CodeGen/RegisterCoalescer.cpp Fri Mar 3 13:05:34 2017
@@ -815,42 +815,14 @@ bool RegisterCoalescer::removeCopyByComm
VNInfo *ASubValNo = SA.getVNInfoAt(AIdx);
assert(ASubValNo != nullptr);
- LaneBitmask AMask = SA.LaneMask;
- for (LiveInterval::SubRange &SB : IntB.subranges()) {
- LaneBitmask BMask = SB.LaneMask;
- LaneBitmask Common = BMask & AMask;
- if (Common.none())
- continue;
-
- DEBUG( dbgs() << "\t\tCopy_Merge " << PrintLaneMask(BMask)
- << " into " << PrintLaneMask(Common) << '\n');
- LaneBitmask BRest = BMask & ~AMask;
- LiveInterval::SubRange *CommonRange;
- if (BRest.any()) {
- SB.LaneMask = BRest;
- DEBUG(dbgs() << "\t\tReduce Lane to " << PrintLaneMask(BRest)
- << '\n');
- // Duplicate SubRange for newly merged common stuff.
- CommonRange = IntB.createSubRangeFrom(Allocator, Common, SB);
- } else {
- // We van reuse the L SubRange.
- SB.LaneMask = Common;
- CommonRange = &SB;
- }
- LiveRange RangeCopy(SB, Allocator);
-
- VNInfo *BSubValNo = CommonRange->getVNInfoAt(CopyIdx);
- assert(BSubValNo->def == CopyIdx);
- BSubValNo->def = ASubValNo->def;
- addSegmentsWithValNo(*CommonRange, BSubValNo, SA, ASubValNo);
- AMask &= ~BMask;
- }
- if (AMask.any()) {
- DEBUG(dbgs() << "\t\tNew Lane " << PrintLaneMask(AMask) << '\n');
- LiveRange *NewRange = IntB.createSubRange(Allocator, AMask);
- VNInfo *BSubValNo = NewRange->getNextValue(CopyIdx, Allocator);
- addSegmentsWithValNo(*NewRange, BSubValNo, SA, ASubValNo);
- }
+ IntB.refineSubRanges(Allocator, SA.LaneMask,
+ [&Allocator,&SA,CopyIdx,ASubValNo](LiveInterval::SubRange &SR) {
+ VNInfo *BSubValNo = SR.empty()
+ ? SR.getNextValue(CopyIdx, Allocator)
+ : SR.getVNInfoAt(CopyIdx);
+ assert(BSubValNo != nullptr);
+ addSegmentsWithValNo(SR, BSubValNo, SA, ASubValNo);
+ });
}
}
@@ -2926,39 +2898,16 @@ void RegisterCoalescer::mergeSubRangeInt
LaneBitmask LaneMask,
CoalescerPair &CP) {
BumpPtrAllocator &Allocator = LIS->getVNInfoAllocator();
- for (LiveInterval::SubRange &R : LI.subranges()) {
- LaneBitmask RMask = R.LaneMask;
- // LaneMask of subregisters common to subrange R and ToMerge.
- LaneBitmask Common = RMask & LaneMask;
- // There is nothing to do without common subregs.
- if (Common.none())
- continue;
-
- DEBUG(dbgs() << "\t\tCopy+Merge " << PrintLaneMask(RMask) << " into "
- << PrintLaneMask(Common) << '\n');
- // LaneMask of subregisters contained in the R range but not in ToMerge,
- // they have to split into their own subrange.
- LaneBitmask LRest = RMask & ~LaneMask;
- LiveInterval::SubRange *CommonRange;
- if (LRest.any()) {
- R.LaneMask = LRest;
- DEBUG(dbgs() << "\t\tReduce Lane to " << PrintLaneMask(LRest) << '\n');
- // Duplicate SubRange for newly merged common stuff.
- CommonRange = LI.createSubRangeFrom(Allocator, Common, R);
+ LI.refineSubRanges(Allocator, LaneMask,
+ [this,&Allocator,&ToMerge,&CP](LiveInterval::SubRange &SR) {
+ if (SR.empty()) {
+ SR.assign(ToMerge, Allocator);
} else {
- // Reuse the existing range.
- R.LaneMask = Common;
- CommonRange = &R;
- }
- LiveRange RangeCopy(ToMerge, Allocator);
- joinSubRegRanges(*CommonRange, RangeCopy, Common, CP);
- LaneMask &= ~RMask;
- }
-
- if (LaneMask.any()) {
- DEBUG(dbgs() << "\t\tNew Lane " << PrintLaneMask(LaneMask) << '\n');
- LI.createSubRangeFrom(Allocator, LaneMask, ToMerge);
- }
+ // joinSubRegRange() destroys the merged range, so we need a copy.
+ LiveRange RangeCopy(ToMerge, Allocator);
+ joinSubRegRanges(SR, RangeCopy, SR.LaneMask, CP);
+ }
+ });
}
bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
More information about the llvm-commits
mailing list