Skip to content

Commit e90686d

Browse files
committed
IRGen: Fix out-of-order task_dealloc with parameter pack metadata
We deallocate an instruction's packs at points where no further control flow path uses the value. In the case of an alloc_stack, this will be right after the dealloc_stack. Thus, if alloc_stack allocates some packs to build type metadata for a tuple type that contains a pack, and then proceeds to allocate a value large enough to hold the tuple, we will free the second allocation first, before we free the pack, as expected. However, after stack allocating the value, alloc_stack does some further work to emit debug info. This could result in emission of additional metadata packs. Split up the debug info emission into two parts; the first we do before we perform the stack allocation, the rest we do after. - Fixes #67702. - Fixes rdar://problem/141363236.
1 parent 9993d29 commit e90686d

File tree

2 files changed

+81
-36
lines changed

2 files changed

+81
-36
lines changed

lib/IRGen/IRGenSIL.cpp

Lines changed: 60 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,12 +1158,10 @@ class IRGenSILFunction :
11581158
}
11591159

11601160
emitTypeMetadataRef(archetype);
1161-
} else if (auto packArchetype = dyn_cast<PackArchetypeType>(t)) {
1162-
emitTypeMetadataRef(packArchetype);
1163-
} else if (auto packtype = dyn_cast<SILPackType>(t)) {
1161+
} else if (auto packType = dyn_cast<SILPackType>(t)) {
11641162
llvm::Value *Shape = emitPackShapeExpression(t);
11651163
emitPackCountDebugVariable(Shape);
1166-
} else if (auto packtype = dyn_cast<PackType>(t)) {
1164+
} else if (auto packType = dyn_cast<PackType>(t)) {
11671165
llvm::Value *Shape = emitPackShapeExpression(t);
11681166
emitPackCountDebugVariable(Shape);
11691167
}
@@ -1212,8 +1210,13 @@ class IRGenSILFunction :
12121210
SILResultInfo ErrorInfo,
12131211
DebugValueInst *DbgValue);
12141212
void emitPoisonDebugValueInst(DebugValueInst *i);
1215-
void emitDebugInfoForAllocStack(AllocStackInst *i, const TypeInfo &type,
1216-
llvm::Value *addr);
1213+
void emitDebugInfoBeforeAllocStack(AllocStackInst *i,
1214+
const TypeInfo &type,
1215+
DebugTypeInfo &DbgTy);
1216+
void emitDebugInfoAfterAllocStack(AllocStackInst *i,
1217+
const TypeInfo &type,
1218+
const DebugTypeInfo &DbgTy,
1219+
llvm::Value *addr);
12171220
void visitAllocStackInst(AllocStackInst *i);
12181221
void visitAllocPackInst(AllocPackInst *i);
12191222
void visitAllocPackMetadataInst(AllocPackMetadataInst *i);
@@ -6410,14 +6413,49 @@ void IRGenSILFunction::visitDestroyNotEscapedClosureInst(
64106413
setLoweredExplosion(i, out);
64116414
}
64126415

6413-
void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
6414-
const TypeInfo &type,
6415-
llvm::Value *addr) {
6416+
void IRGenSILFunction::emitDebugInfoBeforeAllocStack(AllocStackInst *i,
6417+
const TypeInfo &type,
6418+
DebugTypeInfo &DbgTy) {
64166419
auto VarInfo = i->getVarInfo();
6417-
if (!VarInfo)
6420+
if (!VarInfo ||
6421+
!i->getDebugScope() ||
6422+
i->getDebugScope()->getInlinedFunction()->isTransparent())
6423+
return;
6424+
6425+
VarDecl *Decl = i->getDecl();
6426+
6427+
SILType SILTy;
6428+
if (auto MaybeSILTy = VarInfo->Type) {
6429+
// If there is auxiliary type info, use it
6430+
SILTy = *MaybeSILTy;
6431+
} else {
6432+
SILTy = i->getType();
6433+
}
6434+
auto RealType = SILTy.getASTType();
6435+
if (Decl) {
6436+
DbgTy = DebugTypeInfo::getLocalVariable(Decl, RealType, type, IGM);
6437+
} else if (i->getFunction()->isBare() && !SILTy.hasArchetype() &&
6438+
!VarInfo->Name.empty()) {
6439+
DbgTy = DebugTypeInfo::getFromTypeInfo(RealType, getTypeInfo(SILTy), IGM);
6440+
} else
6441+
return;
6442+
6443+
bindArchetypes(DbgTy.getType());
6444+
}
6445+
6446+
void IRGenSILFunction::emitDebugInfoAfterAllocStack(AllocStackInst *i,
6447+
const TypeInfo &type,
6448+
const DebugTypeInfo &DbgTy,
6449+
llvm::Value *addr) {
6450+
auto VarInfo = i->getVarInfo();
6451+
if (!VarInfo ||
6452+
!i->getDebugScope() ||
6453+
i->getDebugScope()->getInlinedFunction()->isTransparent())
64186454
return;
64196455

64206456
VarDecl *Decl = i->getDecl();
6457+
auto *DS = i->getDebugScope();
6458+
64216459
// Describe the underlying alloca. This way an llvm.dbg.declare intrinsic
64226460
// is used, which is valid for the entire lifetime of the alloca.
64236461
if (auto *BitCast = dyn_cast<llvm::BitCastInst>(addr)) {
@@ -6434,13 +6472,6 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
64346472
(void)isTaskAlloc;
64356473
}
64366474
}
6437-
6438-
auto DS = i->getDebugScope();
6439-
if (!DS)
6440-
return;
6441-
6442-
if (i->getDebugScope()->getInlinedFunction()->isTransparent())
6443-
return;
64446475

64456476
bool IsAnonymous = false;
64466477
VarInfo->Name = getVarName(i, IsAnonymous);
@@ -6475,25 +6506,15 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
64756506
}
64766507
}
64776508

6478-
SILType SILTy;
6479-
if (auto MaybeSILTy = VarInfo->Type) {
6480-
// If there is auxiliary type info, use it
6481-
SILTy = *MaybeSILTy;
6482-
} else {
6483-
SILTy = i->getType();
6484-
}
6485-
auto RealType = SILTy.getASTType();
6486-
DebugTypeInfo DbgTy;
6487-
if (Decl) {
6488-
DbgTy = DebugTypeInfo::getLocalVariable(Decl, RealType, type, IGM);
6489-
} else if (i->getFunction()->isBare() && !SILTy.hasArchetype() &&
6490-
!VarInfo->Name.empty()) {
6491-
DbgTy = DebugTypeInfo::getFromTypeInfo(RealType, getTypeInfo(SILTy), IGM);
6492-
} else
6493-
return;
6509+
if (DbgTy.getType() && IGM.DebugInfo) {
6510+
SILType SILTy;
6511+
if (auto MaybeSILTy = VarInfo->Type) {
6512+
// If there is auxiliary type info, use it
6513+
SILTy = *MaybeSILTy;
6514+
} else {
6515+
SILTy = i->getType();
6516+
}
64946517

6495-
bindArchetypes(DbgTy.getType());
6496-
if (IGM.DebugInfo) {
64976518
emitDebugVariableDeclaration(
64986519
addr, DbgTy, SILTy, DS, i->getLoc(), *VarInfo, Indirection,
64996520
AddrDbgInstrKind(i->usesMoveableValueDebugInfo()));
@@ -6511,6 +6532,9 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
65116532
dbgname = getVarName(i, IsAnonymous);
65126533
# endif
65136534

6535+
DebugTypeInfo DbgTy;
6536+
emitDebugInfoBeforeAllocStack(i, type, DbgTy);
6537+
65146538
auto stackAddr = type.allocateStack(*this, i->getElementType(), dbgname);
65156539
setLoweredStackAddress(i, stackAddr);
65166540
Address addr = stackAddr.getAddress();
@@ -6525,7 +6549,7 @@ void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
65256549
Ty->getStructOrBoundGenericStruct())
65266550
zeroInit(dyn_cast<llvm::AllocaInst>(addr.getAddress()));
65276551
}
6528-
emitDebugInfoForAllocStack(i, type, addr.getAddress());
6552+
emitDebugInfoAfterAllocStack(i, type, DbgTy, addr.getAddress());
65296553
}
65306554

65316555
void IRGenSILFunction::visitAllocPackInst(swift::AllocPackInst *i) {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %target-swift-frontend -emit-ir %s | %FileCheck %s
2+
3+
protocol P {
4+
associatedtype A
5+
var a: A { get }
6+
}
7+
8+
func f<each T: P>(_ t: repeat each T) -> (repeat (each T).A) {
9+
let data = (repeat (each t).a)
10+
return data
11+
}
12+
13+
// CHECK-LABEL: define hidden swiftcc void @"$s21pack_metadata_dealloc1fy1AQzxQp_txxQpRvzAA1PRzlF"(ptr noalias sret(%swift.opaque) %0, ptr noalias %1, i64 %2, ptr %"each T", ptr %"each T.P") #0 {
14+
// CHECK: [[SPSAVE:%.*]] = call ptr @llvm.stacksave.p0()
15+
// CHECK: call void @llvm.stackrestore.p0(ptr [[SPSAVE]])
16+
// CHECK: [[SPSAVE1:%.*]] = call ptr @llvm.stacksave.p0()
17+
// CHECK: [[SPSAVE2:%.*]] = call ptr @llvm.stacksave.p0()
18+
// CHECK-NOT: call ptr llvm.stacksave.p0()
19+
// CHECK: call void @llvm.stackrestore.p0(ptr [[SPSAVE2]])
20+
// CHECK: call void @llvm.stackrestore.p0(ptr [[SPSAVE1]])
21+
// CHECK: ret void

0 commit comments

Comments
 (0)