Skip to content

Commit 178032e

Browse files
authored
Merge pull request #66143 from jckarter/debug-info-inout-move-only-5.9
[5.9] Emit updated debug info when inout parameters are consumed and reinitialized.
2 parents 971f43b + 58e832a commit 178032e

File tree

5 files changed

+62
-16
lines changed

5 files changed

+62
-16
lines changed

include/swift/SIL/DebugUtils.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,16 @@ inline Operand *getSingleDebugUse(SILValue value) {
194194
return *ii;
195195
}
196196

197+
/// If \p value has any debug user(s), return the operand associated with some
198+
/// use. Otherwise, returns nullptr.
199+
inline Operand *getAnyDebugUse(SILValue value) {
200+
auto range = getDebugUses(value);
201+
auto ii = range.begin(), ie = range.end();
202+
if (ii == ie)
203+
return nullptr;
204+
return *ii;
205+
}
206+
197207
/// Erases the instruction \p I from it's parent block and deletes it, including
198208
/// all debug instructions which use \p I.
199209
/// Precondition: The instruction may only have debug instructions as uses.

lib/SILGen/SILGenProlog.cpp

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,7 @@ class ArgumentInitHelper {
788788
return;
789789
}
790790

791+
SILValue debugOperand = value;
791792
if (value->getType().isMoveOnly()) {
792793
switch (pd->getValueOwnership()) {
793794
case ValueOwnership::Default:
@@ -827,11 +828,14 @@ class ArgumentInitHelper {
827828
}
828829
}
829830
break;
830-
case ValueOwnership::InOut:
831-
assert(isa<MarkMustCheckInst>(value) &&
832-
"Expected mark must check inst with inout to be handled in "
833-
"emitBBArgs earlier");
831+
case ValueOwnership::InOut: {
832+
assert(isa<MarkMustCheckInst>(value)
833+
&& "Expected mark must check inst with inout to be handled in "
834+
"emitBBArgs earlier");
835+
auto mark = cast<MarkMustCheckInst>(value);
836+
debugOperand = mark->getOperand();
834837
break;
838+
}
835839
case ValueOwnership::Owned:
836840
value = SGF.B.createMarkMustCheckInst(
837841
loc, value, MarkMustCheckInst::CheckKind::ConsumableAndAssignable);
@@ -843,7 +847,17 @@ class ArgumentInitHelper {
843847
}
844848
}
845849

846-
SGF.B.createDebugValueAddr(loc, value, varinfo);
850+
DebugValueInst *debugInst
851+
= SGF.B.createDebugValueAddr(loc, debugOperand, varinfo);
852+
853+
if (value != debugOperand) {
854+
if (auto valueInst = dyn_cast<MarkMustCheckInst>(value)) {
855+
// Move the debug instruction outside of any marker instruction that might
856+
// have been applied to the value, so that analysis doesn't move the
857+
// debug_value anywhere it shouldn't be.
858+
debugInst->moveBefore(valueInst);
859+
}
860+
}
847861
SGF.VarLocs[pd] = SILGenFunction::VarLoc::get(value);
848862
}
849863

lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ static bool isReinitToInitConvertibleInst(SILInstruction *memInst) {
385385

386386
static void insertDebugValueBefore(SILInstruction *insertPt,
387387
DebugVarCarryingInst debugVar,
388-
SILValue operand) {
388+
llvm::function_ref<SILValue ()> operand) {
389389
if (!debugVar) {
390390
return;
391391
}
@@ -395,7 +395,7 @@ static void insertDebugValueBefore(SILInstruction *insertPt,
395395
}
396396
SILBuilderWithScope debugInfoBuilder(insertPt);
397397
debugInfoBuilder.setCurrentDebugScope(debugVar->getDebugScope());
398-
debugInfoBuilder.createDebugValue(debugVar->getLoc(), operand,
398+
debugInfoBuilder.createDebugValue(debugVar->getLoc(), operand(),
399399
*varInfo, false, true);
400400
}
401401

@@ -423,7 +423,7 @@ static void convertMemoryReinitToInitForm(SILInstruction *memInst,
423423
// Insert a new debug_value instruction after the reinitialization, so that
424424
// the debugger knows that the variable is in a usable form again.
425425
insertDebugValueBefore(memInst->getNextInstruction(), debugVar,
426-
stripAccessMarkers(dest));
426+
[&]{ return debugVar.getOperandForDebugValueClone(); });
427427
}
428428

429429
static bool memInstMustConsume(Operand *memOper) {
@@ -2345,12 +2345,10 @@ void MoveOnlyAddressCheckerPImpl::insertDestroysOnBoundary(
23452345
// referring to the same debug variable as the original definition, we have to
23462346
// use the same debug scope and location as the original debug var.
23472347
auto insertUndefDebugValue = [&debugVar](SILInstruction *insertPt) {
2348-
if (!debugVar) {
2349-
return;
2350-
}
2351-
insertDebugValueBefore(insertPt, debugVar,
2352-
SILUndef::get(debugVar.getOperandForDebugValueClone()->getType(),
2353-
insertPt->getModule()));
2348+
insertDebugValueBefore(insertPt, debugVar, [&]{
2349+
return SILUndef::get(debugVar.getOperandForDebugValueClone()->getType(),
2350+
insertPt->getModule());
2351+
});
23542352
};
23552353

23562354
for (auto &pair : boundary.getLastUsers()) {

lib/SILOptimizer/Mandatory/MoveOnlyDiagnostics.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static void getVariableNameForValue(SILValue value2,
7777
SmallString<64> &resultingString) {
7878
// Before we do anything, lets see if we have an exact debug_value on our
7979
// mmci. In such a case, we can end early and are done.
80-
if (auto *use = getSingleDebugUse(value2)) {
80+
if (auto *use = getAnyDebugUse(value2)) {
8181
if (auto debugVar = DebugVarCarryingInst(use->getUser())) {
8282
assert(debugVar.getKind() == DebugVarCarryingInst::Kind::DebugValue);
8383
resultingString += debugVar.getName();
@@ -112,7 +112,7 @@ static void getVariableNameForValue(SILValue value2,
112112

113113
// If we do not do an exact match, see if we can find a debug_var inst. If
114114
// we do, we always break since we have a root value.
115-
if (auto *use = getSingleDebugUse(searchValue)) {
115+
if (auto *use = getAnyDebugUse(searchValue)) {
116116
if (auto debugVar = DebugVarCarryingInst(use->getUser())) {
117117
assert(debugVar.getKind() == DebugVarCarryingInst::Kind::DebugValue);
118118
variableNamePath.push_back(use->getUser());

test/SILOptimizer/moveonly_debug_info_reinit.swift

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,27 @@ func bar(_ x: consuming Foo, y: consuming Foo, z: consuming Foo) {
3939
// CHECK: debug_value undef : $*Foo, var, name "x"
4040
use(&x)
4141
}
42+
43+
// CHECK-LABEL: sil {{.*}} @${{.*}}10inoutParam
44+
func inoutParam(_ x: inout Foo, y: consuming Foo, z: consuming Foo) {
45+
// CHECK: debug_value [[X:%[0-9]+]] : $*Foo, var, name "x"
46+
47+
// CHECK: [[USE:%.*]] = function_ref @use
48+
// CHECK: apply [[USE]]
49+
// CHECK: debug_value undef : $*Foo, var, name "x"
50+
use(&x)
51+
let _ = x
52+
53+
// CHECK: debug_value undef : $*Foo, var, name "y"
54+
// CHECK: debug_value [[X]] : $*Foo, var, name "x"
55+
x = y
56+
// CHECK: [[USE:%.*]] = function_ref @use
57+
// CHECK: apply [[USE]]
58+
// CHECK: debug_value undef : $*Foo, var, name "x"
59+
use(&x)
60+
let _ = x
61+
62+
// CHECK: debug_value undef : $*Foo, var, name "z"
63+
// CHECK: debug_value [[X]] : $*Foo, var, name "x"
64+
x = z
65+
}

0 commit comments

Comments
 (0)