Skip to content

Commit 87d7237

Browse files
committed
Add debug_value [trace] attribute.
This lets us write optimizer unit tests and selectively debug the optimizer in general. We'll be able trace analyses and control optimization selectively for certain values. Adding a trace flag to debug_value is the easiest way to start using it experimentally and develop the rest of the infrastructure. If this takes off, then we can consider a new `trace_value` instruction. For now, reusing debug_value is the least intrusive way to start writing liveness unit tests.
1 parent bc37208 commit 87d7237

File tree

12 files changed

+65
-17
lines changed

12 files changed

+65
-17
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -957,10 +957,12 @@ class SILBuilder {
957957
DebugValueInst *createDebugValue(SILLocation Loc, SILValue src,
958958
SILDebugVariable Var,
959959
bool poisonRefs = false,
960-
bool wasMoved = false);
960+
bool wasMoved = false,
961+
bool trace = false);
961962
DebugValueInst *createDebugValueAddr(SILLocation Loc, SILValue src,
962963
SILDebugVariable Var,
963-
bool wasMoved = false);
964+
bool wasMoved = false,
965+
bool trace = false);
964966

965967
/// Create a debug_value according to the type of \p src
966968
SILInstruction *emitDebugDescription(SILLocation Loc, SILValue src,

include/swift/SIL/SILCloner.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1283,7 +1283,7 @@ SILCloner<ImplClass>::visitDebugValueInst(DebugValueInst *Inst) {
12831283
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
12841284
auto *NewInst = getBuilder().createDebugValue(
12851285
Inst->getLoc(), getOpValue(Inst->getOperand()), VarInfo,
1286-
Inst->poisonRefs(), Inst->getWasMoved());
1286+
Inst->poisonRefs(), Inst->getWasMoved(), Inst->hasTrace());
12871287
remapDebugVarInfo(DebugVarCarryingInst(NewInst));
12881288
recordClonedInstruction(Inst, NewInst);
12891289
}

include/swift/SIL/SILInstruction.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4832,13 +4832,15 @@ class DebugValueInst final
48324832
USE_SHARED_UINT8;
48334833

48344834
DebugValueInst(SILDebugLocation DebugLoc, SILValue Operand,
4835-
SILDebugVariable Var, bool poisonRefs, bool operandWasMoved);
4835+
SILDebugVariable Var, bool poisonRefs, bool operandWasMoved,
4836+
bool trace);
48364837
static DebugValueInst *create(SILDebugLocation DebugLoc, SILValue Operand,
48374838
SILModule &M, SILDebugVariable Var,
4838-
bool poisonRefs, bool operandWasMoved);
4839+
bool poisonRefs, bool operandWasMoved,
4840+
bool trace);
48394841
static DebugValueInst *createAddr(SILDebugLocation DebugLoc, SILValue Operand,
48404842
SILModule &M, SILDebugVariable Var,
4841-
bool operandWasMoved);
4843+
bool operandWasMoved, bool trace);
48424844

48434845
SIL_DEBUG_VAR_SUPPLEMENT_TRAILING_OBJS_IMPL()
48444846

@@ -4915,6 +4917,12 @@ class DebugValueInst final
49154917
void setPoisonRefs(bool poisonRefs = true) {
49164918
sharedUInt8().DebugValueInst.poisonRefs = poisonRefs;
49174919
}
4920+
4921+
bool hasTrace() const { return sharedUInt8().DebugValueInst.trace; }
4922+
4923+
void setTrace(bool trace = true) {
4924+
sharedUInt8().DebugValueInst.trace = trace;
4925+
}
49184926
};
49194927

49204928
/// An abstract class representing a load from some kind of reference storage.

include/swift/SIL/SILNode.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,8 @@ class alignas(8) SILNode :
204204

205205
SHARED_FIELD(DebugValueInst, uint8_t
206206
poisonRefs : 1,
207-
operandWasMoved : 1);
207+
operandWasMoved : 1,
208+
trace : 1);
208209

209210
SHARED_FIELD(AllocStackInst, uint8_t
210211
dynamicLifetime : 1,

include/swift/SIL/SILValue.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,10 @@ class ValueBase : public SILNode, public SILAllocated<ValueBase> {
572572
return true;
573573
}
574574

575+
/// Returns true if this value should be traced for optimization debugging
576+
/// (it has a debug_value [trace] user).
577+
bool hasDebugTrace() const;
578+
575579
static bool classof(SILNodePointer node) {
576580
return node->getKind() >= SILNodeKind::First_ValueBase &&
577581
node->getKind() <= SILNodeKind::Last_ValueBase;

lib/SIL/IR/SILBuilder.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -589,24 +589,26 @@ void SILBuilder::emitDestructureValueOperation(
589589
DebugValueInst *SILBuilder::createDebugValue(SILLocation Loc, SILValue src,
590590
SILDebugVariable Var,
591591
bool poisonRefs,
592-
bool operandWasMoved) {
592+
bool operandWasMoved,
593+
bool trace) {
593594
llvm::SmallString<4> Name;
594595
// Debug location overrides cannot apply to debug value instructions.
595596
DebugLocOverrideRAII LocOverride{*this, None};
596597
return insert(DebugValueInst::create(
597598
getSILDebugLocation(Loc), src, getModule(),
598-
*substituteAnonymousArgs(Name, Var, Loc), poisonRefs, operandWasMoved));
599+
*substituteAnonymousArgs(Name, Var, Loc), poisonRefs, operandWasMoved,
600+
trace));
599601
}
600602

601603
DebugValueInst *SILBuilder::createDebugValueAddr(SILLocation Loc, SILValue src,
602604
SILDebugVariable Var,
603-
bool wasMoved) {
605+
bool wasMoved, bool trace) {
604606
llvm::SmallString<4> Name;
605607
// Debug location overrides cannot apply to debug addr instructions.
606608
DebugLocOverrideRAII LocOverride{*this, None};
607609
return insert(DebugValueInst::createAddr(
608610
getSILDebugLocation(Loc), src, getModule(),
609-
*substituteAnonymousArgs(Name, Var, Loc), wasMoved));
611+
*substituteAnonymousArgs(Name, Var, Loc), wasMoved, trace));
610612
}
611613

612614
void SILBuilder::emitScopedBorrowOperation(SILLocation loc, SILValue original,

lib/SIL/IR/SILInstructions.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ SILType AllocBoxInst::getAddressType() const {
351351

352352
DebugValueInst::DebugValueInst(SILDebugLocation DebugLoc, SILValue Operand,
353353
SILDebugVariable Var, bool poisonRefs,
354-
bool wasMoved)
354+
bool wasMoved, bool trace)
355355
: UnaryInstructionBase(DebugLoc, Operand),
356356
SILDebugVariableSupplement(Var.DIExpr.getNumElements(),
357357
Var.Type.hasValue(), Var.Loc.hasValue(),
@@ -365,29 +365,30 @@ DebugValueInst::DebugValueInst(SILDebugLocation DebugLoc, SILValue Operand,
365365
setPoisonRefs(poisonRefs);
366366
if (wasMoved)
367367
markAsMoved();
368+
setTrace(trace);
368369
}
369370

370371
DebugValueInst *DebugValueInst::create(SILDebugLocation DebugLoc,
371372
SILValue Operand, SILModule &M,
372373
SILDebugVariable Var, bool poisonRefs,
373-
bool wasMoved) {
374+
bool wasMoved, bool trace) {
374375
void *buf = allocateDebugVarCarryingInst<DebugValueInst>(M, Var);
375376
return ::new (buf)
376-
DebugValueInst(DebugLoc, Operand, Var, poisonRefs, wasMoved);
377+
DebugValueInst(DebugLoc, Operand, Var, poisonRefs, wasMoved, trace);
377378
}
378379

379380
DebugValueInst *DebugValueInst::createAddr(SILDebugLocation DebugLoc,
380381
SILValue Operand, SILModule &M,
381382
SILDebugVariable Var,
382-
bool wasMoved) {
383+
bool wasMoved, bool trace) {
383384
// For alloc_stack, debug_value is used to annotate the associated
384385
// memory location, so we shouldn't attach op_deref.
385386
if (!isa<AllocStackInst>(Operand))
386387
Var.DIExpr.prependElements(
387388
{SILDIExprElement::createOperator(SILDIExprOperator::Dereference)});
388389
void *buf = allocateDebugVarCarryingInst<DebugValueInst>(M, Var);
389390
return ::new (buf) DebugValueInst(DebugLoc, Operand, Var,
390-
/*poisonRefs=*/false, wasMoved);
391+
/*poisonRefs=*/false, wasMoved, trace);
391392
}
392393

393394
bool DebugValueInst::exprStartsWithDeref() const {

lib/SIL/IR/SILPrinter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,6 +1737,8 @@ class SILPrinter : public SILInstructionVisitor<SILPrinter> {
17371737
*this << "[poison] ";
17381738
if (DVI->getWasMoved())
17391739
*this << "[moved] ";
1740+
if (DVI->hasTrace())
1741+
*this << "[trace] ";
17401742
*this << getIDAndType(DVI->getOperand());
17411743
printDebugVar(DVI->getVarInfo(),
17421744
&DVI->getModule().getASTContext().SourceMgr);

lib/SIL/IR/SILValue.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,16 @@ bool ValueBase::isLexical() const {
118118
return false;
119119
}
120120

121+
bool ValueBase::hasDebugTrace() const {
122+
for (auto *op : getUses()) {
123+
if (auto *debugValue = dyn_cast<DebugValueInst>(op->getUser())) {
124+
if (debugValue->hasTrace())
125+
return true;
126+
}
127+
}
128+
return false;
129+
}
130+
121131
SILBasicBlock *SILNode::getParentBlock() const {
122132
if (auto *Inst = dyn_cast<SILInstruction>(this))
123133
return Inst->getParent();

lib/SIL/Parser/ParseSIL.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3347,6 +3347,7 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
33473347
case SILInstructionKind::DebugValueInst: {
33483348
bool poisonRefs = false;
33493349
bool wasMoved = false;
3350+
bool hasTrace = false;
33503351
SILDebugVariable VarInfo;
33513352

33523353
// Allow for poison and moved to be in either order.
@@ -3357,6 +3358,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
33573358
poisonRefs = true;
33583359
else if (attributeName == "moved")
33593360
wasMoved = true;
3361+
else if (attributeName == "trace")
3362+
hasTrace = true;
33603363
else {
33613364
P.diagnose(attributeLoc, diag::sil_invalid_attribute_for_instruction,
33623365
attributeName, "debug_value");
@@ -3369,7 +3372,8 @@ bool SILParser::parseSpecificSILInstruction(SILBuilder &B,
33693372
return true;
33703373
if (Val->getType().isAddress())
33713374
assert(!poisonRefs && "debug_value w/ address value does not support poison");
3372-
ResultVal = B.createDebugValue(InstLoc, Val, VarInfo, poisonRefs, wasMoved);
3375+
ResultVal = B.createDebugValue(InstLoc, Val, VarInfo, poisonRefs, wasMoved,
3376+
hasTrace);
33733377
break;
33743378
}
33753379

0 commit comments

Comments
 (0)