Skip to content

Commit

Permalink
Add an argument-number field to DebugValueInst and friends.
Browse files Browse the repository at this point in the history
This commit adds a DebugVariable field that is shared by
- AllocBoxInst
- AllocStackInst
- DebugValueInst
- DebugValueAddrInst
Currently DebugVariable only holds the Swift argument number.

This allows us to retire several expensive heuristics in IRGen that
attempted to identify which local variables actually where arguments
and recover their relative order.

Memory footprint notes:
This commit adds a 4-byte field to 4 SILInstructin subclasses.
This was offset by 8ab1e2d
which removed 20 bytes from *every* SILInstruction.

Caveats:
This commit surfaces a known bug in FunctionSigantureOpts, tracked in
rdar://problem/23727705 — debug info for exploded function arguments
cannot be expressed until this is fixed.

This reapplies ed2b16d with a bugfix for
generic function arrguments and an additional testcase.

<rdar://problem/21185379&22705926>
  • Loading branch information
adrian-prantl committed Dec 3, 2015
1 parent c2448f4 commit 7821341
Show file tree
Hide file tree
Showing 35 changed files with 326 additions and 271 deletions.
23 changes: 14 additions & 9 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,11 @@ class SILBuilder {
// SILInstruction Creation Methods
//===--------------------------------------------------------------------===//

AllocStackInst *createAllocStack(SILLocation Loc, SILType elementType) {
AllocStackInst *createAllocStack(SILLocation Loc, SILType elementType,
unsigned ArgNo = 0) {
Loc.markAsPrologue();
return insert(new (F.getModule()) AllocStackInst(
createSILDebugLocation(Loc), elementType, F));
createSILDebugLocation(Loc), elementType, F, ArgNo));
}

AllocRefInst *createAllocRef(SILLocation Loc, SILType elementType, bool objc,
Expand All @@ -249,10 +250,11 @@ class SILBuilder {
createSILDebugLocation(Loc), valueType, operand));
}

AllocBoxInst *createAllocBox(SILLocation Loc, SILType ElementType) {
AllocBoxInst *createAllocBox(SILLocation Loc, SILType ElementType,
unsigned ArgNo = 0) {
Loc.markAsPrologue();
return insert(new (F.getModule()) AllocBoxInst(createSILDebugLocation(Loc),
ElementType, F));
ElementType, F, ArgNo));
}

AllocExistentialBoxInst *
Expand Down Expand Up @@ -431,13 +433,16 @@ class SILBuilder {
return insert(
MarkFunctionEscapeInst::create(createSILDebugLocation(Loc), vars, F));
}
DebugValueInst *createDebugValue(SILLocation Loc, SILValue src) {

DebugValueInst *createDebugValue(SILLocation Loc, SILValue src,
unsigned ArgNo = 0) {
return insert(new (F.getModule())
DebugValueInst(createSILDebugLocation(Loc), src));
DebugValueInst(createSILDebugLocation(Loc), src, ArgNo));
}
DebugValueAddrInst *createDebugValueAddr(SILLocation Loc, SILValue src) {
return insert(new (F.getModule())
DebugValueAddrInst(createSILDebugLocation(Loc), src));
DebugValueAddrInst *createDebugValueAddr(SILLocation Loc, SILValue src,
unsigned ArgNo = 0) {
return insert(new (F.getModule()) DebugValueAddrInst(
createSILDebugLocation(Loc), src, ArgNo));
}

LoadWeakInst *createLoadWeak(SILLocation Loc, SILValue src, IsTake_t isTake) {
Expand Down
12 changes: 6 additions & 6 deletions include/swift/SIL/SILCloner.h
Original file line number Diff line number Diff line change
Expand Up @@ -668,9 +668,9 @@ SILCloner<ImplClass>::visitDebugValueInst(DebugValueInst *Inst) {

// Since we want the debug info to survive, we do not remap the location here.
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst,
getBuilder().createDebugValue(Inst->getLoc(),
getOpValue(Inst->getOperand())));
doPostProcess(Inst, getBuilder().createDebugValue(
Inst->getLoc(), getOpValue(Inst->getOperand()),
Inst->getVarInfo().getArgNo()));
}
template<typename ImplClass>
void
Expand All @@ -684,9 +684,9 @@ SILCloner<ImplClass>::visitDebugValueAddrInst(DebugValueAddrInst *Inst) {
// Do not remap the location for a debug Instruction.
SILValue OpValue = getOpValue(Inst->getOperand());
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
doPostProcess(Inst,
getBuilder().createDebugValueAddr(Inst->getLoc(),
OpValue));
doPostProcess(
Inst, getBuilder().createDebugValueAddr(Inst->getLoc(), OpValue,
Inst->getVarInfo().getArgNo()));
}


Expand Down
42 changes: 35 additions & 7 deletions include/swift/SIL/SILInstruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,14 +316,27 @@ class UnaryInstructionBase : public BASE {
typename std::enable_if<has_result<X>::value, SILType>::type
getType(unsigned i = 0) const { return ValueBase::getType(i); }

ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }
ArrayRef<Operand> getAllOperands() const { return Operands.asArray(); }\
MutableArrayRef<Operand> getAllOperands() { return Operands.asArray(); }

static bool classof(const ValueBase *V) {
return V->getKind() == KIND;
}
};


/// Holds common debug information about local variables and function
/// arguments that are needed by DebugValueInst, DebugValueAddrInst,
/// AllocStackInst, and AllocBoxInst.
class DebugVariable {
/// The source function argument position from left to right
/// starting with 1 or 0 if this is a local variable.
unsigned char ArgNo;
public:
DebugVariable(unsigned ArgNo) : ArgNo(ArgNo) {};
unsigned getArgNo() const { return ArgNo; }
};

//===----------------------------------------------------------------------===//
// Allocation Instructions
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -368,15 +381,20 @@ class StackPromotable {
/// reference count) stack memory. The memory is provided uninitialized.
class AllocStackInst : public AllocationInst {
friend class SILBuilder;
DebugVariable VarInfo;

AllocStackInst(SILDebugLocation *Loc, SILType elementType, SILFunction &F);
AllocStackInst(SILDebugLocation *Loc, SILType elementType, SILFunction &F,
unsigned ArgNo);

public:

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

DebugVariable getVarInfo() const { return VarInfo; };
void setArgNo(unsigned N) { VarInfo = DebugVariable(N); }

/// getElementType - Get the type of the allocated memory (as opposed to the
/// (second) type of the instruction itself, which will be an address type).
SILType getElementType() const {
Expand Down Expand Up @@ -463,7 +481,10 @@ class AllocValueBufferInst :
class AllocBoxInst : public AllocationInst {
friend class SILBuilder;

AllocBoxInst(SILDebugLocation *DebugLoc, SILType ElementType, SILFunction &F);
DebugVariable VarInfo;

AllocBoxInst(SILDebugLocation *DebugLoc, SILType ElementType, SILFunction &F,
unsigned ArgNo);

public:

Expand All @@ -478,6 +499,8 @@ class AllocBoxInst : public AllocationInst {
/// allocation, or null if this is a temporary allocation.
VarDecl *getDecl() const;

DebugVariable getVarInfo() const { return VarInfo; };

ArrayRef<Operand> getAllOperands() const { return {}; }
MutableArrayRef<Operand> getAllOperands() { return {}; }

Expand Down Expand Up @@ -1341,29 +1364,34 @@ class MarkFunctionEscapeInst : public SILInstruction {
/// types).
class DebugValueInst : public UnaryInstructionBase<ValueKind::DebugValueInst> {
friend class SILBuilder;
DebugVariable VarInfo;

DebugValueInst(SILDebugLocation *DebugLoc, SILValue Operand)
: UnaryInstructionBase(DebugLoc, Operand) {}
DebugValueInst(SILDebugLocation *DebugLoc, SILValue Operand, unsigned ArgNo)
: UnaryInstructionBase(DebugLoc, Operand), VarInfo(ArgNo) {}

public:
/// getDecl - Return the underlying variable declaration that this denotes,
/// or null if we don't have one.
VarDecl *getDecl() const;
DebugVariable getVarInfo() const { return VarInfo; }
};

/// Define the start or update to a symbolic variable value (for address-only
/// types) .
class DebugValueAddrInst
: public UnaryInstructionBase<ValueKind::DebugValueAddrInst> {
friend class SILBuilder;
DebugVariable VarInfo;

DebugValueAddrInst(SILDebugLocation *DebugLoc, SILValue Operand)
: UnaryInstructionBase(DebugLoc, Operand) {}
DebugValueAddrInst(SILDebugLocation *DebugLoc, SILValue Operand,
unsigned ArgNo)
: UnaryInstructionBase(DebugLoc, Operand), VarInfo(ArgNo) {}

public:
/// getDecl - Return the underlying variable declaration that this denotes,
/// or null if we don't have one.
VarDecl *getDecl() const;
DebugVariable getVarInfo() const { return VarInfo; }
};


Expand Down
5 changes: 5 additions & 0 deletions lib/IRGen/DebugTypeInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ namespace swift {
if (ValueDecl *D = getDecl()) return D->getDeclContext();
else return DeclOrContext.get<DeclContext*>();
}

void unwrapInOutType() {
Type = Type->castTo<InOutType>()->getObjectType().getPointer();
}

bool isNull() const { return Type == nullptr; }
bool operator==(DebugTypeInfo T) const;
bool operator!=(DebugTypeInfo T) const;
Expand Down
Loading

0 comments on commit 7821341

Please sign in to comment.