[llvm] 429c6ec - Revert "[DebugInfo] Add DWARF emission for DBG_VALUE_LIST"
Stephen Tozer via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 10 06:35:49 PST 2021
Author: Stephen Tozer
Date: 2021-03-10T14:35:33Z
New Revision: 429c6ecbb302e2beedd8694378ae5be456206209
URL: https://github.com/llvm/llvm-project/commit/429c6ecbb302e2beedd8694378ae5be456206209
DIFF: https://github.com/llvm/llvm-project/commit/429c6ecbb302e2beedd8694378ae5be456206209.diff
LOG: Revert "[DebugInfo] Add DWARF emission for DBG_VALUE_LIST"
This reverts commit 0da27ba56c9f5e3f534a65401962301189eac342.
This revision was causing an error on the sanitizer-x86_64-linux-autoconf build.
Added:
Modified:
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
Removed:
llvm/test/DebugInfo/X86/dbg_value_list_clobbers.mir
llvm/test/DebugInfo/X86/dbg_value_list_emission.mir
################################################################################
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index d55747691ec5..dbe7028b1a48 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -918,6 +918,9 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
OS << V->getName();
OS << " <- ";
+ // The second operand is only an offset if it's an immediate.
+ bool MemLoc = MI->isIndirectDebugValue();
+ auto Offset = StackOffset::getFixed(MemLoc ? MI->getOperand(1).getImm() : 0);
const DIExpression *Expr = MI->getDebugExpression();
if (Expr->getNumElements()) {
OS << '[';
@@ -931,71 +934,56 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
}
// Register or immediate value. Register 0 means undef.
- for (const MachineOperand &Op : MI->debug_operands()) {
- if (&Op != MI->debug_operands().begin())
- OS << ", ";
- switch (Op.getType()) {
- case MachineOperand::MO_FPImmediate: {
- APFloat APF = APFloat(Op.getFPImm()->getValueAPF());
- if (Op.getFPImm()->getType()->isFloatTy()) {
- OS << (double)APF.convertToFloat();
- } else if (Op.getFPImm()->getType()->isDoubleTy()) {
- OS << APF.convertToDouble();
- } else {
- // There is no good way to print long double. Convert a copy to
- // double. Ah well, it's only a comment.
- bool ignored;
- APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
- &ignored);
- OS << "(long double) " << APF.convertToDouble();
- }
- break;
- }
- case MachineOperand::MO_Immediate: {
- OS << Op.getImm();
- break;
+ if (MI->getDebugOperand(0).isFPImm()) {
+ APFloat APF = APFloat(MI->getDebugOperand(0).getFPImm()->getValueAPF());
+ if (MI->getDebugOperand(0).getFPImm()->getType()->isFloatTy()) {
+ OS << (double)APF.convertToFloat();
+ } else if (MI->getDebugOperand(0).getFPImm()->getType()->isDoubleTy()) {
+ OS << APF.convertToDouble();
+ } else {
+ // There is no good way to print long double. Convert a copy to
+ // double. Ah well, it's only a comment.
+ bool ignored;
+ APF.convert(APFloat::IEEEdouble(), APFloat::rmNearestTiesToEven,
+ &ignored);
+ OS << "(long double) " << APF.convertToDouble();
}
- case MachineOperand::MO_CImmediate: {
- Op.getCImm()->getValue().print(OS, false /*isSigned*/);
- break;
+ } else if (MI->getDebugOperand(0).isImm()) {
+ OS << MI->getDebugOperand(0).getImm();
+ } else if (MI->getDebugOperand(0).isCImm()) {
+ MI->getDebugOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
+ } else if (MI->getDebugOperand(0).isTargetIndex()) {
+ auto Op = MI->getDebugOperand(0);
+ OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
+ // NOTE: Want this comment at start of line, don't emit with AddComment.
+ AP.OutStreamer->emitRawComment(OS.str());
+ return true;
+ } else {
+ Register Reg;
+ if (MI->getDebugOperand(0).isReg()) {
+ Reg = MI->getDebugOperand(0).getReg();
+ } else {
+ assert(MI->getDebugOperand(0).isFI() && "Unknown operand type");
+ const TargetFrameLowering *TFI = AP.MF->getSubtarget().getFrameLowering();
+ Offset += TFI->getFrameIndexReference(
+ *AP.MF, MI->getDebugOperand(0).getIndex(), Reg);
+ MemLoc = true;
}
- case MachineOperand::MO_TargetIndex: {
- OS << "!target-index(" << Op.getIndex() << "," << Op.getOffset() << ")";
+ if (Reg == 0) {
+ // Suppress offset, it is not meaningful here.
+ OS << "undef";
// NOTE: Want this comment at start of line, don't emit with AddComment.
AP.OutStreamer->emitRawComment(OS.str());
- break;
- }
- case MachineOperand::MO_Register:
- case MachineOperand::MO_FrameIndex: {
- Register Reg;
- Optional<StackOffset> Offset;
- if (Op.isReg()) {
- Reg = Op.getReg();
- } else {
- const TargetFrameLowering *TFI =
- AP.MF->getSubtarget().getFrameLowering();
- Offset = TFI->getFrameIndexReference(*AP.MF, Op.getIndex(), Reg);
- }
- if (!Reg) {
- // Suppress offset, it is not meaningful here.
- OS << "undef";
- break;
- }
- // The second operand is only an offset if it's an immediate.
- if (MI->isIndirectDebugValue())
- Offset = StackOffset::getFixed(MI->getDebugOffset().getImm());
- if (Offset)
- OS << '[';
- OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
- if (Offset)
- OS << '+' << Offset->getFixed() << ']';
- break;
- }
- default:
- llvm_unreachable("Unknown operand type");
+ return true;
}
+ if (MemLoc)
+ OS << '[';
+ OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
}
+ if (MemLoc)
+ OS << '+' << Offset.getFixed() << ']';
+
// NOTE: Want this comment at start of line, don't emit with AddComment.
AP.OutStreamer->emitRawComment(OS.str());
return true;
diff --git a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
index bb24f1414ef1..a30720cc20ff 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp
@@ -37,6 +37,22 @@ 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.
+static Register isDescribedByReg(const MachineInstr &MI) {
+ assert(MI.isDebugValue());
+ assert(MI.getNumOperands() == 4);
+ // If the location of variable is an entry value (DW_OP_LLVM_entry_value)
+ // do not consider it as a register location.
+ if (MI.getDebugExpression()->isEntryValue())
+ return 0;
+ // If location of variable is described using a register (directly or
+ // indirectly), this register is always a first operand.
+ return MI.getDebugOperand(0).isReg() ? MI.getDebugOperand(0).getReg()
+ : Register();
+}
+
void InstructionOrdering::initialize(const MachineFunction &MF) {
// We give meta instructions the same ordinal as the preceding instruction
// because this class is written for the task of comparing positions of
@@ -317,44 +333,24 @@ static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
}
/// Create a clobbering entry and end all open debug value entries
-/// for \p Var that are described by \p RegNo using that entry. Inserts into \p
-/// FellowRegisters the set of Registers that were also used to describe \p Var
-/// alongside \p RegNo.
+/// for \p Var that are described by \p RegNo using that entry.
static void clobberRegEntries(InlinedEntity Var, unsigned RegNo,
const MachineInstr &ClobberingInstr,
DbgValueEntriesMap &LiveEntries,
- DbgValueHistoryMap &HistMap,
- SmallVectorImpl<Register> &FellowRegisters) {
+ DbgValueHistoryMap &HistMap) {
EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr);
+
// Close all entries whose values are described by the register.
SmallVector<EntryIndex, 4> IndicesToErase;
- // If a given register appears in a live DBG_VALUE_LIST for Var alongside the
- // clobbered register, and never appears in a live DBG_VALUE* for Var without
- // the clobbered register, then it is no longer linked to the variable.
- SmallSet<Register, 4> MaybeRemovedRegisters;
- SmallSet<Register, 4> KeepRegisters;
for (auto Index : LiveEntries[Var]) {
auto &Entry = HistMap.getEntry(Var, Index);
assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries");
- if (Entry.getInstr()->isDebugEntryValue())
- continue;
- if (Entry.getInstr()->hasDebugOperandForReg(RegNo)) {
+ if (isDescribedByReg(*Entry.getInstr()) == RegNo) {
IndicesToErase.push_back(Index);
Entry.endEntry(ClobberIndex);
- for (auto &MO : Entry.getInstr()->debug_operands())
- if (MO.isReg() && MO.getReg() && MO.getReg() != RegNo)
- MaybeRemovedRegisters.insert(MO.getReg());
- } else {
- for (auto &MO : Entry.getInstr()->debug_operands())
- if (MO.isReg() && MO.getReg())
- KeepRegisters.insert(MO.getReg());
}
}
- for (Register Reg : MaybeRemovedRegisters)
- if (!KeepRegisters.contains(Reg))
- FellowRegisters.push_back(Reg);
-
// Drop all entries that have ended.
for (auto Index : IndicesToErase)
LiveEntries[Var].erase(Index);
@@ -382,24 +378,17 @@ static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV,
IndicesToErase.push_back(Index);
Entry.endEntry(NewIndex);
}
- if (!DV.isDebugEntryValue())
- for (const MachineOperand &Op : DV.debug_operands())
- if (Op.isReg() && Op.getReg())
- TrackedRegs[Op.getReg()] |= !Overlaps;
+ if (Register Reg = isDescribedByReg(DV))
+ TrackedRegs[Reg] |= !Overlaps;
}
// If the new debug value is described by a register, add tracking of
// that register if it is not already tracked.
- if (!DV.isDebugEntryValue()) {
- for (const MachineOperand &Op : DV.debug_operands()) {
- if (Op.isReg() && Op.getReg()) {
- Register NewReg = Op.getReg();
- if (!TrackedRegs.count(NewReg))
- addRegDescribedVar(RegVars, NewReg, Var);
- LiveEntries[Var].insert(NewIndex);
- TrackedRegs[NewReg] = true;
- }
- }
+ if (Register NewReg = isDescribedByReg(DV)) {
+ if (!TrackedRegs.count(NewReg))
+ addRegDescribedVar(RegVars, NewReg, Var);
+ LiveEntries[Var].insert(NewIndex);
+ TrackedRegs[NewReg] = true;
}
// Drop tracking of registers that are no longer used.
@@ -422,16 +411,9 @@ static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
DbgValueEntriesMap &LiveEntries,
const MachineInstr &ClobberingInstr) {
// Iterate over all variables described by this register and add this
- // instruction to their history, clobbering it. All registers that also
- // describe the clobbered variables (i.e. in variadic debug values) will have
- // those Variables removed from their DescribedVars.
- for (const auto &Var : I->second) {
- SmallVector<Register, 4> FellowRegisters;
- clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap,
- FellowRegisters);
- for (Register RegNo : FellowRegisters)
- dropRegDescribedVar(RegVars, RegNo, Var);
- }
+ // instruction to their history, clobbering it.
+ for (const auto &Var : I->second)
+ clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap);
RegVars.erase(I);
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index b9a9e1cfaee0..68a4bfba42a7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -35,8 +35,7 @@ Optional<DbgVariableLocation>
DbgVariableLocation::extractFromMachineInstruction(
const MachineInstr &Instruction) {
DbgVariableLocation Location;
- // Variables calculated from multiple locations can't be represented here.
- if (Instruction.getNumDebugOperands() != 1)
+ if (!Instruction.isDebugValue())
return None;
if (!Instruction.getDebugOperand(0).isReg())
return None;
@@ -47,15 +46,6 @@ DbgVariableLocation::extractFromMachineInstruction(
int64_t Offset = 0;
const DIExpression *DIExpr = Instruction.getDebugExpression();
auto Op = DIExpr->expr_op_begin();
- // We can handle a DBG_VALUE_LIST iff it has exactly one location operand that
- // appears exactly once at the start of the expression.
- if (Instruction.isDebugValueList()) {
- if (Instruction.getNumDebugOperands() == 1 &&
- Op->getOp() == dwarf::DW_OP_LLVM_arg)
- ++Op;
- else
- return None;
- }
while (Op != DIExpr->expr_op_end()) {
switch (Op->getOp()) {
case dwarf::DW_OP_constu: {
@@ -271,8 +261,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
continue;
auto IsDescribedByReg = [](const MachineInstr *MI) {
- return any_of(MI->debug_operands(),
- [](auto &MO) { return MO.isReg() && MO.getReg(); });
+ return MI->getDebugOperand(0).isReg() && MI->getDebugOperand(0).getReg();
};
// The first mention of a function argument gets the CurrentFnBegin label,
diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 525b839d67a0..36278f2e9e2d 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -34,10 +34,10 @@ struct TargetIndexLocation {
}
};
-/// A single location or constant within a variable location description, with
-/// either a single entry (with an optional DIExpression) used for a DBG_VALUE,
-/// or a list of entries used for a DBG_VALUE_LIST.
-class DbgValueLocEntry {
+/// A single location or constant.
+class DbgValueLoc {
+ /// Any complex address location expression for this DbgValueLoc.
+ const DIExpression *Expression;
/// Type of entry that this represents.
enum EntryType {
@@ -64,16 +64,24 @@ class DbgValueLocEntry {
};
public:
- DbgValueLocEntry(int64_t i) : EntryKind(E_Integer) { Constant.Int = i; }
- DbgValueLocEntry(const ConstantFP *CFP) : EntryKind(E_ConstantFP) {
+ DbgValueLoc(const DIExpression *Expr, int64_t i)
+ : Expression(Expr), EntryKind(E_Integer) {
+ Constant.Int = i;
+ }
+ DbgValueLoc(const DIExpression *Expr, const ConstantFP *CFP)
+ : Expression(Expr), EntryKind(E_ConstantFP) {
Constant.CFP = CFP;
}
- DbgValueLocEntry(const ConstantInt *CIP) : EntryKind(E_ConstantInt) {
+ DbgValueLoc(const DIExpression *Expr, const ConstantInt *CIP)
+ : Expression(Expr), EntryKind(E_ConstantInt) {
Constant.CIP = CIP;
}
- DbgValueLocEntry(MachineLocation Loc) : EntryKind(E_Location), Loc(Loc) {}
- DbgValueLocEntry(TargetIndexLocation Loc)
- : EntryKind(E_TargetIndexLocation), TIL(Loc) {}
+ DbgValueLoc(const DIExpression *Expr, MachineLocation Loc)
+ : Expression(Expr), EntryKind(E_Location), Loc(Loc) {
+ assert(cast<DIExpression>(Expr)->isValid());
+ }
+ DbgValueLoc(const DIExpression *Expr, TargetIndexLocation Loc)
+ : Expression(Expr), EntryKind(E_TargetIndexLocation), TIL(Loc) {}
bool isLocation() const { return EntryKind == E_Location; }
bool isTargetIndexLocation() const {
@@ -87,7 +95,11 @@ class DbgValueLocEntry {
const ConstantInt *getConstantInt() const { return Constant.CIP; }
MachineLocation getLoc() const { return Loc; }
TargetIndexLocation getTargetIndexLocation() const { return TIL; }
- friend bool operator==(const DbgValueLocEntry &, const DbgValueLocEntry &);
+ bool isFragment() const { return getExpression()->isFragment(); }
+ bool isEntryVal() const { return getExpression()->isEntryValue(); }
+ const DIExpression *getExpression() const { return Expression; }
+ friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
+ friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void dump() const {
if (isLocation()) {
@@ -99,77 +111,6 @@ class DbgValueLocEntry {
Constant.CIP->dump();
else if (isConstantFP())
Constant.CFP->dump();
- }
-#endif
-};
-
-/// The location of a single variable, composed of an expression and 0 or more
-/// DbgValueLocEntries.
-class DbgValueLoc {
- /// Any complex address location expression for this DbgValueLoc.
- const DIExpression *Expression;
-
- SmallVector<DbgValueLocEntry, 2> ValueLocEntries;
-
- bool IsVariadic;
-
-public:
- DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs)
- : Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
- IsVariadic(true) {
-#ifndef NDEBUG
- // Currently, DBG_VALUE_VAR expressions must use stack_value.
- assert(Expr && Expr->isValid() &&
- is_contained(Locs, dwarf::DW_OP_stack_value));
- for (DbgValueLocEntry &Entry : ValueLocEntries) {
- assert(!Entry.isConstantFP() && !Entry.isConstantInt() &&
- "Constant values should only be present in non-variadic "
- "DBG_VALUEs.");
- }
-#endif
- }
-
- DbgValueLoc(const DIExpression *Expr, ArrayRef<DbgValueLocEntry> Locs,
- bool IsVariadic)
- : Expression(Expr), ValueLocEntries(Locs.begin(), Locs.end()),
- IsVariadic(IsVariadic) {
-#ifndef NDEBUG
- assert(cast<DIExpression>(Expr)->isValid() ||
- !any_of(Locs, [](auto LE) { return LE.isLocation(); }));
- if (!IsVariadic) {
- assert(ValueLocEntries.size() == 1);
- } else {
- // Currently, DBG_VALUE_VAR expressions must use stack_value.
- assert(Expr && Expr->isValid() &&
- is_contained(Expr->getElements(), dwarf::DW_OP_stack_value));
- for (DbgValueLocEntry &Entry : ValueLocEntries) {
- assert(!Entry.isConstantFP() && !Entry.isConstantInt() &&
- "Constant values should only be present in non-variadic "
- "DBG_VALUEs.");
- }
- }
-#endif
- }
-
- DbgValueLoc(const DIExpression *Expr, DbgValueLocEntry Loc)
- : Expression(Expr), ValueLocEntries(1, Loc), IsVariadic(false) {
- assert(((Expr && Expr->isValid()) || !Loc.isLocation()) &&
- "DBG_VALUE with a machine location must have a valid expression.");
- }
-
- bool isFragment() const { return getExpression()->isFragment(); }
- bool isEntryVal() const { return getExpression()->isEntryValue(); }
- bool isVariadic() const { return IsVariadic; }
- const DIExpression *getExpression() const { return Expression; }
- const ArrayRef<DbgValueLocEntry> getLocEntries() const {
- return ValueLocEntries;
- }
- friend bool operator==(const DbgValueLoc &, const DbgValueLoc &);
- friend bool operator<(const DbgValueLoc &, const DbgValueLoc &);
-#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
- LLVM_DUMP_METHOD void dump() const {
- for (DbgValueLocEntry DV : ValueLocEntries)
- DV.dump();
if (Expression)
Expression->dump();
}
@@ -239,32 +180,30 @@ class DebugLocEntry {
DwarfCompileUnit &TheCU);
};
-/// Compare two DbgValueLocEntries for equality.
-inline bool operator==(const DbgValueLocEntry &A, const DbgValueLocEntry &B) {
+/// Compare two DbgValueLocs for equality.
+inline bool operator==(const DbgValueLoc &A,
+ const DbgValueLoc &B) {
if (A.EntryKind != B.EntryKind)
return false;
+ if (A.Expression != B.Expression)
+ return false;
+
switch (A.EntryKind) {
- case DbgValueLocEntry::E_Location:
+ case DbgValueLoc::E_Location:
return A.Loc == B.Loc;
- case DbgValueLocEntry::E_TargetIndexLocation:
+ case DbgValueLoc::E_TargetIndexLocation:
return A.TIL == B.TIL;
- case DbgValueLocEntry::E_Integer:
+ case DbgValueLoc::E_Integer:
return A.Constant.Int == B.Constant.Int;
- case DbgValueLocEntry::E_ConstantFP:
+ case DbgValueLoc::E_ConstantFP:
return A.Constant.CFP == B.Constant.CFP;
- case DbgValueLocEntry::E_ConstantInt:
+ case DbgValueLoc::E_ConstantInt:
return A.Constant.CIP == B.Constant.CIP;
}
llvm_unreachable("unhandled EntryKind");
}
-/// Compare two DbgValueLocs for equality.
-inline bool operator==(const DbgValueLoc &A, const DbgValueLoc &B) {
- return A.ValueLocEntries == B.ValueLocEntries &&
- A.Expression == B.Expression && A.IsVariadic == B.IsVariadic;
-}
-
/// Compare two fragments based on their offset.
inline bool operator<(const DbgValueLoc &A,
const DbgValueLoc &B) {
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index cba36ab584e9..3d378df287ac 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -728,95 +728,36 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
// Check if variable has a single location description.
if (auto *DVal = DV.getValueLoc()) {
- if (!DVal->isVariadic()) {
- const DbgValueLocEntry *Entry = DVal->getLocEntries().begin();
- if (Entry->isLocation()) {
- addVariableAddress(DV, *VariableDie, Entry->getLoc());
- } else if (Entry->isInt()) {
- auto *Expr = DV.getSingleExpression();
- if (Expr && Expr->getNumElements()) {
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
- // If there is an expression, emit raw unsigned bytes.
- DwarfExpr.addFragmentOffset(Expr);
- DwarfExpr.addUnsignedConstant(Entry->getInt());
- DwarfExpr.addExpression(Expr);
- addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
- if (DwarfExpr.TagOffset)
- addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
- dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
- } else
- addConstantValue(*VariableDie, Entry->getInt(), DV.getType());
- } else if (Entry->isConstantFP()) {
- addConstantFPValue(*VariableDie, Entry->getConstantFP());
- } else if (Entry->isConstantInt()) {
- addConstantValue(*VariableDie, Entry->getConstantInt(), DV.getType());
- } else if (Entry->isTargetIndexLocation()) {
+ if (DVal->isLocation())
+ addVariableAddress(DV, *VariableDie, DVal->getLoc());
+ else if (DVal->isInt()) {
+ auto *Expr = DV.getSingleExpression();
+ if (Expr && Expr->getNumElements()) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
- const DIBasicType *BT = dyn_cast<DIBasicType>(
- static_cast<const Metadata *>(DV.getVariable()->getType()));
- DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
+ // If there is an expression, emit raw unsigned bytes.
+ DwarfExpr.addFragmentOffset(Expr);
+ DwarfExpr.addUnsignedConstant(DVal->getInt());
+ DwarfExpr.addExpression(Expr);
addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
- }
- return VariableDie;
+ if (DwarfExpr.TagOffset)
+ addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset,
+ dwarf::DW_FORM_data1, *DwarfExpr.TagOffset);
+
+ } else
+ addConstantValue(*VariableDie, DVal->getInt(), DV.getType());
+ } else if (DVal->isConstantFP()) {
+ addConstantFPValue(*VariableDie, DVal->getConstantFP());
+ } else if (DVal->isConstantInt()) {
+ addConstantValue(*VariableDie, DVal->getConstantInt(), DV.getType());
+ } else if (DVal->isTargetIndexLocation()) {
+ DIELoc *Loc = new (DIEValueAllocator) DIELoc;
+ DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
+ const DIBasicType *BT = dyn_cast<DIBasicType>(
+ static_cast<const Metadata *>(DV.getVariable()->getType()));
+ DwarfDebug::emitDebugLocValue(*Asm, BT, *DVal, DwarfExpr);
+ addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
}
- // If any of the location entries are registers with the value 0, then the
- // location is undefined.
- if (any_of(DVal->getLocEntries(), [](const DbgValueLocEntry &Entry) {
- return Entry.isLocation() && !Entry.getLoc().getReg();
- }))
- return VariableDie;
- const DIExpression *Expr = DV.getSingleExpression();
- assert(Expr && "Variadic Debug Value must have an Expression.");
- DIELoc *Loc = new (DIEValueAllocator) DIELoc;
- DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
- DwarfExpr.addFragmentOffset(Expr);
- DIExpressionCursor Cursor(Expr);
- const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
-
- // Declare the TargetMachine locally so we don't need to capture `this` in
- // the lambda.
- TargetMachine &TM = Asm->TM;
- auto AddEntry = [&DwarfExpr, &TRI, &TM](const DbgValueLocEntry &Entry,
- DIExpressionCursor &Cursor) {
- if (Entry.isLocation()) {
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor,
- Entry.getLoc().getReg()))
- return false;
- } else if (Entry.isInt()) {
- // If there is an expression, emit raw unsigned bytes.
- DwarfExpr.addUnsignedConstant(Entry.getInt());
- } else if (Entry.isConstantFP()) {
- APInt RawBytes = Entry.getConstantFP()->getValueAPF().bitcastToAPInt();
- DwarfExpr.addUnsignedConstant(RawBytes);
- } else if (Entry.isConstantInt()) {
- APInt RawBytes = Entry.getConstantInt()->getValue();
- DwarfExpr.addUnsignedConstant(RawBytes);
- } else if (Entry.isTargetIndexLocation()) {
- TargetIndexLocation Loc = Entry.getTargetIndexLocation();
- // TODO TargetIndexLocation is a target-independent. Currently only the
- // WebAssembly-specific encoding is supported.
- assert(TM.getTargetTriple().isWasm());
- DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
- } else {
- llvm_unreachable("Unsupported Entry type.");
- }
- return true;
- };
-
- DwarfExpr.addExpression(
- std::move(Cursor),
- [&AddEntry, &DVal](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
- return AddEntry(DVal->getLocEntries()[Idx], Cursor);
- });
-
- // Now attach the location information to the DIE.
- addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
- if (DwarfExpr.TagOffset)
- addUInt(*VariableDie, dwarf::DW_AT_LLVM_tag_offset, dwarf::DW_FORM_data1,
- *DwarfExpr.TagOffset);
-
return VariableDie;
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 9e20527b2ac3..beed2a5126c4 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -235,27 +235,29 @@ const DIType *DbgVariable::getType() const {
/// Get .debug_loc entry for the instruction range starting at MI.
static DbgValueLoc getDebugLocValue(const MachineInstr *MI) {
const DIExpression *Expr = MI->getDebugExpression();
- const bool IsVariadic = MI->isDebugValueList();
- assert(MI->getNumOperands() >= 3);
- SmallVector<DbgValueLocEntry, 4> DbgValueLocEntries;
- for (const MachineOperand &Op : MI->debug_operands()) {
- if (Op.isReg()) {
- MachineLocation MLoc(Op.getReg(),
- MI->isNonListDebugValue() && MI->isDebugOffsetImm());
- DbgValueLocEntries.push_back(DbgValueLocEntry(MLoc));
- } else if (Op.isTargetIndex()) {
- DbgValueLocEntries.push_back(
- DbgValueLocEntry(TargetIndexLocation(Op.getIndex(), Op.getOffset())));
- } else if (Op.isImm())
- DbgValueLocEntries.push_back(DbgValueLocEntry(Op.getImm()));
- else if (Op.isFPImm())
- DbgValueLocEntries.push_back(DbgValueLocEntry(Op.getFPImm()));
- else if (Op.isCImm())
- DbgValueLocEntries.push_back(DbgValueLocEntry(Op.getCImm()));
- else
- llvm_unreachable("Unexpected debug operand in DBG_VALUE* instruction!");
- }
- return DbgValueLoc(Expr, DbgValueLocEntries, IsVariadic);
+ assert(MI->getNumOperands() == 4);
+ if (MI->getDebugOperand(0).isReg()) {
+ const auto &RegOp = MI->getDebugOperand(0);
+ const auto &Op1 = MI->getDebugOffset();
+ // If the second operand is an immediate, this is a
+ // register-indirect address.
+ assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
+ MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
+ return DbgValueLoc(Expr, MLoc);
+ }
+ if (MI->getDebugOperand(0).isTargetIndex()) {
+ const auto &Op = MI->getDebugOperand(0);
+ return DbgValueLoc(Expr,
+ TargetIndexLocation(Op.getIndex(), Op.getOffset()));
+ }
+ if (MI->getDebugOperand(0).isImm())
+ return DbgValueLoc(Expr, MI->getDebugOperand(0).getImm());
+ if (MI->getDebugOperand(0).isFPImm())
+ return DbgValueLoc(Expr, MI->getDebugOperand(0).getFPImm());
+ if (MI->getDebugOperand(0).isCImm())
+ return DbgValueLoc(Expr, MI->getDebugOperand(0).getCImm());
+
+ llvm_unreachable("Unexpected 4-operand DBG_VALUE instruction!");
}
void DbgVariable::initializeDbgValue(const MachineInstr *DbgValue) {
@@ -643,7 +645,7 @@ static void finishCallSiteParams(ValT Val, const DIExpression *Expr,
assert((!CombinedExpr || CombinedExpr->isValid()) &&
"Combined debug expression is invalid");
- DbgValueLoc DbgLocVal(CombinedExpr, DbgValueLocEntry(Val));
+ DbgValueLoc DbgLocVal(CombinedExpr, Val);
DbgCallSiteParam CSParm(Param.ParamReg, DbgLocVal);
Params.push_back(CSParm);
++NumCSParams;
@@ -1611,9 +1613,7 @@ static bool validThroughout(LexicalScopes &LScopes,
// throughout the function. This is a hack, presumably for DWARF v2 and not
// necessarily correct. It would be much better to use a dbg.declare instead
// if we know the constant is live throughout the scope.
- if (MBB->pred_empty() &&
- all_of(DbgValue->debug_operands(),
- [](const MachineOperand &Op) { return Op.isImm(); }))
+ if (DbgValue->getDebugOperand(0).isImm() && MBB->pred_empty())
return true;
// Test if the location terminates before the end of the scope.
@@ -2486,95 +2486,51 @@ void DwarfDebug::emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
auto *DIExpr = Value.getExpression();
DIExpressionCursor ExprCursor(DIExpr);
DwarfExpr.addFragmentOffset(DIExpr);
-
- // If the DIExpr is is an Entry Value, we want to follow the same code path
- // regardless of whether the DBG_VALUE is variadic or not.
- if (DIExpr && DIExpr->isEntryValue()) {
- // Entry values can only be a single register with no additional DIExpr,
- // so just add it directly.
- assert(Value.getLocEntries().size() == 1);
- assert(Value.getLocEntries()[0].isLocation());
- MachineLocation Location = Value.getLocEntries()[0].getLoc();
+ // Regular entry.
+ if (Value.isInt()) {
+ if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
+ BT->getEncoding() == dwarf::DW_ATE_signed_char))
+ DwarfExpr.addSignedConstant(Value.getInt());
+ else
+ DwarfExpr.addUnsignedConstant(Value.getInt());
+ } else if (Value.isLocation()) {
+ MachineLocation Location = Value.getLoc();
DwarfExpr.setLocation(Location, DIExpr);
+ DIExpressionCursor Cursor(DIExpr);
- DwarfExpr.beginEntryValueExpression(ExprCursor);
+ if (DIExpr->isEntryValue())
+ DwarfExpr.beginEntryValueExpression(Cursor);
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, ExprCursor, Location.getReg()))
- return;
- return DwarfExpr.addExpression(std::move(ExprCursor));
- }
-
- // Regular entry.
- auto EmitValueLocEntry = [&DwarfExpr, &BT,
- &AP](const DbgValueLocEntry &Entry,
- DIExpressionCursor &Cursor) -> bool {
- if (Entry.isInt()) {
- if (BT && (BT->getEncoding() == dwarf::DW_ATE_signed ||
- BT->getEncoding() == dwarf::DW_ATE_signed_char))
- DwarfExpr.addSignedConstant(Entry.getInt());
- else
- DwarfExpr.addUnsignedConstant(Entry.getInt());
- } else if (Entry.isLocation()) {
- MachineLocation Location = Entry.getLoc();
- if (Location.isIndirect())
- DwarfExpr.setMemoryLocationKind();
-
- const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
- if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
- return false;
- } else if (Entry.isTargetIndexLocation()) {
- TargetIndexLocation Loc = Entry.getTargetIndexLocation();
- // TODO TargetIndexLocation is a target-independent. Currently only the
- // WebAssembly-specific encoding is supported.
- assert(AP.TM.getTargetTriple().isWasm());
- DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
- } else if (Entry.isConstantFP()) {
- if (AP.getDwarfVersion() >= 4 && !AP.getDwarfDebug()->tuneForSCE() &&
- !Cursor) {
- DwarfExpr.addConstantFP(Entry.getConstantFP()->getValueAPF(), AP);
- } else if (Entry.getConstantFP()
- ->getValueAPF()
- .bitcastToAPInt()
- .getBitWidth() <= 64 /*bits*/) {
- DwarfExpr.addUnsignedConstant(
- Entry.getConstantFP()->getValueAPF().bitcastToAPInt());
- } else {
- LLVM_DEBUG(
- dbgs() << "Skipped DwarfExpression creation for ConstantFP of size"
- << Entry.getConstantFP()
- ->getValueAPF()
- .bitcastToAPInt()
- .getBitWidth()
- << " bits\n");
- return false;
- }
- } else {
- llvm_unreachable("Invalid Entry for a DW_AT_location expression.");
- }
- return true;
- };
-
- if (!Value.isVariadic()) {
- if (!EmitValueLocEntry(Value.getLocEntries()[0], ExprCursor))
+ if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
return;
+ return DwarfExpr.addExpression(std::move(Cursor));
+ } else if (Value.isTargetIndexLocation()) {
+ TargetIndexLocation Loc = Value.getTargetIndexLocation();
+ // TODO TargetIndexLocation is a target-independent. Currently only the WebAssembly-specific
+ // encoding is supported.
+ assert(AP.TM.getTargetTriple().isWasm());
+ DwarfExpr.addWasmLocation(Loc.Index, static_cast<uint64_t>(Loc.Offset));
DwarfExpr.addExpression(std::move(ExprCursor));
return;
+ } else if (Value.isConstantFP()) {
+ if (AP.getDwarfVersion() >= 4 && !AP.getDwarfDebug()->tuneForSCE() &&
+ !ExprCursor) {
+ DwarfExpr.addConstantFP(Value.getConstantFP()->getValueAPF(), AP);
+ return;
+ }
+ if (Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth() <=
+ 64 /*bits*/)
+ DwarfExpr.addUnsignedConstant(
+ Value.getConstantFP()->getValueAPF().bitcastToAPInt());
+ else
+ LLVM_DEBUG(
+ dbgs()
+ << "Skipped DwarfExpression creation for ConstantFP of size"
+ << Value.getConstantFP()->getValueAPF().bitcastToAPInt().getBitWidth()
+ << " bits\n");
}
-
- // If any of the location entries are registers with the value 0, then the
- // location is undefined.
- if (any_of(Value.getLocEntries(), [](const DbgValueLocEntry &Entry) {
- return Entry.isLocation() && !Entry.getLoc().getReg();
- }))
- return;
-
- DwarfExpr.addExpression(
- std::move(ExprCursor),
- [EmitValueLocEntry, &Value](unsigned Idx,
- DIExpressionCursor &Cursor) -> bool {
- return EmitValueLocEntry(Value.getLocEntries()[Idx], Cursor);
- });
+ DwarfExpr.addExpression(std::move(ExprCursor));
}
void DebugLocEntry::finalize(const AsmPrinter &AP,
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 8dc260130f46..ef61e2e55e18 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -302,12 +302,6 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
}
DwarfRegs.clear();
- // If we need to mask out a subregister, do it now, unless the next
- // operation would emit an OpPiece anyway.
- auto NextOp = ExprCursor.peek();
- if (SubRegisterSizeInBits && NextOp &&
- (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
- maskSubRegister();
return true;
}
@@ -360,14 +354,6 @@ bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
else
addBReg(Reg.DwarfRegNo, SignedOffset);
DwarfRegs.clear();
-
- // If we need to mask out a subregister, do it now, unless the next
- // operation would emit an OpPiece anyway.
- auto NextOp = ExprCursor.peek();
- if (SubRegisterSizeInBits && NextOp &&
- (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
- maskSubRegister();
-
return true;
}
@@ -465,19 +451,16 @@ static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
unsigned FragmentOffsetInBits) {
- addExpression(std::move(ExprCursor),
- [](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
- llvm_unreachable("unhandled opcode found in expression");
- });
-}
-
-void DwarfExpression::addExpression(
- DIExpressionCursor &&ExprCursor,
- std::function<bool(unsigned, DIExpressionCursor &)> InsertArg) {
// Entry values can currently only cover the initial register location,
// and not any other parts of the following DWARF expression.
assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
+ // If we need to mask out a subregister, do it now, unless the next
+ // operation would emit an OpPiece anyway.
+ auto N = ExprCursor.peek();
+ if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
+ maskSubRegister();
+
Optional<DIExpression::ExprOperand> PrevConvertOp = None;
while (ExprCursor) {
@@ -493,12 +476,6 @@ void DwarfExpression::addExpression(
}
switch (OpNum) {
- case dwarf::DW_OP_LLVM_arg:
- if (!InsertArg(Op->getArg(0), ExprCursor)) {
- LocationKind = Unknown;
- return;
- }
- break;
case dwarf::DW_OP_LLVM_fragment: {
unsigned SizeInBits = Op->getArg(1);
unsigned FragmentOffset = Op->getArg(0);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 2e5edf18b38d..0d55144f9827 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -347,9 +347,6 @@ class DwarfExpression {
/// fragment inside the entire variable.
void addExpression(DIExpressionCursor &&Expr,
unsigned FragmentOffsetInBits = 0);
- void
- addExpression(DIExpressionCursor &&Expr,
- std::function<bool(unsigned, DIExpressionCursor &)> InsertArg);
/// If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to
/// the fragment described by \c Expr.
diff --git a/llvm/test/DebugInfo/X86/dbg_value_list_clobbers.mir b/llvm/test/DebugInfo/X86/dbg_value_list_clobbers.mir
deleted file mode 100644
index 601067a80d01..000000000000
--- a/llvm/test/DebugInfo/X86/dbg_value_list_clobbers.mir
+++ /dev/null
@@ -1,84 +0,0 @@
-# RUN: llc %s --start-after=livedebugvalues -filetype=obj -o - \
-# RUN: | llvm-dwarfdump - -name locala -o - | FileCheck %s
-#
-# Test that clobbers between DBG_VALUE_LIST and DBG_VALUE instructions work as
-# expected. Comments and test directives inline.
-
---- |
- target triple = "x86_64-unknown-linux-gnu"
- define dso_local i32 @fun() local_unnamed_addr !dbg !7 {
- entry:
- ret i32 0
- }
-
- !llvm.dbg.cu = !{!0}
- !llvm.module.flags = !{!3, !4, !5}
- !llvm.ident = !{!6}
-
- !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
- !1 = !DIFile(filename: "example.c", directory: "/")
- !2 = !{}
- !3 = !{i32 7, !"Dwarf Version", i32 4}
- !4 = !{i32 2, !"Debug Info Version", i32 3}
- !5 = !{i32 1, !"wchar_size", i32 4}
- !6 = !{!"clang version 11.0.0"}
- !8 = !DISubroutineType(types: !9)
- !9 = !{!10}
- !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
- !11 = !{!12}
- !22 = !DISubroutineType(types: !23)
- !23 = !{!10, !10}
- ; --- Important metadata ---
- !7 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
- !15 = !DILocation(line: 1, column: 1, scope: !7)
- !12 = !DILocalVariable(name: "locala", scope: !7, file: !1, line: 1, type: !10)
-
-...
----
-name: fun
-body: |
- bb.0.entry:
- ; This test checks that we see expected location ranges for a single variable.
- ; CHECK: {{.*}} DW_TAG_variable
- ; CHECK-NEXT: DW_AT_location {{.*}}
-
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $eax, debug-location !15
- ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value
-
- $edi = MOV32ri 1
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $esi, debug-location !15
- ; CHECK-NEXT: [{{.*}}): DW_OP_breg4 RSI+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value
-
- $eax = MOV32ri 2
- DBG_VALUE $eax, $noreg, !12, !DIExpression(), debug-location !15
- ; CHECK-NEXT: [{{.*}}): DW_OP_reg0 RAX
-
- $ecx = MOV32ri 3
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $eax, $ecx, debug-location !15
- ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg2 RCX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value
-
- ; Check that a reg clobber prevents identical locations merging.
- $ecx = MOV32ri 4
- $ecx = MOV32ri 5
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $eax, $ecx, debug-location !15
- ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg2 RCX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value
-
- ; Check that fragments are composed correctly.
- $ecx = MOV32ri 6
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 16), $eax, debug-location !15
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 16, 16), $ecx, debug-location !15
- ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_breg2 RCX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2
-
- ; Check that fragments clobber preceeding overlap.
- $edi = MOV32ri 7
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 16, 16), $edi, debug-location !15
- ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_breg5 RDI+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2
-
- ; Check that a (non-zero-offset) fragment works.
- $ecx = MOV32ri 8
- $ecx = MOV32ri 9
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value, DW_OP_LLVM_fragment, 16, 16), $eax, $ecx, debug-location !15
- ; CHECK-NEXT: [{{.*}}): DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2, DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg2 RCX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value, DW_OP_piece 0x2
-
- RETQ debug-location !15
-...
diff --git a/llvm/test/DebugInfo/X86/dbg_value_list_emission.mir b/llvm/test/DebugInfo/X86/dbg_value_list_emission.mir
deleted file mode 100644
index e3380cb42a4b..000000000000
--- a/llvm/test/DebugInfo/X86/dbg_value_list_emission.mir
+++ /dev/null
@@ -1,101 +0,0 @@
-# RUN: llc %s --start-after=livedebugvalues -filetype=obj -o - \
-# RUN: | llvm-dwarfdump - -name local* -regex \
-# RUN: | FileCheck %s
-#
-# Test that we produce correct DWARF from DBG_VALUE_LIST instructions.
-# Comments and test directives inline.
-
---- |
- target triple = "x86_64-unknown-linux-gnu"
- define dso_local i32 @fun() local_unnamed_addr !dbg !7 {
- entry:
- ret i32 0
- }
-
- !llvm.dbg.cu = !{!0}
- !llvm.module.flags = !{!3, !4, !5}
- !llvm.ident = !{!6}
-
- !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 11.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None)
- !1 = !DIFile(filename: "example.c", directory: "/")
- !2 = !{}
- !3 = !{i32 7, !"Dwarf Version", i32 4}
- !4 = !{i32 2, !"Debug Info Version", i32 3}
- !5 = !{i32 1, !"wchar_size", i32 4}
- !6 = !{!"clang version 11.0.0"}
- !8 = !DISubroutineType(types: !9)
- !9 = !{!10}
- !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
- !11 = !{!12, !13, !25}
- !22 = !DISubroutineType(types: !23)
- !23 = !{!10, !10}
- ; --- Important metadata ---
- !7 = distinct !DISubprogram(name: "fun", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !11)
- !15 = !DILocation(line: 1, column: 1, scope: !7)
- !12 = !DILocalVariable(name: "locala", scope: !7, file: !1, line: 1, type: !10)
- !13 = !DILocalVariable(name: "localb", scope: !7, file: !1, line: 2, type: !10)
- !25 = !DILocalVariable(name: "localc", scope: !7, file: !1, line: 3, type: !10)
- !26 = !DILocalVariable(name: "locald", scope: !7, file: !1, line: 4, type: !10)
- !27 = !DILocalVariable(name: "locale", scope: !7, file: !1, line: 5, type: !10)
- !28 = !DILocalVariable(name: "localf", scope: !7, file: !1, line: 6, type: !10)
- !29 = !DILocalVariable(name: "localg", scope: !7, file: !1, line: 6, type: !10)
- !30 = !DILocalVariable(name: "localh", scope: !7, file: !1, line: 6, type: !10)
-
-...
----
-name: fun
-body: |
- bb.0.entry:
- ; NOTE: By design, all DBG_VALUE_LIST instructions describe stack_value
- ; locations, so they are always created with a DW_OP_stack_value op.
- ;
- ; (1) Check a single reg arg works.
- DBG_VALUE_LIST !12, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value), $eax, debug-location !15
- ; CHECK: DW_TAG_variable
- ; CHECK-NEXT: (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value)
- ; CHECK-NEXT: DW_AT_name ("locala")
-
- ; (2) Check multiple reg args work.
- DBG_VALUE_LIST !13, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $eax, $edi, debug-location !15
- ; CHECK: DW_TAG_variable
- ; CHECK-NEXT: (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg5 RDI+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value)
- ; CHECK-NEXT: DW_AT_name ("localb")
-
- ; (3) Check that multiple references to one reg arg works.
- DBG_VALUE_LIST !25, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 0, DW_OP_minus, DW_OP_stack_value), $eax, debug-location !15
- ; CHECK: DW_TAG_variable
- ; CHECK-NEXT: (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_minus, DW_OP_stack_value)
- ; CHECK-NEXT: DW_AT_name ("localc")
-
- ; (4) Check constant and reg args work together.
- DBG_VALUE_LIST !26, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_mul, DW_OP_stack_value), $eax, 5, debug-location !15
- ; CHECK: DW_TAG_variable
- ; CHECK-NEXT: (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_lit5, DW_OP_mul, DW_OP_stack_value)
- ; CHECK-NEXT: DW_AT_name ("locald")
-
- ; (5) Check that arg deref works.
- DBG_VALUE_LIST !27, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_deref, DW_OP_stack_value), $eax, debug-location !15
- ; CHECK: DW_TAG_variable
- ; CHECK-NEXT: (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_deref, DW_OP_stack_value)
- ; CHECK-NEXT: DW_AT_name ("locale")
-
- ; (6) Check that fragments work.
- DBG_VALUE_LIST !28, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_stack_value, DW_OP_LLVM_fragment, 0, 16), $eax, debug-location !15
- ; CHECK: DW_TAG_variable
- ; CHECK-NEXT: (DW_OP_breg0 RAX+0, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_stack_value, DW_OP_piece 0x2)
- ; CHECK-NEXT: DW_AT_name ("localf")
-
- ; (7) Check that constant register offsets are correctly folded.
- DBG_VALUE_LIST !29, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 5, DW_OP_LLVM_arg, 1, DW_OP_plus_uconst, 17, DW_OP_plus, DW_OP_stack_value), $eax, $edi, debug-location !15
- ; CHECK: DW_TAG_variable
- ; CHECK-NEXT: (DW_OP_breg0 RAX+5, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_breg5 RDI+17, DW_OP_constu 0xffffffff, DW_OP_and, DW_OP_plus, DW_OP_stack_value)
- ; CHECK-NEXT: DW_AT_name ("localg")
-
- ; (8) Check that a single $noreg location invalidates the entire entry.
- DBG_VALUE_LIST !30, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value), $eax, $noreg, debug-location !15
- ; CHECK: DW_TAG_variable
- ; CHECK-NEXT: DW_AT_name ("localh")
- ; CHECK-NOT: DW_AT_location
-
- RETQ debug-location !15
-...
More information about the llvm-commits
mailing list