Skip to content

[RemoveDIs][DebugInfo] Enable creation of DPVAssigns, update outstanding AT tests #79148

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions llvm/lib/IR/BasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ void BasicBlock::convertToNewDbgValues() {
for (Instruction &I : make_early_inc_range(InstList)) {
assert(!I.DbgMarker && "DbgMarker already set on old-format instrs?");
if (DbgVariableIntrinsic *DVI = dyn_cast<DbgVariableIntrinsic>(&I)) {
if (isa<DbgAssignIntrinsic>(DVI))
continue;

// Convert this dbg.value to a DPValue.
DPValue *Value = new DPValue(DVI);
DPVals.push_back(Value);
Expand Down
114 changes: 63 additions & 51 deletions llvm/lib/IR/DebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1816,8 +1816,12 @@ void at::RAUW(DIAssignID *Old, DIAssignID *New) {

void at::deleteAll(Function *F) {
SmallVector<DbgAssignIntrinsic *, 12> ToDelete;
SmallVector<DPValue *, 12> DPToDelete;
for (BasicBlock &BB : *F) {
for (Instruction &I : BB) {
for (auto &DPV : I.getDbgValueRange())
if (DPV.isDbgAssign())
DPToDelete.push_back(&DPV);
if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I))
ToDelete.push_back(DAI);
else
Expand All @@ -1826,6 +1830,8 @@ void at::deleteAll(Function *F) {
}
for (auto *DAI : ToDelete)
DAI->eraseFromParent();
for (auto *DPV : DPToDelete)
DPV->eraseFromParent();
}

/// Get the FragmentInfo for the variable if it exists, otherwise return a
Expand Down Expand Up @@ -2056,9 +2062,9 @@ std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL,
}

/// Returns nullptr if the assignment shouldn't be attributed to this variable.
static CallInst *emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest,
Instruction &StoreLikeInst,
const VarRecord &VarRec, DIBuilder &DIB) {
static void emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest,
Instruction &StoreLikeInst, const VarRecord &VarRec,
DIBuilder &DIB) {
auto *ID = StoreLikeInst.getMetadata(LLVMContext::MD_DIAssignID);
assert(ID && "Store instruction must have DIAssignID metadata");
(void)ID;
Expand All @@ -2082,7 +2088,7 @@ static CallInst *emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest,

// Discard stores to bits outside this variable.
if (FragStartBit >= FragEndBit)
return nullptr;
return;

StoreToWholeVariable = FragStartBit <= VarStartBit && FragEndBit >= *Size;
}
Expand All @@ -2097,8 +2103,17 @@ static CallInst *emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest,
}
DIExpression *AddrExpr =
DIExpression::get(StoreLikeInst.getContext(), std::nullopt);
return DIB.insertDbgAssign(&StoreLikeInst, Val, VarRec.Var, Expr, Dest,
AddrExpr, VarRec.DL);
if (StoreLikeInst.getParent()->IsNewDbgInfoFormat) {
auto *Assign = DPValue::createLinkedDPVAssign(
&StoreLikeInst, Val, VarRec.Var, Expr, Dest, AddrExpr, VarRec.DL);
(void)Assign;
LLVM_DEBUG(if (Assign) errs() << " > INSERT: " << *Assign << "\n");
return;
}
auto *Assign = DIB.insertDbgAssign(&StoreLikeInst, Val, VarRec.Var, Expr,
Dest, AddrExpr, VarRec.DL);
(void)Assign;
LLVM_DEBUG(if (Assign) errs() << " > INSERT: " << *Assign << "\n");
}

#undef DEBUG_TYPE // Silence redefinition warning (from ConstantsContext.h).
Expand Down Expand Up @@ -2185,12 +2200,8 @@ void at::trackAssignments(Function::iterator Start, Function::iterator End,
I.setMetadata(LLVMContext::MD_DIAssignID, ID);
}

for (const VarRecord &R : LocalIt->second) {
auto *Assign =
emitDbgAssign(*Info, ValueComponent, DestComponent, I, R, DIB);
(void)Assign;
LLVM_DEBUG(if (Assign) errs() << " > INSERT: " << *Assign << "\n");
}
for (const VarRecord &R : LocalIt->second)
emitDbgAssign(*Info, ValueComponent, DestComponent, I, R, DIB);
}
}
}
Expand All @@ -2206,32 +2217,38 @@ bool AssignmentTrackingPass::runOnFunction(Function &F) {
// storage" is limited to Allocas). We'll use this to find dbg.declares to
// delete after running `trackAssignments`.
DenseMap<const AllocaInst *, SmallPtrSet<DbgDeclareInst *, 2>> DbgDeclares;
DenseMap<const AllocaInst *, SmallPtrSet<DPValue *, 2>> DPVDeclares;
// Create another similar map of {storage : variables} that we'll pass to
// trackAssignments.
StorageToVarsMap Vars;
auto ProcessDeclare = [&](auto *Declare, auto &DeclareList) {
// FIXME: trackAssignments doesn't let you specify any modifiers to the
// variable (e.g. fragment) or location (e.g. offset), so we have to
// leave dbg.declares with non-empty expressions in place.
if (Declare->getExpression()->getNumElements() != 0)
return;
if (!Declare->getAddress())
return;
if (AllocaInst *Alloca =
dyn_cast<AllocaInst>(Declare->getAddress()->stripPointerCasts())) {
// FIXME: Skip VLAs for now (let these variables use dbg.declares).
if (!Alloca->isStaticAlloca())
return;
// Similarly, skip scalable vectors (use dbg.declares instead).
if (auto Sz = Alloca->getAllocationSize(*DL); Sz && Sz->isScalable())
return;
DeclareList[Alloca].insert(Declare);
Vars[Alloca].insert(VarRecord(Declare));
}
};
for (auto &BB : F) {
for (auto &I : BB) {
DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(&I);
if (!DDI)
continue;
// FIXME: trackAssignments doesn't let you specify any modifiers to the
// variable (e.g. fragment) or location (e.g. offset), so we have to
// leave dbg.declares with non-empty expressions in place.
if (DDI->getExpression()->getNumElements() != 0)
continue;
if (!DDI->getAddress())
continue;
if (AllocaInst *Alloca =
dyn_cast<AllocaInst>(DDI->getAddress()->stripPointerCasts())) {
// FIXME: Skip VLAs for now (let these variables use dbg.declares).
if (!Alloca->isStaticAlloca())
continue;
// Similarly, skip scalable vectors (use dbg.declares instead).
if (auto Sz = Alloca->getAllocationSize(*DL); Sz && Sz->isScalable())
continue;
DbgDeclares[Alloca].insert(DDI);
Vars[Alloca].insert(VarRecord(DDI));
for (auto &DPV : I.getDbgValueRange()) {
if (DPV.isDbgDeclare())
ProcessDeclare(&DPV, DPVDeclares);
}
if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(&I))
ProcessDeclare(DDI, DbgDeclares);
}
}

Expand All @@ -2247,35 +2264,30 @@ bool AssignmentTrackingPass::runOnFunction(Function &F) {
trackAssignments(F.begin(), F.end(), Vars, *DL);

// Delete dbg.declares for variables now tracked with assignment tracking.
for (auto &P : DbgDeclares) {
const AllocaInst *Alloca = P.first;
auto Markers = at::getAssignmentMarkers(Alloca);
SmallVector<DPValue *> DPMarkers = at::getDPVAssignmentMarkers(Alloca);
auto DeleteSubsumedDeclare = [&](const auto &Markers, auto &Declares) {
(void)Markers;
(void)DPMarkers;
for (DbgDeclareInst *DDI : P.second) {
// Assert that the alloca that DDI uses is now linked to a dbg.assign
for (auto *Declare : Declares) {
// Assert that the alloca that Declare uses is now linked to a dbg.assign
// describing the same variable (i.e. check that this dbg.declare has
// been replaced by a dbg.assign). Use DebugVariableAggregate to Discard
// the fragment part because trackAssignments may alter the
// fragment. e.g. if the alloca is smaller than the variable, then
// trackAssignments will create an alloca-sized fragment for the
// dbg.assign.
assert(llvm::any_of(Markers,
[DDI](DbgAssignIntrinsic *DAI) {
return DebugVariableAggregate(DAI) ==
DebugVariableAggregate(DDI);
}) ||
llvm::any_of(DPMarkers, [DDI](DPValue *DPV) {
return DebugVariableAggregate(DPV) ==
DebugVariableAggregate(DDI);
}));
// Delete DDI because the variable location is now tracked using
assert(llvm::any_of(Markers, [Declare](auto *Assign) {
return DebugVariableAggregate(Assign) ==
DebugVariableAggregate(Declare);
}));
// Delete Declare because the variable location is now tracked using
// assignment tracking.
DDI->eraseFromParent();
Declare->eraseFromParent();
Changed = true;
}
}
};
for (auto &P : DbgDeclares)
DeleteSubsumedDeclare(at::getAssignmentMarkers(P.first), P.second);
for (auto &P : DPVDeclares)
DeleteSubsumedDeclare(at::getDPVAssignmentMarkers(P.first), P.second);
return Changed;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt %s -S -passes=declare-to-assign -o - | FileCheck %s
; RUN: opt --try-experimental-debuginfo-iterators %s -S -passes=declare-to-assign -o - | FileCheck %s

;; Generated from this C++:
;; long double get();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt %s -passes=declare-to-assign -S | FileCheck %s
; RUN: opt --try-experimental-debuginfo-iterators %s -passes=declare-to-assign -S | FileCheck %s

;; Check AssignmentTrackingPass ignores a dbg.declare with an empty metadata
;; location operand.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt -passes=declare-to-assign %s -S | FileCheck %s
; RUN: opt --try-experimental-debuginfo-iterators -passes=declare-to-assign %s -S | FileCheck %s

;; Check declare-to-assign skips scalable vectors for now. i.e. do not replace
;; the dbg.declare with a dbg.assign intrinsic.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: opt -passes=declare-to-assign -S %s -o - \
; RUN: | FileCheck %s --check-prefix=WITHOUT-INTRINSIC
; RUN: opt --try-experimental-debuginfo-iterators -passes=declare-to-assign -S %s -o - \
; RUN: | FileCheck %s --check-prefix=WITHOUT-INTRINSIC

; RUN: sed 's/;Uncomment-with-sed//g' < %s \
; RUN: | opt -passes=declare-to-assign -S - -o - \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt -passes=declare-to-assign -S %s -o - | FileCheck %s
; RUN: opt --try-experimental-debuginfo-iterators -passes=declare-to-assign -S %s -o - | FileCheck %s

;; Check assignment tracking debug info for structured bindings. FIXME only
;; variables at offset 0 in the backing alloca are currently tracked with the
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt -passes=declare-to-assign -S %s -o - | FileCheck %s
; RUN: opt --try-experimental-debuginfo-iterators -passes=declare-to-assign -S %s -o - | FileCheck %s

;; The variable doesn't fill the whole alloca which has a range of different
;; sized stores to it, overlapping (or not) the variable in various ways. Check
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
; RUN: opt -S %s -passes=declare-to-assign -o - | FileCheck %s
; RUN: opt --try-experimental-debuginfo-iterators -S %s -passes=declare-to-assign -o - | FileCheck %s

;; Check declare-to-assign ignores VLA-backed variables (for now).
;; From C++ source:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: opt -passes=sroa -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
; RUN: opt --try-experimental-debuginfo-iterators -passes=sroa -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"

;; Check that sroa removes redundant debug intrinsics after it makes a
;; change. This has a significant positive impact on peak memory and compiler
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: opt %s -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=2 -S -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
; RUN: opt --try-experimental-debuginfo-iterators %s -passes=loop-vectorize -force-vector-width=2 -force-vector-interleave=2 -S -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"

;; Check that loop-vectorize removes redundant debug intrinsics after it makes
;; a change. This has a significant positive impact on peak memory and compiler
Expand Down
2 changes: 2 additions & 0 deletions llvm/test/DebugInfo/Generic/assignment-tracking/optnone.ll
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: opt -S %s -o - --passes=declare-to-assign \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
; RUN: opt --try-experimental-debuginfo-iterators -S %s -o - --passes=declare-to-assign \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"

;; Assignment tracking doesn't add any value when optimisations are disabled.
;; Check it doesn't get applied to functions marked optnone.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
; RUN: opt %s -passes=verify \
; RUN: | opt -passes=verify -S \
; RUN: | FileCheck %s
; RUN: opt --try-experimental-debuginfo-iterators %s -passes=verify \
; RUN: | opt -passes=verify -S \
; RUN: | FileCheck %s

;; Roundtrip test (text -> bitcode -> text) for DIAssignID metadata and
;; llvm.dbg.assign intrinsics.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: opt -passes=redundant-dbg-inst-elim -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
; RUN: opt --try-experimental-debuginfo-iterators -passes=redundant-dbg-inst-elim -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"

;; Hand-written. Test how RemoveRedundantDbgInstrs interacts with dbg.assign
;; intrinsics. FileCehck directives are inline.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: opt -passes=sroa -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
; RUN: opt --try-experimental-debuginfo-iterators -passes=sroa -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"

;; Check that sroa removes redundant debug intrinsics after it makes a
;; change. This has a significant positive impact on peak memory and compiler
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: opt -passes=sroa -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
; RUN: opt --try-experimental-debuginfo-iterators -passes=sroa -S %s -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"

;; Check that the fragments generated in SROA for a split alloca that has a
;; dbg.assign with non-zero-offset fragment are correct.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: opt -passes='declare-to-assign,verify' %s -S -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"
; RUN: opt --try-experimental-debuginfo-iterators -passes='declare-to-assign,verify' %s -S -o - \
; RUN: | FileCheck %s --implicit-check-not="call void @llvm.dbg"

;; This test checks that `trackAssignments` is working correctly by using the
;; pass-wrapper `declare-to-assign`. Each function checks some specific
Expand Down
10 changes: 10 additions & 0 deletions llvm/test/DebugInfo/assignment-tracking/X86/coalesce-options.ll
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,30 @@
;; Coalescing default + instructino-referencing enabled = enable.
; RUN: llc %s -o - -stop-after=finalize-isel -experimental-debug-variable-locations=true \
; RUN: | FileCheck %s --check-prefixes=CHECK,ENABLE
; RUN: llc --try-experimental-debuginfo-iterators %s -o - -stop-after=finalize-isel -experimental-debug-variable-locations=true \
; RUN: | FileCheck %s --check-prefixes=CHECK,ENABLE

;; Coalescing default + instructino-referencing disabled = disable.
; RUN: llc %s -o - -stop-after=finalize-isel -experimental-debug-variable-locations=false \
; RUN: | FileCheck %s --check-prefixes=CHECK,DISABLE
; RUN: llc --try-experimental-debuginfo-iterators %s -o - -stop-after=finalize-isel -experimental-debug-variable-locations=false \
; RUN: | FileCheck %s --check-prefixes=CHECK,DISABLE

;; Coalescing enabled + instructino-referencing disabled = enable.
; RUN: llc %s -o - -stop-after=finalize-isel -experimental-debug-variable-locations=false \
; RUN: -debug-ata-coalesce-frags=true \
; RUN: | FileCheck %s --check-prefixes=CHECK,ENABLE
; RUN: llc --try-experimental-debuginfo-iterators %s -o - -stop-after=finalize-isel -experimental-debug-variable-locations=false \
; RUN: -debug-ata-coalesce-frags=true \
; RUN: | FileCheck %s --check-prefixes=CHECK,ENABLE

;; Coalescing disabled + instructino-referencing enabled = disable.
; RUN: llc %s -o - -stop-after=finalize-isel -experimental-debug-variable-locations=true \
; RUN: -debug-ata-coalesce-frags=false \
; RUN: | FileCheck %s --check-prefixes=CHECK,DISABLE
; RUN: llc --try-experimental-debuginfo-iterators %s -o - -stop-after=finalize-isel -experimental-debug-variable-locations=true \
; RUN: -debug-ata-coalesce-frags=false \
; RUN: | FileCheck %s --check-prefixes=CHECK,DISABLE

; CHECK: MOV32mi %stack.0.a, 1, $noreg, 0, $noreg, 5
; ENABLE-NEXT: DBG_VALUE %stack.0.a, $noreg, ![[#]], !DIExpression(DW_OP_deref)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: llc %s -o - -stop-after=finalize-isel \
; RUN: | FileCheck %s --implicit-check-not=DBG_
; RUN: llc --try-experimental-debuginfo-iterators %s -o - -stop-after=finalize-isel \
; RUN: | FileCheck %s --implicit-check-not=DBG_

;; Test coalescing of contiguous fragments in adjacent location definitions.
;; Further details and check directives inline.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: llc %s -o - -stop-after=finalize-isel \
; RUN: | FileCheck %s --implicit-check-not=DBG
; RUN: llc --try-experimental-debuginfo-iterators %s -o - -stop-after=finalize-isel \
; RUN: | FileCheck %s --implicit-check-not=DBG

;; In the IR below, for variable n, we get dbg intrinsics that describe this:
;;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
; RUN: llc %s -stop-after=finalize-isel -o - \
; RUN: | FileCheck %s --implicit-check-not=DBG_
; RUN: llc --try-experimental-debuginfo-iterators %s -stop-after=finalize-isel -o - \
; RUN: | FileCheck %s --implicit-check-not=DBG_

;; Hand-written to test untagged store handling on a simple case. Here's what
;; we're looking at in the IR:
Expand Down