aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveDebugVariables.cpp
diff options
context:
space:
mode:
authorBjorn Pettersson <bjorn.a.pettersson@ericsson.com>2019-10-25 19:03:18 +0200
committerBjorn Pettersson <bjorn.a.pettersson@ericsson.com>2019-11-01 16:25:32 +0100
commit56c22931bdfafe8257e610cb9f29b9d64478f812 (patch)
tree2f336be899b6ffec57ba7f2d16f96d027c4b8774 /llvm/lib/CodeGen/LiveDebugVariables.cpp
parent449882b5442aa5138b5a89f56996ed990a3ead20 (diff)
downloadllvm-56c22931bdfafe8257e610cb9f29b9d64478f812.zip
llvm-56c22931bdfafe8257e610cb9f29b9d64478f812.tar.gz
llvm-56c22931bdfafe8257e610cb9f29b9d64478f812.tar.bz2
[LDV][RAGreedy] Inform LiveDebugVariables about new VRegs added by InlineSpiller
Summary: Make sure RAGreedy informs LiveDebugVariables about new VRegs that is introduced at spill by InlineSpiller. Consider this example LDV: !"var" [48r;128r):0 Loc0=%2 48B %2 = ... ... 128B %7 = ADD %2, ... If %2 is spilled the InlineSpiller will insert spill/reload instructions and introduces some new vregs. So we get 48B %4 = ... 56B spill %4 ... 120B reload %5 128B %3 = ADD %5, ... In the past we did not inform LDV about this, and when reintroducing DBG_VALUE instruction LDV still got information that "var" had the location of the spilled register %2 for the interval [48r;128r). The result was bad, since we mapped "var" to the spill slot even before the spill happened: %4 = ... DBG_VALUE %spill.0, !"var" spill %4 to %spill.0 ... reload %5 %3 = ADD %5, ... This patch will inform LDV about the interval split introduced due to spilling. So the location map in LDV will become !"var" [48r;56r):1 [56r;120r):0 [120r;128r):2 Loc0=%2 Loc1=%4 Loc2=%5 And when inserting DBG_VALUE instructions we get %4 = ... DBG_VALUE %4, !"var" spill %4 to %spill.0 DBG_VALUE %spill.0, !"var" ... reload %5 DBG_VALUE %5, !"var" %3 = ADD %5, ... Fixes: https://bugs.llvm.org/show_bug.cgi?id=38899 Reviewers: jmorse, vsk, aprantl Reviewed By: jmorse Subscribers: dstenb, wuzish, MatzeB, qcolombet, nemanjai, hiraditya, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D69584
Diffstat (limited to 'llvm/lib/CodeGen/LiveDebugVariables.cpp')
-rw-r--r--llvm/lib/CodeGen/LiveDebugVariables.cpp44
1 files changed, 27 insertions, 17 deletions
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 253bdbb..cace044 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -255,6 +255,25 @@ public:
return locations.size() - 1;
}
+ /// Remove (recycle) a location number. If \p LocNo still is used by the
+ /// locInts nothing is done.
+ void removeLocationIfUnused(unsigned LocNo) {
+ // Bail out if LocNo still is used.
+ for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) {
+ DbgValueLocation Loc = I.value();
+ if (Loc.locNo() == LocNo)
+ return;
+ }
+ // Remove the entry in the locations vector, and adjust all references to
+ // location numbers above the removed entry.
+ locations.erase(locations.begin() + LocNo);
+ for (LocMap::iterator I = locInts.begin(); I.valid(); ++I) {
+ DbgValueLocation Loc = I.value();
+ if (!Loc.isUndef() && Loc.locNo() > LocNo)
+ I.setValueUnchecked(Loc.changeLocNo(Loc.locNo() - 1));
+ }
+ }
+
/// Ensure that all virtual register locations are mapped.
void mapVirtRegs(LDVImpl *LDV);
@@ -1073,23 +1092,14 @@ UserValue::splitLocation(unsigned OldLocNo, ArrayRef<unsigned> NewRegs,
}
}
- // Finally, remove any remaining OldLocNo intervals and OldLocNo itself.
- locations.erase(locations.begin() + OldLocNo);
- LocMapI.goToBegin();
- while (LocMapI.valid()) {
- DbgValueLocation v = LocMapI.value();
- if (v.locNo() == OldLocNo) {
- LLVM_DEBUG(dbgs() << "Erasing [" << LocMapI.start() << ';'
- << LocMapI.stop() << ")\n");
- LocMapI.erase();
- } else {
- // Undef values always have location number UndefLocNo, so don't change
- // locNo in that case. See getLocationNo().
- if (!v.isUndef() && v.locNo() > OldLocNo)
- LocMapI.setValueUnchecked(v.changeLocNo(v.locNo() - 1));
- ++LocMapI;
- }
- }
+ // Finally, remove OldLocNo unless it is still used by some interval in the
+ // locInts map. One case when OldLocNo still is in use is when the register
+ // has been spilled. In such situations the spilled register is kept as a
+ // location until rewriteLocations is called (VirtRegMap is mapping the old
+ // register to the spill slot). So for a while we can have locations that map
+ // to virtual registers that have been removed from both the MachineFunction
+ // and from LiveIntervals.
+ removeLocationIfUnused(OldLocNo);
LLVM_DEBUG({
dbgs() << "Split result: \t";