Skip to content
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
23 changes: 0 additions & 23 deletions include/swift/SIL/DebugUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -534,29 +534,6 @@ struct DebugVarCarryingInst : VarDeclCarryingInst {
}
};

inline DebugVarCarryingInst DebugVarCarryingInst::getFromValue(SILValue value) {
if (auto *svi = dyn_cast<SingleValueInstruction>(value)) {
if (auto result = VarDeclCarryingInst(svi)) {
switch (result.getKind()) {
case VarDeclCarryingInst::Kind::Invalid:
llvm_unreachable("ShouldKind have never seen this");
case VarDeclCarryingInst::Kind::DebugValue:
case VarDeclCarryingInst::Kind::AllocStack:
case VarDeclCarryingInst::Kind::AllocBox:
return DebugVarCarryingInst(svi);
case VarDeclCarryingInst::Kind::GlobalAddr:
case VarDeclCarryingInst::Kind::RefElementAddr:
return DebugVarCarryingInst();
}
}
}

if (auto *use = getSingleDebugUse(value))
return DebugVarCarryingInst(use->getUser());

return DebugVarCarryingInst();
}

static_assert(sizeof(DebugVarCarryingInst) == sizeof(VarDeclCarryingInst) &&
alignof(DebugVarCarryingInst) == alignof(VarDeclCarryingInst),
"Expected debug var carrying inst to have the same "
Expand Down
23 changes: 23 additions & 0 deletions lib/SIL/Utils/DebugUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,26 @@ bool swift::hasNonTrivialNonDebugTransitiveUsers(
}
return false;
}

DebugVarCarryingInst DebugVarCarryingInst::getFromValue(SILValue value) {
if (auto *svi = dyn_cast<SingleValueInstruction>(value)) {
if (auto result = VarDeclCarryingInst(svi)) {
switch (result.getKind()) {
case VarDeclCarryingInst::Kind::Invalid:
llvm_unreachable("ShouldKind have never seen this");
case VarDeclCarryingInst::Kind::DebugValue:
case VarDeclCarryingInst::Kind::AllocStack:
case VarDeclCarryingInst::Kind::AllocBox:
return DebugVarCarryingInst(svi);
case VarDeclCarryingInst::Kind::GlobalAddr:
case VarDeclCarryingInst::Kind::RefElementAddr:
return DebugVarCarryingInst();
}
}
}

if (auto *use = getSingleDebugUse(value))
return DebugVarCarryingInst(use->getUser());

return DebugVarCarryingInst();
}
56 changes: 39 additions & 17 deletions lib/SILOptimizer/Mandatory/MoveOnlyAddressCheckerUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,22 +382,47 @@ static bool isReinitToInitConvertibleInst(SILInstruction *memInst) {
}
}

static void convertMemoryReinitToInitForm(SILInstruction *memInst) {
static void insertDebugValueBefore(SILInstruction *insertPt,
DebugVarCarryingInst debugVar,
SILValue operand) {
if (!debugVar) {
return;
}
auto varInfo = debugVar.getVarInfo();
if (!varInfo) {
return;
}
SILBuilderWithScope debugInfoBuilder(insertPt);
debugInfoBuilder.setCurrentDebugScope(debugVar->getDebugScope());
debugInfoBuilder.createDebugValue(debugVar->getLoc(), operand,
*varInfo, false, true);
}

static void convertMemoryReinitToInitForm(SILInstruction *memInst,
DebugVarCarryingInst debugVar) {
SILValue dest;
switch (memInst->getKind()) {
default:
llvm_unreachable("unsupported?!");

case SILInstructionKind::CopyAddrInst: {
auto *cai = cast<CopyAddrInst>(memInst);
cai->setIsInitializationOfDest(IsInitialization_t::IsInitialization);
return;
dest = cai->getDest();
break;
}
case SILInstructionKind::StoreInst: {
auto *si = cast<StoreInst>(memInst);
si->setOwnershipQualifier(StoreOwnershipQualifier::Init);
return;
dest = si->getDest();
break;
}
}

// Insert a new debug_value instruction after the reinitialization, so that
// the debugger knows that the variable is in a usable form again.
insertDebugValueBefore(memInst->getNextInstruction(), debugVar,
stripAccessMarkers(dest));
}

static bool memInstMustConsume(Operand *memOper) {
Expand Down Expand Up @@ -1151,7 +1176,8 @@ struct MoveOnlyAddressCheckerPImpl {
FieldSensitiveMultiDefPrunedLiveRange &liveness,
FieldSensitivePrunedLivenessBoundary &boundary);

void rewriteUses(FieldSensitiveMultiDefPrunedLiveRange &liveness,
void rewriteUses(MarkMustCheckInst *markedValue,
FieldSensitiveMultiDefPrunedLiveRange &liveness,
const FieldSensitivePrunedLivenessBoundary &boundary);

void handleSingleBlockDestroy(SILInstruction *destroy, bool isReinit);
Expand Down Expand Up @@ -2210,17 +2236,9 @@ void MoveOnlyAddressCheckerPImpl::insertDestroysOnBoundary(
if (!debugVar) {
return;
}
auto varInfo = debugVar.getVarInfo();
if (!varInfo) {
return;
}
SILBuilderWithScope debugInfoBuilder(insertPt);
debugInfoBuilder.setCurrentDebugScope(debugVar->getDebugScope());
debugInfoBuilder.createDebugValue(
debugVar->getLoc(),
SILUndef::get(debugVar.getOperandForDebugValueClone()->getType(),
insertPt->getModule()),
*varInfo, false, true);
insertDebugValueBefore(insertPt, debugVar,
SILUndef::get(debugVar.getOperandForDebugValueClone()->getType(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Btw, for future reference. I introduced a new API on SILUndef that takes a SILValue and grabs the type/SILModule from it. https://github.com/apple/swift/blob/a1219cc6625991ac13b0187a801ac1eb358e92ee/include/swift/SIL/SILUndef.h#L36

insertPt->getModule()));
};

for (auto &pair : boundary.getLastUsers()) {
Expand Down Expand Up @@ -2326,6 +2344,7 @@ void MoveOnlyAddressCheckerPImpl::insertDestroysOnBoundary(
}

void MoveOnlyAddressCheckerPImpl::rewriteUses(
MarkMustCheckInst *markedValue,
FieldSensitiveMultiDefPrunedLiveRange &liveness,
const FieldSensitivePrunedLivenessBoundary &boundary) {
LLVM_DEBUG(llvm::dbgs() << "MoveOnlyAddressChecker Rewrite Uses!\n");
Expand All @@ -2336,12 +2355,15 @@ void MoveOnlyAddressCheckerPImpl::rewriteUses(
}
}

auto debugVar = DebugVarCarryingInst::getFromValue(
stripAccessMarkers(markedValue->getOperand()));

// Then convert all claimed reinits to inits.
for (auto reinitPair : addressUseState.reinitInsts) {
if (!isReinitToInitConvertibleInst(reinitPair.first))
continue;
if (!consumes.claimConsume(reinitPair.first, reinitPair.second))
convertMemoryReinitToInitForm(reinitPair.first);
convertMemoryReinitToInitForm(reinitPair.first, debugVar);
}

// Check all takes.
Expand Down Expand Up @@ -2524,7 +2546,7 @@ bool MoveOnlyAddressCheckerPImpl::performSingleCheck(
FieldSensitivePrunedLivenessBoundary boundary(liveness.getNumSubElements());
liveness.computeBoundary(boundary);
insertDestroysOnBoundary(markedAddress, liveness, boundary);
rewriteUses(liveness, boundary);
rewriteUses(markedAddress, liveness, boundary);

return true;
}
Expand Down
41 changes: 41 additions & 0 deletions test/SILOptimizer/moveonly_debug_info_reinit.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// RUN: %target-swift-frontend -emit-sil -g %s | %FileCheck %s
// RUN: %target-swift-frontend -DADDRESS_ONLY -emit-sil -g %s | %FileCheck %s

struct Foo: ~Copyable {
#if ADDRESS_ONLY
private var x: Any
#else
private var x: Int
#endif
}

@_silgen_name("use")
func use(_: inout Foo)

// CHECK-LABEL: sil {{.*}} @${{.*}}3bar
func bar(_ x: consuming Foo, y: consuming Foo, z: consuming Foo) {
// CHECK: [[X:%.*]] = alloc_stack{{.*}} $Foo, var, name "x"

// CHECK: [[USE:%.*]] = function_ref @use
// CHECK: apply [[USE]]
// CHECK: debug_value undef : $*Foo, var, name "x"
use(&x)
let _ = x

// CHECK: debug_value undef : $*Foo, var, name "y"
// CHECK: debug_value [[X]] : $*Foo, var, name "x"
x = y
// CHECK: [[USE:%.*]] = function_ref @use
// CHECK: apply [[USE]]
// CHECK: debug_value undef : $*Foo, var, name "x"
use(&x)
let _ = x

// CHECK: debug_value undef : $*Foo, var, name "z"
// CHECK: debug_value [[X]] : $*Foo, var, name "x"
x = z
// CHECK: [[USE:%.*]] = function_ref @use
// CHECK: apply [[USE]]
// CHECK: debug_value undef : $*Foo, var, name "x"
use(&x)
}