Skip to content

Commit 9984d1d

Browse files
committed
[SILCombine] Correctly drop debug info when fragmenting an enum
1 parent 0be63d0 commit 9984d1d

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -572,8 +572,15 @@ bool SILCombiner::optimizeStackAllocatedEnum(AllocStackInst *AS) {
572572
}
573573

574574
// Second step: replace the enum alloc_stack with a payload alloc_stack.
575+
Builder.setCurrentDebugScope(AS->getDebugScope());
575576
auto *newAlloc = Builder.createAllocStack(
576-
AS->getLoc(), payloadType, AS->getVarInfo(), AS->hasDynamicLifetime());
577+
AS->getLoc(), payloadType, {}, AS->hasDynamicLifetime(), IsNotLexical,
578+
IsNotFromVarDecl, DoesNotUseMoveableValueDebugInfo, true);
579+
if (auto varInfo = AS->getVarInfo()) {
580+
// TODO: Add support for op_enum_fragment
581+
// For now, we can't represent this variable correctly, so we drop it.
582+
Builder.createDebugValue(AS->getLoc(), SILUndef::get(AS), *varInfo);
583+
}
577584

578585
while (!AS->use_empty()) {
579586
Operand *use = *AS->use_begin();
@@ -610,11 +617,9 @@ bool SILCombiner::optimizeStackAllocatedEnum(AllocStackInst *AS) {
610617
break;
611618
}
612619
case SILInstructionKind::DebugValueInst:
613-
if (DebugValueInst::hasAddrVal(user)) {
614-
eraseInstFromFunction(*user);
615-
break;
616-
}
617-
LLVM_FALLTHROUGH;
620+
// TODO: Add support for op_enum_fragment
621+
use->set(SILUndef::get(AS));
622+
break;
618623
default:
619624
llvm_unreachable("unexpected alloc_stack user");
620625
}

test/DebugInfo/sil_combine.sil

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,49 @@ bb0(%0 : $Builtin.RawPointer):
2525
return %ptr : $Builtin.RawPointer
2626
}
2727

28+
public struct S {}
29+
public struct C {
30+
var x: MP
31+
}
32+
33+
enum MP {
34+
case A(S)
35+
case B(S)
36+
}
37+
38+
// CHECK-LABEL: sil @expand_alloc_stack_of_enum_without_take
39+
// CHECK: [[A:%[0-9]+]] = alloc_stack $S
40+
// CHECK-NOT: name "a"
41+
// CHECK-NEXT: debug_value undef : $*MP, let, name "a", expr op_fragment:#C.x
42+
// CHECK-NEXT: debug_value undef : $*MP, let, name "b"
43+
// CHECK: bb1:
44+
// CHECK-NEXT: store %0 to [[A]]
45+
// CHECK: bb2:
46+
// CHECK-NEXT: store %0 to [[A]]
47+
// CHECK: bb3:
48+
// CHECK: destroy_addr [[A]]
49+
// CHECK: } // end sil function 'expand_alloc_stack_of_enum_without_take'
50+
sil @expand_alloc_stack_of_enum_without_take : $@convention(method) (S) -> () {
51+
bb0(%0 : $S):
52+
%1 = alloc_stack $MP, let, name "a", expr op_fragment:#C.x
53+
debug_value %1 : $*MP, let, name "b", expr op_deref
54+
cond_br undef, bb1, bb2
55+
bb1:
56+
%2 = init_enum_data_addr %1 : $*MP, #MP.A!enumelt
57+
store %0 to %2 : $*S
58+
inject_enum_addr %1 : $*MP, #MP.A!enumelt
59+
br bb3
60+
bb2:
61+
%3 = init_enum_data_addr %1 : $*MP, #MP.A!enumelt
62+
store %0 to %3 : $*S
63+
inject_enum_addr %1 : $*MP, #MP.A!enumelt
64+
br bb3
65+
bb3:
66+
destroy_addr %1 : $*MP
67+
dealloc_stack %1 : $*MP
68+
%11 = tuple ()
69+
return %11 : $()
70+
}
71+
72+
2873
// CHECK-IR: ![[DBG_VAR]] = !DILocalVariable(name: "hello"

0 commit comments

Comments
 (0)