Skip to content

Commit 64cbec3

Browse files
committed
Add SIL syntax for declaring debug variables.
Debug variable info may be attached to debug_value, debug_value_addr, alloc_box, and alloc_stack instructions. In order to write textual SIL -> SIL testcases that exercise the handling of debug information by SIL passes, we need to make a couple of additions to the textual SIL language. In memory, the debug information attached to SIL instructions references information from the AST. If we want to create debug info from parsing a textual .sil file, these bits need to be made explicit. Performance Notes: This is memory neutral for compilations from Swift source code, because the variable name is still stored in the AST. For compilations from textual source the variable name is stored in tail- allocated memory following the SIL instruction that introduces the variable. <rdar://problem/22707128>
1 parent e6442dc commit 64cbec3

File tree

79 files changed

+597
-418
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+597
-418
lines changed

docs/SIL.rst

+16-4
Original file line numberDiff line numberDiff line change
@@ -1630,7 +1630,7 @@ alloc_stack
16301630
```````````
16311631
::
16321632

1633-
sil-instruction ::= 'alloc_stack' sil-type
1633+
sil-instruction ::= 'alloc_stack' sil-type (',' debug-var-attr)*
16341634

16351635
%1 = alloc_stack $T
16361636
// %1#0 has type $*@local_storage T
@@ -1697,7 +1697,7 @@ alloc_box
16971697
`````````
16981698
::
16991699
1700-
sil-instruction ::= 'alloc_box' sil-type
1700+
sil-instruction ::= 'alloc_box' sil-type (',' debug-var-attr)*
17011701

17021702
%1 = alloc_box $T
17031703
// %1 has two values:
@@ -1886,7 +1886,7 @@ debug_value
18861886

18871887
::
18881888

1889-
sil-instruction ::= debug_value sil-operand
1889+
sil-instruction ::= debug_value sil-operand (',' debug-var-attr)*
18901890
18911891
debug_value %1 : $Int
18921892
@@ -1896,12 +1896,24 @@ the SILLocation attached to the debug_value instruction.
18961896

18971897
The operand must have loadable type.
18981898

1899+
::
1900+
1901+
debug-var-attr ::= 'var'
1902+
debug-var-attr ::= 'let'
1903+
debug-var-attr ::= 'name' string-literal
1904+
debug-var-attr ::= 'argno' integer-literal
1905+
1906+
There are a number of attributes that provide details about the source
1907+
variable that is being described, including the name of the
1908+
variable. For function and closure arguments ``argno`` is the number
1909+
of the function argument starting with 1.
1910+
18991911
debug_value_addr
19001912
````````````````
19011913

19021914
::
19031915

1904-
sil-instruction ::= debug_value_addr sil-operand
1916+
sil-instruction ::= debug_value_addr sil-operand (',' debug-var-attr)*
19051917
19061918
debug_value_addr %7 : $*SomeProtocol
19071919

include/swift/AST/DiagnosticsParse.def

+2
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,8 @@ ERROR(sil_missing_substitutions,decl_parsing,none,
485485
"missing substitutions", ())
486486
ERROR(sil_too_many_substitutions,decl_parsing,none,
487487
"too many substitutions", ())
488+
ERROR(sil_dbg_unknown_key,decl_parsing,none,
489+
"unknown key '%0' in debug variable declaration", (StringRef))
488490

489491
// SIL Basic Blocks
490492
ERROR(expected_sil_block_name, decl_parsing,none,

include/swift/SIL/SILBuilder.h

+15-14
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,10 @@ class SILBuilder {
221221
//===--------------------------------------------------------------------===//
222222

223223
AllocStackInst *createAllocStack(SILLocation Loc, SILType elementType,
224-
unsigned ArgNo = 0) {
224+
SILDebugVariable Var = SILDebugVariable()) {
225225
Loc.markAsPrologue();
226-
return insert(new (F.getModule()) AllocStackInst(
227-
createSILDebugLocation(Loc), elementType, F, ArgNo));
226+
return insert(AllocStackInst::create(createSILDebugLocation(Loc),
227+
elementType, F, Var));
228228
}
229229

230230
AllocRefInst *createAllocRef(SILLocation Loc, SILType elementType, bool objc,
@@ -252,10 +252,10 @@ class SILBuilder {
252252
}
253253

254254
AllocBoxInst *createAllocBox(SILLocation Loc, SILType ElementType,
255-
unsigned ArgNo = 0) {
255+
SILDebugVariable Var = SILDebugVariable()) {
256256
Loc.markAsPrologue();
257-
return insert(new (F.getModule()) AllocBoxInst(createSILDebugLocation(Loc),
258-
ElementType, F, ArgNo));
257+
return insert(
258+
AllocBoxInst::create(createSILDebugLocation(Loc), ElementType, F, Var));
259259
}
260260

261261
AllocExistentialBoxInst *
@@ -436,14 +436,15 @@ class SILBuilder {
436436
}
437437

438438
DebugValueInst *createDebugValue(SILLocation Loc, SILValue src,
439-
unsigned ArgNo = 0) {
440-
return insert(new (F.getModule())
441-
DebugValueInst(createSILDebugLocation(Loc), src, ArgNo));
442-
}
443-
DebugValueAddrInst *createDebugValueAddr(SILLocation Loc, SILValue src,
444-
unsigned ArgNo = 0) {
445-
return insert(new (F.getModule()) DebugValueAddrInst(
446-
createSILDebugLocation(Loc), src, ArgNo));
439+
SILDebugVariable Var = SILDebugVariable()) {
440+
return insert(DebugValueInst::create(createSILDebugLocation(Loc), src,
441+
F.getModule(), Var));
442+
}
443+
DebugValueAddrInst *
444+
createDebugValueAddr(SILLocation Loc, SILValue src,
445+
SILDebugVariable Var = SILDebugVariable()) {
446+
return insert(DebugValueAddrInst::create(createSILDebugLocation(Loc), src,
447+
F.getModule(), Var));
447448
}
448449

449450
LoadWeakInst *createLoadWeak(SILLocation Loc, SILValue src, IsTake_t isTake) {

include/swift/SIL/SILCloner.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ SILCloner<ImplClass>::visitDebugValueInst(DebugValueInst *Inst) {
670670
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
671671
doPostProcess(Inst, getBuilder().createDebugValue(
672672
Inst->getLoc(), getOpValue(Inst->getOperand()),
673-
Inst->getVarInfo().getArgNo()));
673+
Inst->getVarInfo()));
674674
}
675675
template<typename ImplClass>
676676
void
@@ -684,9 +684,8 @@ SILCloner<ImplClass>::visitDebugValueAddrInst(DebugValueAddrInst *Inst) {
684684
// Do not remap the location for a debug Instruction.
685685
SILValue OpValue = getOpValue(Inst->getOperand());
686686
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
687-
doPostProcess(
688-
Inst, getBuilder().createDebugValueAddr(Inst->getLoc(), OpValue,
689-
Inst->getVarInfo().getArgNo()));
687+
doPostProcess(Inst, getBuilder().createDebugValueAddr(
688+
Inst->getLoc(), OpValue, Inst->getVarInfo()));
690689
}
691690

692691

include/swift/SIL/SILInstruction.h

+74-22
Original file line numberDiff line numberDiff line change
@@ -341,13 +341,45 @@ class UnaryInstructionBase : public BASE {
341341
/// Holds common debug information about local variables and function
342342
/// arguments that are needed by DebugValueInst, DebugValueAddrInst,
343343
/// AllocStackInst, and AllocBoxInst.
344-
class DebugVariable {
344+
struct SILDebugVariable {
345+
SILDebugVariable() : Constant(true), ArgNo(0) {}
346+
SILDebugVariable(bool Constant, unsigned ArgNo)
347+
: Constant(Constant), ArgNo(ArgNo) {}
348+
SILDebugVariable(StringRef Name, bool Constant, unsigned ArgNo)
349+
: Name(Name), Constant(Constant), ArgNo(ArgNo) {}
350+
StringRef Name;
351+
bool Constant;
352+
unsigned ArgNo;
353+
};
354+
355+
/// A DebugVariable where storage for the strings has been
356+
/// tail-allocated following the parent SILInstruction.
357+
class TailAllocatedDebugVariable {
345358
/// The source function argument position from left to right
346359
/// starting with 1 or 0 if this is a local variable.
347-
unsigned char ArgNo;
360+
unsigned ArgNo : 16;
361+
/// When this is nonzero there is a tail-allocated string storing
362+
/// variable name present. This typically only happens for
363+
/// instructions that were created from parsing SIL assembler.
364+
unsigned NameLength : 15;
365+
bool Constant : 1;
348366
public:
349-
DebugVariable(unsigned ArgNo) : ArgNo(ArgNo) {};
367+
TailAllocatedDebugVariable(SILDebugVariable DbgVar, char *buf);
368+
350369
unsigned getArgNo() const { return ArgNo; }
370+
void setArgNo(unsigned N) { ArgNo = N; }
371+
/// Returns the name of the source variable, if it is stored in the
372+
/// instruction.
373+
StringRef getName(const char *buf) const;
374+
bool isLet() const { return Constant; }
375+
376+
SILDebugVariable get(VarDecl *VD, const char *buf) const {
377+
if (VD)
378+
return {VD->getName().empty() ? "" : VD->getName().str(), VD->isLet(),
379+
getArgNo()};
380+
else
381+
return {getName(buf), isLet(), getArgNo()};
382+
}
351383
};
352384

353385
//===----------------------------------------------------------------------===//
@@ -394,19 +426,24 @@ class StackPromotable {
394426
/// reference count) stack memory. The memory is provided uninitialized.
395427
class AllocStackInst : public AllocationInst {
396428
friend class SILBuilder;
397-
DebugVariable VarInfo;
429+
TailAllocatedDebugVariable VarInfo;
398430

399431
AllocStackInst(SILDebugLocation *Loc, SILType elementType, SILFunction &F,
400-
unsigned ArgNo);
432+
SILDebugVariable Var);
433+
static AllocStackInst *create(SILDebugLocation *Loc, SILType elementType,
434+
SILFunction &F, SILDebugVariable Var);
401435

402436
public:
403437

404-
/// getDecl - Return the underlying variable declaration associated with this
438+
/// Return the underlying variable declaration associated with this
405439
/// allocation, or null if this is a temporary allocation.
406440
VarDecl *getDecl() const;
407441

408-
DebugVariable getVarInfo() const { return VarInfo; };
409-
void setArgNo(unsigned N) { VarInfo = DebugVariable(N); }
442+
/// Return the debug variable information attached to this instruction.
443+
SILDebugVariable getVarInfo() const {
444+
return VarInfo.get(getDecl(), reinterpret_cast<const char *>(this + 1));
445+
};
446+
void setArgNo(unsigned N) { VarInfo.setArgNo(N); }
410447

411448
/// getElementType - Get the type of the allocated memory (as opposed to the
412449
/// (second) type of the instruction itself, which will be an address type).
@@ -494,10 +531,12 @@ class AllocValueBufferInst :
494531
class AllocBoxInst : public AllocationInst {
495532
friend class SILBuilder;
496533

497-
DebugVariable VarInfo;
534+
TailAllocatedDebugVariable VarInfo;
498535

499536
AllocBoxInst(SILDebugLocation *DebugLoc, SILType ElementType, SILFunction &F,
500-
unsigned ArgNo);
537+
SILDebugVariable Var);
538+
static AllocBoxInst *create(SILDebugLocation *Loc, SILType elementType,
539+
SILFunction &F, SILDebugVariable Var);
501540

502541
public:
503542

@@ -508,11 +547,14 @@ class AllocBoxInst : public AllocationInst {
508547
SILValue getContainerResult() const { return SILValue(this, 0); }
509548
SILValue getAddressResult() const { return SILValue(this, 1); }
510549

511-
/// getDecl - Return the underlying variable declaration associated with this
550+
/// Return the underlying variable declaration associated with this
512551
/// allocation, or null if this is a temporary allocation.
513552
VarDecl *getDecl() const;
514553

515-
DebugVariable getVarInfo() const { return VarInfo; };
554+
/// Return the debug variable information attached to this instruction.
555+
SILDebugVariable getVarInfo() const {
556+
return VarInfo.get(getDecl(), reinterpret_cast<const char *>(this + 1));
557+
};
516558

517559
ArrayRef<Operand> getAllOperands() const { return {}; }
518560
MutableArrayRef<Operand> getAllOperands() { return {}; }
@@ -1377,34 +1419,44 @@ class MarkFunctionEscapeInst : public SILInstruction {
13771419
/// types).
13781420
class DebugValueInst : public UnaryInstructionBase<ValueKind::DebugValueInst> {
13791421
friend class SILBuilder;
1380-
DebugVariable VarInfo;
1422+
TailAllocatedDebugVariable VarInfo;
13811423

1382-
DebugValueInst(SILDebugLocation *DebugLoc, SILValue Operand, unsigned ArgNo)
1383-
: UnaryInstructionBase(DebugLoc, Operand), VarInfo(ArgNo) {}
1424+
DebugValueInst(SILDebugLocation *DebugLoc, SILValue Operand,
1425+
SILDebugVariable Var);
1426+
static DebugValueInst *create(SILDebugLocation *DebugLoc, SILValue Operand,
1427+
SILModule &M, SILDebugVariable Var);
13841428

13851429
public:
1386-
/// getDecl - Return the underlying variable declaration that this denotes,
1430+
/// Return the underlying variable declaration that this denotes,
13871431
/// or null if we don't have one.
13881432
VarDecl *getDecl() const;
1389-
DebugVariable getVarInfo() const { return VarInfo; }
1433+
/// Return the debug variable information attached to this instruction.
1434+
SILDebugVariable getVarInfo() const {
1435+
return VarInfo.get(getDecl(), reinterpret_cast<const char *>(this + 1));
1436+
}
13901437
};
13911438

13921439
/// Define the start or update to a symbolic variable value (for address-only
13931440
/// types) .
13941441
class DebugValueAddrInst
13951442
: public UnaryInstructionBase<ValueKind::DebugValueAddrInst> {
13961443
friend class SILBuilder;
1397-
DebugVariable VarInfo;
1444+
TailAllocatedDebugVariable VarInfo;
13981445

13991446
DebugValueAddrInst(SILDebugLocation *DebugLoc, SILValue Operand,
1400-
unsigned ArgNo)
1401-
: UnaryInstructionBase(DebugLoc, Operand), VarInfo(ArgNo) {}
1447+
SILDebugVariable Var);
1448+
static DebugValueAddrInst *create(SILDebugLocation *DebugLoc,
1449+
SILValue Operand, SILModule &M,
1450+
SILDebugVariable Var);
14021451

14031452
public:
1404-
/// getDecl - Return the underlying variable declaration that this denotes,
1453+
/// Return the underlying variable declaration that this denotes,
14051454
/// or null if we don't have one.
14061455
VarDecl *getDecl() const;
1407-
DebugVariable getVarInfo() const { return VarInfo; }
1456+
/// Return the debug variable information attached to this instruction.
1457+
SILDebugVariable getVarInfo() const {
1458+
return VarInfo.get(getDecl(), reinterpret_cast<const char *>(this + 1));
1459+
};
14081460
};
14091461

14101462

lib/IRGen/IRGenSIL.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -2955,7 +2955,7 @@ void IRGenSILFunction::visitDebugValueInst(DebugValueInst *i) {
29552955
llvm::SmallVector<llvm::Value *, 8> Copy;
29562956
emitShadowCopy(e.claimAll(), Name, Copy);
29572957
emitDebugVariableDeclaration(Copy, DbgTy, i->getDebugScope(), Name,
2958-
i->getVarInfo().getArgNo());
2958+
i->getVarInfo().ArgNo);
29592959
}
29602960

29612961
void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
@@ -2975,7 +2975,7 @@ void IRGenSILFunction::visitDebugValueAddrInst(DebugValueAddrInst *i) {
29752975
// Put the value into a stack slot at -Onone and emit a debug intrinsic.
29762976
emitDebugVariableDeclaration(emitShadowCopy(Addr, Name), DbgTy,
29772977
i->getDebugScope(), Name,
2978-
i->getVarInfo().getArgNo(), IndirectValue);
2978+
i->getVarInfo().ArgNo, IndirectValue);
29792979
}
29802980

29812981
void IRGenSILFunction::visitLoadWeakInst(swift::LoadWeakInst *i) {
@@ -3235,7 +3235,7 @@ static void emitDebugDeclarationForAllocStack(IRGenSILFunction &IGF,
32353235
if (DS) {
32363236
assert(DS->SILFn == IGF.CurSILFn || DS->InlinedCallSite);
32373237
IGF.emitDebugVariableDeclaration(addr, DbgTy, DS, Name,
3238-
i->getVarInfo().getArgNo());
3238+
i->getVarInfo().ArgNo);
32393239
}
32403240
}
32413241
}

0 commit comments

Comments
 (0)