Skip to content

[SIL][DebugInfo] PATCH 3/3: Deprecate debug_value_addr SIL instruciton #39082

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 1 addition & 14 deletions include/swift/SIL/DebugUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//===----------------------------------------------------------------------===//
//
// This file contains utilities to work with debug-info related instructions:
// debug_value and debug_value_addr.
// debug_value, alloc_stack, and alloc_box.
//
// SIL optimizations should deal with debug-info related instructions when
// looking at the uses of a value.
Expand Down Expand Up @@ -228,7 +228,6 @@ struct DebugVarCarryingInst {
enum class Kind {
Invalid = 0,
DebugValue,
DebugValueAddr,
AllocStack,
AllocBox,
};
Expand All @@ -239,8 +238,6 @@ struct DebugVarCarryingInst {
DebugVarCarryingInst() : kind(Kind::Invalid), inst(nullptr) {}
DebugVarCarryingInst(DebugValueInst *dvi)
: kind(Kind::DebugValue), inst(dvi) {}
DebugVarCarryingInst(DebugValueAddrInst *dvai)
: kind(Kind::DebugValueAddr), inst(dvai) {}
DebugVarCarryingInst(AllocStackInst *asi)
: kind(Kind::AllocStack), inst(asi) {}
DebugVarCarryingInst(AllocBoxInst *abi) : kind(Kind::AllocBox), inst(abi) {}
Expand All @@ -252,9 +249,6 @@ struct DebugVarCarryingInst {
case SILInstructionKind::DebugValueInst:
kind = Kind::DebugValue;
break;
case SILInstructionKind::DebugValueAddrInst:
kind = Kind::DebugValueAddr;
break;
case SILInstructionKind::AllocStackInst:
kind = Kind::AllocStack;
break;
Expand Down Expand Up @@ -283,8 +277,6 @@ struct DebugVarCarryingInst {
llvm_unreachable("Invalid?!");
case Kind::DebugValue:
return cast<DebugValueInst>(inst)->getDecl();
case Kind::DebugValueAddr:
return cast<DebugValueAddrInst>(inst)->getDecl();
case Kind::AllocStack:
return cast<AllocStackInst>(inst)->getDecl();
case Kind::AllocBox:
Expand All @@ -299,8 +291,6 @@ struct DebugVarCarryingInst {
llvm_unreachable("Invalid?!");
case Kind::DebugValue:
return cast<DebugValueInst>(inst)->getVarInfo();
case Kind::DebugValueAddr:
return cast<DebugValueAddrInst>(inst)->getVarInfo();
case Kind::AllocStack:
return cast<AllocStackInst>(inst)->getVarInfo();
case Kind::AllocBox:
Expand All @@ -316,9 +306,6 @@ struct DebugVarCarryingInst {
case Kind::DebugValue:
cast<DebugValueInst>(inst)->setDebugVarScope(NewDS);
break;
case Kind::DebugValueAddr:
cast<DebugValueAddrInst>(inst)->setDebugVarScope(NewDS);
break;
case Kind::AllocStack:
cast<AllocStackInst>(inst)->setDebugVarScope(NewDS);
break;
Expand Down
2 changes: 1 addition & 1 deletion include/swift/SIL/Projection.h
Original file line number Diff line number Diff line change
Expand Up @@ -859,7 +859,7 @@ class ProjectionTree {
ProjectionTree &operator=(ProjectionTree &&) = default;

/// Compute liveness and use information in this projection tree using Base.
/// All debug instructions (debug_value, debug_value_addr) are ignored.
/// All debug_value instructions are ignored.
void computeUsesAndLiveness(SILValue Base);

/// Create a root SILValue iout of the given leaf node values by walking on
Expand Down
6 changes: 3 additions & 3 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -927,10 +927,10 @@ class SILBuilder {
DebugValueInst *createDebugValue(SILLocation Loc, SILValue src,
SILDebugVariable Var,
bool poisonRefs = false);
DebugValueAddrInst *createDebugValueAddr(SILLocation Loc, SILValue src,
SILDebugVariable Var);
DebugValueInst *createDebugValueAddr(SILLocation Loc, SILValue src,
SILDebugVariable Var);

/// Create a debug_value_addr if \p src is an address; a debug_value if not.
/// Create a debug_value according to the type of \p src
SILInstruction *emitDebugDescription(SILLocation Loc, SILValue src,
SILDebugVariable Var) {
if (src->getType().isAddress())
Expand Down
18 changes: 0 additions & 18 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -1254,24 +1254,6 @@ SILCloner<ImplClass>::visitDebugValueInst(DebugValueInst *Inst) {
remapDebugVarInfo(DebugVarCarryingInst(NewInst));
recordClonedInstruction(Inst, NewInst);
}
template<typename ImplClass>
void
SILCloner<ImplClass>::visitDebugValueAddrInst(DebugValueAddrInst *Inst) {
// We cannot inline/clone debug intrinsics without a scope. If they
// describe function arguments there is no way to determine which
// function they belong to.
if (!Inst->getDebugScope())
return;

// Do not remap the location for a debug Instruction.
SILDebugVariable VarInfo = *Inst->getVarInfo();
SILValue OpValue = getOpValue(Inst->getOperand());
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
auto *NewInst = getBuilder().createDebugValueAddr(Inst->getLoc(), OpValue,
*Inst->getVarInfo());
remapDebugVarInfo(DebugVarCarryingInst(NewInst));
recordClonedInstruction(Inst, NewInst);
}

#define NEVER_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
template <typename ImplClass> \
Expand Down
9 changes: 9 additions & 0 deletions include/swift/SIL/SILDebugInfoExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,15 @@ class SILDebugInfoExpression {
appendElements(Tail.Elements);
}

void prependElements(llvm::ArrayRef<SILDIExprElement> NewElements) {
Elements.insert(Elements.begin(),
NewElements.begin(), NewElements.end());
}

void eraseElement(const_iterator It) {
Elements.erase(It);
}

/// The iterator for SILDIExprOperand
class op_iterator {
friend class SILDebugInfoExpression;
Expand Down
78 changes: 22 additions & 56 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -734,8 +734,7 @@ class SILInstruction : public llvm::ilist_node<SILInstruction> {
/// Returns true if the instruction is only relevant for debug
/// informations and has no other impact on program semantics.
bool isDebugInstruction() const {
return getKind() == SILInstructionKind::DebugValueInst ||
getKind() == SILInstructionKind::DebugValueAddrInst;
return getKind() == SILInstructionKind::DebugValueInst;
}

/// Returns true if the instruction is a meta instruction which is
Expand Down Expand Up @@ -1720,8 +1719,8 @@ class UnaryInstructionWithTypeDependentOperandsBase
};

/// Holds common debug information about local variables and function
/// arguments that are needed by DebugValueInst, DebugValueAddrInst,
/// AllocStackInst, and AllocBoxInst.
/// arguments that are needed by DebugValueInst, AllocStackInst,
/// and AllocBoxInst.
struct SILDebugVariable {
StringRef Name;
unsigned ArgNo : 16;
Expand Down Expand Up @@ -4672,6 +4671,8 @@ class DebugValueInst final
static DebugValueInst *create(SILDebugLocation DebugLoc, SILValue Operand,
SILModule &M, SILDebugVariable Var,
bool poisonRefs);
static DebugValueInst *createAddr(SILDebugLocation DebugLoc, SILValue Operand,
SILModule &M, SILDebugVariable Var);

SIL_DEBUG_VAR_SUPPLEMENT_TRAILING_OBJS_IMPL()

Expand Down Expand Up @@ -4706,6 +4707,23 @@ class DebugValueInst final
*getTrailingObjects<const SILDebugScope *>() = NewDS;
}

/// Whether the SSA value associated with the current debug_value
/// instruction has an address type.
bool hasAddrVal() const {
return getOperand()->getType().isAddress();
}

/// An utility to check if \p I is DebugValueInst and
/// whether it's associated with address type SSA value.
static DebugValueInst *hasAddrVal(SILInstruction *I) {
auto *DVI = dyn_cast_or_null<DebugValueInst>(I);
return DVI && DVI->hasAddrVal()? DVI : nullptr;
}

/// Whether the attached di-expression (if there is any) starts
/// with `op_deref`.
bool exprStartsWithDeref() const;

/// True if all references within this debug value will be overwritten with a
/// poison sentinel at this point in the program. This is used in debug builds
/// when shortening non-trivial value lifetimes to ensure the debugger cannot
Expand All @@ -4722,58 +4740,6 @@ class DebugValueInst final
}
};

/// Define the start or update to a symbolic variable value (for address-only
/// types) .
class DebugValueAddrInst final
: public UnaryInstructionBase<SILInstructionKind::DebugValueAddrInst,
NonValueInstruction>,
private SILDebugVariableSupplement,
private llvm::TrailingObjects<DebugValueAddrInst, SILType, SILLocation,
const SILDebugScope *, SILDIExprElement,
char> {
friend TrailingObjects;
friend SILBuilder;

TailAllocatedDebugVariable VarInfo;

DebugValueAddrInst(SILDebugLocation DebugLoc, SILValue Operand,
SILDebugVariable Var);
static DebugValueAddrInst *create(SILDebugLocation DebugLoc,
SILValue Operand, SILModule &M,
SILDebugVariable Var);

SIL_DEBUG_VAR_SUPPLEMENT_TRAILING_OBJS_IMPL()

public:
/// Return the underlying variable declaration that this denotes,
/// or null if we don't have one.
VarDecl *getDecl() const;
/// Return the debug variable information attached to this instruction.
Optional<SILDebugVariable> getVarInfo() const {
Optional<SILType> AuxVarType;
Optional<SILLocation> VarDeclLoc;
const SILDebugScope *VarDeclScope = nullptr;
if (HasAuxDebugVariableType)
AuxVarType = *getTrailingObjects<SILType>();

if (hasAuxDebugLocation())
VarDeclLoc = *getTrailingObjects<SILLocation>();
if (hasAuxDebugScope())
VarDeclScope = *getTrailingObjects<const SILDebugScope *>();

llvm::ArrayRef<SILDIExprElement> DIExprElements(
getTrailingObjects<SILDIExprElement>(), NumDIExprOperands);

return VarInfo.get(getDecl(), getTrailingObjects<char>(), AuxVarType,
VarDeclLoc, VarDeclScope, DIExprElements);
}

void setDebugVarScope(const SILDebugScope *NewDS) {
if (hasAuxDebugScope())
*getTrailingObjects<const SILDebugScope *>() = NewDS;
}
};

/// An abstract class representing a load from some kind of reference storage.
template <SILInstructionKind K>
class LoadReferenceInstBase
Expand Down
2 changes: 0 additions & 2 deletions include/swift/SIL/SILNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -875,8 +875,6 @@ NON_VALUE_INST(MarkFunctionEscapeInst, mark_function_escape,
SILInstruction, None, DoesNotRelease)
BRIDGED_NON_VALUE_INST(DebugValueInst, debug_value,
SILInstruction, None, DoesNotRelease)
BRIDGED_NON_VALUE_INST(DebugValueAddrInst, debug_value_addr,
SILInstruction, None, DoesNotRelease)
#define NEVER_OR_SOMETIMES_LOADABLE_CHECKED_REF_STORAGE(Name, name, ...) \
NON_VALUE_INST(Store##Name##Inst, store_##name, \
SILInstruction, MayWrite, DoesNotRelease)
Expand Down
8 changes: 4 additions & 4 deletions include/swift/SILOptimizer/Utils/CanonicalOSSALifetime.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@
/// bb0(%arg : @owned $T, %addr : @trivial $*T):
/// %copy = copy_value %arg : $T
/// store %copy to [init] %addr : $*T
/// debug_value_addr %addr : $*T
/// debug_value %addr : $*T, expr op_deref
/// destroy_value %arg : $T
///
/// Will be transformed to:
///
/// bb0(%arg : @owned $T, %addr : @trivial $*T):
/// store %copy to [init] %addr : $*T
/// debug_value_addr %addr : $*T
/// debug_value %addr : $*T, expr op_deref
///
/// Example #2: Destroys are hoisted to the last use. Copies are inserted only
/// at consumes within the lifetime (to directly satisfy ownership conventions):
Expand All @@ -43,7 +43,7 @@
/// %copy1 = copy_value %arg : $T
/// store %arg to [init] %addr : $*T
/// %_ = apply %_(%copy1) : $@convention(thin) (@guaranteed T) -> ()
/// debug_value_addr %addr : $*T
/// debug_value %addr : $*T, expr op_deref
/// destroy_value %copy1 : $T
///
/// Will be transformed to:
Expand All @@ -53,7 +53,7 @@
/// store %copy1 to [init] %addr : $*T
/// %_ = apply %_(%arg) : $@convention(thin) (@guaranteed T) -> ()
/// destroy_value %arg : $T
/// debug_value_addr %addr : $*T
/// debug_value %addr : $*T, expr op_deref
///
/// Example #3: Handle control flow.
///
Expand Down
3 changes: 1 addition & 2 deletions include/swift/SILOptimizer/Utils/DebugOptUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ inline void deleteAllDebugUses(SILInstruction *inst,
}

/// Transfer debug info associated with (the result of) \p I to a
/// new `debug_value` or `debug_value_addr` instruction before \p I is
/// deleted.
/// new `debug_value` instruction before \p I is deleted.
void salvageDebugInfo(SILInstruction *I);

/// Erases the instruction \p I from it's parent block and deletes it, including
Expand Down
3 changes: 3 additions & 0 deletions lib/IRGen/IRGenDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2410,6 +2410,9 @@ bool IRGenDebugInfoImpl::buildDebugInfoExpression(
if (!handleFragmentDIExpr(ExprOperand, Operands))
return false;
break;
case SILDIExprOperator::Dereference:
Operands.push_back(llvm::dwarf::DW_OP_deref);
break;
default:
llvm_unreachable("Unrecognized operator");
}
Expand Down
Loading