aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
diff options
context:
space:
mode:
authorOrlando Cazalet-Hyams <orlando.hyams@sony.com>2023-12-11 12:23:26 +0000
committerGitHub <noreply@github.com>2023-12-11 12:23:26 +0000
commit5d5583979179e3b0702888adf188b10831037758 (patch)
tree90ee1f7830c2694e4a7597cc5d591b28fe4837a6 /llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
parentae7bffd71c44c8fa21b91e62da22e4d9272b0193 (diff)
downloadllvm-5d5583979179e3b0702888adf188b10831037758.zip
llvm-5d5583979179e3b0702888adf188b10831037758.tar.gz
llvm-5d5583979179e3b0702888adf188b10831037758.tar.bz2
[AssignmentTracking] Skip large types in redundant debug info pruning (#74329)
Fix https://github.com/llvm/llvm-project/issues/74189 (crash report). The pruning code uses a BitVector to track which parts of a variable have been defined in order to find redundant debug records. BitVector uses a u32 to track size; variable of types with a bit-size greater than max(u32) ish* can't be represented using a BitVector. Fix the assertion by introducing a limit on type size. Improve performance by bringing the limit down to a sensible number and tracking byte-sizes instead of bit-sizes. Skipping variables in this pruning code doesn't cause debug info correctness issues; it just means there may be some extra redundant debug records. (*) `max(u32) - 63` due to BitVector::NumBitWords implementation.
Diffstat (limited to 'llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp')
-rw-r--r--llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp27
1 files changed, 17 insertions, 10 deletions
diff --git a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
index f005280..ad3ad99 100644
--- a/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
+++ b/llvm/lib/CodeGen/AssignmentTrackingAnalysis.cpp
@@ -2269,14 +2269,14 @@ static bool
removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB,
FunctionVarLocsBuilder &FnVarLocs) {
bool Changed = false;
- SmallDenseMap<DebugAggregate, BitVector> VariableDefinedBits;
+ SmallDenseMap<DebugAggregate, BitVector> VariableDefinedBytes;
// Scan over the entire block, not just over the instructions mapped by
// FnVarLocs, because wedges in FnVarLocs may only be seperated by debug
// instructions.
for (const Instruction &I : reverse(*BB)) {
if (!isa<DbgVariableIntrinsic>(I)) {
// Sequence of consecutive defs ended. Clear map for the next one.
- VariableDefinedBits.clear();
+ VariableDefinedBytes.clear();
}
// Get the location defs that start just before this instruction.
@@ -2295,9 +2295,15 @@ removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB,
DebugAggregate Aggr =
getAggregate(FnVarLocs.getVariable(RIt->VariableID));
uint64_t SizeInBits = Aggr.first->getSizeInBits().value_or(0);
+ uint64_t SizeInBytes = divideCeil(SizeInBits, 8);
- if (SizeInBits == 0) {
+ // Cutoff for large variables to prevent expensive bitvector operations.
+ const uint64_t MaxSizeBytes = 2048;
+
+ if (SizeInBytes == 0 || SizeInBytes > MaxSizeBytes) {
// If the size is unknown (0) then keep this location def to be safe.
+ // Do the same for defs of large variables, which would be expensive
+ // to represent with a BitVector.
NewDefsReversed.push_back(*RIt);
continue;
}
@@ -2305,23 +2311,24 @@ removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB,
// Only keep this location definition if it is not fully eclipsed by
// other definitions in this wedge that come after it
- // Inert the bits the location definition defines.
+ // Inert the bytes the location definition defines.
auto InsertResult =
- VariableDefinedBits.try_emplace(Aggr, BitVector(SizeInBits));
+ VariableDefinedBytes.try_emplace(Aggr, BitVector(SizeInBytes));
bool FirstDefinition = InsertResult.second;
- BitVector &DefinedBits = InsertResult.first->second;
+ BitVector &DefinedBytes = InsertResult.first->second;
DIExpression::FragmentInfo Fragment =
RIt->Expr->getFragmentInfo().value_or(
DIExpression::FragmentInfo(SizeInBits, 0));
bool InvalidFragment = Fragment.endInBits() > SizeInBits;
+ uint64_t StartInBytes = Fragment.startInBits() / 8;
+ uint64_t EndInBytes = divideCeil(Fragment.endInBits(), 8);
- // If this defines any previously undefined bits, keep it.
+ // If this defines any previously undefined bytes, keep it.
if (FirstDefinition || InvalidFragment ||
- DefinedBits.find_first_unset_in(Fragment.startInBits(),
- Fragment.endInBits()) != -1) {
+ DefinedBytes.find_first_unset_in(StartInBytes, EndInBytes) != -1) {
if (!InvalidFragment)
- DefinedBits.set(Fragment.startInBits(), Fragment.endInBits());
+ DefinedBytes.set(StartInBytes, EndInBytes);
NewDefsReversed.push_back(*RIt);
continue;
}