Skip to content

[DebugInfo] Suppress lots of users of DbgValueInst #149476

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
Jul 18, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 0 additions & 4 deletions llvm/include/llvm/Transforms/Utils/SSAUpdater.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ template <typename T> class SSAUpdaterTraits;
class Type;
class Use;
class Value;
class DbgValueInst;

/// Helper class for SSA formation on a set of values defined in
/// multiple blocks.
Expand Down Expand Up @@ -122,8 +121,6 @@ class SSAUpdater {
/// the instruction. Anything outside of its block will have its
/// value set to the new SSA value if available, and undef if not.
void UpdateDebugValues(Instruction *I);
void UpdateDebugValues(Instruction *I,
SmallVectorImpl<DbgValueInst *> &DbgValues);
void UpdateDebugValues(Instruction *I,
SmallVectorImpl<DbgVariableRecord *> &DbgValues);

Expand All @@ -136,7 +133,6 @@ class SSAUpdater {

private:
Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
void UpdateDebugValue(Instruction *I, DbgValueInst *DbgValue);
void UpdateDebugValue(Instruction *I, DbgVariableRecord *DbgValue);
};

Expand Down
59 changes: 5 additions & 54 deletions llvm/lib/CodeGen/CodeGenPrepare.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,6 @@ class CodeGenPrepare {
bool optimizeSwitchInst(SwitchInst *SI);
bool optimizeExtractElementInst(Instruction *Inst);
bool dupRetToEnableTailCallOpts(BasicBlock *BB, ModifyDT &ModifiedDT);
bool fixupDbgValue(Instruction *I);
bool fixupDbgVariableRecord(DbgVariableRecord &I);
bool fixupDbgVariableRecordsOnInst(Instruction &I);
bool placeDbgValues(Function &F);
Expand Down Expand Up @@ -2762,9 +2761,6 @@ bool CodeGenPrepare::optimizeCallInst(CallInst *CI, ModifyDT &ModifiedDT) {
case Intrinsic::fshl:
case Intrinsic::fshr:
return optimizeFunnelShift(II);
case Intrinsic::dbg_assign:
case Intrinsic::dbg_value:
return fixupDbgValue(II);
case Intrinsic::masked_gather:
return optimizeGatherScatterInst(II, II->getArgOperand(0));
case Intrinsic::masked_scatter:
Expand Down Expand Up @@ -3554,8 +3550,6 @@ class TypePromotionTransaction {
/// Keep track of the original uses (pair Instruction, Index).
SmallVector<InstructionAndIdx, 4> OriginalUses;
/// Keep track of the debug users.
SmallVector<DbgValueInst *, 1> DbgValues;
/// And non-instruction debug-users too.
SmallVector<DbgVariableRecord *, 1> DbgVariableRecords;

/// Keep track of the new value so that we can undo it by replacing
Expand All @@ -3577,7 +3571,9 @@ class TypePromotionTransaction {
}
// Record the debug uses separately. They are not in the instruction's
// use list, but they are replaced by RAUW.
SmallVector<DbgValueInst *> DbgValues;
findDbgValues(DbgValues, Inst, &DbgVariableRecords);
assert(DbgValues.empty());

// Now, we can replace the uses.
Inst->replaceAllUsesWith(New);
Expand All @@ -3591,11 +3587,7 @@ class TypePromotionTransaction {
// RAUW has replaced all original uses with references to the new value,
// including the debug uses. Since we are undoing the replacements,
// the original debug uses must also be reinstated to maintain the
// correctness and utility of debug value instructions.
for (auto *DVI : DbgValues)
DVI->replaceVariableLocationOp(New, Inst);
// Similar story with DbgVariableRecords, the non-instruction
// representation of dbg.values.
// correctness and utility of debug value records.
for (DbgVariableRecord *DVR : DbgVariableRecords)
DVR->replaceVariableLocationOp(New, Inst);
}
Expand Down Expand Up @@ -8933,32 +8925,6 @@ bool CodeGenPrepare::optimizeBlock(BasicBlock &BB, ModifyDT &ModifiedDT) {
return MadeChange;
}

// Some CGP optimizations may move or alter what's computed in a block. Check
// whether a dbg.value intrinsic could be pointed at a more appropriate operand.
bool CodeGenPrepare::fixupDbgValue(Instruction *I) {
assert(isa<DbgValueInst>(I));
DbgValueInst &DVI = *cast<DbgValueInst>(I);

// Does this dbg.value refer to a sunk address calculation?
bool AnyChange = false;
SmallDenseSet<Value *> LocationOps(DVI.location_ops().begin(),
DVI.location_ops().end());
for (Value *Location : LocationOps) {
WeakTrackingVH SunkAddrVH = SunkAddrs[Location];
Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr;
if (SunkAddr) {
// Point dbg.value at locally computed address, which should give the best
// opportunity to be accurately lowered. This update may change the type
// of pointer being referred to; however this makes no difference to
// debugging information, and we can't generate bitcasts that may affect
// codegen.
DVI.replaceVariableLocationOp(Location, SunkAddr);
AnyChange = true;
}
}
return AnyChange;
}

bool CodeGenPrepare::fixupDbgVariableRecordsOnInst(Instruction &I) {
bool AnyChange = false;
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange()))
Expand Down Expand Up @@ -8993,14 +8959,6 @@ bool CodeGenPrepare::fixupDbgVariableRecord(DbgVariableRecord &DVR) {
return AnyChange;
}

static void DbgInserterHelper(DbgValueInst *DVI, BasicBlock::iterator VI) {
DVI->removeFromParent();
if (isa<PHINode>(VI))
DVI->insertBefore(VI->getParent()->getFirstInsertionPt());
else
DVI->insertAfter(VI);
}

static void DbgInserterHelper(DbgVariableRecord *DVR, BasicBlock::iterator VI) {
DVR->removeFromParent();
BasicBlock *VIBB = VI->getParent();
Expand Down Expand Up @@ -9065,15 +9023,8 @@ bool CodeGenPrepare::placeDbgValues(Function &F) {

for (BasicBlock &BB : F) {
for (Instruction &Insn : llvm::make_early_inc_range(BB)) {
// Process dbg.value intrinsics.
DbgValueInst *DVI = dyn_cast<DbgValueInst>(&Insn);
if (DVI) {
DbgProcessor(DVI, DVI);
continue;
}

// If this isn't a dbg.value, process any attached DbgVariableRecord
// records attached to this instruction.
// Process any attached DbgVariableRecord records attached to this
// instruction.
for (DbgVariableRecord &DVR : llvm::make_early_inc_range(
filterDbgVars(Insn.getDbgRecordRange()))) {
if (DVR.Type != DbgVariableRecord::LocationType::Value)
Expand Down
18 changes: 1 addition & 17 deletions llvm/lib/CodeGen/MachineDebugify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,24 +63,9 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
// which cover a wide range of lines can help stress the debug info passes:
// if we can't do that, fall back to using the local variable which precedes
// all the others.
Function *DbgValF = M.getFunction("llvm.dbg.value");
DbgValueInst *EarliestDVI = nullptr;
DbgVariableRecord *EarliestDVR = nullptr;
DenseMap<unsigned, DILocalVariable *> Line2Var;
DIExpression *Expr = nullptr;
if (DbgValF) {
for (const Use &U : DbgValF->uses()) {
auto *DVI = dyn_cast<DbgValueInst>(U.getUser());
if (!DVI || DVI->getFunction() != &F)
continue;
unsigned Line = DVI->getDebugLoc().getLine();
assert(Line != 0 && "debugify should not insert line 0 locations");
Line2Var[Line] = DVI->getVariable();
if (!EarliestDVI || Line < EarliestDVI->getDebugLoc().getLine())
EarliestDVI = DVI;
Expr = DVI->getExpression();
}
}
for (BasicBlock &BB : F) {
for (Instruction &I : BB) {
for (DbgVariableRecord &DVR : filterDbgVars(I.getDbgRecordRange())) {
Expand Down Expand Up @@ -125,8 +110,7 @@ bool applyDebugifyMetadataToMachineFunction(MachineModuleInfo &MMI,
unsigned Line = MI.getDebugLoc().getLine();
auto It = Line2Var.find(Line);
if (It == Line2Var.end()) {
Line = EarliestDVI ? EarliestDVI->getDebugLoc().getLine()
: EarliestDVR->getDebugLoc().getLine();
Line = EarliestDVR->getDebugLoc().getLine();
It = Line2Var.find(Line);
assert(It != Line2Var.end());
}
Expand Down
6 changes: 2 additions & 4 deletions llvm/lib/Transforms/Coroutines/SpillUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,17 +514,15 @@ void collectSpillsAndAllocasFromInsts(
void collectSpillsFromDbgInfo(SpillInfo &Spills, Function &F,
const SuspendCrossingInfo &Checker) {
// We don't want the layout of coroutine frame to be affected
// by debug information. So we only choose to salvage DbgValueInst for
// by debug information. So we only choose to salvage dbg.values for
// whose value is already in the frame.
// We would handle the dbg.values for allocas specially
for (auto &Iter : Spills) {
auto *V = Iter.first;
SmallVector<DbgValueInst *, 16> DVIs;
SmallVector<DbgVariableRecord *, 16> DVRs;
findDbgValues(DVIs, V, &DVRs);
for (DbgValueInst *DVI : DVIs)
if (Checker.isDefinitionAcrossSuspend(*V, DVI))
Spills[V].push_back(DVI);
assert(DVIs.empty());
// Add the instructions which carry debug info that is in the frame.
for (DbgVariableRecord *DVR : DVRs)
if (Checker.isDefinitionAcrossSuspend(*V, DVR->Marker->MarkedInstr))
Expand Down
19 changes: 8 additions & 11 deletions llvm/lib/Transforms/IPO/MergeFunctions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ void MergeFunctions::filterInstsUnrelatedToPDI(

// Work out whether a dbg.value intrinsic or an equivalent DbgVariableRecord
// is a parameter to be preserved.
auto ExamineDbgValue = [](auto *DbgVal, auto &Container) {
auto ExamineDbgValue = [&PDVRRelated](DbgVariableRecord *DbgVal) {
LLVM_DEBUG(dbgs() << " Deciding: ");
LLVM_DEBUG(DbgVal->print(dbgs()));
LLVM_DEBUG(dbgs() << "\n");
Expand All @@ -581,15 +581,16 @@ void MergeFunctions::filterInstsUnrelatedToPDI(
LLVM_DEBUG(dbgs() << " Include (parameter): ");
LLVM_DEBUG(DbgVal->print(dbgs()));
LLVM_DEBUG(dbgs() << "\n");
Container.insert(DbgVal);
PDVRRelated.insert(DbgVal);
} else {
LLVM_DEBUG(dbgs() << " Delete (!parameter): ");
LLVM_DEBUG(DbgVal->print(dbgs()));
LLVM_DEBUG(dbgs() << "\n");
}
};

auto ExamineDbgDeclare = [&PDIRelated](auto *DbgDecl, auto &Container) {
auto ExamineDbgDeclare = [&PDIRelated,
&PDVRRelated](DbgVariableRecord *DbgDecl) {
LLVM_DEBUG(dbgs() << " Deciding: ");
LLVM_DEBUG(DbgDecl->print(dbgs()));
LLVM_DEBUG(dbgs() << "\n");
Expand All @@ -616,7 +617,7 @@ void MergeFunctions::filterInstsUnrelatedToPDI(
LLVM_DEBUG(dbgs() << " Include: ");
LLVM_DEBUG(DbgDecl->print(dbgs()));
LLVM_DEBUG(dbgs() << "\n");
Container.insert(DbgDecl);
PDVRRelated.insert(DbgDecl);
} else {
LLVM_DEBUG(dbgs() << " Delete (!parameter): ");
LLVM_DEBUG(SI->print(dbgs()));
Expand Down Expand Up @@ -647,18 +648,14 @@ void MergeFunctions::filterInstsUnrelatedToPDI(
// they connected to parameters?
for (DbgVariableRecord &DVR : filterDbgVars(BI->getDbgRecordRange())) {
if (DVR.isDbgValue() || DVR.isDbgAssign()) {
ExamineDbgValue(&DVR, PDVRRelated);
ExamineDbgValue(&DVR);
} else {
assert(DVR.isDbgDeclare());
ExamineDbgDeclare(&DVR, PDVRRelated);
ExamineDbgDeclare(&DVR);
}
}

if (auto *DVI = dyn_cast<DbgValueInst>(&*BI)) {
ExamineDbgValue(DVI, PDIRelated);
} else if (auto *DDI = dyn_cast<DbgDeclareInst>(&*BI)) {
ExamineDbgDeclare(DDI, PDIRelated);
} else if (BI->isTerminator() && &*BI == GEntryBlock->getTerminator()) {
if (BI->isTerminator() && &*BI == GEntryBlock->getTerminator()) {
LLVM_DEBUG(dbgs() << " Will Include Terminator: ");
LLVM_DEBUG(BI->print(dbgs()));
LLVM_DEBUG(dbgs() << "\n");
Expand Down
11 changes: 3 additions & 8 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1420,21 +1420,16 @@ void InstCombinerImpl::freelyInvertAllUsersOf(Value *I, Value *IgnoredUser) {
SmallVector<DbgValueInst *, 4> DbgValues;
SmallVector<DbgVariableRecord *, 4> DbgVariableRecords;
llvm::findDbgValues(DbgValues, I, &DbgVariableRecords);
assert(DbgValues.empty());

auto InvertDbgValueUse = [&](auto *DbgVal) {
for (DbgVariableRecord *DbgVal : DbgVariableRecords) {
SmallVector<uint64_t, 1> Ops = {dwarf::DW_OP_not};
for (unsigned Idx = 0, End = DbgVal->getNumVariableLocationOps();
Idx != End; ++Idx)
if (DbgVal->getVariableLocationOp(Idx) == I)
DbgVal->setExpression(
DIExpression::appendOpsToArg(DbgVal->getExpression(), Ops, Idx));
};

for (DbgValueInst *DVI : DbgValues)
InvertDbgValueUse(DVI);

for (DbgVariableRecord *DVR : DbgVariableRecords)
InvertDbgValueUse(DVR);
}
}

/// Given a 'sub' instruction, return the RHS of the instruction if the LHS is a
Expand Down
39 changes: 4 additions & 35 deletions llvm/lib/Transforms/Scalar/JumpThreading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1979,15 +1979,13 @@ void JumpThreadingPass::updateSSA(BasicBlock *BB, BasicBlock *NewBB,

// Find debug values outside of the block
findDbgValues(DbgValues, &I, &DbgVariableRecords);
llvm::erase_if(DbgValues, [&](const DbgValueInst *DbgVal) {
return DbgVal->getParent() == BB;
});
assert(DbgValues.empty());
llvm::erase_if(DbgVariableRecords, [&](const DbgVariableRecord *DbgVarRec) {
return DbgVarRec->getParent() == BB;
});

// If there are no uses outside the block, we're done with this instruction.
if (UsesToRename.empty() && DbgValues.empty() && DbgVariableRecords.empty())
if (UsesToRename.empty() && DbgVariableRecords.empty())
continue;
LLVM_DEBUG(dbgs() << "JT: Renaming non-local uses of: " << I << "\n");

Expand All @@ -2000,8 +1998,7 @@ void JumpThreadingPass::updateSSA(BasicBlock *BB, BasicBlock *NewBB,

while (!UsesToRename.empty())
SSAUpdate.RewriteUse(*UsesToRename.pop_back_val());
if (!DbgValues.empty() || !DbgVariableRecords.empty()) {
SSAUpdate.UpdateDebugValues(&I, DbgValues);
if (!DbgVariableRecords.empty()) {
SSAUpdate.UpdateDebugValues(&I, DbgVariableRecords);
DbgValues.clear();
DbgVariableRecords.clear();
Expand Down Expand Up @@ -2032,32 +2029,7 @@ void JumpThreadingPass::cloneInstructions(ValueToValueMapTy &ValueMapping,
// copy of the block 'NewBB'. If there are PHI nodes in the source basic
// block, evaluate them to account for entry from PredBB.

// Retargets llvm.dbg.value to any renamed variables.
auto RetargetDbgValueIfPossible = [&](Instruction *NewInst) -> bool {
auto DbgInstruction = dyn_cast<DbgValueInst>(NewInst);
if (!DbgInstruction)
return false;

SmallSet<std::pair<Value *, Value *>, 16> OperandsToRemap;
for (auto DbgOperand : DbgInstruction->location_ops()) {
auto DbgOperandInstruction = dyn_cast<Instruction>(DbgOperand);
if (!DbgOperandInstruction)
continue;

auto I = ValueMapping.find(DbgOperandInstruction);
if (I != ValueMapping.end()) {
OperandsToRemap.insert(
std::pair<Value *, Value *>(DbgOperand, I->second));
}
}

for (auto &[OldOp, MappedOp] : OperandsToRemap)
DbgInstruction->replaceVariableLocationOp(OldOp, MappedOp);
return true;
};

// Duplicate implementation of the above dbg.value code, using
// DbgVariableRecords instead.
// Retargets dbg.value to any renamed variables.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since you've been updating comments, dbg.value -> (#?)dbg_value / DbgRecord, DbgVariableRecord or whatever

auto RetargetDbgVariableRecordIfPossible = [&](DbgVariableRecord *DVR) {
SmallSet<std::pair<Value *, Value *>, 16> OperandsToRemap;
for (auto *Op : DVR->location_ops()) {
Expand Down Expand Up @@ -2116,9 +2088,6 @@ void JumpThreadingPass::cloneInstructions(ValueToValueMapTy &ValueMapping,
if (const DebugLoc &DL = New->getDebugLoc())
mapAtomInstance(DL, ValueMapping);

if (RetargetDbgValueIfPossible(New))
continue;

// Remap operands to patch up intra-block references.
for (unsigned i = 0, e = New->getNumOperands(); i != e; ++i)
if (Instruction *Inst = dyn_cast<Instruction>(New->getOperand(i))) {
Expand Down
Loading
Loading