Skip to content

Commit 31032b9

Browse files
authored
Merge pull request #65992 from jckarter/debug-info-for-move-only-reinitialization
MoveOnlyAddressChecker: Reintroduce debug info for variables after reassignment.
2 parents efe762d + 51f75c9 commit 31032b9

File tree

4 files changed

+103
-40
lines changed

4 files changed

+103
-40
lines changed

include/swift/SIL/DebugUtils.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -534,29 +534,6 @@ struct DebugVarCarryingInst : VarDeclCarryingInst {
534534
}
535535
};
536536

537-
inline DebugVarCarryingInst DebugVarCarryingInst::getFromValue(SILValue value) {
538-
if (auto *svi = dyn_cast<SingleValueInstruction>(value)) {
539-
if (auto result = VarDeclCarryingInst(svi)) {
540-
switch (result.getKind()) {
541-
case VarDeclCarryingInst::Kind::Invalid:
542-
llvm_unreachable("ShouldKind have never seen this");
543-
case VarDeclCarryingInst::Kind::DebugValue:
544-
case VarDeclCarryingInst::Kind::AllocStack:
545-
case VarDeclCarryingInst::Kind::AllocBox:
546-
return DebugVarCarryingInst(svi);
547-
case VarDeclCarryingInst::Kind::GlobalAddr:
548-
case VarDeclCarryingInst::Kind::RefElementAddr:
549-
return DebugVarCarryingInst();
550-
}
551-
}
552-
}
553-
554-
if (auto *use = getSingleDebugUse(value))
555-
return DebugVarCarryingInst(use->getUser());
556-
557-
return DebugVarCarryingInst();
558-
}
559-
560537
static_assert(sizeof(DebugVarCarryingInst) == sizeof(VarDeclCarryingInst) &&
561538
alignof(DebugVarCarryingInst) == alignof(VarDeclCarryingInst),
562539
"Expected debug var carrying inst to have the same "

lib/SIL/Utils/DebugUtils.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,26 @@ bool swift::hasNonTrivialNonDebugTransitiveUsers(
6464
}
6565
return false;
6666
}
67+
68+
DebugVarCarryingInst DebugVarCarryingInst::getFromValue(SILValue value) {
69+
if (auto *svi = dyn_cast<SingleValueInstruction>(value)) {
70+
if (auto result = VarDeclCarryingInst(svi)) {
71+
switch (result.getKind()) {
72+
case VarDeclCarryingInst::Kind::Invalid:
73+
llvm_unreachable("ShouldKind have never seen this");
74+
case VarDeclCarryingInst::Kind::DebugValue:
75+
case VarDeclCarryingInst::Kind::AllocStack:
76+
case VarDeclCarryingInst::Kind::AllocBox:
77+
return DebugVarCarryingInst(svi);
78+
case VarDeclCarryingInst::Kind::GlobalAddr:
79+
case VarDeclCarryingInst::Kind::RefElementAddr:
80+
return DebugVarCarryingInst();
81+
}
82+
}
83+
}
84+
85+
if (auto *use = getSingleDebugUse(value))
86+
return DebugVarCarryingInst(use->getUser());
87+
88+
return DebugVarCarryingInst();
89+
}

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -383,22 +383,47 @@ static bool isReinitToInitConvertibleInst(SILInstruction *memInst) {
383383
}
384384
}
385385

386-
static void convertMemoryReinitToInitForm(SILInstruction *memInst) {
386+
static void insertDebugValueBefore(SILInstruction *insertPt,
387+
DebugVarCarryingInst debugVar,
388+
SILValue operand) {
389+
if (!debugVar) {
390+
return;
391+
}
392+
auto varInfo = debugVar.getVarInfo();
393+
if (!varInfo) {
394+
return;
395+
}
396+
SILBuilderWithScope debugInfoBuilder(insertPt);
397+
debugInfoBuilder.setCurrentDebugScope(debugVar->getDebugScope());
398+
debugInfoBuilder.createDebugValue(debugVar->getLoc(), operand,
399+
*varInfo, false, true);
400+
}
401+
402+
static void convertMemoryReinitToInitForm(SILInstruction *memInst,
403+
DebugVarCarryingInst debugVar) {
404+
SILValue dest;
387405
switch (memInst->getKind()) {
388406
default:
389407
llvm_unreachable("unsupported?!");
390408

391409
case SILInstructionKind::CopyAddrInst: {
392410
auto *cai = cast<CopyAddrInst>(memInst);
393411
cai->setIsInitializationOfDest(IsInitialization_t::IsInitialization);
394-
return;
412+
dest = cai->getDest();
413+
break;
395414
}
396415
case SILInstructionKind::StoreInst: {
397416
auto *si = cast<StoreInst>(memInst);
398417
si->setOwnershipQualifier(StoreOwnershipQualifier::Init);
399-
return;
418+
dest = si->getDest();
419+
break;
400420
}
401421
}
422+
423+
// Insert a new debug_value instruction after the reinitialization, so that
424+
// the debugger knows that the variable is in a usable form again.
425+
insertDebugValueBefore(memInst->getNextInstruction(), debugVar,
426+
stripAccessMarkers(dest));
402427
}
403428

404429
static bool memInstMustConsume(Operand *memOper) {
@@ -1238,7 +1263,8 @@ struct MoveOnlyAddressCheckerPImpl {
12381263
FieldSensitiveMultiDefPrunedLiveRange &liveness,
12391264
FieldSensitivePrunedLivenessBoundary &boundary);
12401265

1241-
void rewriteUses(FieldSensitiveMultiDefPrunedLiveRange &liveness,
1266+
void rewriteUses(MarkMustCheckInst *markedValue,
1267+
FieldSensitiveMultiDefPrunedLiveRange &liveness,
12421268
const FieldSensitivePrunedLivenessBoundary &boundary);
12431269

12441270
void handleSingleBlockDestroy(SILInstruction *destroy, bool isReinit);
@@ -2310,17 +2336,9 @@ void MoveOnlyAddressCheckerPImpl::insertDestroysOnBoundary(
23102336
if (!debugVar) {
23112337
return;
23122338
}
2313-
auto varInfo = debugVar.getVarInfo();
2314-
if (!varInfo) {
2315-
return;
2316-
}
2317-
SILBuilderWithScope debugInfoBuilder(insertPt);
2318-
debugInfoBuilder.setCurrentDebugScope(debugVar->getDebugScope());
2319-
debugInfoBuilder.createDebugValue(
2320-
debugVar->getLoc(),
2321-
SILUndef::get(debugVar.getOperandForDebugValueClone()->getType(),
2322-
insertPt->getModule()),
2323-
*varInfo, false, true);
2339+
insertDebugValueBefore(insertPt, debugVar,
2340+
SILUndef::get(debugVar.getOperandForDebugValueClone()->getType(),
2341+
insertPt->getModule()));
23242342
};
23252343

23262344
for (auto &pair : boundary.getLastUsers()) {
@@ -2426,6 +2444,7 @@ void MoveOnlyAddressCheckerPImpl::insertDestroysOnBoundary(
24262444
}
24272445

24282446
void MoveOnlyAddressCheckerPImpl::rewriteUses(
2447+
MarkMustCheckInst *markedValue,
24292448
FieldSensitiveMultiDefPrunedLiveRange &liveness,
24302449
const FieldSensitivePrunedLivenessBoundary &boundary) {
24312450
LLVM_DEBUG(llvm::dbgs() << "MoveOnlyAddressChecker Rewrite Uses!\n");
@@ -2436,12 +2455,15 @@ void MoveOnlyAddressCheckerPImpl::rewriteUses(
24362455
}
24372456
}
24382457

2458+
auto debugVar = DebugVarCarryingInst::getFromValue(
2459+
stripAccessMarkers(markedValue->getOperand()));
2460+
24392461
// Then convert all claimed reinits to inits.
24402462
for (auto reinitPair : addressUseState.reinitInsts) {
24412463
if (!isReinitToInitConvertibleInst(reinitPair.first))
24422464
continue;
24432465
if (!consumes.claimConsume(reinitPair.first, reinitPair.second))
2444-
convertMemoryReinitToInitForm(reinitPair.first);
2466+
convertMemoryReinitToInitForm(reinitPair.first, debugVar);
24452467
}
24462468

24472469
// Check all takes.
@@ -2624,7 +2646,7 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
26242646
FieldSensitivePrunedLivenessBoundary boundary(liveness.getNumSubElements());
26252647
liveness.computeBoundary(boundary);
26262648
insertDestroysOnBoundary(markedAddress, liveness, boundary);
2627-
rewriteUses(liveness, boundary);
2649+
rewriteUses(markedAddress, liveness, boundary);
26282650

26292651
return true;
26302652
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// RUN: %target-swift-frontend -emit-sil -g %s | %FileCheck %s
2+
// RUN: %target-swift-frontend -DADDRESS_ONLY -emit-sil -g %s | %FileCheck %s
3+
4+
struct Foo: ~Copyable {
5+
#if ADDRESS_ONLY
6+
private var x: Any
7+
#else
8+
private var x: Int
9+
#endif
10+
}
11+
12+
@_silgen_name("use")
13+
func use(_: inout Foo)
14+
15+
// CHECK-LABEL: sil {{.*}} @${{.*}}3bar
16+
func bar(_ x: consuming Foo, y: consuming Foo, z: consuming Foo) {
17+
// CHECK: [[X:%.*]] = alloc_stack{{.*}} $Foo, var, name "x"
18+
19+
// CHECK: [[USE:%.*]] = function_ref @use
20+
// CHECK: apply [[USE]]
21+
// CHECK: debug_value undef : $*Foo, var, name "x"
22+
use(&x)
23+
let _ = x
24+
25+
// CHECK: debug_value undef : $*Foo, var, name "y"
26+
// CHECK: debug_value [[X]] : $*Foo, var, name "x"
27+
x = y
28+
// CHECK: [[USE:%.*]] = function_ref @use
29+
// CHECK: apply [[USE]]
30+
// CHECK: debug_value undef : $*Foo, var, name "x"
31+
use(&x)
32+
let _ = x
33+
34+
// CHECK: debug_value undef : $*Foo, var, name "z"
35+
// CHECK: debug_value [[X]] : $*Foo, var, name "x"
36+
x = z
37+
// CHECK: [[USE:%.*]] = function_ref @use
38+
// CHECK: apply [[USE]]
39+
// CHECK: debug_value undef : $*Foo, var, name "x"
40+
use(&x)
41+
}

0 commit comments

Comments
 (0)