aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveDebugVariables.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-09-20 17:32:54 +0000
committerReid Kleckner <rnk@google.com>2017-09-20 17:32:54 +0000
commit92687d45db566cdc47905555ee4b249d47a46d25 (patch)
tree9751fd2da53c88c97459829715884f1f63bb7a36 /llvm/lib/CodeGen/LiveDebugVariables.cpp
parentaa103b3d86c0bd9d1b4452244173990457af5a4e (diff)
downloadllvm-92687d45db566cdc47905555ee4b249d47a46d25.zip
llvm-92687d45db566cdc47905555ee4b249d47a46d25.tar.gz
llvm-92687d45db566cdc47905555ee4b249d47a46d25.tar.bz2
[DebugInfo] Use a MapVector to coalesce MachineOperand locations
Summary: The new code should be linear in the number of DBG_VALUEs, while the old code was quadratic. NFC intended. This is also hopefully a more direct expression of the problem, which is to: 1. Rewrite all virtual register operands to stack slots or physical registers 2. Uniquely number those machine operands, assigning them location numbers 3. Rewrite all uses of the old location numbers in the interval map to use the new location numbers In r313400, I attempted to track which locations were spilled in a parallel bitvector indexed by location number. My code was broken because these location numbers are not stable during rewriting. Reviewers: aprantl, hans Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D38068 llvm-svn: 313775
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugVariables.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugVariables.cpp102
1 files changed, 46 insertions, 56 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 0e95209..93cb7c3 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -126,11 +126,6 @@ class UserValue {
/// lexical scope.
SmallSet<SlotIndex, 2> trimmedDefs;
- /// coalesceLocation - After LocNo was changed, check if it has become
- /// identical to another location, and coalesce them. This may cause LocNo or
- /// a later location to be erased, but no earlier location will be erased.
- void coalesceLocation(unsigned LocNo);
-
/// insertDebugValue - Insert a DBG_VALUE into MBB at Idx for LocNo.
void insertDebugValue(MachineBasicBlock *MBB, SlotIndex Idx, unsigned LocNo,
LiveIntervals &LIS, const TargetInstrInfo &TII);
@@ -421,34 +416,6 @@ void LDVImpl::print(raw_ostream &OS) {
}
#endif
-void UserValue::coalesceLocation(unsigned LocNo) {
- unsigned KeepLoc = 0;
- for (unsigned e = locations.size(); KeepLoc != e; ++KeepLoc) {
- if (KeepLoc == LocNo)
- continue;
- if (locations[KeepLoc].isIdenticalTo(locations[LocNo]))
- break;
- }
- // No matches.
- if (KeepLoc == locations.size())
- return;
-
- // Keep the smaller location, erase the larger one.
- unsigned EraseLoc = LocNo;
- if (KeepLoc > EraseLoc)
- std::swap(KeepLoc, EraseLoc);
- locations.erase(locations.begin() + EraseLoc);
-
- // Rewrite values.
- for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) {
- unsigned v = I.value();
- if (v == EraseLoc)
- I.setValue(KeepLoc); // Coalesce when possible.
- else if (v > EraseLoc)
- I.setValueUnchecked(v-1); // Avoid coalescing with untransformed values.
- }
-}
-
void UserValue::mapVirtRegs(LDVImpl *LDV) {
for (unsigned i = 0, e = locations.size(); i != e; ++i)
if (locations[i].isReg() &&
@@ -973,31 +940,54 @@ splitRegister(unsigned OldReg, ArrayRef<unsigned> NewRegs, LiveIntervals &LIS) {
static_cast<LDVImpl*>(pImpl)->splitRegister(OldReg, NewRegs);
}
-void
-UserValue::rewriteLocations(VirtRegMap &VRM, const TargetRegisterInfo &TRI) {
- // Iterate over locations in reverse makes it easier to handle coalescing.
- for (unsigned i = locations.size(); i ; --i) {
- unsigned LocNo = i-1;
- MachineOperand &Loc = locations[LocNo];
+void UserValue::rewriteLocations(VirtRegMap &VRM,
+ const TargetRegisterInfo &TRI) {
+ // Build a set of new locations with new numbers so we can coalesce our
+ // IntervalMap if two vreg intervals collapse to the same physical location.
+ // Use MapVector instead of SetVector because MapVector::insert returns the
+ // position of the previously or newly inserted element.
+ MapVector<MachineOperand, bool> NewLocations;
+ SmallVector<unsigned, 4> LocNoMap(locations.size());
+ for (unsigned I = 0, E = locations.size(); I != E; ++I) {
+ MachineOperand Loc = locations[I];
// Only virtual registers are rewritten.
- if (!Loc.isReg() || !Loc.getReg() ||
- !TargetRegisterInfo::isVirtualRegister(Loc.getReg()))
- continue;
- unsigned VirtReg = Loc.getReg();
- if (VRM.isAssignedReg(VirtReg) &&
- TargetRegisterInfo::isPhysicalRegister(VRM.getPhys(VirtReg))) {
- // This can create a %noreg operand in rare cases when the sub-register
- // index is no longer available. That means the user value is in a
- // non-existent sub-register, and %noreg is exactly what we want.
- Loc.substPhysReg(VRM.getPhys(VirtReg), TRI);
- } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) {
- // FIXME: Translate SubIdx to a stackslot offset.
- Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg));
- } else {
- Loc.setReg(0);
- Loc.setSubReg(0);
+ if (Loc.isReg() && Loc.getReg() &&
+ TargetRegisterInfo::isVirtualRegister(Loc.getReg())) {
+ unsigned VirtReg = Loc.getReg();
+ if (VRM.isAssignedReg(VirtReg) &&
+ TargetRegisterInfo::isPhysicalRegister(VRM.getPhys(VirtReg))) {
+ // This can create a %noreg operand in rare cases when the sub-register
+ // index is no longer available. That means the user value is in a
+ // non-existent sub-register, and %noreg is exactly what we want.
+ Loc.substPhysReg(VRM.getPhys(VirtReg), TRI);
+ } else if (VRM.getStackSlot(VirtReg) != VirtRegMap::NO_STACK_SLOT) {
+ // FIXME: Translate SubIdx to a stackslot offset.
+ Loc = MachineOperand::CreateFI(VRM.getStackSlot(VirtReg));
+ } else {
+ Loc.setReg(0);
+ Loc.setSubReg(0);
+ }
}
- coalesceLocation(LocNo);
+
+ // Insert this location if it doesn't already exist and record a mapping
+ // from the old number to the new number.
+ auto InsertResult = NewLocations.insert({Loc, false});
+ LocNoMap[I] = std::distance(NewLocations.begin(), InsertResult.first);
+ }
+
+ // Rewrite the locations.
+ locations.clear();
+ for (const auto &Pair : NewLocations)
+ locations.push_back(Pair.first);
+
+ // Update the interval map, but only coalesce left, since intervals to the
+ // right use the old location numbers. This should merge two contiguous
+ // DBG_VALUE intervals with different vregs that were allocated to the same
+ // physical register.
+ for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) {
+ unsigned NewLocNo = LocNoMap[I.value()];
+ I.setValueUnchecked(NewLocNo);
+ I.setStart(I.start());
}
}