@@ -60,28 +60,26 @@ struct PerFunctionStats {
60
60
struct GlobalStats {
61
61
// / Total number of PC range bytes covered by DW_AT_locations.
62
62
unsigned ScopeBytesCovered = 0 ;
63
- // / Total number of PC range bytes in each variable's enclosing scope,
64
- // / starting from the first definition of the variable.
65
- unsigned ScopeBytesFromFirstDefinition = 0 ;
63
+ // / Total number of PC range bytes in each variable's enclosing scope.
64
+ unsigned ScopeBytes = 0 ;
66
65
// / Total number of PC range bytes covered by DW_AT_locations with
67
66
// / the debug entry values (DW_OP_entry_value).
68
67
unsigned ScopeEntryValueBytesCovered = 0 ;
69
68
// / Total number of PC range bytes covered by DW_AT_locations of
70
69
// / formal parameters.
71
70
unsigned ParamScopeBytesCovered = 0 ;
72
- // / Total number of PC range bytes in each variable's enclosing scope,
73
- // / starting from the first definition of the variable (only for parameters).
74
- unsigned ParamScopeBytesFromFirstDefinition = 0 ;
71
+ // / Total number of PC range bytes in each variable's enclosing scope
72
+ // / (only for parameters).
73
+ unsigned ParamScopeBytes = 0 ;
75
74
// / Total number of PC range bytes covered by DW_AT_locations with
76
75
// / the debug entry values (DW_OP_entry_value) (only for parameters).
77
76
unsigned ParamScopeEntryValueBytesCovered = 0 ;
78
77
// / Total number of PC range bytes covered by DW_AT_locations (only for local
79
78
// / variables).
80
79
unsigned VarScopeBytesCovered = 0 ;
81
- // / Total number of PC range bytes in each variable's enclosing scope,
82
- // / starting from the first definition of the variable (only for local
83
- // / variables).
84
- unsigned VarScopeBytesFromFirstDefinition = 0 ;
80
+ // / Total number of PC range bytes in each variable's enclosing scope
81
+ // / (only for local variables).
82
+ unsigned VarScopeBytes = 0 ;
85
83
// / Total number of PC range bytes covered by DW_AT_locations with
86
84
// / the debug entry values (DW_OP_entry_value) (only for local variables).
87
85
unsigned VarScopeEntryValueBytesCovered = 0 ;
@@ -133,19 +131,6 @@ struct LocationStats {
133
131
unsigned NumVar = 0 ;
134
132
};
135
133
136
- // / Extract the low pc from a Die.
137
- static uint64_t getLowPC (DWARFDie Die) {
138
- auto RangesOrError = Die.getAddressRanges ();
139
- DWARFAddressRangesVector Ranges;
140
- if (RangesOrError)
141
- Ranges = RangesOrError.get ();
142
- else
143
- llvm::consumeError (RangesOrError.takeError ());
144
- if (Ranges.size ())
145
- return Ranges[0 ].LowPC ;
146
- return dwarf::toAddress (Die.find (dwarf::DW_AT_low_pc), 0 );
147
- }
148
-
149
134
// / Collect debug location statistics for one DIE.
150
135
static void collectLocStats (uint64_t BytesCovered, uint64_t BytesInScope,
151
136
std::vector<unsigned > &VarParamLocStats,
@@ -177,8 +162,8 @@ static void collectLocStats(uint64_t BytesCovered, uint64_t BytesInScope,
177
162
178
163
// / Collect debug info quality metrics for one DIE.
179
164
static void collectStatsForDie (DWARFDie Die, std::string FnPrefix,
180
- std::string VarPrefix, uint64_t ScopeLowPC ,
181
- uint64_t BytesInScope, uint32_t InlineDepth,
165
+ std::string VarPrefix, uint64_t BytesInScope ,
166
+ uint32_t InlineDepth,
182
167
StringMap<PerFunctionStats> &FnStatMap,
183
168
GlobalStats &GlobalStats,
184
169
LocationStats &LocStats) {
@@ -188,7 +173,6 @@ static void collectStatsForDie(DWARFDie Die, std::string FnPrefix,
188
173
bool IsArtificial = false ;
189
174
uint64_t BytesCovered = 0 ;
190
175
uint64_t BytesEntryValuesCovered = 0 ;
191
- uint64_t OffsetToFirstDefinition = 0 ;
192
176
auto &FnStats = FnStatMap[FnPrefix];
193
177
bool IsParam = Die.getTag () == dwarf::DW_TAG_formal_parameter;
194
178
bool IsLocalVar = Die.getTag () == dwarf::DW_TAG_variable;
@@ -262,16 +246,6 @@ static void collectStatsForDie(DWARFDie Die, std::string FnPrefix,
262
246
if (IsEntryValue (Entry.Expr ))
263
247
BytesEntryValuesCovered += BytesEntryCovered;
264
248
}
265
- if (!Loc->empty ()) {
266
- uint64_t FirstDef = Loc->front ().Range ->LowPC ;
267
- // Ranges sometimes start before the lexical scope.
268
- if (FirstDef >= ScopeLowPC)
269
- OffsetToFirstDefinition = FirstDef - ScopeLowPC;
270
- // Or even after it. Count that as a failure.
271
- if (OffsetToFirstDefinition > BytesInScope)
272
- OffsetToFirstDefinition = 0 ;
273
- }
274
- assert (BytesInScope);
275
249
}
276
250
}
277
251
}
@@ -304,25 +278,21 @@ static void collectStatsForDie(DWARFDie Die, std::string FnPrefix,
304
278
FnStats.VarsInFunction .insert (VarPrefix + VarName);
305
279
if (BytesInScope) {
306
280
FnStats.TotalVarWithLoc += (unsigned )HasLoc;
307
- // Adjust for the fact the variables often start their lifetime in the
308
- // middle of the scope.
309
- BytesInScope -= OffsetToFirstDefinition;
310
281
// Turns out we have a lot of ranges that extend past the lexical scope.
311
282
GlobalStats.ScopeBytesCovered += std::min (BytesInScope, BytesCovered);
312
- GlobalStats.ScopeBytesFromFirstDefinition += BytesInScope;
283
+ GlobalStats.ScopeBytes += BytesInScope;
313
284
GlobalStats.ScopeEntryValueBytesCovered += BytesEntryValuesCovered;
314
285
if (IsParam) {
315
286
GlobalStats.ParamScopeBytesCovered +=
316
287
std::min (BytesInScope, BytesCovered);
317
- GlobalStats.ParamScopeBytesFromFirstDefinition += BytesInScope;
288
+ GlobalStats.ParamScopeBytes += BytesInScope;
318
289
GlobalStats.ParamScopeEntryValueBytesCovered += BytesEntryValuesCovered;
319
290
} else if (IsLocalVar) {
320
291
GlobalStats.VarScopeBytesCovered += std::min (BytesInScope, BytesCovered);
321
- GlobalStats.VarScopeBytesFromFirstDefinition += BytesInScope;
292
+ GlobalStats.VarScopeBytes += BytesInScope;
322
293
GlobalStats.VarScopeEntryValueBytesCovered += BytesEntryValuesCovered;
323
294
}
324
- assert (GlobalStats.ScopeBytesCovered <=
325
- GlobalStats.ScopeBytesFromFirstDefinition );
295
+ assert (GlobalStats.ScopeBytesCovered <= GlobalStats.ScopeBytes );
326
296
} else if (Die.getTag () == dwarf::DW_TAG_member) {
327
297
FnStats.ConstantMembers ++;
328
298
} else {
@@ -351,8 +321,8 @@ static void collectStatsForDie(DWARFDie Die, std::string FnPrefix,
351
321
352
322
// / Recursively collect debug info quality metrics.
353
323
static void collectStatsRecursive (DWARFDie Die, std::string FnPrefix,
354
- std::string VarPrefix, uint64_t ScopeLowPC ,
355
- uint64_t BytesInScope, uint32_t InlineDepth,
324
+ std::string VarPrefix, uint64_t BytesInScope ,
325
+ uint32_t InlineDepth,
356
326
StringMap<PerFunctionStats> &FnStatMap,
357
327
GlobalStats &GlobalStats,
358
328
LocationStats &LocStats) {
@@ -387,7 +357,6 @@ static void collectStatsRecursive(DWARFDie Die, std::string FnPrefix,
387
357
uint64_t BytesInThisScope = 0 ;
388
358
for (auto Range : Ranges)
389
359
BytesInThisScope += Range.HighPC - Range.LowPC ;
390
- ScopeLowPC = getLowPC (Die);
391
360
392
361
// Count the function.
393
362
if (!IsBlock) {
@@ -423,8 +392,8 @@ static void collectStatsRecursive(DWARFDie Die, std::string FnPrefix,
423
392
}
424
393
} else {
425
394
// Not a scope, visit the Die itself. It could be a variable.
426
- collectStatsForDie (Die, FnPrefix, VarPrefix, ScopeLowPC, BytesInScope ,
427
- InlineDepth, FnStatMap, GlobalStats, LocStats);
395
+ collectStatsForDie (Die, FnPrefix, VarPrefix, BytesInScope, InlineDepth ,
396
+ FnStatMap, GlobalStats, LocStats);
428
397
}
429
398
430
399
// Set InlineDepth correctly for child recursion
@@ -441,9 +410,8 @@ static void collectStatsRecursive(DWARFDie Die, std::string FnPrefix,
441
410
if (Child.getTag () == dwarf::DW_TAG_lexical_block)
442
411
ChildVarPrefix += toHex (LexicalBlockIndex++) + ' .' ;
443
412
444
- collectStatsRecursive (Child, FnPrefix, ChildVarPrefix, ScopeLowPC,
445
- BytesInScope, InlineDepth, FnStatMap, GlobalStats,
446
- LocStats);
413
+ collectStatsRecursive (Child, FnPrefix, ChildVarPrefix, BytesInScope,
414
+ InlineDepth, FnStatMap, GlobalStats, LocStats);
447
415
Child = Child.getSibling ();
448
416
}
449
417
}
@@ -496,13 +464,13 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
496
464
StringMap<PerFunctionStats> Statistics;
497
465
for (const auto &CU : static_cast <DWARFContext *>(&DICtx)->compile_units ())
498
466
if (DWARFDie CUDie = CU->getNonSkeletonUnitDIE (false ))
499
- collectStatsRecursive (CUDie, " /" , " g" , 0 , 0 , 0 , Statistics, GlobalStats,
467
+ collectStatsRecursive (CUDie, " /" , " g" , 0 , 0 , Statistics, GlobalStats,
500
468
LocStats);
501
469
502
470
// / The version number should be increased every time the algorithm is changed
503
471
// / (including bug fixes). New metrics may be added without increasing the
504
472
// / version.
505
- unsigned Version = 3 ;
473
+ unsigned Version = 4 ;
506
474
unsigned VarParamTotal = 0 ;
507
475
unsigned VarParamUnique = 0 ;
508
476
unsigned VarParamWithLoc = 0 ;
@@ -562,19 +530,17 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
562
530
printDatum (OS, " call site entries" , GlobalStats.CallSiteEntries );
563
531
printDatum (OS, " call site DIEs" , GlobalStats.CallSiteDIEs );
564
532
printDatum (OS, " call site parameter DIEs" , GlobalStats.CallSiteParamDIEs );
565
- printDatum (OS, " scope bytes total" ,
566
- GlobalStats.ScopeBytesFromFirstDefinition );
533
+ printDatum (OS, " scope bytes total" , GlobalStats.ScopeBytes );
567
534
printDatum (OS, " scope bytes covered" , GlobalStats.ScopeBytesCovered );
568
535
printDatum (OS, " entry value scope bytes covered" ,
569
536
GlobalStats.ScopeEntryValueBytesCovered );
570
537
printDatum (OS, " formal params scope bytes total" ,
571
- GlobalStats.ParamScopeBytesFromFirstDefinition );
538
+ GlobalStats.ParamScopeBytes );
572
539
printDatum (OS, " formal params scope bytes covered" ,
573
540
GlobalStats.ParamScopeBytesCovered );
574
541
printDatum (OS, " formal params entry value scope bytes covered" ,
575
542
GlobalStats.ParamScopeEntryValueBytesCovered );
576
- printDatum (OS, " vars scope bytes total" ,
577
- GlobalStats.VarScopeBytesFromFirstDefinition );
543
+ printDatum (OS, " vars scope bytes total" , GlobalStats.VarScopeBytes );
578
544
printDatum (OS, " vars scope bytes covered" , GlobalStats.VarScopeBytesCovered );
579
545
printDatum (OS, " vars entry value scope bytes covered" ,
580
546
GlobalStats.VarScopeEntryValueBytesCovered );
@@ -609,7 +575,7 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
609
575
<< " %\n " ;
610
576
llvm::dbgs () << " PC Ranges covered: "
611
577
<< (int )std::round ((GlobalStats.ScopeBytesCovered * 100.0 ) /
612
- GlobalStats.ScopeBytesFromFirstDefinition )
578
+ GlobalStats.ScopeBytes )
613
579
<< " %\n " );
614
580
return true ;
615
581
}
0 commit comments