[PATCH] D69027: [llvm-dwarfdump][Statistics] Fix calculation of OffsetToFirstDefinition

Alexey Lapshin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 22 16:37:15 PDT 2019


avl added a comment.

I am not the author of statistics in llvm-dwarfdump tool, and the following information could be irrelevant.
It needs to be checked by someone from the DebugInfo project.

It seems, calculating scope coverage is incomplete currently.
The original idea based on the fact that the variable's enclosing scope could be determined by subtracting OffsetFromFirstDefinition:

  /// Total number of PC range bytes covered by DW_AT_locations.
  unsigned ScopeBytesCovered = 0;
  /// Total number of PC range bytes in each variable's enclosing scope,
  /// starting from the first definition of the variable.
  unsigned ScopeBytesFromFirstDefinition = 0;

But, if generated debug info is not complete, then start and end of address ranges could not match with the real beginning and end of variable`s address range. In that case, coverage calculated using OffsetFromFirstDefinition would always be 100%, as in the above example. It would be hard to guess that debug info is incomplete, looking at 100% coverage. Instead, comparing with scope range would show us that the coverage small(in case incomplete debug info generated). That could be used to discover incomplete debug info case.

Speaking of variable's enclosing scope: it is necessary to take into account not only OffsetFromFirstDefinition, which points into the start of the variable's enclosing scope. The end of the variable's address ranges should also be encountered.

Currently llvm-dwarfdump tool calculates scope`s and variable`s statistic separately:

  unsigned VarScopeBytesCovered = 0;
  /// Total number of PC range bytes in each variable's enclosing scope,
  /// starting from the first definition of the variable (only for local
  /// variables).
  unsigned VarScopeBytesFromFirstDefinition = 0;
  /// Total number of PC range bytes covered by DW_AT_locations with
  /// the debug entry values (DW_OP_entry_value) (only for local variables).

So it is probably OK to have coverage for variable against overall scope(which allows us to see above problem) and to see coverage for variable against it`s enclosing scope, assuming start and end of address ranges of the variable are correct.

In that case it looks like coverage statistic could be calculated like this :

for DIE

  from start_scope_pc till end_scope_pc 
      ScopeBytes += scope_pc_range
      ScopeBytesCovered += scope_pc_range INTERSECTION OF variable_pc_range
  
  ScopeCoverage = ScopeBytes / ScopeBytesCovered;
  
  from start_var_pc till end_var_pc 
      VarBytes += scope_pc_range 
      VarBytesCovered += scope_pc_range INTERSECTION OF variable_pc_range
  
  VarCoverage = VarBytes / VarBytesCovered;



================
Comment at: tools/llvm-dwarfdump/Statistics.cpp:297
             uint64_t FirstDef = List->Entries[0].Begin;
-            uint64_t UnitOfs = UnitLowPC; 
-            // Ranges sometimes start before the lexical scope.
-            if (UnitOfs + FirstDef >= ScopeLowPC)
-              OffsetToFirstDefinition = UnitOfs + FirstDef - ScopeLowPC;
-            // Or even after it. Count that as a failure.
-            if (OffsetToFirstDefinition > BytesInScope)
-              OffsetToFirstDefinition = 0;
+            BytesInScope = adjustScopeToFirstDef(BytesInScope, FirstDef,
+                                                 ScopeDie, UnitLowPC);
----------------
adjustScopeToFirstDef() returns BytesInScope with already subtracted OffsetToFirstDefinition. That BytesInScope value later passed into collectLocStats(). Previously it was passed without subtracting OffsetToFirstDefinition. Is that correct?


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69027/new/

https://reviews.llvm.org/D69027





More information about the llvm-commits mailing list