Skip to content

[DLCov][NFC] Propagate annotated DebugLocs through transformations #138047

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

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ class LegalizationArtifactCombiner {
const LLT DstTy = MRI.getType(DstReg);
if (isInstLegal({TargetOpcode::G_CONSTANT, {DstTy}})) {
auto &CstVal = SrcMI->getOperand(1);
auto *MergedLocation = DILocation::getMergedLocation(
MI.getDebugLoc().get(), SrcMI->getDebugLoc().get());
auto MergedLocation =
DebugLoc::getMergedLocation(MI.getDebugLoc(), SrcMI->getDebugLoc());
// Set the debug location to the merged location of the SrcMI and the MI
// if the aext fold is successful.
Builder.setDebugLoc(MergedLocation);
Expand Down
25 changes: 25 additions & 0 deletions llvm/include/llvm/IR/DebugLoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,31 @@ namespace llvm {
static inline DebugLoc getDropped() { return DebugLoc(); }
#endif // LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING

static DebugLoc getMergedLocations(ArrayRef<DebugLoc> Locs);
static DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB);

/// If this DebugLoc is non-empty, returns this DebugLoc; otherwise, selects
/// \p Other.
/// In coverage-tracking builds, this also accounts for whether this or
/// \p Other have an annotative DebugLocKind applied, such that if both are
/// empty but exactly one has an annotation, we prefer that annotated
/// location.
DebugLoc orElse(DebugLoc Other) const {
if (*this)
return *this;
#if LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING
if (Other)
return Other;
if (getKind() != DebugLocKind::Normal)
return *this;
if (Other.getKind() != DebugLocKind::Normal)
return Other;
return *this;
#else
return Other;
#endif // LLVM_ENABLE_DEBUGLOC_COVERAGE_TRACKING
}

/// Get the underlying \a DILocation.
///
/// \pre !*this or \c isa<DILocation>(getAsMDNode()).
Expand Down
21 changes: 17 additions & 4 deletions llvm/include/llvm/IR/IRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,18 @@ class FMFSource {
/// Common base class shared among various IRBuilders.
class IRBuilderBase {
/// Pairs of (metadata kind, MDNode *) that should be added to all newly
/// created instructions, like !dbg metadata.
/// created instructions, excluding !dbg metadata, which is stored in the
// StoredDL field.
SmallVector<std::pair<unsigned, MDNode *>, 2> MetadataToCopy;
// The DebugLoc that will be applied to instructions inserted by this builder.
DebugLoc StoredDL;

/// Add or update the an entry (Kind, MD) to MetadataToCopy, if \p MD is not
/// null. If \p MD is null, remove the entry with \p Kind.
void AddOrRemoveMetadataToCopy(unsigned Kind, MDNode *MD) {
assert(Kind != LLVMContext::MD_dbg &&
"MD_dbg metadata must be stored in StoredDL");

if (!MD) {
erase_if(MetadataToCopy, [Kind](const std::pair<unsigned, MDNode *> &KV) {
return KV.first == Kind;
Expand Down Expand Up @@ -237,7 +243,9 @@ class IRBuilderBase {

/// Set location information used by debugging information.
void SetCurrentDebugLocation(DebugLoc L) {
AddOrRemoveMetadataToCopy(LLVMContext::MD_dbg, L.getAsMDNode());
// For !dbg metadata attachments, we use DebugLoc instead of the raw MDNode
// to include optional introspection data for use in Debugify.
StoredDL = std::move(L);
}

/// Set nosanitize metadata.
Expand All @@ -251,8 +259,12 @@ class IRBuilderBase {
/// not on \p Src will be dropped from MetadataToCopy.
void CollectMetadataToCopy(Instruction *Src,
ArrayRef<unsigned> MetadataKinds) {
for (unsigned K : MetadataKinds)
AddOrRemoveMetadataToCopy(K, Src->getMetadata(K));
for (unsigned K : MetadataKinds) {
if (K == LLVMContext::MD_dbg)
SetCurrentDebugLocation(Src->getDebugLoc());
else
AddOrRemoveMetadataToCopy(K, Src->getMetadata(K));
}
}

/// Get location information used by debugging information.
Expand All @@ -266,6 +278,7 @@ class IRBuilderBase {
void AddMetadataToInst(Instruction *I) const {
for (const auto &KV : MetadataToCopy)
I->setMetadata(KV.first, KV.second);
SetInstDebugLocation(I);
}

/// Get the return type of the current function that we're emitting
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/IR/Instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,7 @@ class Instruction : public User,
/// applications, thus the N-way merging should be in code path.
/// The DebugLoc attached to this instruction will be overwritten by the
/// merged DebugLoc.
void applyMergedLocation(DILocation *LocA, DILocation *LocB);
void applyMergedLocation(DebugLoc LocA, DebugLoc LocB);

/// Updates the debug location given that the instruction has been hoisted
/// from a block to a predecessor of that block.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/BranchFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ void BranchFolder::mergeCommonTails(unsigned commonTailIndex) {
"Reached BB end within common tail");
}
assert(MI.isIdenticalTo(*Pos) && "Expected matching MIIs!");
DL = DILocation::getMergedLocation(DL, Pos->getDebugLoc());
DL = DebugLoc::getMergedLocation(DL, Pos->getDebugLoc());
NextCommonInsts[i] = ++Pos;
}
MI.setDebugLoc(DL);
Expand Down
5 changes: 2 additions & 3 deletions llvm/lib/CodeGen/GlobalISel/CSEMIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@ CSEMIRBuilder::getDominatingInstrForID(FoldingSetNodeID &ID,
} else if (!dominates(MI, CurrPos)) {
// Update the spliced machineinstr's debug location by merging it with the
// debug location of the instruction at the insertion point.
auto *Loc = DILocation::getMergedLocation(getDebugLoc().get(),
MI->getDebugLoc().get());
auto Loc = DebugLoc::getMergedLocation(getDebugLoc(), MI->getDebugLoc());
MI->setDebugLoc(Loc);
CurMBB->splice(CurrPos, CurMBB, MI);
}
Expand Down Expand Up @@ -170,7 +169,7 @@ CSEMIRBuilder::generateCopiesIfRequired(ArrayRef<DstOp> DstOps,
if (Observer)
Observer->changingInstr(*MIB);
MIB->setDebugLoc(
DILocation::getMergedLocation(MIB->getDebugLoc(), getDebugLoc()));
DebugLoc::getMergedLocation(MIB->getDebugLoc(), getDebugLoc()));
if (Observer)
Observer->changedInstr(*MIB);
}
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/GlobalISel/LoadStoreOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ bool LoadStoreOpt::doSingleStoreMerge(SmallVectorImpl<GStore *> &Stores) {
// For each store, compute pairwise merged debug locs.
DebugLoc MergedLoc = Stores.front()->getDebugLoc();
for (auto *Store : drop_begin(Stores))
MergedLoc = DILocation::getMergedLocation(MergedLoc, Store->getDebugLoc());
MergedLoc = DebugLoc::getMergedLocation(MergedLoc, Store->getDebugLoc());

Builder.setInstr(*Stores.back());
Builder.setDebugLoc(MergedLoc);
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineBasicBlock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1575,7 +1575,7 @@ MachineBasicBlock::findBranchDebugLoc() {
DL = TI->getDebugLoc();
for (++TI ; TI != end() ; ++TI)
if (TI->isBranch())
DL = DILocation::getMergedLocation(DL, TI->getDebugLoc());
DL = DebugLoc::getMergedLocation(DL, TI->getDebugLoc());
}
return DL;
}
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/CodeGen/MachineSink.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1611,8 +1611,8 @@ static void performSink(MachineInstr &MI, MachineBasicBlock &SuccToSinkTo,
// location to prevent debug-info driven tools from potentially reporting
// wrong location information.
if (!SuccToSinkTo.empty() && InsertPos != SuccToSinkTo.end())
MI.setDebugLoc(DILocation::getMergedLocation(MI.getDebugLoc(),
InsertPos->getDebugLoc()));
MI.setDebugLoc(DebugLoc::getMergedLocation(MI.getDebugLoc(),
InsertPos->getDebugLoc()));
else
MI.setDebugLoc(DebugLoc());

Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/IR/DebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -951,8 +951,8 @@ unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
return 0;
}

void Instruction::applyMergedLocation(DILocation *LocA, DILocation *LocB) {
setDebugLoc(DILocation::getMergedLocation(LocA, LocB));
void Instruction::applyMergedLocation(DebugLoc LocA, DebugLoc LocB) {
setDebugLoc(DebugLoc::getMergedLocation(LocA, LocB));
}

void Instruction::mergeDIAssignID(
Expand Down
21 changes: 21 additions & 0 deletions llvm/lib/IR/DebugLoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,27 @@ DebugLoc DebugLoc::appendInlinedAt(const DebugLoc &DL, DILocation *InlinedAt,
return Last;
}

DebugLoc DebugLoc::getMergedLocations(ArrayRef<DebugLoc> Locs) {
if (Locs.empty())
return DebugLoc();
if (Locs.size() == 1)
return Locs[0];
DebugLoc Merged = Locs[0];
for (const DebugLoc &DL : llvm::drop_begin(Locs)) {
Merged = getMergedLocation(Merged, DL);
if (!Merged)
break;
}
return Merged;
}
DebugLoc DebugLoc::getMergedLocation(DebugLoc LocA, DebugLoc LocB) {
if (!LocA)
return LocA;
if (!LocB)
return LocB;
return DILocation::getMergedLocation(LocA, LocB);
}

#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void DebugLoc::dump() const { print(dbgs()); }
#endif
Expand Down
17 changes: 5 additions & 12 deletions llvm/lib/IR/IRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,12 @@ Type *IRBuilderBase::getCurrentFunctionReturnType() const {
return BB->getParent()->getReturnType();
}

DebugLoc IRBuilderBase::getCurrentDebugLocation() const {
for (auto &KV : MetadataToCopy)
if (KV.first == LLVMContext::MD_dbg)
return {cast<DILocation>(KV.second)};

return {};
}
DebugLoc IRBuilderBase::getCurrentDebugLocation() const { return StoredDL; }
void IRBuilderBase::SetInstDebugLocation(Instruction *I) const {
for (const auto &KV : MetadataToCopy)
if (KV.first == LLVMContext::MD_dbg) {
I->setDebugLoc(DebugLoc(KV.second));
return;
}
// We prefer to set our current debug location if any has been set, but if
// our debug location is empty and I has a valid location, we shouldn't
// overwrite it.
I->setDebugLoc(StoredDL.orElse(I->getDebugLoc()));
}

Value *IRBuilderBase::CreateAggregateCast(Value *V, Type *DestTy) {
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/IR/Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,9 @@ void Instruction::swapProfMetadata() {

void Instruction::copyMetadata(const Instruction &SrcInst,
ArrayRef<unsigned> WL) {
if (WL.empty() || is_contained(WL, LLVMContext::MD_dbg))
setDebugLoc(SrcInst.getDebugLoc().orElse(getDebugLoc()));

if (!SrcInst.hasMetadata())
return;

Expand All @@ -1368,8 +1371,6 @@ void Instruction::copyMetadata(const Instruction &SrcInst,
if (WL.empty() || WLS.count(MD.first))
setMetadata(MD.first, MD.second);
}
if (WL.empty() || WLS.count(LLVMContext::MD_dbg))
setDebugLoc(SrcInst.getDebugLoc());
}

Instruction *Instruction::clone() const {
Expand Down
11 changes: 5 additions & 6 deletions llvm/lib/Target/BPF/BPFPreserveStaticOffset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ static CallInst *isGEPAndStore(Value *I) {
}

template <class T = Instruction>
static DILocation *mergeDILocations(SmallVector<T *> &Insns) {
DILocation *Merged = (*Insns.begin())->getDebugLoc();
static DebugLoc mergeDebugLocs(SmallVector<T *> &Insns) {
DebugLoc Merged = (*Insns.begin())->getDebugLoc();
for (T *I : Insns)
Merged = DILocation::getMergedLocation(Merged, I->getDebugLoc());
Merged = DebugLoc::getMergedLocation(Merged, I->getDebugLoc());
return Merged;
}

Expand Down Expand Up @@ -227,7 +227,7 @@ static Instruction *makeGEPAndLoad(Module *M, GEPChainInfo &GEP,
CallInst *Call = makeIntrinsicCall(M, Intrinsic::bpf_getelementptr_and_load,
{Load->getType()}, Args);
setParamElementType(Call, 0, GEP.SourceElementType);
Call->applyMergedLocation(mergeDILocations(GEP.Members), Load->getDebugLoc());
Call->applyMergedLocation(mergeDebugLocs(GEP.Members), Load->getDebugLoc());
Call->setName((*GEP.Members.rbegin())->getName());
if (Load->isUnordered()) {
Call->setOnlyReadsMemory();
Expand All @@ -251,8 +251,7 @@ static Instruction *makeGEPAndStore(Module *M, GEPChainInfo &GEP,
setParamElementType(Call, 1, GEP.SourceElementType);
if (Store->getValueOperand()->getType()->isPointerTy())
setParamReadNone(Call, 0);
Call->applyMergedLocation(mergeDILocations(GEP.Members),
Store->getDebugLoc());
Call->applyMergedLocation(mergeDebugLocs(GEP.Members), Store->getDebugLoc());
if (Store->isUnordered()) {
Call->setOnlyWritesMemory();
Call->setOnlyAccessesArgMemory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1581,8 +1581,8 @@ bool InstCombinerImpl::mergeStoreIntoSuccessor(StoreInst &SI) {
// Insert a PHI node now if we need it.
Value *MergedVal = OtherStore->getValueOperand();
// The debug locations of the original instructions might differ. Merge them.
DebugLoc MergedLoc = DILocation::getMergedLocation(SI.getDebugLoc(),
OtherStore->getDebugLoc());
DebugLoc MergedLoc =
DebugLoc::getMergedLocation(SI.getDebugLoc(), OtherStore->getDebugLoc());
if (MergedVal != SI.getValueOperand()) {
PHINode *PN =
PHINode::Create(SI.getValueOperand()->getType(), 2, "storemerge");
Expand Down
3 changes: 1 addition & 2 deletions llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5334,8 +5334,7 @@ bool InstCombinerImpl::run() {
// We copy the old instruction's DebugLoc to the new instruction, unless
// InstCombine already assigned a DebugLoc to it, in which case we
// should trust the more specifically selected DebugLoc.
if (!Result->getDebugLoc())
Result->setDebugLoc(I->getDebugLoc());
Result->setDebugLoc(Result->getDebugLoc().orElse(I->getDebugLoc()));
// We also copy annotation metadata to the new instruction.
Result->copyMetadata(*I, LLVMContext::MD_annotation);
// Everything uses the new instruction now.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Transforms/Scalar/ConstantHoisting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,7 +883,7 @@ bool ConstantHoistingPass::emitBaseConstants(GlobalVariable *BaseGV) {
emitBaseConstants(Base, &R);
ReBasesNum++;
// Use the same debug location as the last user of the constant.
Base->setDebugLoc(DILocation::getMergedLocation(
Base->setDebugLoc(DebugLoc::getMergedLocation(
Base->getDebugLoc(), R.User.Inst->getDebugLoc()));
}
assert(!Base->use_empty() && "The use list is empty!?");
Expand Down
8 changes: 4 additions & 4 deletions llvm/lib/Transforms/Scalar/LICM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2225,10 +2225,10 @@ bool llvm::promoteLoopAccessesToScalars(
});

// Look at all the loop uses, and try to merge their locations.
std::vector<DILocation *> LoopUsesLocs;
for (auto *U : LoopUses)
LoopUsesLocs.push_back(U->getDebugLoc().get());
auto DL = DebugLoc(DILocation::getMergedLocations(LoopUsesLocs));
std::vector<DebugLoc> LoopUsesLocs;
for (auto U : LoopUses)
LoopUsesLocs.push_back(U->getDebugLoc());
auto DL = DebugLoc::getMergedLocations(LoopUsesLocs);

// We use the SSAUpdater interface to insert phi nodes as required.
SmallVector<PHINode *, 16> NewPHIs;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Scalar/SimplifyCFGPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ performBlockTailMerging(Function &F, ArrayRef<BasicBlock *> BBs,

// Now, go through each block (with the current terminator type)
// we've recorded, and rewrite it to branch to the new common block.
DILocation *CommonDebugLoc = nullptr;
DebugLoc CommonDebugLoc;
for (BasicBlock *BB : BBs) {
auto *Term = BB->getTerminator();
assert(Term->getOpcode() == CanonicalTerm->getOpcode() &&
Expand All @@ -145,7 +145,7 @@ performBlockTailMerging(Function &F, ArrayRef<BasicBlock *> BBs,
CommonDebugLoc = Term->getDebugLoc();
else
CommonDebugLoc =
DILocation::getMergedLocation(CommonDebugLoc, Term->getDebugLoc());
DebugLoc::getMergedLocation(CommonDebugLoc, Term->getDebugLoc());

// And turn BB into a block that just unconditionally branches
// to the canonical block.
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Transforms/Utils/SimplifyCFG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2077,11 +2077,11 @@ bool SimplifyCFGOpt::hoistSuccIdenticalTerminatorToSwitchOrIf(

// Ensure terminator gets a debug location, even an unknown one, in case
// it involves inlinable calls.
SmallVector<DILocation *, 4> Locs;
SmallVector<DebugLoc, 4> Locs;
Locs.push_back(I1->getDebugLoc());
for (auto *OtherSuccTI : OtherSuccTIs)
Locs.push_back(OtherSuccTI->getDebugLoc());
NT->setDebugLoc(DILocation::getMergedLocations(Locs));
NT->setDebugLoc(DebugLoc::getMergedLocations(Locs));

// PHIs created below will adopt NT's merged DebugLoc.
IRBuilder<NoFolder> Builder(NT);
Expand Down Expand Up @@ -2885,7 +2885,7 @@ static void mergeCompatibleInvokesImpl(ArrayRef<InvokeInst *> Invokes,
MergedDebugLoc = II->getDebugLoc();
else
MergedDebugLoc =
DILocation::getMergedLocation(MergedDebugLoc, II->getDebugLoc());
DebugLoc::getMergedLocation(MergedDebugLoc, II->getDebugLoc());

// And replace the old `invoke` with an unconditionally branch
// to the block with the merged `invoke`.
Expand Down