@@ -23,6 +23,9 @@ struct PerFunctionStats {
23
23
StringSet<> VarsInFunction;
24
24
// / Compile units also cover a PC range, but have this flag set to false.
25
25
bool IsFunction = false ;
26
+ // / Verify function definition has PC addresses (for detecting when
27
+ // / a function has been inlined everywhere).
28
+ bool HasPCAddresses = false ;
26
29
};
27
30
28
31
// / Holds accumulated global statistics about DIEs.
@@ -136,8 +139,10 @@ static void collectStatsForDie(DWARFDie Die, std::string FnPrefix,
136
139
GlobalStats.ScopeBytesFromFirstDefinition += BytesInScope;
137
140
assert (GlobalStats.ScopeBytesCovered <=
138
141
GlobalStats.ScopeBytesFromFirstDefinition );
139
- } else {
142
+ } else if (Die. getTag () == dwarf::DW_TAG_member) {
140
143
FnStats.ConstantMembers ++;
144
+ } else {
145
+ FnStats.TotalVarWithLoc += (unsigned )HasLoc;
141
146
}
142
147
}
143
148
@@ -164,6 +169,19 @@ static void collectStatsRecursive(DWARFDie Die, std::string FnPrefix,
164
169
if (Die.find (dwarf::DW_AT_declaration))
165
170
return ;
166
171
172
+ // PC Ranges.
173
+ auto RangesOrError = Die.getAddressRanges ();
174
+ if (!RangesOrError) {
175
+ llvm::consumeError (RangesOrError.takeError ());
176
+ return ;
177
+ }
178
+
179
+ auto Ranges = RangesOrError.get ();
180
+ uint64_t BytesInThisScope = 0 ;
181
+ for (auto Range : Ranges)
182
+ BytesInThisScope += Range.HighPC - Range.LowPC ;
183
+ ScopeLowPC = getLowPC (Die);
184
+
167
185
// Count the function.
168
186
if (!IsBlock) {
169
187
StringRef Name = Die.getName (DINameKind::LinkageName);
@@ -175,23 +193,13 @@ static void collectStatsRecursive(DWARFDie Die, std::string FnPrefix,
175
193
return ;
176
194
// We've seen an (inlined) instance of this function.
177
195
auto &FnStats = FnStatMap[Name];
178
- FnStats.NumFnInlined ++;
196
+ if (IsInlinedFunction)
197
+ FnStats.NumFnInlined ++;
179
198
FnStats.IsFunction = true ;
199
+ if (BytesInThisScope && !IsInlinedFunction)
200
+ FnStats.HasPCAddresses = true ;
180
201
}
181
202
182
- // PC Ranges.
183
- auto RangesOrError = Die.getAddressRanges ();
184
- if (!RangesOrError) {
185
- llvm::consumeError (RangesOrError.takeError ());
186
- return ;
187
- }
188
-
189
- auto Ranges = RangesOrError.get ();
190
- uint64_t BytesInThisScope = 0 ;
191
- for (auto Range : Ranges)
192
- BytesInThisScope += Range.HighPC - Range.LowPC ;
193
- ScopeLowPC = getLowPC (Die);
194
-
195
203
if (BytesInThisScope) {
196
204
BytesInScope = BytesInThisScope;
197
205
if (IsFunction)
@@ -258,7 +266,7 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
258
266
// / The version number should be increased every time the algorithm is changed
259
267
// / (including bug fixes). New metrics may be added without increasing the
260
268
// / version.
261
- unsigned Version = 1 ;
269
+ unsigned Version = 2 ;
262
270
unsigned VarTotal = 0 ;
263
271
unsigned VarUnique = 0 ;
264
272
unsigned VarWithLoc = 0 ;
@@ -267,9 +275,12 @@ bool collectStatsForObjectFile(ObjectFile &Obj, DWARFContext &DICtx,
267
275
for (auto &Entry : Statistics) {
268
276
PerFunctionStats &Stats = Entry.getValue ();
269
277
unsigned TotalVars = Stats.VarsInFunction .size () * Stats.NumFnInlined ;
278
+ // Count variables in concrete out-of-line functions and in global scope.
279
+ if (Stats.HasPCAddresses || !Stats.IsFunction )
280
+ TotalVars += Stats.VarsInFunction .size ();
270
281
unsigned Constants = Stats.ConstantMembers ;
271
282
VarWithLoc += Stats.TotalVarWithLoc + Constants;
272
- VarTotal += TotalVars + Constants ;
283
+ VarTotal += TotalVars;
273
284
VarUnique += Stats.VarsInFunction .size ();
274
285
LLVM_DEBUG (for (auto &V : Stats.VarsInFunction ) llvm::dbgs ()
275
286
<< Entry.getKey () << " : " << V.getKey () << " \n " );
0 commit comments