[DebugInfo] Refactor SalvageDebugInfo and SalvageDebugInfoForDbgValues

- Simplify the salvaging interface and the algorithm in InstCombine

Reviewers: vsk, aprantl, Orlando, jmorse, TWeaver

Reviewed by: Orlando

Differential Revision: https://reviews.llvm.org/D79863
This commit is contained in:
Chris Jackson 2020-06-11 10:28:39 +01:00
parent 818ab3d654
commit 4707bc2177
4 changed files with 52 additions and 51 deletions

View File

@ -374,8 +374,10 @@ void salvageDebugInfo(Instruction &I);
/// Implementation of salvageDebugInfo, applying only to instructions in
/// \p Insns, rather than all debug users of \p I.
bool salvageDebugInfoForDbgValues(Instruction &I,
/// \p Insns, rather than all debug users from findDbgUsers( \p I).
/// Returns true if any debug users were updated.
/// Mark undef if salvaging cannot be completed.
void salvageDebugInfoForDbgValues(Instruction &I,
ArrayRef<DbgVariableIntrinsic *> Insns);
/// Given an instruction \p I and DIExpression \p DIExpr operating on it, write

View File

@ -3337,46 +3337,42 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
// here, but that computation has been sunk.
SmallVector<DbgVariableIntrinsic *, 2> DbgUsers;
findDbgUsers(DbgUsers, I);
for (auto *DII : reverse(DbgUsers)) {
if (DII->getParent() == SrcBlock) {
if (isa<DbgDeclareInst>(DII)) {
// A dbg.declare instruction should not be cloned, since there can only be
// one per variable fragment. It should be left in the original place since
// sunk instruction is not an alloca(otherwise we could not be here).
// But we need to update arguments of dbg.declare instruction, so that it
// would not point into sunk instruction.
if (!isa<CastInst>(I))
continue; // dbg.declare points at something it shouldn't
DII->setOperand(
0, MetadataAsValue::get(I->getContext(),
ValueAsMetadata::get(I->getOperand(0))));
continue;
}
// Update the arguments of a dbg.declare instruction, so that it
// does not point into a sunk instruction.
auto updateDbgDeclare = [&I](DbgVariableIntrinsic *DII) {
if (!isa<DbgDeclareInst>(DII))
return false;
// dbg.value is in the same basic block as the sunk inst, see if we can
// salvage it. Clone a new copy of the instruction: on success we need
// both salvaged and unsalvaged copies.
SmallVector<DbgVariableIntrinsic *, 1> TmpUser{
cast<DbgVariableIntrinsic>(DII->clone())};
if (isa<CastInst>(I))
DII->setOperand(
0, MetadataAsValue::get(I->getContext(),
ValueAsMetadata::get(I->getOperand(0))));
return true;
};
if (!salvageDebugInfoForDbgValues(*I, TmpUser)) {
// We are unable to salvage: sink the cloned dbg.value, and mark the
// original as undef, terminating any earlier variable location.
LLVM_DEBUG(dbgs() << "SINK: " << *DII << '\n');
TmpUser[0]->insertBefore(&*InsertPos);
Value *Undef = UndefValue::get(I->getType());
DII->setOperand(0, MetadataAsValue::get(DII->getContext(),
ValueAsMetadata::get(Undef)));
} else {
// We successfully salvaged: place the salvaged dbg.value in the
// original location, and move the unmodified dbg.value to sink with
// the sunk inst.
TmpUser[0]->insertBefore(DII);
DII->moveBefore(&*InsertPos);
}
SmallVector<DbgVariableIntrinsic *, 2> DIIClones;
for (auto User : DbgUsers) {
// A dbg.declare instruction should not be cloned, since there can only be
// one per variable fragment. It should be left in the original place
// because the sunk instruction is not an alloca (otherwise we could not be
// here).
if (User->getParent() != SrcBlock || updateDbgDeclare(User))
continue;
DIIClones.emplace_back(cast<DbgVariableIntrinsic>(User->clone()));
LLVM_DEBUG(dbgs() << "CLONE: " << *DIIClones.back() << '\n');
}
// Perform salvaging without the clones, then sink the clones.
if (!DIIClones.empty()) {
salvageDebugInfoForDbgValues(*I, DbgUsers);
for (auto &DIIClone : DIIClones) {
DIIClone->insertBefore(&*InsertPos);
LLVM_DEBUG(dbgs() << "SINK: " << *DIIClone << '\n');
}
}
return true;
}

View File

@ -1628,23 +1628,18 @@ static MetadataAsValue *wrapValueInMetadata(LLVMContext &C, Value *V) {
return MetadataAsValue::get(C, ValueAsMetadata::get(V));
}
static bool attemptToSalvageDebugInfo(Instruction &I) {
/// Where possible to salvage debug information for \p I do so
/// and return True. If not possible mark undef and return False.
void llvm::salvageDebugInfo(Instruction &I) {
SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
findDbgUsers(DbgUsers, &I);
if (DbgUsers.empty())
return false;
return salvageDebugInfoForDbgValues(I, DbgUsers);
salvageDebugInfoForDbgValues(I, DbgUsers);
}
void llvm::salvageDebugInfo(Instruction &I) {
if (!attemptToSalvageDebugInfo(I))
replaceDbgUsesWithUndef(&I);
}
bool llvm::salvageDebugInfoForDbgValues(
void llvm::salvageDebugInfoForDbgValues(
Instruction &I, ArrayRef<DbgVariableIntrinsic *> DbgUsers) {
auto &Ctx = I.getContext();
bool Salvaged = false;
auto wrapMD = [&](Value *V) { return wrapValueInMetadata(Ctx, V); };
for (auto *DII : DbgUsers) {
@ -1659,14 +1654,22 @@ bool llvm::salvageDebugInfoForDbgValues(
// salvageDebugInfoImpl should fail on examining the first element of
// DbgUsers, or none of them.
if (!DIExpr)
return false;
break;
DII->setOperand(0, wrapMD(I.getOperand(0)));
DII->setOperand(2, MetadataAsValue::get(Ctx, DIExpr));
LLVM_DEBUG(dbgs() << "SALVAGE: " << *DII << '\n');
Salvaged = true;
}
return true;
if (Salvaged)
return;
for (auto *DII : DbgUsers) {
Value *Undef = UndefValue::get(I.getType());
DII->setOperand(0, MetadataAsValue::get(DII->getContext(),
ValueAsMetadata::get(Undef)));
}
}
DIExpression *llvm::salvageDebugInfoImpl(Instruction &I,

View File

@ -36,8 +36,8 @@ for.body.lr.ph: ; preds = %entry
; The add is later eliminated, so we verify that the dbg.value is salvaged by using DW_OP_minus.
; CHECK-LABEL: for.body.lr.ph:
; CHECK-NEXT: %0 = load
; CHECK-NEXT: call void @llvm.dbg.value(metadata i64 %0, metadata !25, metadata !DIExpression()), !dbg !
; CHECK-NEXT: call void @llvm.dbg.value(metadata i64 %0, metadata !26, metadata !DIExpression(DW_OP_constu, 4096, DW_OP_minus, DW_OP_stack_value)), !dbg !
; CHECK-NEXT: call void @llvm.dbg.value(metadata i64 %0, metadata !25, metadata !DIExpression()), !dbg !
br label %for.body, !dbg !32
for.body: ; preds = %for.body.lr.ph, %for.body