Skip to content

Commit 9b6a994

Browse files
committed
Be explicit about whether a DebugInfo-carying SILInstruction has debug info.
This patch both makes debug variable information it optional on alloc_stack and alloc_box instructions, and forced variable information on debug_value and debug_value_addr instructions. The change of the interface uncovered a plethora of bugs in SILGen, SILTransform, and IRGen's LoadableByAddress pass. Most importantly this fixes the previously commented part of the DebugInfo/local-vars.swift.gyb testcase. rdar://problem/37720555
1 parent 49b9c1f commit 9b6a994

22 files changed

+200
-174
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ class SILBuilder {
286286
//===--------------------------------------------------------------------===//
287287

288288
AllocStackInst *createAllocStack(SILLocation Loc, SILType elementType,
289-
SILDebugVariable Var = SILDebugVariable()) {
289+
Optional<SILDebugVariable> Var = None) {
290290
Loc.markAsPrologue();
291291
return insert(AllocStackInst::create(getSILDebugLocation(Loc),
292292
elementType, getFunction(),
@@ -327,7 +327,7 @@ class SILBuilder {
327327
}
328328

329329
AllocBoxInst *createAllocBox(SILLocation Loc, CanSILBoxType BoxType,
330-
SILDebugVariable Var = SILDebugVariable()) {
330+
Optional<SILDebugVariable> Var = None) {
331331
Loc.markAsPrologue();
332332
return insert(AllocBoxInst::create(getSILDebugLocation(Loc), BoxType, *F,
333333
OpenedArchetypes, Var));
@@ -733,13 +733,13 @@ class SILBuilder {
733733
}
734734

735735
DebugValueInst *createDebugValue(SILLocation Loc, SILValue src,
736-
SILDebugVariable Var = SILDebugVariable()) {
736+
SILDebugVariable Var) {
737737
return insert(DebugValueInst::create(getSILDebugLocation(Loc), src,
738738
getModule(), Var));
739739
}
740740
DebugValueAddrInst *
741741
createDebugValueAddr(SILLocation Loc, SILValue src,
742-
SILDebugVariable Var = SILDebugVariable()) {
742+
SILDebugVariable Var) {
743743
return insert(DebugValueAddrInst::create(getSILDebugLocation(Loc), src,
744744
getModule(), Var));
745745
}

include/swift/SIL/SILCloner.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ SILCloner<ImplClass>::visitDebugValueInst(DebugValueInst *Inst) {
886886
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
887887
doPostProcess(Inst, getBuilder().createDebugValue(
888888
Inst->getLoc(), getOpValue(Inst->getOperand()),
889-
Inst->getVarInfo()));
889+
*Inst->getVarInfo()));
890890
}
891891
template<typename ImplClass>
892892
void
@@ -900,8 +900,8 @@ SILCloner<ImplClass>::visitDebugValueAddrInst(DebugValueAddrInst *Inst) {
900900
// Do not remap the location for a debug Instruction.
901901
SILValue OpValue = getOpValue(Inst->getOperand());
902902
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
903-
doPostProcess(Inst, getBuilder().createDebugValueAddr(
904-
Inst->getLoc(), OpValue, Inst->getVarInfo()));
903+
doPostProcess(Inst, getBuilder().createDebugValueAddr(Inst->getLoc(), OpValue,
904+
*Inst->getVarInfo()));
905905
}
906906

907907

include/swift/SIL/SILInstruction.h

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1196,14 +1196,14 @@ class UnaryInstructionWithTypeDependentOperandsBase
11961196
/// arguments that are needed by DebugValueInst, DebugValueAddrInst,
11971197
/// AllocStackInst, and AllocBoxInst.
11981198
struct SILDebugVariable {
1199-
SILDebugVariable() : Constant(true), ArgNo(0) {}
1200-
SILDebugVariable(bool Constant, unsigned ArgNo)
1201-
: Constant(Constant), ArgNo(ArgNo) {}
1199+
SILDebugVariable() : ArgNo(0), Constant(false) {}
1200+
SILDebugVariable(bool Constant, uint16_t ArgNo)
1201+
: ArgNo(ArgNo), Constant(Constant) {}
12021202
SILDebugVariable(StringRef Name, bool Constant, unsigned ArgNo)
1203-
: Name(Name), Constant(Constant), ArgNo(ArgNo) {}
1203+
: Name(Name), ArgNo(ArgNo), Constant(Constant) {}
12041204
StringRef Name;
1205-
bool Constant;
1206-
unsigned ArgNo;
1205+
unsigned ArgNo : 16;
1206+
unsigned Constant : 1;
12071207
};
12081208

12091209
/// A DebugVariable where storage for the strings has been
@@ -1212,18 +1212,21 @@ class TailAllocatedDebugVariable {
12121212
union {
12131213
uint32_t RawValue;
12141214
struct {
1215+
/// Whether this is a debug variable at all.
1216+
unsigned HasValue : 1;
1217+
/// True if this is a let-binding.
1218+
unsigned Constant : 1;
12151219
/// The source function argument position from left to right
12161220
/// starting with 1 or 0 if this is a local variable.
12171221
unsigned ArgNo : 16;
1218-
unsigned Constant : 1;
12191222
/// When this is nonzero there is a tail-allocated string storing
12201223
/// variable name present. This typically only happens for
12211224
/// instructions that were created from parsing SIL assembler.
1222-
unsigned NameLength : 15;
1225+
unsigned NameLength : 14;
12231226
} Data;
12241227
};
12251228
public:
1226-
TailAllocatedDebugVariable(SILDebugVariable DbgVar, char *buf);
1229+
TailAllocatedDebugVariable(Optional<SILDebugVariable>, char *buf);
12271230
TailAllocatedDebugVariable(uint32_t RawValue) : RawValue(RawValue) {}
12281231
uint32_t getRawValue() const { return RawValue; }
12291232

@@ -1234,12 +1237,14 @@ class TailAllocatedDebugVariable {
12341237
StringRef getName(const char *buf) const;
12351238
bool isLet() const { return Data.Constant; }
12361239

1237-
SILDebugVariable get(VarDecl *VD, const char *buf) const {
1240+
Optional<SILDebugVariable> get(VarDecl *VD, const char *buf) const {
1241+
if (!Data.HasValue)
1242+
return None;
12381243
if (VD)
1239-
return {VD->getName().empty() ? "" : VD->getName().str(), VD->isLet(),
1240-
getArgNo()};
1244+
return SILDebugVariable(VD->getName().empty() ? "" : VD->getName().str(),
1245+
VD->isLet(), getArgNo());
12411246
else
1242-
return {getName(buf), isLet(), getArgNo()};
1247+
return SILDebugVariable(getName(buf), isLet(), getArgNo());
12431248
}
12441249
};
12451250
static_assert(sizeof(TailAllocatedDebugVariable) == 4,
@@ -1272,12 +1277,12 @@ class AllocStackInst final
12721277
AllocStackInst(SILDebugLocation Loc, SILType elementType,
12731278
ArrayRef<SILValue> TypeDependentOperands,
12741279
SILFunction &F,
1275-
SILDebugVariable Var);
1280+
Optional<SILDebugVariable> Var);
12761281

12771282
static AllocStackInst *create(SILDebugLocation Loc, SILType elementType,
12781283
SILFunction &F,
12791284
SILOpenedArchetypesState &OpenedArchetypes,
1280-
SILDebugVariable Var);
1285+
Optional<SILDebugVariable> Var);
12811286

12821287
size_t numTrailingObjects(OverloadToken<Operand>) const {
12831288
return SILInstruction::Bits.AllocStackInst.NumOperands;
@@ -1297,7 +1302,7 @@ class AllocStackInst final
12971302
VarDecl *getDecl() const;
12981303

12991304
/// Return the debug variable information attached to this instruction.
1300-
SILDebugVariable getVarInfo() const {
1305+
Optional<SILDebugVariable> getVarInfo() const {
13011306
auto RawValue = SILInstruction::Bits.AllocStackInst.VarInfo;
13021307
auto VI = TailAllocatedDebugVariable(RawValue);
13031308
return VI.get(getDecl(), getTrailingObjects<char>());
@@ -1514,12 +1519,12 @@ class AllocBoxInst final
15141519

15151520
AllocBoxInst(SILDebugLocation DebugLoc, CanSILBoxType BoxType,
15161521
ArrayRef<SILValue> TypeDependentOperands, SILFunction &F,
1517-
SILDebugVariable Var);
1522+
Optional<SILDebugVariable> Var);
15181523

15191524
static AllocBoxInst *create(SILDebugLocation Loc, CanSILBoxType boxType,
15201525
SILFunction &F,
15211526
SILOpenedArchetypesState &OpenedArchetypes,
1522-
SILDebugVariable Var);
1527+
Optional<SILDebugVariable> Var);
15231528

15241529
public:
15251530
CanSILBoxType getBoxType() const {
@@ -1536,7 +1541,7 @@ class AllocBoxInst final
15361541
VarDecl *getDecl() const;
15371542

15381543
/// Return the debug variable information attached to this instruction.
1539-
SILDebugVariable getVarInfo() const {
1544+
Optional<SILDebugVariable> getVarInfo() const {
15401545
return VarInfo.get(getDecl(), getTrailingObjects<char>());
15411546
};
15421547

@@ -3629,7 +3634,7 @@ class DebugValueInst final
36293634
/// or null if we don't have one.
36303635
VarDecl *getDecl() const;
36313636
/// Return the debug variable information attached to this instruction.
3632-
SILDebugVariable getVarInfo() const {
3637+
Optional<SILDebugVariable> getVarInfo() const {
36333638
return VarInfo.get(getDecl(), getTrailingObjects<char>());
36343639
}
36353640
};
@@ -3655,7 +3660,7 @@ class DebugValueAddrInst final
36553660
/// or null if we don't have one.
36563661
VarDecl *getDecl() const;
36573662
/// Return the debug variable information attached to this instruction.
3658-
SILDebugVariable getVarInfo() const {
3663+
Optional<SILDebugVariable> getVarInfo() const {
36593664
return VarInfo.get(getDecl(), getTrailingObjects<char>());
36603665
};
36613666
};

lib/IRGen/IRGenSIL.cpp

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,11 @@ class IRGenSILFunction :
631631

632632
template <class DebugVarCarryingInst>
633633
StringRef getVarName(DebugVarCarryingInst *i, bool &IsAnonymous) {
634-
StringRef Name = i->getVarInfo().Name;
634+
auto VarInfo = i->getVarInfo();
635+
if (!VarInfo)
636+
return StringRef();
637+
638+
StringRef Name = i->getVarInfo()->Name;
635639
// The $match variables generated by the type checker are not
636640
// guaranteed to be unique within their scope, but they have
637641
// unique VarDecls.
@@ -3589,28 +3593,30 @@ void IRGenSILFunction::emitErrorResultVar(SILResultInfo ErrorInfo,
35893593
if (IGM.IsSwiftErrorInRegister)
35903594
return;
35913595
auto ErrorResultSlot = getErrorResultSlot(IGM.silConv.getSILType(ErrorInfo));
3592-
SILDebugVariable Var = DbgValue->getVarInfo();
3596+
auto Var = DbgValue->getVarInfo();
3597+
assert(Var && "error result without debug info");
35933598
auto Storage =
35943599
emitShadowCopyIfNeeded(ErrorResultSlot.getAddress(), getDebugScope(),
3595-
Var.Name, Var.ArgNo, false);
3600+
Var->Name, Var->ArgNo, false);
35963601
DebugTypeInfo DTI(nullptr, nullptr, ErrorInfo.getType(),
35973602
ErrorResultSlot->getType(), IGM.getPointerSize(),
35983603
IGM.getPointerAlignment(), true);
35993604
IGM.DebugInfo->emitVariableDeclaration(Builder, Storage, DTI, getDebugScope(),
3600-
nullptr, Var.Name, Var.ArgNo,
3605+
nullptr, Var->Name, Var->ArgNo,
36013606
IndirectValue, ArtificialValue);
36023607
}
36033608

36043609
void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
36053610
if (!IGM.DebugInfo)
36063611
return;
36073612

3613+
auto VarInfo = i->getVarInfo();
3614+
assert(VarInfo && "debug_value without debug info");
36083615
auto SILVal = i->getOperand();
36093616
if (isa<SILUndef>(SILVal)) {
36103617
// We cannot track the location of inlined error arguments because it has no
36113618
// representation in SIL.
3612-
if (!i->getDebugScope()->InlinedCallSite &&
3613-
i->getVarInfo().Name == "$error") {
3619+
if (!i->getDebugScope()->InlinedCallSite && VarInfo->Name == "$error") {
36143620
auto funcTy = CurSILFn->getLoweredFunctionType();
36153621
emitErrorResultVar(funcTy->getErrorResult(), i);
36163622
}
@@ -3636,12 +3642,11 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
36363642
return;
36373643

36383644
// Put the value into a stack slot at -Onone.
3639-
llvm::SmallVector<llvm::Value *, 8> Copy;
3640-
unsigned ArgNo = i->getVarInfo().ArgNo;
3641-
emitShadowCopyIfNeeded(SILVal, i->getDebugScope(), Name, ArgNo, IsAnonymous,
3642-
Copy);
3645+
llvm::SmallVector<llvm::Value *, 8> Copy;
3646+
emitShadowCopyIfNeeded(SILVal, i->getDebugScope(), Name, VarInfo->ArgNo,
3647+
IsAnonymous, Copy);
36433648
emitDebugVariableDeclaration(Copy, DbgTy, SILTy, i->getDebugScope(),
3644-
i->getDecl(), Name, ArgNo);
3649+
i->getDecl(), Name, VarInfo->ArgNo);
36453650
}
36463651

36473652
void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
@@ -3655,6 +3660,8 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
36553660
if (isa<SILUndef>(SILVal))
36563661
return;
36573662

3663+
auto VarInfo = i->getVarInfo();
3664+
assert(VarInfo && "debug_value_addr without debug info");
36583665
bool IsAnonymous = false;
36593666
bool IsLoadablyByAddress = isa<AllocStackInst>(SILVal);
36603667
StringRef Name = getVarName(i, IsAnonymous);
@@ -3669,19 +3676,16 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
36693676
// FIXME: Should this check if the lowered SILType is address only
36703677
// instead? Otherwise optionals of archetypes etc will still have
36713678
// 'Unwrap' set to false.
3672-
bool Unwrap =
3673-
i->getVarInfo().Constant ||
3674-
SILTy.is<ArchetypeType>();
3679+
bool Unwrap = VarInfo->Constant || SILTy.is<ArchetypeType>();
36753680
auto DbgTy = DebugTypeInfo::getLocalVariable(
36763681
CurSILFn->getDeclContext(), CurSILFn->getGenericEnvironment(), Decl,
36773682
RealType, getTypeInfo(SILVal->getType()), Unwrap);
36783683
// Put the value's address into a stack slot at -Onone and emit a debug
36793684
// intrinsic.
3680-
unsigned ArgNo = i->getVarInfo().ArgNo;
36813685
emitDebugVariableDeclaration(
3682-
emitShadowCopyIfNeeded(Addr, i->getDebugScope(), Name, ArgNo,
3686+
emitShadowCopyIfNeeded(Addr, i->getDebugScope(), Name, VarInfo->ArgNo,
36833687
IsAnonymous),
3684-
DbgTy, SILType(), i->getDebugScope(), Decl, Name, ArgNo,
3688+
DbgTy, SILType(), i->getDebugScope(), Decl, Name, VarInfo->ArgNo,
36853689
(IsLoadablyByAddress || DbgTy.isImplicitlyIndirect()) ? DirectValue
36863690
: IndirectValue);
36873691
}
@@ -3885,6 +3889,10 @@ visitIsUniqueOrPinnedInst(swift::IsUniqueOrPinnedInst *i) {
38853889
void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
38863890
const TypeInfo &type,
38873891
llvm::Value *addr) {
3892+
auto VarInfo = i->getVarInfo();
3893+
if (!VarInfo)
3894+
return;
3895+
38883896
VarDecl *Decl = i->getDecl();
38893897
// Describe the underlying alloca. This way an llvm.dbg.declare instrinsic
38903898
// is used, which is valid for the entire lifetime of the alloca.
@@ -3897,7 +3905,6 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
38973905
return;
38983906

38993907
bool IsAnonymous = false;
3900-
unsigned ArgNo = i->getVarInfo().ArgNo;
39013908
StringRef Name = getVarName(i, IsAnonymous);
39023909

39033910
// At this point addr must be an alloca or an undef.
@@ -3907,7 +3914,8 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
39073914
if (auto *Alloca = dyn_cast<llvm::AllocaInst>(addr))
39083915
if (!Alloca->isStaticAlloca()) {
39093916
// Store the address of the dynamic alloca on the stack.
3910-
addr = emitShadowCopy(addr, DS, Name, ArgNo, IGM.getPointerAlignment());
3917+
addr = emitShadowCopy(addr, DS, Name, VarInfo->ArgNo,
3918+
IGM.getPointerAlignment());
39113919
Indirection = IndirectValue;
39123920
}
39133921

@@ -3928,8 +3936,8 @@ void IRGenSILFunction::emitDebugInfoForAllocStack(AllocStackInst *i,
39283936
if (DbgTy.isImplicitlyIndirect())
39293937
Indirection = DirectValue;
39303938

3931-
emitDebugVariableDeclaration(addr, DbgTy, SILTy, DS, Decl, Name, ArgNo,
3932-
Indirection);
3939+
emitDebugVariableDeclaration(addr, DbgTy, SILTy, DS, Decl, Name,
3940+
VarInfo->ArgNo, Indirection);
39333941
}
39343942
}
39353943

lib/IRGen/LoadableByAddress.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,7 +1514,8 @@ static void setInstrUsers(StructLoweringState &pass, AllocStackInst *allocInstr,
15141514
} else if (auto *dbgInst = dyn_cast<DebugValueInst>(user)) {
15151515
SILBuilderWithScope dbgBuilder(dbgInst);
15161516
// Rewrite the debug_value to point to the variable in the alloca.
1517-
dbgBuilder.createDebugValueAddr(dbgInst->getLoc(), allocInstr);
1517+
dbgBuilder.createDebugValueAddr(dbgInst->getLoc(), allocInstr,
1518+
*dbgInst->getVarInfo());
15181519
dbgInst->eraseFromParent();
15191520
}
15201521
}
@@ -1883,7 +1884,8 @@ static void rewriteFunction(StructLoweringState &pass,
18831884
SILBuilderWithScope allocBuilder(instr);
18841885
SILType currSILType = instr->getType();
18851886
SILType newSILType = getNewSILType(genEnv, currSILType, pass.Mod);
1886-
auto *newInstr = allocBuilder.createAllocStack(instr->getLoc(), newSILType);
1887+
auto *newInstr = allocBuilder.createAllocStack(instr->getLoc(), newSILType,
1888+
instr->getVarInfo());
18871889
instr->replaceAllUsesWith(newInstr);
18881890
instr->getParent()->erase(instr);
18891891
}
@@ -1916,7 +1918,7 @@ static void rewriteFunction(StructLoweringState &pass,
19161918
"Expected an address type");
19171919
SILBuilderWithScope debugBuilder(instr);
19181920
debugBuilder.createDebugValueAddr(instr->getLoc(), currOperand,
1919-
instr->getVarInfo());
1921+
*instr->getVarInfo());
19201922
instr->getParent()->erase(instr);
19211923
}
19221924
}

lib/ParseSIL/ParseSIL.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1450,8 +1450,10 @@ bool SILParser::parseSILDebugVar(SILDebugVariable &Var) {
14501450
P.diagnose(P.Tok, diag::expected_tok_in_sil_instr, "integer");
14511451
return true;
14521452
}
1453-
if (P.Tok.getText().getAsInteger(0, Var.ArgNo))
1453+
uint16_t ArgNo;
1454+
if (P.Tok.getText().getAsInteger(0, ArgNo))
14541455
return true;
1456+
Var.ArgNo = ArgNo;
14551457
} else if (Key == "let") {
14561458
Var.Constant = true;
14571459
} else if (Key == "var") {

0 commit comments

Comments
 (0)