Skip to content

Commit 65e20e7

Browse files
committed
[move-function] Teach debug info how to handle reinits properly of vars.
This fixes the issues I was in my earlier PR about seeing with vars not getting appropriate debug info when moved. Now we get the right debug info and in the dwarf can see the two live ranges of our moved value as we hoped for. NOTE: I disabled alloc stack hoisting on move_function_debuginfo.swift since it can result in us eliminating debug info at -Onone when we merge alloc_stack. I am preparing a separate patch that fixes that issue but hit a lldb problem. This unblocks this PR from that change since they are not /actually/ related.
1 parent 781a90c commit 65e20e7

File tree

4 files changed

+226
-47
lines changed

4 files changed

+226
-47
lines changed

lib/IRGen/IRGenDebugInfo.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
219219
bool buildDebugInfoExpression(const SILDebugVariable &VarInfo,
220220
SmallVectorImpl<uint64_t> &Operands);
221221

222+
/// Emit a dbg.declare at the current insertion point in Builder.
222223
void emitVariableDeclaration(IRBuilder &Builder,
223224
ArrayRef<llvm::Value *> Storage,
224225
DebugTypeInfo Ty, const SILDebugScope *DS,
@@ -227,6 +228,7 @@ class IRGenDebugInfoImpl : public IRGenDebugInfo {
227228
IndirectionKind = DirectValue,
228229
ArtificialKind = RealValue,
229230
AddrDbgInstrKind = AddrDbgInstrKind::DbgDeclare);
231+
230232
void emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
231233
llvm::DILocalVariable *Var, llvm::DIExpression *Expr,
232234
unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
@@ -2646,7 +2648,6 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
26462648
auto *InlinedAt = createInlinedAt(DS);
26472649
auto DL =
26482650
llvm::DILocation::get(IGM.getLLVMContext(), Line, Col, Scope, InlinedAt);
2649-
auto *BB = Builder.GetInsertBlock();
26502651

26512652
// An alloca may only be described by exactly one dbg.declare.
26522653
if (isa<llvm::AllocaInst>(Storage) &&
@@ -2695,17 +2696,25 @@ void IRGenDebugInfoImpl::emitDbgIntrinsic(
26952696
};
26962697
DbgInserter inserter{DBuilder, AddrDInstKind};
26972698

2698-
// If we have a single alloca, just insert the debug in
2699+
// If we have a single alloca...
26992700
if (auto *Alloca = dyn_cast<llvm::AllocaInst>(Storage)) {
2700-
auto *ParentBB = Alloca->getParent();
2701-
auto InsertBefore = std::next(Alloca->getIterator());
2702-
if (InsertBefore != ParentBB->end())
2701+
auto *ParentBB = Builder.GetInsertBlock();
2702+
auto InsertBefore = Builder.GetInsertPoint();
2703+
2704+
if (AddrDInstKind == AddrDbgInstrKind::DbgDeclare) {
2705+
ParentBB = Alloca->getParent();
2706+
InsertBefore = std::next(Alloca->getIterator());
2707+
}
2708+
2709+
if (InsertBefore != ParentBB->end()) {
27032710
inserter.insert(Alloca, Var, Expr, DL, &*InsertBefore);
2704-
else
2711+
} else {
27052712
inserter.insert(Alloca, Var, Expr, DL, ParentBB);
2713+
}
27062714
return;
27072715
}
27082716

2717+
auto *BB = Builder.GetInsertBlock();
27092718
if ((isa<llvm::IntrinsicInst>(Storage) &&
27102719
cast<llvm::IntrinsicInst>(Storage)->getIntrinsicID() ==
27112720
llvm::Intrinsic::coro_alloca_get)) {

lib/IRGen/IRGenSIL.cpp

Lines changed: 69 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -893,19 +893,44 @@ class IRGenSILFunction :
893893
/// Unconditionally emit a stack shadow copy of an \c llvm::Value.
894894
llvm::Value *emitShadowCopy(llvm::Value *Storage, const SILDebugScope *Scope,
895895
SILDebugVariable VarInfo,
896-
llvm::Optional<Alignment> _Align, bool Init) {
896+
llvm::Optional<Alignment> _Align, bool Init,
897+
bool WasMoved) {
897898
auto Align = _Align.getValueOr(IGM.getPointerAlignment());
898899
unsigned ArgNo = VarInfo.ArgNo;
899900
auto &Alloca = ShadowStackSlots[{ArgNo, {Scope, VarInfo.Name}}];
901+
900902
if (!Alloca.isValid())
901903
Alloca = createAlloca(Storage->getType(), Align, VarInfo.Name + ".debug");
902-
assert(canAllocaStoreValue(Alloca.getAddress(), Storage, VarInfo, Scope) &&
904+
905+
// If our value was ever moved, we may be reinitializing the shadow
906+
// copy. Insert the bit cast so that the types line up and we do not get the
907+
// duplicate shadow copy error (which triggers based off of type
908+
// differences).
909+
auto *Address = Alloca.getAddress();
910+
if (WasMoved) {
911+
auto nonPtrAllocaType =
912+
cast<llvm::PointerType>(Address->getType())->getElementType();
913+
if (nonPtrAllocaType != Storage->getType())
914+
Address = Builder.CreateBitOrPointerCast(
915+
Address, llvm::PointerType::get(Storage->getType(), 0));
916+
}
917+
918+
assert(canAllocaStoreValue(Address, Storage, VarInfo, Scope) &&
903919
"bad scope?");
920+
904921
if (Init) {
922+
// Zero init our bare allocation.
905923
zeroInit(cast<llvm::AllocaInst>(Alloca.getAddress()));
906924
ArtificialLocation AutoRestore(Scope, IGM.DebugInfo.get(), Builder);
907-
Builder.CreateStore(Storage, Alloca.getAddress(), Align);
925+
// But store into the address with maybe bitcast.
926+
Builder.CreateStore(Storage, Address, Align);
908927
}
928+
929+
// If this allocation was moved at some point, we might be reinitializing a
930+
// shadow copy. In such a case, lets insert an identity bit cast so that our
931+
// callers will use this address with respect to the place where we
932+
// reinit. Otherwise, callers may use the alloca's insert point. The
933+
// optimizer will eliminate these later without issue.
909934
return Alloca.getAddress();
910935
}
911936

@@ -928,7 +953,7 @@ class IRGenSILFunction :
928953
llvm::Value *emitShadowCopyIfNeeded(llvm::Value *Storage,
929954
const SILDebugScope *Scope,
930955
SILDebugVariable VarInfo,
931-
bool IsAnonymous,
956+
bool IsAnonymous, bool WasMoved,
932957
llvm::Optional<Alignment> Align = None) {
933958
// Never emit shadow copies when optimizing, or if already on the stack. No
934959
// debug info is emitted for refcounts either
@@ -950,7 +975,8 @@ class IRGenSILFunction :
950975
}
951976

952977
// Emit a shadow copy.
953-
auto shadow = emitShadowCopy(Storage, Scope, VarInfo, Align, true);
978+
auto shadow =
979+
emitShadowCopy(Storage, Scope, VarInfo, Align, true, WasMoved);
954980

955981
// Mark variables in async functions for lifetime extension, so they get
956982
// spilled into the async context.
@@ -969,14 +995,16 @@ class IRGenSILFunction :
969995
llvm::Value *emitShadowCopyIfNeeded(Address Storage,
970996
const SILDebugScope *Scope,
971997
SILDebugVariable VarInfo,
972-
bool IsAnonymous) {
998+
bool IsAnonymous, bool WasMoved) {
973999
return emitShadowCopyIfNeeded(Storage.getAddress(), Scope, VarInfo,
974-
IsAnonymous, Storage.getAlignment());
1000+
IsAnonymous, WasMoved,
1001+
Storage.getAlignment());
9751002
}
9761003

9771004
/// Like \c emitShadowCopyIfNeeded() but takes an exploded value.
9781005
void emitShadowCopyIfNeeded(SILValue &SILVal, const SILDebugScope *Scope,
9791006
SILDebugVariable VarInfo, bool IsAnonymous,
1007+
bool WasMoved,
9801008
llvm::SmallVectorImpl<llvm::Value *> &copy) {
9811009
Explosion e = getLoweredExplosion(SILVal);
9821010

@@ -1003,8 +1031,8 @@ class IRGenSILFunction :
10031031
return;
10041032

10051033
if (e.size() == 1) {
1006-
copy.push_back(
1007-
emitShadowCopyIfNeeded(e.claimNext(), Scope, VarInfo, IsAnonymous));
1034+
copy.push_back(emitShadowCopyIfNeeded(e.claimNext(), Scope, VarInfo,
1035+
IsAnonymous, WasMoved));
10081036
return;
10091037
}
10101038

@@ -1053,12 +1081,11 @@ class IRGenSILFunction :
10531081

10541082
/// Emit debug info for a function argument or a local variable.
10551083
template <typename StorageType>
1056-
void emitDebugVariableDeclaration(StorageType Storage, DebugTypeInfo Ty,
1057-
SILType SILTy, const SILDebugScope *DS,
1058-
SILLocation VarLoc,
1059-
SILDebugVariable VarInfo,
1060-
IndirectionKind Indirection,
1061-
AddrDbgInstrKind DbgInstrKind = AddrDbgInstrKind::DbgDeclare) {
1084+
void emitDebugVariableDeclaration(
1085+
StorageType Storage, DebugTypeInfo Ty, SILType SILTy,
1086+
const SILDebugScope *DS, SILLocation VarLoc, SILDebugVariable VarInfo,
1087+
IndirectionKind Indirection,
1088+
AddrDbgInstrKind DbgInstrKind = AddrDbgInstrKind::DbgDeclare) {
10621089
// TODO: fix demangling for C++ types (SR-13223).
10631090
if (swift::TypeBase *ty = SILTy.getASTType().getPointer()) {
10641091
if (MetatypeType *metaTy = dyn_cast<MetatypeType>(ty))
@@ -1070,15 +1097,18 @@ class IRGenSILFunction :
10701097
}
10711098

10721099
assert(IGM.DebugInfo && "debug info not enabled");
1100+
10731101
if (VarInfo.ArgNo) {
10741102
PrologueLocation AutoRestore(IGM.DebugInfo.get(), Builder);
10751103
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, Ty, DS, VarLoc,
10761104
VarInfo, Indirection, ArtificialKind::RealValue,
10771105
DbgInstrKind);
1078-
} else
1079-
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, Ty, DS, VarLoc,
1080-
VarInfo, Indirection, ArtificialKind::RealValue,
1081-
DbgInstrKind);
1106+
return;
1107+
}
1108+
1109+
IGM.DebugInfo->emitVariableDeclaration(
1110+
Builder, Storage, Ty, DS, VarLoc, VarInfo, Indirection,
1111+
ArtificialKind::RealValue, DbgInstrKind);
10821112
}
10831113

10841114
void emitFailBB() {
@@ -4787,8 +4817,9 @@ void IRGenSILFunction::emitErrorResultVar(CanSILFunctionType FnTy,
47874817
ErrorInfo, FnTy, IGM.getMaximalTypeExpansionContext()));
47884818
auto Var = DbgValue->getVarInfo();
47894819
assert(Var && "error result without debug info");
4790-
auto Storage = emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(),
4791-
getDebugScope(), *Var, false);
4820+
auto Storage =
4821+
emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(), getDebugScope(),
4822+
*Var, false, false /*was move*/);
47924823
if (!IGM.DebugInfo)
47934824
return;
47944825
auto DbgTy = DebugTypeInfo::getErrorResult(
@@ -4853,7 +4884,8 @@ void IRGenSILFunction::emitPoisonDebugValueInst(DebugValueInst *i) {
48534884
// vs. multi-value explosions.
48544885
llvm::Value *shadowAddress;
48554886
if (singleValueExplosion) {
4856-
shadowAddress = emitShadowCopy(storage, scope, *varInfo, ptrAlign, false);
4887+
shadowAddress = emitShadowCopy(storage, scope, *varInfo, ptrAlign, false,
4888+
false /*was moved*/);
48574889
} else {
48584890
assert(refTy->isClassExistentialType() && "unknown multi-value explosion");
48594891
// FIXME: Handling Optional existentials requires TypeInfo
@@ -4984,12 +5016,12 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
49845016
// Put the value into a shadow-copy stack slot at -Onone.
49855017
llvm::SmallVector<llvm::Value *, 8> Copy;
49865018
if (IsAddrVal)
4987-
Copy.emplace_back(
4988-
emitShadowCopyIfNeeded(getLoweredAddress(SILVal).getAddress(),
4989-
i->getDebugScope(), *VarInfo, IsAnonymous));
5019+
Copy.emplace_back(emitShadowCopyIfNeeded(
5020+
getLoweredAddress(SILVal).getAddress(), i->getDebugScope(), *VarInfo,
5021+
IsAnonymous, i->getWasMoved()));
49905022
else
49915023
emitShadowCopyIfNeeded(SILVal, i->getDebugScope(), *VarInfo, IsAnonymous,
4992-
Copy);
5024+
i->getWasMoved(), Copy);
49935025

49945026
bindArchetypes(DbgTy.getType());
49955027
if (!IGM.DebugInfo)
@@ -5314,7 +5346,7 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
53145346
if (!Alloca->isStaticAlloca()) {
53155347
// Store the address of the dynamic alloca on the stack.
53165348
addr = emitShadowCopy(addr, DS, *VarInfo, IGM.getPointerAlignment(),
5317-
/*init*/ true);
5349+
/*init*/ true, i->getWasMoved());
53185350
Indirection =
53195351
InCoroContext(*CurSILFn, *i) ? CoroIndirectValue : IndirectValue;
53205352
}
@@ -5356,17 +5388,18 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
53565388
!isa<llvm::UndefValue>(shadow)) {
53575389
if (ValueVariables.insert(shadow).second)
53585390
ValueDomPoints.push_back({shadow, getActiveDominancePoint()});
5359-
auto inst = cast<llvm::Instruction>(shadow);
5360-
llvm::IRBuilder<> builder(inst->getNextNode());
5391+
auto shadowInst = cast<llvm::Instruction>(shadow);
5392+
llvm::IRBuilder<> builder(shadowInst->getNextNode());
53615393
addr =
53625394
builder.CreateLoad(shadow->getType()->getPointerElementType(), shadow);
53635395
}
53645396

53655397
bindArchetypes(DbgTy.getType());
5366-
if (IGM.DebugInfo)
5367-
emitDebugVariableDeclaration(addr, DbgTy, SILTy, DS,
5368-
i->getLoc(), *VarInfo,
5369-
Indirection);
5398+
if (IGM.DebugInfo) {
5399+
emitDebugVariableDeclaration(addr, DbgTy, SILTy, DS, i->getLoc(), *VarInfo,
5400+
Indirection,
5401+
AddrDbgInstrKind(i->getWasMoved()));
5402+
}
53705403
}
53715404

53725405
void IRGenSILFunction::visitAllocStackInst(swift::AllocStackInst *i) {
@@ -5585,8 +5618,9 @@ void IRGenSILFunction::visitAllocBoxInst(swift::AllocBoxInst *i) {
55855618
auto VarInfo = i->getVarInfo();
55865619
assert(VarInfo && "debug_value without debug info");
55875620

5588-
auto Storage = emitShadowCopyIfNeeded(
5589-
boxWithAddr.getAddress(), i->getDebugScope(), *VarInfo, IsAnonymous);
5621+
auto Storage =
5622+
emitShadowCopyIfNeeded(boxWithAddr.getAddress(), i->getDebugScope(),
5623+
*VarInfo, IsAnonymous, false /*was moved*/);
55905624

55915625
if (!IGM.DebugInfo)
55925626
return;

lib/SILOptimizer/Mandatory/MoveKillsCopyableAddressesChecker.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,8 @@ bool DataflowState::cleanupAllDestroyAddr(
14291429
bool madeChange = false;
14301430
BasicBlockWorklist worklist(fn);
14311431

1432+
auto debugVarInst = DebugVarCarryingInst::getFromValue(address);
1433+
14321434
LLVM_DEBUG(llvm::dbgs() << "Cleanup up destroy addr!\n");
14331435
LLVM_DEBUG(llvm::dbgs() << " Visiting destroys!\n");
14341436
LLVM_DEBUG(llvm::dbgs() << " Destroy Indices: " << destroyIndices << "\n");
@@ -1531,6 +1533,15 @@ bool DataflowState::cleanupAllDestroyAddr(
15311533
continue;
15321534
LLVM_DEBUG(llvm::dbgs() << "Converting reinit to init: " << *reinit);
15331535
convertMemoryReinitToInitForm(*reinit);
1536+
1537+
// Make sure to create a new debug_value for the reinit value.
1538+
if (debugVarInst) {
1539+
if (auto varInfo = debugVarInst.getVarInfo()) {
1540+
SILBuilderWithScope reinitBuilder(*reinit);
1541+
reinitBuilder.createDebugValue(debugVarInst.inst->getLoc(), address,
1542+
*varInfo, false, /*was moved*/ true);
1543+
}
1544+
}
15341545
madeChange = true;
15351546
}
15361547

@@ -2025,6 +2036,14 @@ static bool performSingleBasicBlockAnalysis(DataflowState &dataflowState,
20252036
SILUndef::get(address->getType(), builder.getModule()), *varInfo,
20262037
false,
20272038
/*was moved*/ true);
2039+
{
2040+
// Make sure at the reinit point to create a new debug value after the
2041+
// reinit instruction so we reshow the variable.
2042+
auto *next = interestingUser->getNextInstruction();
2043+
SILBuilderWithScope reinitBuilder(next);
2044+
reinitBuilder.createDebugValue(debug.inst->getLoc(), address,
2045+
*varInfo, false, /*was moved*/ true);
2046+
}
20282047
}
20292048
debug.markAsMoved();
20302049
}

0 commit comments

Comments
 (0)