summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp28
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp140
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp28
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp130
4 files changed, 220 insertions, 106 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 75a63df083a..89cd7a8e3bd 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -1160,7 +1160,9 @@ void CodeViewDebug::calculateRanges(
// Calculate the definition ranges.
for (auto I = Entries.begin(), E = Entries.end(); I != E; ++I) {
const auto &Entry = *I;
- const MachineInstr *DVInst = Entry.getBegin();
+ if (!Entry.isDbgValue())
+ continue;
+ const MachineInstr *DVInst = Entry.getInstr();
assert(DVInst->isDebugValue() && "Invalid History entry");
// FIXME: Find a way to represent constant variables, since they are
// relatively common.
@@ -1215,21 +1217,15 @@ void CodeViewDebug::calculateRanges(
}
// Compute the label range.
- const MCSymbol *Begin = getLabelBeforeInsn(Entry.getBegin());
- const MCSymbol *End = getLabelAfterInsn(Entry.getEnd());
- if (!End) {
- // This range is valid until the next overlapping bitpiece. In the
- // common case, ranges will not be bitpieces, so they will overlap.
- auto J = std::next(I);
- const DIExpression *DIExpr = DVInst->getDebugExpression();
- while (J != E &&
- !DIExpr->fragmentsOverlap(J->getBegin()->getDebugExpression()))
- ++J;
- if (J != E)
- End = getLabelBeforeInsn(J->getBegin());
- else
- End = Asm->getFunctionEnd();
- }
+ const MCSymbol *Begin = getLabelBeforeInsn(Entry.getInstr());
+ const MCSymbol *End;
+ if (Entry.getEndIndex() != DbgValueHistoryMap::NoEntry) {
+ auto &EndingEntry = Entries[Entry.getEndIndex()];
+ End = EndingEntry.isDbgValue()
+ ? getLabelBeforeInsn(EndingEntry.getInstr())
+ : getLabelAfterInsn(EndingEntry.getInstr());
+ } else
+ End = Asm->getFunctionEnd();
// If the last range end is our begin, just extend the last range.
// Otherwise make a new range.
diff --git a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
index 618fee9544d..5dec591c722 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
@@ -9,6 +9,7 @@
#include "llvm/CodeGen/DbgEntityHistoryCalculator.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -30,6 +31,10 @@ using namespace llvm;
#define DEBUG_TYPE "dwarfdebug"
+namespace {
+using EntryIndex = DbgValueHistoryMap::EntryIndex;
+}
+
// If @MI is a DBG_VALUE with debug value described by a
// defined register, returns the number of this register.
// In the other case, returns 0.
@@ -41,33 +46,39 @@ static unsigned isDescribedByReg(const MachineInstr &MI) {
return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
}
-void DbgValueHistoryMap::startEntry(InlinedEntity Var, const MachineInstr &MI) {
+bool DbgValueHistoryMap::startDbgValue(InlinedEntity Var,
+ const MachineInstr &MI,
+ EntryIndex &NewIndex) {
// Instruction range should start with a DBG_VALUE instruction for the
// variable.
assert(MI.isDebugValue() && "not a DBG_VALUE");
auto &Entries = VarEntries[Var];
- if (!Entries.empty() && !Entries.back().isClosed() &&
- Entries.back().getBegin()->isIdenticalTo(MI)) {
+ if (!Entries.empty() && Entries.back().isDbgValue() &&
+ !Entries.back().isClosed() &&
+ Entries.back().getInstr()->isIdenticalTo(MI)) {
LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
- << "\t" << Entries.back().getBegin() << "\t" << MI
+ << "\t" << Entries.back().getInstr() << "\t" << MI
<< "\n");
- return;
+ return false;
}
- Entries.emplace_back(&MI);
+ Entries.emplace_back(&MI, Entry::DbgValue);
+ NewIndex = Entries.size() - 1;
+ return true;
}
-void DbgValueHistoryMap::endEntry(InlinedEntity Var, const MachineInstr &MI) {
+EntryIndex DbgValueHistoryMap::startClobber(InlinedEntity Var,
+ const MachineInstr &MI) {
auto &Entries = VarEntries[Var];
- assert(!Entries.empty() && "No range exists for variable!");
- Entries.back().endEntry(MI);
+ Entries.emplace_back(&MI, Entry::Clobber);
+ return Entries.size() - 1;
}
-void DbgValueHistoryMap::Entry::endEntry(const MachineInstr &MI) {
+void DbgValueHistoryMap::Entry::endEntry(EntryIndex Index) {
// For now, instruction ranges are not allowed to cross basic block
// boundaries.
- assert(Begin->getParent() == MI.getParent());
- assert(!isClosed() && "Range is already closed!");
- End = &MI;
+ assert(isDbgValue() && "Setting end index for non-debug value");
+ assert(!isClosed() && "End index has already been set");
+ EndIndex = Index;
}
unsigned DbgValueHistoryMap::getRegisterForVar(InlinedEntity Var) const {
@@ -77,7 +88,9 @@ unsigned DbgValueHistoryMap::getRegisterForVar(InlinedEntity Var) const {
const auto &Entries = I->second;
if (Entries.empty() || Entries.back().isClosed())
return 0;
- return isDescribedByReg(*Entries.back().getBegin());
+ if (Entries.back().isClobber())
+ return 0;
+ return isDescribedByReg(*Entries.back().getInstr());
}
void DbgLabelInstrMap::addInstr(InlinedEntity Label, const MachineInstr &MI) {
@@ -91,6 +104,12 @@ namespace {
using InlinedEntity = DbgValueHistoryMap::InlinedEntity;
using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedEntity, 1>>;
+// Keeps track of the debug value entries that are currently live for each
+// inlined entity. As the history map entries are stored in a SmallVector, they
+// may be moved at insertion of new entries, so store indices rather than
+// pointers.
+using DbgValueEntriesMap = std::map<InlinedEntity, SmallSet<EntryIndex, 1>>;
+
} // end anonymous namespace
// Claim that @Var is not described by @RegNo anymore.
@@ -116,16 +135,67 @@ static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
VarSet.push_back(Var);
}
+static void clobberRegEntries(InlinedEntity Var, unsigned RegNo,
+ const MachineInstr &ClobberingInstr,
+ DbgValueEntriesMap &LiveEntries,
+ DbgValueHistoryMap &HistMap) {
+ EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr);
+
+ // TODO: Close all preceding live entries that are clobbered by this
+ // instruction.
+ EntryIndex ValueIndex = ClobberIndex - 1;
+ auto &ValueEntry = HistMap.getEntry(Var, ValueIndex);
+ ValueEntry.endEntry(ClobberIndex);
+ LiveEntries[Var].erase(ValueIndex);
+}
+
+/// Add a new debug value for \p Var. Closes all overlapping debug values.
+static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV,
+ RegDescribedVarsMap &RegVars,
+ DbgValueEntriesMap &LiveEntries,
+ DbgValueHistoryMap &HistMap) {
+ // TODO: We should track all registers which this variable is currently
+ // described by.
+
+ if (unsigned PrevReg = HistMap.getRegisterForVar(Var))
+ dropRegDescribedVar(RegVars, PrevReg, Var);
+
+ EntryIndex NewIndex;
+ if (HistMap.startDbgValue(Var, DV, NewIndex)) {
+ // If we have created a new debug value entry, close all preceding
+ // live entries that overlap.
+ SmallVector<EntryIndex, 4> IndicesToErase;
+ const DIExpression *DIExpr = DV.getDebugExpression();
+ for (auto Index : LiveEntries[Var]) {
+ auto &Entry = HistMap.getEntry(Var, Index);
+ assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
+ const MachineInstr &DV = *Entry.getInstr();
+ if (DIExpr->fragmentsOverlap(DV.getDebugExpression())) {
+ IndicesToErase.push_back(Index);
+ Entry.endEntry(NewIndex);
+ }
+ }
+ // Drop all entries that have ended, and mark the new entry as live.
+ for (auto Index : IndicesToErase)
+ LiveEntries[Var].erase(Index);
+ LiveEntries[Var].insert(NewIndex);
+ }
+
+ if (unsigned NewReg = isDescribedByReg(DV))
+ addRegDescribedVar(RegVars, NewReg, Var);
+}
+
// Terminate the location range for variables described by register at
// @I by inserting @ClobberingInstr to their history.
static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
RegDescribedVarsMap::iterator I,
DbgValueHistoryMap &HistMap,
+ DbgValueEntriesMap &LiveEntries,
const MachineInstr &ClobberingInstr) {
// Iterate over all variables described by this register and add this
// instruction to their history, clobbering it.
for (const auto &Var : I->second)
- HistMap.endEntry(Var, ClobberingInstr);
+ clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap);
RegVars.erase(I);
}
@@ -133,11 +203,12 @@ static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
// @RegNo by inserting @ClobberingInstr to their history.
static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo,
DbgValueHistoryMap &HistMap,
+ DbgValueEntriesMap &LiveEntries,
const MachineInstr &ClobberingInstr) {
const auto &I = RegVars.find(RegNo);
if (I == RegVars.end())
return;
- clobberRegisterUses(RegVars, I, HistMap, ClobberingInstr);
+ clobberRegisterUses(RegVars, I, HistMap, LiveEntries, ClobberingInstr);
}
// Returns the first instruction in @MBB which corresponds to
@@ -204,6 +275,7 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
const TargetLowering *TLI = MF->getSubtarget().getTargetLowering();
unsigned SP = TLI->getStackPointerRegisterToSaveRestore();
RegDescribedVarsMap RegVars;
+ DbgValueEntriesMap LiveEntries;
for (const auto &MBB : *MF) {
for (const auto &MI : MBB) {
if (!MI.isDebugInstr()) {
@@ -218,14 +290,15 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
// If this is a virtual register, only clobber it since it doesn't
// have aliases.
if (TRI->isVirtualRegister(MO.getReg()))
- clobberRegisterUses(RegVars, MO.getReg(), DbgValues, MI);
+ clobberRegisterUses(RegVars, MO.getReg(), DbgValues, LiveEntries,
+ MI);
// If this is a register def operand, it may end a debug value
// range.
else {
for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
++AI)
if (ChangingRegs.test(*AI))
- clobberRegisterUses(RegVars, *AI, DbgValues, MI);
+ clobberRegisterUses(RegVars, *AI, DbgValues, LiveEntries, MI);
}
} else if (MO.isRegMask()) {
// If this is a register mask operand, clobber all debug values in
@@ -234,7 +307,7 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
// Don't consider SP to be clobbered by register masks.
if (unsigned(I) != SP && TRI->isPhysicalRegister(I) &&
MO.clobbersPhysReg(I)) {
- clobberRegisterUses(RegVars, I, DbgValues, MI);
+ clobberRegisterUses(RegVars, I, DbgValues, LiveEntries, MI);
}
}
}
@@ -252,13 +325,7 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
"Expected inlined-at fields to agree");
InlinedEntity Var(RawVar, MI.getDebugLoc()->getInlinedAt());
- if (unsigned PrevReg = DbgValues.getRegisterForVar(Var))
- dropRegDescribedVar(RegVars, PrevReg, Var);
-
- DbgValues.startEntry(Var, MI);
-
- if (unsigned NewReg = isDescribedByReg(MI))
- addRegDescribedVar(RegVars, NewReg, Var);
+ handleNewDebugValue(Var, MI, RegVars, LiveEntries, DbgValues);
} else if (MI.isDebugLabel()) {
assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL instruction!");
const DILabel *RawLabel = MI.getDebugLabel();
@@ -280,7 +347,8 @@ void llvm::calculateDbgEntityHistory(const MachineFunction *MF,
auto CurElem = I++; // CurElem can be erased below.
if (TRI->isVirtualRegister(CurElem->first) ||
ChangingRegs.test(CurElem->first))
- clobberRegisterUses(RegVars, CurElem, DbgValues, MBB.back());
+ clobberRegisterUses(RegVars, CurElem, DbgValues, LiveEntries,
+ MBB.back());
}
}
}
@@ -306,10 +374,20 @@ LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const {
dbgs() << " --\n";
- for (const auto &Entry : Entries) {
- dbgs() << " Begin: " << *Entry.getBegin();
- if (Entry.getEnd())
- dbgs() << " End : " << *Entry.getEnd();
+ for (const auto &E : enumerate(Entries)) {
+ const auto &Entry = E.value();
+ dbgs() << " Entry[" << E.index() << "]: ";
+ if (Entry.isDbgValue())
+ dbgs() << "Debug value\n";
+ else
+ dbgs() << "Clobber\n";
+ dbgs() << " Instr: " << *Entry.getInstr();
+ if (Entry.isDbgValue()) {
+ if (Entry.getEndIndex() == NoEntry)
+ dbgs() << " - Valid until end of function\n";
+ else
+ dbgs() << " - Closed by Entry[" << Entry.getEndIndex() << "]\n";
+ }
dbgs() << "\n";
}
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 00e4cea3135..f24dbf148e7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -229,31 +229,35 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
// However, we currently do not emit debug values for constant arguments
// directly at the start of the function, so this code is still useful.
const DILocalVariable *DIVar =
- Entries.front().getBegin()->getDebugVariable();
+ Entries.front().getInstr()->getDebugVariable();
if (DIVar->isParameter() &&
getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
- if (!IsDescribedByReg(Entries.front().getBegin()))
- LabelsBeforeInsn[Entries.front().getBegin()] = Asm->getFunctionBegin();
- if (Entries.front().getBegin()->getDebugExpression()->isFragment()) {
+ if (!IsDescribedByReg(Entries.front().getInstr()))
+ LabelsBeforeInsn[Entries.front().getInstr()] = Asm->getFunctionBegin();
+ if (Entries.front().getInstr()->getDebugExpression()->isFragment()) {
// Mark all non-overlapping initial fragments.
for (auto I = Entries.begin(); I != Entries.end(); ++I) {
- const DIExpression *Fragment = I->getBegin()->getDebugExpression();
+ if (!I->isDbgValue())
+ continue;
+ const DIExpression *Fragment = I->getInstr()->getDebugExpression();
if (std::any_of(Entries.begin(), I,
[&](DbgValueHistoryMap::Entry Pred) {
- return Fragment->fragmentsOverlap(
- Pred.getBegin()->getDebugExpression());
+ return Pred.isDbgValue() &&
+ Fragment->fragmentsOverlap(
+ Pred.getInstr()->getDebugExpression());
}))
break;
- if (!IsDescribedByReg(I->getBegin()))
- LabelsBeforeInsn[I->getBegin()] = Asm->getFunctionBegin();
+ if (!IsDescribedByReg(I->getInstr()))
+ LabelsBeforeInsn[I->getInstr()] = Asm->getFunctionBegin();
}
}
}
for (const auto &Entry : Entries) {
- requestLabelBeforeInsn(Entry.getBegin());
- if (Entry.getEnd())
- requestLabelAfterInsn(Entry.getEnd());
+ if (Entry.isDbgValue())
+ requestLabelBeforeInsn(Entry.getInstr());
+ else
+ requestLabelAfterInsn(Entry.getInstr());
}
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 07232b5082a..c0b0d0c9273 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1095,67 +1095,92 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
}
/// Build the location list for all DBG_VALUEs in the function that
-/// describe the same variable. If the ranges of several independent
-/// fragments of the same variable overlap partially, split them up and
-/// combine the ranges. The resulting DebugLocEntries are will have
+/// describe the same variable. The resulting DebugLocEntries will have
/// strict monotonically increasing begin addresses and will never
/// overlap.
//
+// See the definition of DbgValueHistoryMap::Entry for an explanation of the
+// different kinds of history map entries. One thing to be aware of is that if
+// a debug value is ended by another entry (rather than being valid until the
+// end of the function), that entry's instruction may or may not be included in
+// the range, depending on if the entry is a clobbering entry (it has an
+// instruction that clobbers one or more preceding locations), or if it is an
+// (overlapping) debug value entry. This distinction can be seen in the example
+// below. The first debug value is ended by the clobbering entry 2, and the
+// second and third debug values are ended by the overlapping debug value entry
+// 4.
+//
// Input:
//
-// Ranges History [var, loc, fragment ofs size]
-// 0 | [x, (reg0, fragment 0, 32)]
-// 1 | | [x, (reg1, fragment 32, 32)] <- IsFragmentOfPrevEntry
-// 2 | | ...
-// 3 | [clobber reg0]
-// 4 [x, (mem, fragment 0, 64)] <- overlapping with both previous fragments of
-// x.
+// History map entries [type, end index, mi]
+//
+// 0 | [DbgValue, 2, DBG_VALUE $reg0, [...] (fragment 0, 32)]
+// 1 | | [DbgValue, 4, DBG_VALUE $reg1, [...] (fragment 32, 32)]
+// 2 | | [Clobber, $reg0 = [...], -, -]
+// 3 | | [DbgValue, 4, DBG_VALUE 123, [...] (fragment 64, 32)]
+// 4 [DbgValue, ~0, DBG_VALUE @g, [...] (fragment 0, 96)]
//
-// Output:
+// Output [start, end) [Value...]:
//
-// [0-1] [x, (reg0, fragment 0, 32)]
-// [1-3] [x, (reg0, fragment 0, 32), (reg1, fragment 32, 32)]
-// [3-4] [x, (reg1, fragment 32, 32)]
-// [4- ] [x, (mem, fragment 0, 64)]
+// [0-1) [(reg0, fragment 0, 32)]
+// [1-3) [(reg0, fragment 0, 32), (reg1, fragment 32, 32)]
+// [3-4) [(reg1, fragment 32, 32), (123, fragment 64, 32)]
+// [4-) [(@g, fragment 0, 96)]
void DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
const DbgValueHistoryMap::Entries &Entries) {
- SmallVector<DebugLocEntry::Value, 4> OpenRanges;
-
- for (auto EI = Entries.begin(), EE = Entries.end(); EI != EE; ++EI) {
- const MachineInstr *Begin = EI->getBegin();
- const MachineInstr *End = EI->getEnd();
- assert(Begin->isDebugValue() && "Invalid History entry");
-
- // Check if a variable is inaccessible in this range.
- if (Begin->getNumOperands() > 1 &&
- Begin->getOperand(0).isReg() && !Begin->getOperand(0).getReg()) {
- OpenRanges.clear();
- continue;
+ using OpenRange =
+ std::pair<DbgValueHistoryMap::EntryIndex, DebugLocEntry::Value>;
+ SmallVector<OpenRange, 4> OpenRanges;
+
+ for (auto EB = Entries.begin(), EI = EB, EE = Entries.end(); EI != EE; ++EI) {
+ const MachineInstr *Instr = EI->getInstr();
+
+ if (EI->isDbgValue()) {
+ // Check if a variable is inaccessible in this range.
+ // TODO: This should only truncate open ranges that are overlapping.
+ if (Instr->getNumOperands() > 1 &&
+ Instr->getOperand(0).isReg() && !Instr->getOperand(0).getReg()) {
+ OpenRanges.clear();
+ continue;
+ }
}
- // If this debug value overlaps with any open ranges, truncate them.
- const DIExpression *DIExpr = Begin->getDebugExpression();
- auto Last = remove_if(OpenRanges, [&](DebugLocEntry::Value R) {
- return DIExpr->fragmentsOverlap(R.getExpression());
- });
+ // Remove all values that are no longer live.
+ size_t Index = std::distance(EB, EI);
+ auto Last =
+ remove_if(OpenRanges, [&](OpenRange &R) { return R.first <= Index; });
OpenRanges.erase(Last, OpenRanges.end());
- const MCSymbol *StartLabel = getLabelBeforeInsn(Begin);
- assert(StartLabel && "Forgot label before DBG_VALUE starting a range!");
+ // If we are dealing with a clobbering entry, this iteration will result in
+ // a location list entry starting after the clobbering instruction.
+ const MCSymbol *StartLabel =
+ EI->isClobber() ? getLabelAfterInsn(Instr) : getLabelBeforeInsn(Instr);
+ assert(StartLabel &&
+ "Forgot label before/after instruction starting a range!");
const MCSymbol *EndLabel;
- if (End != nullptr)
- EndLabel = getLabelAfterInsn(End);
- else if (std::next(EI) == Entries.end())
+ if (std::next(EI) == Entries.end())
EndLabel = Asm->getFunctionEnd();
+ else if (std::next(EI)->isClobber())
+ EndLabel = getLabelAfterInsn(std::next(EI)->getInstr());
else
- EndLabel = getLabelBeforeInsn(std::next(EI)->getBegin());
+ EndLabel = getLabelBeforeInsn(std::next(EI)->getInstr());
assert(EndLabel && "Forgot label after instruction ending a range!");
- LLVM_DEBUG(dbgs() << "DotDebugLoc: " << *Begin << "\n");
+ if (EI->isDbgValue())
+ LLVM_DEBUG(dbgs() << "DotDebugLoc: " << *Instr << "\n");
- auto Value = getDebugLocValue(Begin);
- OpenRanges.push_back(Value);
+ // If this history map entry has a debug value, add that to the list of
+ // open ranges.
+ if (EI->isDbgValue()) {
+ auto Value = getDebugLocValue(Instr);
+ OpenRanges.emplace_back(EI->getEndIndex(), Value);
+ }
+
+ // Location list entries with empty location descriptions are redundant
+ // information in DWARF, so do not emit those.
+ if (OpenRanges.empty())
+ continue;
// Omit entries with empty ranges as they do not have any effect in DWARF.
if (StartLabel == EndLabel) {
@@ -1163,7 +1188,10 @@ void DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
continue;
}
- DebugLoc.emplace_back(StartLabel, EndLabel, OpenRanges);
+ SmallVector<DebugLocEntry::Value, 4> Values;
+ for (auto &R : OpenRanges)
+ Values.push_back(R.second);
+ DebugLoc.emplace_back(StartLabel, EndLabel, Values);
// Attempt to coalesce the ranges of two otherwise identical
// DebugLocEntries.
@@ -1292,15 +1320,23 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
DbgVariable *RegVar = cast<DbgVariable>(createConcreteEntity(TheCU,
*Scope, LocalVar, IV.second));
- const MachineInstr *MInsn = HistoryMapEntries.front().getBegin();
+ const MachineInstr *MInsn = HistoryMapEntries.front().getInstr();
assert(MInsn->isDebugValue() && "History must begin with debug value");
// Check if there is a single DBG_VALUE, valid throughout the var's scope.
- if (HistoryMapEntries.size() == 1 &&
- validThroughout(LScopes, MInsn, HistoryMapEntries.front().getEnd())) {
- RegVar->initializeDbgValue(MInsn);
- continue;
+ // If the history map contains a single debug value, there may be an
+ // additional entry which clobbers the debug value.
+ bool SingleValueWithClobber =
+ HistoryMapEntries.size() == 2 && HistoryMapEntries[1].isClobber();
+ if (HistoryMapEntries.size() == 1 || SingleValueWithClobber) {
+ const auto *End =
+ SingleValueWithClobber ? HistoryMapEntries[1].getInstr() : nullptr;
+ if (validThroughout(LScopes, MInsn, End)) {
+ RegVar->initializeDbgValue(MInsn);
+ continue;
+ }
}
+
// Do not emit location lists if .debug_loc secton is disabled.
if (!useLocSection())
continue;
OpenPOWER on IntegriCloud