[llvm] [DebugInfo] Strip more debug-intrinsic code from local utils (PR #149037)
Jeremy Morse via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 16 03:45:22 PDT 2025
https://github.com/jmorse updated https://github.com/llvm/llvm-project/pull/149037
>From e76c3b90e4148d37b1861264d2aab8366ec4d24f Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 15 Jul 2025 16:29:20 +0100
Subject: [PATCH 1/2] [DebugInfo] Strip more debug-intrinsic code from local
utils
SROA and a few other facilities use generic-lambdas and some overloaded
functions to deal with both intrinsics and debug-records at the same time.
As part of stripping out intrinsic support, delete a swathe of this code
from things in the Utils directory.
---
.../Transforms/Utils/MemoryTaggingSupport.h | 3 -
llvm/lib/Transforms/Scalar/SROA.cpp | 107 +-----------------
llvm/lib/Transforms/Utils/CloneFunction.cpp | 30 +----
.../Transforms/Utils/MemoryTaggingSupport.cpp | 26 +----
.../Utils/PromoteMemoryToRegister.cpp | 37 ++----
5 files changed, 19 insertions(+), 184 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
index 8b7daf616b110..f288bdfb84f49 100644
--- a/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
+++ b/llvm/include/llvm/Transforms/Utils/MemoryTaggingSupport.h
@@ -23,7 +23,6 @@
namespace llvm {
class DominatorTree;
-class DbgVariableIntrinsic;
class IntrinsicInst;
class PostDominatorTree;
class AllocaInst;
@@ -53,8 +52,6 @@ struct AllocaInfo {
AllocaInst *AI;
SmallVector<IntrinsicInst *, 2> LifetimeStart;
SmallVector<IntrinsicInst *, 2> LifetimeEnd;
- SmallVector<DbgVariableIntrinsic *, 2> DbgVariableIntrinsics;
- // Non-intrinsic records of variable locations.
SmallVector<DbgVariableRecord *, 2> DbgVariableRecords;
};
diff --git a/llvm/lib/Transforms/Scalar/SROA.cpp b/llvm/lib/Transforms/Scalar/SROA.cpp
index 70b4552190a4e..23256cf2acbd2 100644
--- a/llvm/lib/Transforms/Scalar/SROA.cpp
+++ b/llvm/lib/Transforms/Scalar/SROA.cpp
@@ -315,18 +315,11 @@ calculateFragment(DILocalVariable *Variable,
return UseFrag;
}
-static DebugVariable getAggregateVariable(DbgVariableIntrinsic *DVI) {
- return DebugVariable(DVI->getVariable(), std::nullopt,
- DVI->getDebugLoc().getInlinedAt());
-}
static DebugVariable getAggregateVariable(DbgVariableRecord *DVR) {
return DebugVariable(DVR->getVariable(), std::nullopt,
DVR->getDebugLoc().getInlinedAt());
}
-/// Helpers for handling new and old debug info modes in migrateDebugInfo.
-/// These overloads unwrap a DbgInstPtr {Instruction* | DbgRecord*} union based
-/// on the \p Unused parameter type.
DbgVariableRecord *UnwrapDbgInstPtr(DbgInstPtr P, DbgVariableRecord *Unused) {
(void)Unused;
return static_cast<DbgVariableRecord *>(cast<DbgRecord *>(P));
@@ -376,9 +369,6 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
/// Map of aggregate variables to their fragment associated with OldAlloca.
DenseMap<DebugVariable, std::optional<DIExpression::FragmentInfo>>
BaseFragments;
- for (auto *DAI : at::getAssignmentMarkers(OldAlloca))
- BaseFragments[getAggregateVariable(DAI)] =
- DAI->getExpression()->getFragmentInfo();
for (auto *DVR : at::getDVRAssignmentMarkers(OldAlloca))
BaseFragments[getAggregateVariable(DVR)] =
DVR->getExpression()->getFragmentInfo();
@@ -391,7 +381,7 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
DIBuilder DIB(*OldInst->getModule(), /*AllowUnresolved*/ false);
assert(OldAlloca->isStaticAlloca());
- auto MigrateDbgAssign = [&](auto *DbgAssign) {
+ auto MigrateDbgAssign = [&](DbgVariableRecord *DbgAssign) {
LLVM_DEBUG(dbgs() << " existing dbg.assign is: " << *DbgAssign
<< "\n");
auto *Expr = DbgAssign->getExpression();
@@ -486,7 +476,6 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
LLVM_DEBUG(dbgs() << "Created new assign: " << *NewAssign << "\n");
};
- for_each(MarkerRange, MigrateDbgAssign);
for_each(DVRAssignMarkerRange, MigrateDbgAssign);
}
@@ -5119,36 +5108,13 @@ AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
}
// There isn't a shared interface to get the "address" parts out of a
-// dbg.declare and dbg.assign, so provide some wrappers now for
-// both debug intrinsics and records.
-const Value *getAddress(const DbgVariableIntrinsic *DVI) {
- if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
- return DAI->getAddress();
- return cast<DbgDeclareInst>(DVI)->getAddress();
-}
-
-const Value *getAddress(const DbgVariableRecord *DVR) {
- return DVR->getAddress();
-}
-
-bool isKillAddress(const DbgVariableIntrinsic *DVI) {
- if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
- return DAI->isKillAddress();
- return cast<DbgDeclareInst>(DVI)->isKillLocation();
-}
-
+// dbg.declare and dbg.assign, so provide some wrappers.
bool isKillAddress(const DbgVariableRecord *DVR) {
if (DVR->getType() == DbgVariableRecord::LocationType::Assign)
return DVR->isKillAddress();
return DVR->isKillLocation();
}
-const DIExpression *getAddressExpression(const DbgVariableIntrinsic *DVI) {
- if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
- return DAI->getAddressExpression();
- return cast<DbgDeclareInst>(DVI)->getExpression();
-}
-
const DIExpression *getAddressExpression(const DbgVariableRecord *DVR) {
if (DVR->getType() == DbgVariableRecord::LocationType::Assign)
return DVR->getAddressExpression();
@@ -5236,66 +5202,6 @@ static DIExpression *createOrReplaceFragment(const DIExpression *Expr,
return DIExpression::get(Expr->getContext(), Ops);
}
-/// Insert a new dbg.declare.
-/// \p Orig Original to copy debug loc and variable from.
-/// \p NewAddr Location's new base address.
-/// \p NewAddrExpr New expression to apply to address.
-/// \p BeforeInst Insert position.
-/// \p NewFragment New fragment (absolute, non-relative).
-/// \p BitExtractAdjustment Offset to apply to any extract_bits op.
-static void
-insertNewDbgInst(DIBuilder &DIB, DbgDeclareInst *Orig, AllocaInst *NewAddr,
- DIExpression *NewAddrExpr, Instruction *BeforeInst,
- std::optional<DIExpression::FragmentInfo> NewFragment,
- int64_t BitExtractAdjustment) {
- if (NewFragment)
- NewAddrExpr = createOrReplaceFragment(NewAddrExpr, *NewFragment,
- BitExtractAdjustment);
- if (!NewAddrExpr)
- return;
-
- DIB.insertDeclare(NewAddr, Orig->getVariable(), NewAddrExpr,
- Orig->getDebugLoc(), BeforeInst->getIterator());
-}
-
-/// Insert a new dbg.assign.
-/// \p Orig Original to copy debug loc, variable, value and value expression
-/// from.
-/// \p NewAddr Location's new base address.
-/// \p NewAddrExpr New expression to apply to address.
-/// \p BeforeInst Insert position.
-/// \p NewFragment New fragment (absolute, non-relative).
-/// \p BitExtractAdjustment Offset to apply to any extract_bits op.
-static void
-insertNewDbgInst(DIBuilder &DIB, DbgAssignIntrinsic *Orig, AllocaInst *NewAddr,
- DIExpression *NewAddrExpr, Instruction *BeforeInst,
- std::optional<DIExpression::FragmentInfo> NewFragment,
- int64_t BitExtractAdjustment) {
- // DIBuilder::insertDbgAssign will insert the #dbg_assign after NewAddr.
- (void)BeforeInst;
-
- // A dbg.assign puts fragment info in the value expression only. The address
- // expression has already been built: NewAddrExpr.
- DIExpression *NewFragmentExpr = Orig->getExpression();
- if (NewFragment)
- NewFragmentExpr = createOrReplaceFragment(NewFragmentExpr, *NewFragment,
- BitExtractAdjustment);
- if (!NewFragmentExpr)
- return;
-
- // Apply a DIAssignID to the store if it doesn't already have it.
- if (!NewAddr->hasMetadata(LLVMContext::MD_DIAssignID)) {
- NewAddr->setMetadata(LLVMContext::MD_DIAssignID,
- DIAssignID::getDistinct(NewAddr->getContext()));
- }
-
- Instruction *NewAssign = cast<Instruction *>(DIB.insertDbgAssign(
- NewAddr, Orig->getValue(), Orig->getVariable(), NewFragmentExpr, NewAddr,
- NewAddrExpr, Orig->getDebugLoc()));
- LLVM_DEBUG(dbgs() << "Created new assign intrinsic: " << *NewAssign << "\n");
- (void)NewAssign;
-}
-
/// Insert a new DbgRecord.
/// \p Orig Original to copy record type, debug loc and variable from, and
/// additionally value and value expression for dbg_assign records.
@@ -5457,12 +5363,12 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
// Migrate debug information from the old alloca to the new alloca(s)
// and the individual partitions.
- auto MigrateOne = [&](auto *DbgVariable) {
+ auto MigrateOne = [&](DbgVariableRecord *DbgVariable) {
// Can't overlap with undef memory.
if (isKillAddress(DbgVariable))
return;
- const Value *DbgPtr = getAddress(DbgVariable);
+ const Value *DbgPtr = DbgVariable->getAddress();
DIExpression::FragmentInfo VarFrag =
DbgVariable->getFragmentOrEntireVariable();
// Get the address expression constant offset if one exists and the ops
@@ -5543,7 +5449,6 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
if (SameVariableFragment(OldDII, DbgVariable))
OldDII->eraseFromParent();
};
- for_each(findDbgDeclares(Fragment.Alloca), RemoveOne);
for_each(findDVRDeclares(Fragment.Alloca), RemoveOne);
for_each(findDVRValues(Fragment.Alloca), RemoveOne);
insertNewDbgInst(DIB, DbgVariable, Fragment.Alloca, NewExpr, &AI,
@@ -5553,10 +5458,8 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
// Migrate debug information from the old alloca to the new alloca(s)
// and the individual partitions.
- for_each(findDbgDeclares(&AI), MigrateOne);
for_each(findDVRDeclares(&AI), MigrateOne);
for_each(findDVRValues(&AI), MigrateOne);
- for_each(at::getAssignmentMarkers(&AI), MigrateOne);
for_each(at::getDVRAssignmentMarkers(&AI), MigrateOne);
return Changed;
@@ -5777,8 +5680,6 @@ bool SROA::deleteDeadInstructions(
// not be able to find it.
if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
DeletedAllocas.insert(AI);
- for (DbgDeclareInst *OldDII : findDbgDeclares(AI))
- OldDII->eraseFromParent();
for (DbgVariableRecord *OldDII : findDVRDeclares(AI))
OldDII->eraseFromParent();
}
diff --git a/llvm/lib/Transforms/Utils/CloneFunction.cpp b/llvm/lib/Transforms/Utils/CloneFunction.cpp
index fccb73a36b182..b187208bc238c 100644
--- a/llvm/lib/Transforms/Utils/CloneFunction.cpp
+++ b/llvm/lib/Transforms/Utils/CloneFunction.cpp
@@ -576,9 +576,8 @@ void PruningFunctionCloner::CloneBlock(
}
// Eagerly remap operands to the newly cloned instruction, except for PHI
- // nodes for which we defer processing until we update the CFG. Also defer
- // debug intrinsic processing because they may contain use-before-defs.
- if (!isa<PHINode>(NewInst) && !isa<DbgVariableIntrinsic>(NewInst)) {
+ // nodes for which we defer processing until we update the CFG.
+ if (!isa<PHINode>(NewInst)) {
RemapInstruction(NewInst, VMap,
ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges);
@@ -733,15 +732,6 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
StartingInst = &StartingBB->front();
}
- // Collect debug intrinsics for remapping later.
- SmallVector<const DbgVariableIntrinsic *, 8> DbgIntrinsics;
- for (const auto &BB : *OldFunc) {
- for (const auto &I : BB) {
- if (const auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I))
- DbgIntrinsics.push_back(DVI);
- }
- }
-
// Clone the entry block, and anything recursively reachable from it.
std::vector<const BasicBlock *> CloneWorklist;
PFC.CloneBlock(StartingBB, StartingInst->getIterator(), CloneWorklist);
@@ -899,21 +889,11 @@ void llvm::CloneAndPruneIntoFromInst(Function *NewFunc, const Function *OldFunc,
// Restore attributes.
NewFunc->setAttributes(Attrs);
- // Remap debug intrinsic operands now that all values have been mapped.
- // Doing this now (late) preserves use-before-defs in debug intrinsics. If
+ // Remap debug records operands now that all values have been mapped.
+ // Doing this now (late) preserves use-before-defs in debug records. If
// we didn't do this, ValueAsMetadata(use-before-def) operands would be
// replaced by empty metadata. This would signal later cleanup passes to
- // remove the debug intrinsics, potentially causing incorrect locations.
- for (const auto *DVI : DbgIntrinsics) {
- if (DbgVariableIntrinsic *NewDVI =
- cast_or_null<DbgVariableIntrinsic>(VMap.lookup(DVI)))
- RemapInstruction(NewDVI, VMap,
- ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
- TypeMapper, Materializer);
- }
-
- // Do the same for DbgVariableRecords, touching all the instructions in the
- // cloned range of blocks.
+ // remove the debug records, potentially causing incorrect locations.
Function::iterator Begin = cast<BasicBlock>(VMap[StartingBB])->getIterator();
for (BasicBlock &BB : make_range(Begin, NewFunc->end())) {
for (Instruction &I : BB) {
diff --git a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
index 511c15555fa83..6226596017980 100644
--- a/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
+++ b/llvm/lib/Transforms/Utils/MemoryTaggingSupport.cpp
@@ -168,22 +168,6 @@ void StackInfoBuilder::visit(OptimizationRemarkEmitter &ORE,
Info.AllocasToInstrument[AI].LifetimeEnd.push_back(II);
return;
}
- if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(&Inst)) {
- auto AddIfInteresting = [&](Value *V) {
- if (auto *AI = dyn_cast_or_null<AllocaInst>(V)) {
- if (getAllocaInterestingness(*AI) !=
- AllocaInterestingness::kInteresting)
- return;
- AllocaInfo &AInfo = Info.AllocasToInstrument[AI];
- auto &DVIVec = AInfo.DbgVariableIntrinsics;
- if (DVIVec.empty() || DVIVec.back() != DVI)
- DVIVec.push_back(DVI);
- }
- };
- for_each(DVI->location_ops(), AddIfInteresting);
- if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
- AddIfInteresting(DAI->getAddress());
- }
Instruction *ExitUntag = getUntagLocationIfFunctionExit(Inst);
if (ExitUntag)
@@ -297,19 +281,12 @@ Value *getAndroidSlotPtr(IRBuilder<> &IRB, int Slot) {
IRB.CreateCall(ThreadPointerFunc), 8 * Slot);
}
-static DbgAssignIntrinsic *DynCastToDbgAssign(DbgVariableIntrinsic *DVI) {
- return dyn_cast<DbgAssignIntrinsic>(DVI);
-}
-
static DbgVariableRecord *DynCastToDbgAssign(DbgVariableRecord *DVR) {
return DVR->isDbgAssign() ? DVR : nullptr;
}
void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag) {
- // Helper utility for adding DW_OP_LLVM_tag_offset to debug-info records,
- // abstracted over whether they're intrinsic-stored or DbgVariableRecord
- // stored.
- auto AnnotateDbgRecord = [&](auto *DPtr) {
+ auto AnnotateDbgRecord = [&](DbgVariableRecord *DPtr) {
// Prepend "tag_offset, N" to the dwarf expression.
// Tag offset logically applies to the alloca pointer, and it makes sense
// to put it at the beginning of the expression.
@@ -325,7 +302,6 @@ void annotateDebugRecords(AllocaInfo &Info, unsigned int Tag) {
}
};
- llvm::for_each(Info.DbgVariableIntrinsics, AnnotateDbgRecord);
llvm::for_each(Info.DbgVariableRecords, AnnotateDbgRecord);
}
diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index 46808a818cb26..f1c051e46d1a0 100644
--- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -128,16 +128,11 @@ class AssignmentTrackingInfo {
/// DbgAssignIntrinsics linked to the alloca with at most one per variable
/// fragment. (i.e. not be a comprehensive set if there are multiple
/// dbg.assigns for one variable fragment).
- SmallVector<DbgVariableIntrinsic *> DbgAssigns;
SmallVector<DbgVariableRecord *> DVRAssigns;
public:
void init(AllocaInst *AI) {
SmallSet<DebugVariable, 2> Vars;
- for (DbgAssignIntrinsic *DAI : at::getAssignmentMarkers(AI)) {
- if (Vars.insert(DebugVariable(DAI)).second)
- DbgAssigns.push_back(DAI);
- }
for (DbgVariableRecord *DVR : at::getDVRAssignmentMarkers(AI)) {
if (Vars.insert(DebugVariable(DVR)).second)
DVRAssigns.push_back(DVR);
@@ -148,11 +143,10 @@ class AssignmentTrackingInfo {
/// \p ToDelete that stores to this alloca.
void updateForDeletedStore(
StoreInst *ToDelete, DIBuilder &DIB,
- SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete,
SmallSet<DbgVariableRecord *, 8> *DVRAssignsToDelete) const {
// There's nothing to do if the alloca doesn't have any variables using
// assignment tracking.
- if (DbgAssigns.empty() && DVRAssigns.empty())
+ if (DVRAssigns.empty())
return;
// Insert a dbg.value where the linked dbg.assign is and remember to delete
@@ -169,25 +163,22 @@ class AssignmentTrackingInfo {
DbgAssign->getExpression(), DbgAssign->getDebugLoc(),
DbgAssign);
};
- for (auto *Assign : at::getAssignmentMarkers(ToDelete))
- InsertValueForAssign(Assign, DbgAssignsToDelete);
for (auto *Assign : at::getDVRAssignmentMarkers(ToDelete))
InsertValueForAssign(Assign, DVRAssignsToDelete);
// It's possible for variables using assignment tracking to have no
- // dbg.assign linked to this store. These are variables in DbgAssigns that
+ // dbg.assign linked to this store. These are variables in DVRAssigns that
// are missing from VarHasDbgAssignForStore. Since there isn't a dbg.assign
// to mark the assignment - and the store is going to be deleted - insert a
// dbg.value to do that now. An untracked store may be either one that
// cannot be represented using assignment tracking (non-const offset or
// size) or one that is trackable but has had its DIAssignID attachment
// dropped accidentally.
- auto ConvertUnlinkedAssignToValue = [&](auto *Assign) {
+ auto ConvertUnlinkedAssignToValue = [&](DbgVariableRecord *Assign) {
if (VarHasDbgAssignForStore.contains(DebugVariableAggregate(Assign)))
return;
ConvertDebugDeclareToDebugValue(Assign, ToDelete, DIB);
};
- for_each(DbgAssigns, ConvertUnlinkedAssignToValue);
for_each(DVRAssigns, ConvertUnlinkedAssignToValue);
}
@@ -197,17 +188,14 @@ class AssignmentTrackingInfo {
// Regardless of the position of dbg.assigns relative to stores, the
// incoming values into a new PHI should be the same for the (imaginary)
// debug-phi.
- for (auto *DAI : DbgAssigns)
- ConvertDebugDeclareToDebugValue(DAI, NewPhi, DIB);
for (auto *DVR : DVRAssigns)
ConvertDebugDeclareToDebugValue(DVR, NewPhi, DIB);
}
void clear() {
- DbgAssigns.clear();
DVRAssigns.clear();
}
- bool empty() { return DbgAssigns.empty() && DVRAssigns.empty(); }
+ bool empty() { return DVRAssigns.empty(); }
};
struct AllocaInfo {
@@ -412,7 +400,6 @@ struct PromoteMem2Reg {
SmallVector<AssignmentTrackingInfo, 8> AllocaATInfo;
/// A set of dbg.assigns to delete because they've been demoted to
/// dbg.values. Call cleanUpDbgAssigns to delete them.
- SmallSet<DbgAssignIntrinsic *, 8> DbgAssignsToDelete;
SmallSet<DbgVariableRecord *, 8> DVRAssignsToDelete;
/// The set of basic blocks the renamer has already visited.
@@ -467,9 +454,6 @@ struct PromoteMem2Reg {
/// Delete dbg.assigns that have been demoted to dbg.values.
void cleanUpDbgAssigns() {
- for (auto *DAI : DbgAssignsToDelete)
- DAI->eraseFromParent();
- DbgAssignsToDelete.clear();
for (auto *DVR : DVRAssignsToDelete)
DVR->eraseFromParent();
DVRAssignsToDelete.clear();
@@ -571,7 +555,6 @@ static bool
rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI,
const DataLayout &DL, DominatorTree &DT,
AssumptionCache *AC,
- SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete,
SmallSet<DbgVariableRecord *, 8> *DVRAssignsToDelete) {
StoreInst *OnlyStore = Info.OnlyStore;
Value *ReplVal = OnlyStore->getOperand(0);
@@ -638,7 +621,7 @@ rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI,
DIBuilder DIB(*AI->getModule(), /*AllowUnresolved*/ false);
// Update assignment tracking info for the store we're going to delete.
Info.AssignmentTracking.updateForDeletedStore(
- Info.OnlyStore, DIB, DbgAssignsToDelete, DVRAssignsToDelete);
+ Info.OnlyStore, DIB, DVRAssignsToDelete);
// Record debuginfo for the store and remove the declaration's
// debuginfo.
@@ -690,7 +673,6 @@ static bool
promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
LargeBlockInfo &LBI, const DataLayout &DL,
DominatorTree &DT, AssumptionCache *AC,
- SmallSet<DbgAssignIntrinsic *, 8> *DbgAssignsToDelete,
SmallSet<DbgVariableRecord *, 8> *DVRAssignsToDelete) {
// The trickiest case to handle is when we have large blocks. Because of this,
// this code is optimized assuming that large blocks happen. This does not
@@ -755,8 +737,7 @@ promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
while (!AI->use_empty()) {
StoreInst *SI = cast<StoreInst>(AI->user_back());
// Update assignment tracking info for the store we're going to delete.
- Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DbgAssignsToDelete,
- DVRAssignsToDelete);
+ Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DVRAssignsToDelete);
// Record debuginfo for the store before removing it.
auto DbgUpdateForStore = [&](auto &Container) {
for (auto *DbgItem : Container) {
@@ -830,7 +811,7 @@ void PromoteMem2Reg::run() {
// it that are directly dominated by the definition with the value stored.
if (Info.DefiningBlocks.size() == 1) {
if (rewriteSingleStoreAlloca(AI, Info, LBI, SQ.DL, DT, AC,
- &DbgAssignsToDelete, &DVRAssignsToDelete)) {
+ &DVRAssignsToDelete)) {
// The alloca has been processed, move on.
RemoveFromAllocasList(AllocaNum);
++NumSingleStore;
@@ -842,7 +823,7 @@ void PromoteMem2Reg::run() {
// linear sweep over the block to eliminate it.
if (Info.OnlyUsedInOneBlock &&
promoteSingleBlockAlloca(AI, Info, LBI, SQ.DL, DT, AC,
- &DbgAssignsToDelete, &DVRAssignsToDelete)) {
+ &DVRAssignsToDelete)) {
// The alloca has been processed, move on.
RemoveFromAllocasList(AllocaNum);
continue;
@@ -1242,7 +1223,7 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
// Record debuginfo for the store before removing it.
IncomingLocs.set(AllocaNo, SI->getDebugLoc());
- AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB, &DbgAssignsToDelete,
+ AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB,
&DVRAssignsToDelete);
auto ConvertDbgDeclares = [&](auto &Container) {
for (auto *DbgItem : Container)
>From 8108d4b855c5cf0aab9f5294bbfac05c6c884ae6 Mon Sep 17 00:00:00 2001
From: Jeremy Morse <jeremy.morse at sony.com>
Date: Tue, 15 Jul 2025 17:09:00 +0100
Subject: [PATCH 2/2] Remove a ton of local declare-to-value functions
---
llvm/include/llvm/Transforms/Utils/Local.h | 34 +-
.../InstCombine/InstructionCombining.cpp | 3 -
llvm/lib/Transforms/Utils/Local.cpp | 305 ++----------------
.../Utils/PromoteMemoryToRegister.cpp | 65 ++--
4 files changed, 50 insertions(+), 357 deletions(-)
diff --git a/llvm/include/llvm/Transforms/Utils/Local.h b/llvm/include/llvm/Transforms/Utils/Local.h
index df146458b4e6f..bb79d2568fca0 100644
--- a/llvm/include/llvm/Transforms/Utils/Local.h
+++ b/llvm/include/llvm/Transforms/Utils/Local.h
@@ -36,7 +36,6 @@ class BasicBlock;
class BranchInst;
class CallBase;
class CallInst;
-class DbgVariableIntrinsic;
class DIBuilder;
class DomTreeUpdater;
class Function;
@@ -275,36 +274,23 @@ LLVM_ABI CallInst *changeToCall(InvokeInst *II, DomTreeUpdater *DTU = nullptr);
LLVM_ABI void InsertDebugValueAtStoreLoc(DbgVariableRecord *DVR, StoreInst *SI,
DIBuilder &Builder);
-/// Creates and inserts an llvm.dbg.value intrinsic before a store
-/// that has an associated llvm.dbg.value intrinsic.
-LLVM_ABI void InsertDebugValueAtStoreLoc(DbgVariableIntrinsic *DII,
- StoreInst *SI, DIBuilder &Builder);
-
-/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
-/// that has an associated llvm.dbg.declare intrinsic.
-LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
- StoreInst *SI,
- DIBuilder &Builder);
+/// Inserts a dbg.value record before a store to an alloca'd value
+/// that has an associated dbg.declare record.
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
StoreInst *SI,
DIBuilder &Builder);
-/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
-/// that has an associated llvm.dbg.declare intrinsic.
-LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
- LoadInst *LI, DIBuilder &Builder);
+/// Inserts a dbg.value record before a load of an alloca'd value
+/// that has an associated dbg.declare record.
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
LoadInst *LI, DIBuilder &Builder);
-/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
-/// llvm.dbg.declare intrinsic.
-LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
- PHINode *LI, DIBuilder &Builder);
+/// Inserts a dbg.value record after a phi that has an associated
+/// llvm.dbg.declare record.
LLVM_ABI void ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
PHINode *LI, DIBuilder &Builder);
-/// Lowers llvm.dbg.declare intrinsics into appropriate set of
-/// llvm.dbg.value intrinsics.
+/// Lowers dbg.declare records into appropriate set of dbg.value records.
LLVM_ABI bool LowerDbgDeclare(Function &F);
/// Propagate dbg.value intrinsics through the newly inserted PHIs.
@@ -312,7 +298,7 @@ LLVM_ABI void
insertDebugValuesForPHIs(BasicBlock *BB,
SmallVectorImpl<PHINode *> &InsertedPHIs);
-/// Replaces llvm.dbg.declare instruction when the address it
+/// Replaces dbg.declare record when the address it
/// describes is replaced with a new value. If Deref is true, an
/// additional DW_OP_deref is prepended to the expression. If Offset
/// is non-zero, a constant displacement is added to the expression
@@ -321,10 +307,10 @@ LLVM_ABI bool replaceDbgDeclare(Value *Address, Value *NewAddress,
DIBuilder &Builder, uint8_t DIExprFlags,
int Offset);
-/// Replaces multiple llvm.dbg.value instructions when the alloca it describes
+/// Replaces multiple dbg.value records when the alloca it describes
/// is replaced with a new value. If Offset is non-zero, a constant displacement
/// is added to the expression (after the mandatory Deref). Offset can be
-/// negative. New llvm.dbg.value instructions are inserted at the locations of
+/// negative. New dbg.value records are inserted at the locations of
/// the instructions they replace.
LLVM_ABI void replaceDbgValueForAlloca(AllocaInst *AI, Value *NewAllocaAddress,
DIBuilder &Builder, int Offset = 0);
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 91a1b61ddc483..abee26fc9c222 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3644,9 +3644,6 @@ Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) {
ConstantInt::get(Type::getInt1Ty(C->getContext()),
C->isFalseWhenEqual()));
} else if (auto *SI = dyn_cast<StoreInst>(I)) {
- for (auto *DVI : DVIs)
- if (DVI->isAddressOfVariable())
- ConvertDebugDeclareToDebugValue(DVI, SI, *DIB);
for (auto *DVR : DVRs)
if (DVR->isAddressOfVariable())
ConvertDebugDeclareToDebugValue(DVR, SI, *DIB);
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 81d85375b9e1d..12186b3e2df6e 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -428,10 +428,6 @@ bool llvm::wouldInstructionBeTriviallyDead(const Instruction *I,
if (I->isEHPad())
return false;
- // We don't want debug info removed by anything this general.
- if (isa<DbgVariableIntrinsic>(I))
- return false;
-
if (const DbgLabelInst *DLI = dyn_cast<DbgLabelInst>(I)) {
if (DLI->getLabel())
return false;
@@ -1632,33 +1628,6 @@ static bool PhiHasDebugValue(DILocalVariable *DIVar,
/// describes an alloca'd variable, so we need to use the alloc size of the
/// value when doing the comparison. E.g. an i1 value will be identified as
/// covering an n-bit fragment, if the store size of i1 is at least n bits.
-static bool valueCoversEntireFragment(Type *ValTy, DbgVariableIntrinsic *DII) {
- const DataLayout &DL = DII->getDataLayout();
- TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy);
- if (std::optional<uint64_t> FragmentSize =
- DII->getExpression()->getActiveBits(DII->getVariable()))
- return TypeSize::isKnownGE(ValueSize, TypeSize::getFixed(*FragmentSize));
-
- // We can't always calculate the size of the DI variable (e.g. if it is a
- // VLA). Try to use the size of the alloca that the dbg intrinsic describes
- // instead.
- if (DII->isAddressOfVariable()) {
- // DII should have exactly 1 location when it is an address.
- assert(DII->getNumVariableLocationOps() == 1 &&
- "address of variable must have exactly 1 location operand.");
- if (auto *AI =
- dyn_cast_or_null<AllocaInst>(DII->getVariableLocationOp(0))) {
- if (std::optional<TypeSize> FragmentSize =
- AI->getAllocationSizeInBits(DL)) {
- return TypeSize::isKnownGE(ValueSize, *FragmentSize);
- }
- }
- }
- // Could not determine size of variable. Conservatively return false.
- return false;
-}
-// RemoveDIs: duplicate implementation of the above, using DbgVariableRecords,
-// the replacement for dbg.values.
static bool valueCoversEntireFragment(Type *ValTy, DbgVariableRecord *DVR) {
const DataLayout &DL = DVR->getModule()->getDataLayout();
TypeSize ValueSize = DL.getTypeAllocSizeInBits(ValTy);
@@ -1703,98 +1672,12 @@ static void insertDbgValueOrDbgVariableRecordAfter(
insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc, NextIt);
}
-/// Inserts a llvm.dbg.value intrinsic before a store to an alloca'd value
-/// that has an associated llvm.dbg.declare intrinsic.
-void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
- StoreInst *SI, DIBuilder &Builder) {
- assert(DII->isAddressOfVariable() || isa<DbgAssignIntrinsic>(DII));
- auto *DIVar = DII->getVariable();
- assert(DIVar && "Missing variable");
- auto *DIExpr = DII->getExpression();
- Value *DV = SI->getValueOperand();
-
- DebugLoc NewLoc = getDebugValueLoc(DII);
-
- // If the alloca describes the variable itself, i.e. the expression in the
- // dbg.declare doesn't start with a dereference, we can perform the
- // conversion if the value covers the entire fragment of DII.
- // If the alloca describes the *address* of DIVar, i.e. DIExpr is
- // *just* a DW_OP_deref, we use DV as is for the dbg.value.
- // We conservatively ignore other dereferences, because the following two are
- // not equivalent:
- // dbg.declare(alloca, ..., !Expr(deref, plus_uconstant, 2))
- // dbg.value(DV, ..., !Expr(deref, plus_uconstant, 2))
- // The former is adding 2 to the address of the variable, whereas the latter
- // is adding 2 to the value of the variable. As such, we insist on just a
- // deref expression.
- bool CanConvert =
- DIExpr->isDeref() || (!DIExpr->startsWithDeref() &&
- valueCoversEntireFragment(DV->getType(), DII));
- if (CanConvert) {
- insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc,
- SI->getIterator());
- return;
- }
-
- // FIXME: If storing to a part of the variable described by the dbg.declare,
- // then we want to insert a dbg.value for the corresponding fragment.
- LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: " << *DII
- << '\n');
- // For now, when there is a store to parts of the variable (but we do not
- // know which part) we insert an dbg.value intrinsic to indicate that we
- // know nothing about the variable's content.
- DV = PoisonValue::get(DV->getType());
- insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc,
- SI->getIterator());
-}
-
static DIExpression *dropInitialDeref(const DIExpression *DIExpr) {
int NumEltDropped = DIExpr->getElements()[0] == dwarf::DW_OP_LLVM_arg ? 3 : 1;
return DIExpression::get(DIExpr->getContext(),
DIExpr->getElements().drop_front(NumEltDropped));
}
-void llvm::InsertDebugValueAtStoreLoc(DbgVariableIntrinsic *DII, StoreInst *SI,
- DIBuilder &Builder) {
- auto *DIVar = DII->getVariable();
- assert(DIVar && "Missing variable");
- auto *DIExpr = DII->getExpression();
- DIExpr = dropInitialDeref(DIExpr);
- Value *DV = SI->getValueOperand();
-
- DebugLoc NewLoc = getDebugValueLoc(DII);
-
- insertDbgValueOrDbgVariableRecord(Builder, DV, DIVar, DIExpr, NewLoc,
- SI->getIterator());
-}
-
-/// Inserts a llvm.dbg.value intrinsic before a load of an alloca'd value
-/// that has an associated llvm.dbg.declare intrinsic.
-void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
- LoadInst *LI, DIBuilder &Builder) {
- auto *DIVar = DII->getVariable();
- auto *DIExpr = DII->getExpression();
- assert(DIVar && "Missing variable");
-
- if (!valueCoversEntireFragment(LI->getType(), DII)) {
- // FIXME: If only referring to a part of the variable described by the
- // dbg.declare, then we want to insert a dbg.value for the corresponding
- // fragment.
- LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: "
- << *DII << '\n');
- return;
- }
-
- DebugLoc NewLoc = getDebugValueLoc(DII);
-
- // We are now tracking the loaded value instead of the address. In the
- // future if multi-location support is added to the IR, it might be
- // preferable to keep tracking both the loaded value and the original
- // address in case the alloca can not be elided.
- insertDbgValueOrDbgVariableRecordAfter(Builder, LI, DIVar, DIExpr, NewLoc,
- LI);
-}
-
void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR,
StoreInst *SI, DIBuilder &Builder) {
assert(DVR->isAddressOfVariable() || DVR->isDbgAssign());
@@ -1855,40 +1738,6 @@ void llvm::InsertDebugValueAtStoreLoc(DbgVariableRecord *DVR, StoreInst *SI,
SI->getIterator());
}
-/// Inserts a llvm.dbg.value intrinsic after a phi that has an associated
-/// llvm.dbg.declare intrinsic.
-void llvm::ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII,
- PHINode *APN, DIBuilder &Builder) {
- auto *DIVar = DII->getVariable();
- auto *DIExpr = DII->getExpression();
- assert(DIVar && "Missing variable");
-
- if (PhiHasDebugValue(DIVar, DIExpr, APN))
- return;
-
- if (!valueCoversEntireFragment(APN->getType(), DII)) {
- // FIXME: If only referring to a part of the variable described by the
- // dbg.declare, then we want to insert a dbg.value for the corresponding
- // fragment.
- LLVM_DEBUG(dbgs() << "Failed to convert dbg.declare to dbg.value: "
- << *DII << '\n');
- return;
- }
-
- BasicBlock *BB = APN->getParent();
- auto InsertionPt = BB->getFirstInsertionPt();
-
- DebugLoc NewLoc = getDebugValueLoc(DII);
-
- // The block may be a catchswitch block, which does not have a valid
- // insertion point.
- // FIXME: Insert dbg.value markers in the successors when appropriate.
- if (InsertionPt != BB->end()) {
- insertDbgValueOrDbgVariableRecord(Builder, APN, DIVar, DIExpr, NewLoc,
- InsertionPt);
- }
-}
-
void llvm::ConvertDebugDeclareToDebugValue(DbgVariableRecord *DVR, LoadInst *LI,
DIBuilder &Builder) {
auto *DIVar = DVR->getVariable();
@@ -1981,7 +1830,7 @@ bool llvm::LowerDbgDeclare(Function &F) {
if (Dbgs.empty() && DVRs.empty())
return Changed;
- auto LowerOne = [&](auto *DDI) {
+ auto LowerOne = [&](DbgVariableRecord *DDI) {
AllocaInst *AI =
dyn_cast_or_null<AllocaInst>(DDI->getVariableLocationOp(0));
// If this is an alloca for a scalar variable, insert a dbg.value
@@ -2036,7 +1885,6 @@ bool llvm::LowerDbgDeclare(Function &F) {
Changed = true;
};
- for_each(Dbgs, LowerOne);
for_each(DVRs, LowerOne);
if (Changed)
@@ -2046,12 +1894,9 @@ bool llvm::LowerDbgDeclare(Function &F) {
return Changed;
}
-// RemoveDIs: re-implementation of insertDebugValuesForPHIs, but which pulls the
-// debug-info out of the block's DbgVariableRecords rather than dbg.value
-// intrinsics.
-static void
-insertDbgVariableRecordsForPHIs(BasicBlock *BB,
- SmallVectorImpl<PHINode *> &InsertedPHIs) {
+/// Propagate dbg.value records through the newly inserted PHIs.
+void llvm::insertDebugValuesForPHIs(BasicBlock *BB,
+ SmallVectorImpl<PHINode *> &InsertedPHIs) {
assert(BB && "No BasicBlock to clone DbgVariableRecord(s) from.");
if (InsertedPHIs.size() == 0)
return;
@@ -2113,76 +1958,12 @@ insertDbgVariableRecordsForPHIs(BasicBlock *BB,
}
}
-/// Propagate dbg.value intrinsics through the newly inserted PHIs.
-void llvm::insertDebugValuesForPHIs(BasicBlock *BB,
- SmallVectorImpl<PHINode *> &InsertedPHIs) {
- assert(BB && "No BasicBlock to clone dbg.value(s) from.");
- if (InsertedPHIs.size() == 0)
- return;
-
- insertDbgVariableRecordsForPHIs(BB, InsertedPHIs);
-
- // Map existing PHI nodes to their dbg.values.
- ValueToValueMapTy DbgValueMap;
- for (auto &I : *BB) {
- if (auto DbgII = dyn_cast<DbgVariableIntrinsic>(&I)) {
- for (Value *V : DbgII->location_ops())
- if (auto *Loc = dyn_cast_or_null<PHINode>(V))
- DbgValueMap.insert({Loc, DbgII});
- }
- }
- if (DbgValueMap.size() == 0)
- return;
-
- // Map a pair of the destination BB and old dbg.value to the new dbg.value,
- // so that if a dbg.value is being rewritten to use more than one of the
- // inserted PHIs in the same destination BB, we can update the same dbg.value
- // with all the new PHIs instead of creating one copy for each.
- MapVector<std::pair<BasicBlock *, DbgVariableIntrinsic *>,
- DbgVariableIntrinsic *>
- NewDbgValueMap;
- // Then iterate through the new PHIs and look to see if they use one of the
- // previously mapped PHIs. If so, create a new dbg.value intrinsic that will
- // propagate the info through the new PHI. If we use more than one new PHI in
- // a single destination BB with the same old dbg.value, merge the updates so
- // that we get a single new dbg.value with all the new PHIs.
- for (auto *PHI : InsertedPHIs) {
- BasicBlock *Parent = PHI->getParent();
- // Avoid inserting an intrinsic into an EH block.
- if (Parent->getFirstNonPHIIt()->isEHPad())
- continue;
- for (auto *VI : PHI->operand_values()) {
- auto V = DbgValueMap.find(VI);
- if (V != DbgValueMap.end()) {
- auto *DbgII = cast<DbgVariableIntrinsic>(V->second);
- auto [NewDI, Inserted] = NewDbgValueMap.try_emplace({Parent, DbgII});
- if (Inserted)
- NewDI->second = cast<DbgVariableIntrinsic>(DbgII->clone());
- DbgVariableIntrinsic *NewDbgII = NewDI->second;
- // If PHI contains VI as an operand more than once, we may
- // replaced it in NewDbgII; confirm that it is present.
- if (is_contained(NewDbgII->location_ops(), VI))
- NewDbgII->replaceVariableLocationOp(VI, PHI);
- }
- }
- }
- // Insert thew new dbg.values into their destination blocks.
- for (auto DI : NewDbgValueMap) {
- BasicBlock *Parent = DI.first.first;
- auto *NewDbgII = DI.second;
- auto InsertionPt = Parent->getFirstInsertionPt();
- assert(InsertionPt != Parent->end() && "Ill-formed basic block");
- NewDbgII->insertBefore(InsertionPt);
- }
-}
-
bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress,
DIBuilder &Builder, uint8_t DIExprFlags,
int Offset) {
- TinyPtrVector<DbgDeclareInst *> DbgDeclares = findDbgDeclares(Address);
TinyPtrVector<DbgVariableRecord *> DVRDeclares = findDVRDeclares(Address);
- auto ReplaceOne = [&](auto *DII) {
+ auto ReplaceOne = [&](DbgVariableRecord *DII) {
assert(DII->getVariable() && "Missing variable");
auto *DIExpr = DII->getExpression();
DIExpr = DIExpression::prepend(DIExpr, DIExprFlags, Offset);
@@ -2190,10 +1971,9 @@ bool llvm::replaceDbgDeclare(Value *Address, Value *NewAddress,
DII->replaceVariableLocationOp(Address, NewAddress);
};
- for_each(DbgDeclares, ReplaceOne);
for_each(DVRDeclares, ReplaceOne);
- return !DbgDeclares.empty() || !DVRDeclares.empty();
+ return !DVRDeclares.empty();
}
static void updateOneDbgValueForAlloca(const DebugLoc &Loc,
@@ -2645,7 +2425,6 @@ using DbgValReplacement = std::optional<DIExpression *>;
/// changes are made.
static bool rewriteDebugUsers(
Instruction &From, Value &To, Instruction &DomPoint, DominatorTree &DT,
- function_ref<DbgValReplacement(DbgVariableIntrinsic &DII)> RewriteExpr,
function_ref<DbgValReplacement(DbgVariableRecord &DVR)> RewriteDVRExpr) {
// Find debug users of From.
SmallVector<DbgVariableIntrinsic *, 1> Users;
@@ -2654,43 +2433,32 @@ static bool rewriteDebugUsers(
if (Users.empty() && DPUsers.empty())
return false;
+ // Ignore intrinsic-users: they are no longer supported and should never
+ // appear.
+ assert(Users.empty());
+
// Prevent use-before-def of To.
bool Changed = false;
- SmallPtrSet<DbgVariableIntrinsic *, 1> UndefOrSalvage;
SmallPtrSet<DbgVariableRecord *, 1> UndefOrSalvageDVR;
if (isa<Instruction>(&To)) {
bool DomPointAfterFrom = From.getNextNonDebugInstruction() == &DomPoint;
- for (auto *DII : Users) {
- // It's common to see a debug user between From and DomPoint. Move it
- // after DomPoint to preserve the variable update without any reordering.
- if (DomPointAfterFrom && DII->getNextNonDebugInstruction() == &DomPoint) {
- LLVM_DEBUG(dbgs() << "MOVE: " << *DII << '\n');
- DII->moveAfter(&DomPoint);
- Changed = true;
-
- // Users which otherwise aren't dominated by the replacement value must
- // be salvaged or deleted.
- } else if (!DT.dominates(&DomPoint, DII)) {
- UndefOrSalvage.insert(DII);
- }
- }
-
// DbgVariableRecord implementation of the above.
for (auto *DVR : DPUsers) {
Instruction *MarkedInstr = DVR->getMarker()->MarkedInstr;
Instruction *NextNonDebug = MarkedInstr;
- // The next instruction might still be a dbg.declare, skip over it.
- if (isa<DbgVariableIntrinsic>(NextNonDebug))
- NextNonDebug = NextNonDebug->getNextNonDebugInstruction();
+ // It's common to see a debug user between From and DomPoint. Move it
+ // after DomPoint to preserve the variable update without any reordering.
if (DomPointAfterFrom && NextNonDebug == &DomPoint) {
LLVM_DEBUG(dbgs() << "MOVE: " << *DVR << '\n');
DVR->removeFromParent();
- // Ensure there's a marker.
DomPoint.getParent()->insertDbgRecordAfter(DVR, &DomPoint);
Changed = true;
+
+ // Users which otherwise aren't dominated by the replacement value must
+ // be salvaged or deleted.
} else if (!DT.dominates(&DomPoint, MarkedInstr)) {
UndefOrSalvageDVR.insert(DVR);
}
@@ -2698,19 +2466,6 @@ static bool rewriteDebugUsers(
}
// Update debug users without use-before-def risk.
- for (auto *DII : Users) {
- if (UndefOrSalvage.count(DII))
- continue;
-
- DbgValReplacement DVRepl = RewriteExpr(*DII);
- if (!DVRepl)
- continue;
-
- DII->replaceVariableLocationOp(&From, &To);
- DII->setExpression(*DVRepl);
- LLVM_DEBUG(dbgs() << "REWRITE: " << *DII << '\n');
- Changed = true;
- }
for (auto *DVR : DPUsers) {
if (UndefOrSalvageDVR.count(DVR))
continue;
@@ -2725,7 +2480,7 @@ static bool rewriteDebugUsers(
Changed = true;
}
- if (!UndefOrSalvage.empty() || !UndefOrSalvageDVR.empty()) {
+ if (!UndefOrSalvageDVR.empty()) {
// Try to salvage the remaining debug users.
salvageDebugInfo(From);
Changed = true;
@@ -2770,9 +2525,6 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
Type *FromTy = From.getType();
Type *ToTy = To.getType();
- auto Identity = [&](DbgVariableIntrinsic &DII) -> DbgValReplacement {
- return DII.getExpression();
- };
auto IdentityDVR = [&](DbgVariableRecord &DVR) -> DbgValReplacement {
return DVR.getExpression();
};
@@ -2781,7 +2533,7 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
Module &M = *From.getModule();
const DataLayout &DL = M.getDataLayout();
if (isBitCastSemanticsPreserving(DL, FromTy, ToTy))
- return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDVR);
+ return rewriteDebugUsers(From, To, DomPoint, DT, IdentityDVR);
// Handle integer-to-integer widening and narrowing.
// FIXME: Use DW_OP_convert when it's available everywhere.
@@ -2793,24 +2545,10 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
// When the width of the result grows, assume that a debugger will only
// access the low `FromBits` bits when inspecting the source variable.
if (FromBits < ToBits)
- return rewriteDebugUsers(From, To, DomPoint, DT, Identity, IdentityDVR);
+ return rewriteDebugUsers(From, To, DomPoint, DT, IdentityDVR);
// The width of the result has shrunk. Use sign/zero extension to describe
// the source variable's high bits.
- auto SignOrZeroExt = [&](DbgVariableIntrinsic &DII) -> DbgValReplacement {
- DILocalVariable *Var = DII.getVariable();
-
- // Without knowing signedness, sign/zero extension isn't possible.
- auto Signedness = Var->getSignedness();
- if (!Signedness)
- return std::nullopt;
-
- bool Signed = *Signedness == DIBasicType::Signedness::Signed;
- return DIExpression::appendExt(DII.getExpression(), ToBits, FromBits,
- Signed);
- };
- // RemoveDIs: duplicate implementation working on DbgVariableRecords rather
- // than on dbg.value intrinsics.
auto SignOrZeroExtDVR = [&](DbgVariableRecord &DVR) -> DbgValReplacement {
DILocalVariable *Var = DVR.getVariable();
@@ -2823,8 +2561,7 @@ bool llvm::replaceAllDbgUsesWith(Instruction &From, Value &To,
return DIExpression::appendExt(DVR.getExpression(), ToBits, FromBits,
Signed);
};
- return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExt,
- SignOrZeroExtDVR);
+ return rewriteDebugUsers(From, To, DomPoint, DT, SignOrZeroExtDVR);
}
// TODO: Floating-point conversions, vectors.
@@ -3800,10 +3537,6 @@ void llvm::remapDebugVariable(ValueToValueMapTy &Mapping, Instruction *Inst) {
if (I != Mapping.end())
DA->setAddress(I->second);
};
- if (auto DVI = dyn_cast<DbgVariableIntrinsic>(Inst))
- RemapDebugOperands(DVI, DVI->location_ops());
- if (auto DAI = dyn_cast<DbgAssignIntrinsic>(Inst))
- RemapAssignAddress(DAI);
for (DbgVariableRecord &DVR : filterDbgVars(Inst->getDbgRecordRange())) {
RemapDebugOperands(&DVR, DVR.location_ops());
if (DVR.isDbgAssign())
diff --git a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
index f1c051e46d1a0..837bc0731434f 100644
--- a/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
+++ b/llvm/lib/Transforms/Utils/PromoteMemoryToRegister.cpp
@@ -115,13 +115,6 @@ static void createDebugValue(DIBuilder &DIB, Value *NewValue,
DbgVariableRecord::createDbgVariableRecord(NewValue, Variable, Expression, DI,
*InsertBefore);
}
-static void createDebugValue(DIBuilder &DIB, Value *NewValue,
- DILocalVariable *Variable,
- DIExpression *Expression, const DILocation *DI,
- Instruction *InsertBefore) {
- DIB.insertDbgValueIntrinsic(NewValue, Variable, Expression, DI,
- InsertBefore->getIterator());
-}
/// Helper for updating assignment tracking debug info when promoting allocas.
class AssignmentTrackingInfo {
@@ -625,22 +618,18 @@ rewriteSingleStoreAlloca(AllocaInst *AI, AllocaInfo &Info, LargeBlockInfo &LBI,
// Record debuginfo for the store and remove the declaration's
// debuginfo.
- auto ConvertDebugInfoForStore = [&](auto &Container) {
- for (auto *DbgItem : Container) {
- if (DbgItem->isAddressOfVariable()) {
- ConvertDebugDeclareToDebugValue(DbgItem, Info.OnlyStore, DIB);
- DbgItem->eraseFromParent();
- } else if (DbgItem->isValueOfVariable() &&
- DbgItem->getExpression()->startsWithDeref()) {
- InsertDebugValueAtStoreLoc(DbgItem, Info.OnlyStore, DIB);
- DbgItem->eraseFromParent();
- } else if (DbgItem->getExpression()->startsWithDeref()) {
- DbgItem->eraseFromParent();
- }
+ for (DbgVariableRecord *DbgItem : Info.DPUsers) {
+ if (DbgItem->isAddressOfVariable()) {
+ ConvertDebugDeclareToDebugValue(DbgItem, Info.OnlyStore, DIB);
+ DbgItem->eraseFromParent();
+ } else if (DbgItem->isValueOfVariable() &&
+ DbgItem->getExpression()->startsWithDeref()) {
+ InsertDebugValueAtStoreLoc(DbgItem, Info.OnlyStore, DIB);
+ DbgItem->eraseFromParent();
+ } else if (DbgItem->getExpression()->startsWithDeref()) {
+ DbgItem->eraseFromParent();
}
- };
- ConvertDebugInfoForStore(Info.DbgUsers);
- ConvertDebugInfoForStore(Info.DPUsers);
+ }
// Remove dbg.assigns linked to the alloca as these are now redundant.
at::deleteAssignmentMarkers(AI);
@@ -739,15 +728,11 @@ promoteSingleBlockAlloca(AllocaInst *AI, const AllocaInfo &Info,
// Update assignment tracking info for the store we're going to delete.
Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DVRAssignsToDelete);
// Record debuginfo for the store before removing it.
- auto DbgUpdateForStore = [&](auto &Container) {
- for (auto *DbgItem : Container) {
- if (DbgItem->isAddressOfVariable()) {
- ConvertDebugDeclareToDebugValue(DbgItem, SI, DIB);
- }
+ for (DbgVariableRecord *DbgItem : Info.DPUsers) {
+ if (DbgItem->isAddressOfVariable()) {
+ ConvertDebugDeclareToDebugValue(DbgItem, SI, DIB);
}
- };
- DbgUpdateForStore(Info.DbgUsers);
- DbgUpdateForStore(Info.DPUsers);
+ }
SI->eraseFromParent();
LBI.deleteValue(SI);
@@ -1163,13 +1148,9 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
// The currently active variable for this block is now the PHI.
IncomingVals.set(AllocaNo, APN);
AllocaATInfo[AllocaNo].updateForNewPhi(APN, DIB);
- auto ConvertDbgDeclares = [&](auto &Container) {
- for (auto *DbgItem : Container)
- if (DbgItem->isAddressOfVariable())
- ConvertDebugDeclareToDebugValue(DbgItem, APN, DIB);
- };
- ConvertDbgDeclares(AllocaDbgUsers[AllocaNo]);
- ConvertDbgDeclares(AllocaDPUsers[AllocaNo]);
+ for (DbgVariableRecord *DbgItem : AllocaDPUsers[AllocaNo])
+ if (DbgItem->isAddressOfVariable())
+ ConvertDebugDeclareToDebugValue(DbgItem, APN, DIB);
// Get the next phi node.
++PNI;
@@ -1225,13 +1206,9 @@ void PromoteMem2Reg::RenamePass(BasicBlock *BB, BasicBlock *Pred) {
IncomingLocs.set(AllocaNo, SI->getDebugLoc());
AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB,
&DVRAssignsToDelete);
- auto ConvertDbgDeclares = [&](auto &Container) {
- for (auto *DbgItem : Container)
- if (DbgItem->isAddressOfVariable())
- ConvertDebugDeclareToDebugValue(DbgItem, SI, DIB);
- };
- ConvertDbgDeclares(AllocaDbgUsers[ai->second]);
- ConvertDbgDeclares(AllocaDPUsers[ai->second]);
+ for (DbgVariableRecord *DbgItem : AllocaDPUsers[ai->second])
+ if (DbgItem->isAddressOfVariable())
+ ConvertDebugDeclareToDebugValue(DbgItem, SI, DIB);
SI->eraseFromParent();
}
}
More information about the llvm-commits
mailing list