forked from OSchip/llvm-project
[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:
parent
818ab3d654
commit
4707bc2177
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue