Skip to content

Commit

Permalink
Debug Info: Insert dbg.value intrinsics immediately after the instruc…
Browse files Browse the repository at this point in the history
…tion

they describe.

This improves the live ranges of local variables during debugging.

<rdar://problem/26627376>
  • Loading branch information
adrian-prantl committed Sep 23, 2016
1 parent c198611 commit fa28b5e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 17 deletions.
42 changes: 26 additions & 16 deletions lib/IRGen/IRGenDebugInfo.cpp
Expand Up @@ -922,9 +922,6 @@ void IRGenDebugInfo::emitVariableDeclaration(
: DBuilder.createAutoVariable(Scope, Name, Unit, Line, DITy,
Optimized, Flags);

// Insert a debug intrinsic into the current block.
auto *BB = Builder.GetInsertBlock();

// Running variables for the current/previous piece.
bool IsPiece = Storage.size() > 1;
uint64_t SizeOfByte = CI.getTargetInfo().getCharWidth();
Expand Down Expand Up @@ -960,40 +957,53 @@ void IRGenDebugInfo::emitVariableDeclaration(
Operands.push_back(OffsetInBits);
Operands.push_back(SizeInBits);
}
emitDbgIntrinsic(BB, Piece, Var, DBuilder.createExpression(Operands), Line,
Loc.Column, Scope, DS);
emitDbgIntrinsic(Builder, Piece, Var, DBuilder.createExpression(Operands),
Line, Loc.Column, Scope, DS);
}

// Emit locationless intrinsic for variables that were optimized away.
if (Storage.size() == 0) {
auto Zero = llvm::ConstantInt::get(IGM.Int64Ty, 0);
emitDbgIntrinsic(BB, Zero, Var, DBuilder.createExpression(), Line,
Loc.Column, Scope, DS);
}
if (Storage.size() == 0)
emitDbgIntrinsic(Builder, llvm::ConstantInt::get(IGM.Int64Ty, 0), Var,
DBuilder.createExpression(), Line, Loc.Column, Scope, DS);
}

void IRGenDebugInfo::emitDbgIntrinsic(llvm::BasicBlock *BB,
llvm::Value *Storage,
void IRGenDebugInfo::emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
llvm::DILocalVariable *Var,
llvm::DIExpression *Expr, unsigned Line,
unsigned Col, llvm::DILocalScope *Scope,
const SILDebugScope *DS) {
// Set the location/scope of the intrinsic.
auto *InlinedAt = createInlinedAt(DS);
auto DL = llvm::DebugLoc::get(Line, Col, Scope, InlinedAt);
auto *BB = Builder.GetInsertBlock();

// An alloca may only be described by exactly one dbg.declare.
if (isa<llvm::AllocaInst>(Storage) && llvm::FindAllocaDbgDeclare(Storage))
return;

// A dbg.declare is only meaningful if there is a single alloca for
// the variable that is live throughout the function. With SIL
// optimizations this is not guaranteed and a variable can end up in
// two allocas (for example, one function inlined twice).
if (isa<llvm::AllocaInst>(Storage))
if (isa<llvm::AllocaInst>(Storage)) {
DBuilder.insertDeclare(Storage, Var, Expr, DL, BB);
else
DBuilder.insertDbgValueIntrinsic(Storage, 0, Var, Expr, DL, BB);
return;
}

// If the storage is an instruction, insert the dbg.value directly after it.
if (auto *I = dyn_cast<llvm::Instruction>(Storage)) {
auto InsPt = std::next(I->getIterator());
auto E = I->getParent()->end();
while (InsPt != E && isa<llvm::PHINode>(&*InsPt))
++InsPt;
if (InsPt != E) {
DBuilder.insertDbgValueIntrinsic(Storage, 0, Var, Expr, DL, &*InsPt);
return;
}
}

// Otherwise just insert it at the current insertion point.
DBuilder.insertDbgValueIntrinsic(Storage, 0, Var, Expr, DL, BB);
}

void IRGenDebugInfo::emitGlobalVariableDeclaration(
Expand Down
2 changes: 1 addition & 1 deletion lib/IRGen/IRGenDebugInfo.h
Expand Up @@ -188,7 +188,7 @@ class IRGenDebugInfo {
ArtificialKind = RealValue);

/// Emit a dbg.declare or dbg.value intrinsic, depending on Storage.
void emitDbgIntrinsic(llvm::BasicBlock *BB, llvm::Value *Storage,
void emitDbgIntrinsic(IRBuilder &Builder, llvm::Value *Storage,
llvm::DILocalVariable *Var, llvm::DIExpression *Expr,
unsigned Line, unsigned Col, llvm::DILocalScope *Scope,
const SILDebugScope *DS);
Expand Down
9 changes: 9 additions & 0 deletions test/DebugInfo/dbgvalue-insertpt.swift
@@ -0,0 +1,9 @@
// RUN: %target-swift-frontend -g -emit-ir %s | %FileCheck %s
for i in 0 ..< 3 {
// CHECK: %[[ALLOCA:[0-9]+]] = alloca %GSqSi_
// CHECK: %[[CAST:[0-9]+]] = bitcast %GSqSi_* %[[ALLOCA]] to i{{32|64}}*
// CHECK: %[[LD:[0-9]+]] = load i{{32|64}}, i{{32|64}}* %[[CAST]]
// CHECK-NEXT: call void @llvm.dbg.value(metadata i{{32|64}} %[[LD]],
// CHECK-SAME: metadata ![[I:[0-9]+]],
// CHECK: ![[I]] = !DILocalVariable(name: "i",
}

0 comments on commit fa28b5e

Please sign in to comment.