Skip to content

Commit d49387b

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

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

lib/SILOptimizer/SILCombiner/SILCombinerMiscVisitors.cpp

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,13 @@ bool SILCombiner::optimizeStackAllocatedEnum(AllocStackInst *AS) {
573573

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

578584
while (!AS->use_empty()) {
579585
Operand *use = *AS->use_begin();
@@ -610,11 +616,9 @@ bool SILCombiner::optimizeStackAllocatedEnum(AllocStackInst *AS) {
610616
break;
611617
}
612618
case SILInstructionKind::DebugValueInst:
613-
if (DebugValueInst::hasAddrVal(user)) {
614-
eraseInstFromFunction(*user);
615-
break;
616-
}
617-
LLVM_FALLTHROUGH;
619+
// TODO: Add support for op_enum_fragment
620+
use->set(SILUndef::get(AS));
621+
break;
618622
default:
619623
llvm_unreachable("unexpected alloc_stack user");
620624
}

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)