forked from OSchip/llvm-project
RegisterCoalescer: Simplify subrange splitting code; NFC
- Use slightly better variable names / compute in a more direct way. llvm-svn: 296905
This commit is contained in:
parent
b471d4f25a
commit
a04d7ad851
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -75,34 +75,11 @@ void LiveRangeCalc::calculate(LiveInterval &LI, bool TrackSubRegs) {
|
|||
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
|
||||
|
|
|
@ -815,42 +815,14 @@ bool RegisterCoalescer::removeCopyByCommutingDef(const CoalescerPair &CP,
|
|||
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::mergeSubRangeInto(LiveInterval &LI,
|
|||
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;
|
||||
// joinSubRegRange() destroys the merged range, so we need a copy.
|
||||
LiveRange RangeCopy(ToMerge, Allocator);
|
||||
joinSubRegRanges(SR, RangeCopy, SR.LaneMask, CP);
|
||||
}
|
||||
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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool RegisterCoalescer::joinVirtRegs(CoalescerPair &CP) {
|
||||
|
|
Loading…
Reference in New Issue