Skip to content

Commit e9f0052

Browse files
authored
Merge pull request swiftlang#41959 from gottesmm/alloc_stack_propagation_and_hoist
[move-function] Add support for propagating from vars
2 parents 1dabda8 + 5acbeed commit e9f0052

File tree

4 files changed

+97
-13
lines changed

4 files changed

+97
-13
lines changed

include/swift/SIL/DebugUtils.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,39 @@ struct DebugVarCarryingInst {
341341
}
342342
}
343343

344+
/// Returns true if this DebugVarCarryingInst was moved.
345+
bool getWasMoved() const {
346+
switch (kind) {
347+
case Kind::Invalid:
348+
llvm_unreachable("Invalid?!");
349+
case Kind::DebugValue:
350+
return cast<DebugValueInst>(inst)->getWasMoved();
351+
case Kind::AllocStack:
352+
return cast<AllocStackInst>(inst)->getWasMoved();
353+
case Kind::AllocBox:
354+
llvm_unreachable("Not implemented");
355+
}
356+
}
357+
358+
/// If we are attempting to create a "debug_value" clone of this debug var
359+
/// carrying inst, return the appropriate SILValue to use as the operand of
360+
/// that debug value.
361+
///
362+
/// For a debug_value, we just return the actual operand, otherwise we return
363+
/// the pointer address.
364+
SILValue getOperandForDebugValueClone() const {
365+
switch (kind) {
366+
case Kind::Invalid:
367+
llvm_unreachable("Invalid?!");
368+
case Kind::DebugValue:
369+
return cast<DebugValueInst>(inst)->getOperand();
370+
case Kind::AllocStack:
371+
return cast<AllocStackInst>(inst);
372+
case Kind::AllocBox:
373+
llvm_unreachable("Not implemented");
374+
}
375+
}
376+
344377
/// If \p value is an alloc_stack, alloc_box use that. Otherwise, see if \p
345378
/// value has a single debug user, return that. Otherwise return the invalid
346379
/// DebugVarCarryingInst.

lib/LLVMPasses/DbgAddrBlockSplitter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ struct SwiftDbgAddrBlockSplitter : FunctionPass {
3939
bool SwiftDbgAddrBlockSplitter::runOnFunction(Function &fn) {
4040
SmallVector<Instruction *, 32> breakBlockPoints;
4141

42+
// If we are in the first block,
43+
4244
for (auto &block : fn) {
4345
for (auto &inst : block) {
4446
if (isa<DbgAddrIntrinsic>(&inst)) {

lib/SILOptimizer/Mandatory/DebugInfoCanonicalizer.cpp

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "swift/SIL/ApplySite.h"
5151
#include "swift/SIL/BasicBlockBits.h"
5252
#include "swift/SIL/BasicBlockDatastructures.h"
53+
#include "swift/SIL/DebugUtils.h"
5354
#include "swift/SIL/SILBuilder.h"
5455
#include "swift/SIL/SILInstruction.h"
5556
#include "swift/SIL/SILUndef.h"
@@ -68,22 +69,22 @@ using namespace swift;
6869
// Utility
6970
//===----------------------------------------------------------------------===//
7071

71-
static SILInstruction *cloneDebugValue(DebugValueInst *original,
72+
static SILInstruction *cloneDebugValue(DebugVarCarryingInst original,
7273
SILInstruction *insertPt) {
7374
SILBuilderWithScope builder(std::next(insertPt->getIterator()));
7475
builder.setCurrentDebugScope(original->getDebugScope());
75-
return builder.createDebugValue(original->getLoc(), original->getOperand(),
76-
*original->getVarInfo(), false,
77-
true /*was moved*/);
76+
return builder.createDebugValue(
77+
original->getLoc(), original.getOperandForDebugValueClone(),
78+
*original.getVarInfo(), false, true /*was moved*/);
7879
}
7980

80-
static SILInstruction *cloneDebugValue(DebugValueInst *original,
81+
static SILInstruction *cloneDebugValue(DebugVarCarryingInst original,
8182
SILBasicBlock *block) {
8283
SILBuilderWithScope builder(&block->front());
8384
builder.setCurrentDebugScope(original->getDebugScope());
84-
return builder.createDebugValue(original->getLoc(), original->getOperand(),
85-
*original->getVarInfo(), false,
86-
true /*was moved*/);
85+
return builder.createDebugValue(
86+
original->getLoc(), original.getOperandForDebugValueClone(),
87+
*original.getVarInfo(), false, true /*was moved*/);
8788
}
8889

8990
//===----------------------------------------------------------------------===//
@@ -93,7 +94,7 @@ static SILInstruction *cloneDebugValue(DebugValueInst *original,
9394
namespace {
9495

9596
struct BlockState {
96-
llvm::SmallMapVector<SILDebugVariable, DebugValueInst *, 4> debugValues;
97+
llvm::SmallMapVector<SILDebugVariable, DebugVarCarryingInst, 4> debugValues;
9798
};
9899

99100
struct DebugInfoCanonicalizer {
@@ -202,13 +203,20 @@ bool DebugInfoCanonicalizer::process() {
202203
// Then for each inst in the block...
203204
for (auto &inst : *block) {
204205
LLVM_DEBUG(llvm::dbgs() << " Inst: " << inst);
205-
// If we have a debug_value that was moved, store state for it.
206-
if (auto *dvi = dyn_cast<DebugValueInst>(&inst)) {
207-
if (!dvi->getWasMoved())
206+
207+
// Skip any alloc box inst we see, we do not support them yet.
208+
if (isa<AllocBoxInst>(&inst))
209+
continue;
210+
211+
// If we have a debug_value or alloc_stack that was moved, store state for
212+
// it. Once the isa check above is removed, this will handle alloc_box as
213+
// well.
214+
if (auto dvi = DebugVarCarryingInst(&inst)) {
215+
if (!dvi.getWasMoved())
208216
continue;
209217

210218
LLVM_DEBUG(llvm::dbgs() << " Found DebugValueInst!\n");
211-
auto debugInfo = dvi->getVarInfo();
219+
auto debugInfo = dvi.getVarInfo();
212220
if (!debugInfo) {
213221
LLVM_DEBUG(llvm::dbgs() << " Has no var info?! Skipping!\n");
214222
continue;

test/DebugInfo/move_function_dbginfo_async.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ public func letSimpleTest<T>(_ msg: __owned T) async {
165165
// DWARF: [0x{{[a-f0-9]+}}, 0x{{[a-f0-9]+}}): DW_OP_breg6 RBP-88, DW_OP_deref, DW_OP_plus_uconst 0x10, DW_OP_plus_uconst 0x8, DW_OP_deref)
166166
// DWARF: DW_AT_name ("msg")
167167

168+
// Change name to varSimpleTestArg
168169
public func varSimpleTest<T>(_ msg: inout T, _ msg2: T) async {
169170
await forceSplit()
170171
use(_move(msg))
@@ -175,3 +176,43 @@ public func varSimpleTest<T>(_ msg: inout T, _ msg2: T) async {
175176
msg = msg2
176177
await forceSplit()
177178
}
179+
180+
// We don't have an argument here, so we shouldn't have an llvm.dbg.addr in the
181+
// initial function.
182+
//
183+
// CHECK-LABEL: define swifttailcc void @"$s27move_function_dbginfo_async16varSimpleTestVaryyYaF"(%swift.context* swiftasync %0)
184+
// CHECK-NOT: llvm.dbg.addr
185+
//
186+
// CHECK-LABEL: define internal swifttailcc void @"$s27move_function_dbginfo_async16varSimpleTestVaryyYaFTY0_"(i8* swiftasync %0)
187+
// CHECK: call void @llvm.dbg.addr(metadata i8* %0, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_plus_uconst, 16, DW_OP_plus_uconst, 8))
188+
//
189+
// CHECK-LABEL: define internal swifttailcc void @"$s27move_function_dbginfo_async16varSimpleTestVaryyYaFTQ1_"(i8* swiftasync %0)
190+
// CHECK: call void @llvm.dbg.addr(metadata i8* %0, metadata !{{[0-9]+}}, metadata !DIExpression(DW_OP_deref, DW_OP_plus_uconst, 16, DW_OP_plus_uconst, 8))
191+
192+
// CHECK-LABEL: define internal swifttailcc void @"$s27move_function_dbginfo_async16varSimpleTestVaryyYaFTY2_"(i8* swiftasync %0)
193+
// CHECK: call void @llvm.dbg.addr(metadata i8* %0, metadata ![[METADATA:[0-9]+]], metadata !DIExpression(DW_OP_plus_uconst, 16, DW_OP_plus_uconst, 8)), !dbg ![[ADDR_LOC:[0-9]+]]
194+
// CHECK: call void @llvm.dbg.value(metadata %T27move_function_dbginfo_async5KlassC** undef, metadata ![[METADATA]], metadata !DIExpression()), !dbg ![[ADDR_LOC]]
195+
196+
// CHECK-LABEL: define internal swifttailcc void @"$s27move_function_dbginfo_async16varSimpleTestVaryyYaFTQ3_"(i8* swiftasync %0)
197+
// We should only see an llvm.dbg.value here.
198+
// CHECK-NOT: llvm.dbg.addr
199+
// CHECK: call void @llvm.dbg.value(metadata %T27move_function_dbginfo_async5KlassC** undef,
200+
// CHECK-NOT: llvm.dbg.addr
201+
//
202+
// We should see first a llvm.dbg.value to undef the value until we reinit. Then
203+
// we should see a llvm.dbg.addr to reinit.
204+
//
205+
// CHECK-LABEL: define internal swifttailcc void @"$s27move_function_dbginfo_async16varSimpleTestVaryyYaFTY4_"(i8* swiftasync %0)
206+
// CHECK: call void @llvm.dbg.value(metadata %T27move_function_dbginfo_async5KlassC** undef, metadata ![[METADATA:[0-9]+]], metadata !DIExpression()), !dbg ![[ADDR_LOC:[0-9]+]]
207+
// CHECK: call void @llvm.dbg.addr(metadata i8* %0, metadata ![[METADATA]], metadata !DIExpression(DW_OP_plus_uconst, 16, DW_OP_plus_uconst, 8)), !dbg ![[ADDR_LOC]]
208+
public func varSimpleTestVar() async {
209+
var k = Klass()
210+
k.doSomething()
211+
await forceSplit()
212+
let m = _move(k)
213+
m.doSomething()
214+
await forceSplit()
215+
k = Klass()
216+
k.doSomething()
217+
print("stop here")
218+
}

0 commit comments

Comments
 (0)