Index: llvm/test/tools/llvm-dwarfdump/X86/locstats-big-number-of-bytes.yaml =================================================================== --- /dev/null +++ llvm/test/tools/llvm-dwarfdump/X86/locstats-big-number-of-bytes.yaml @@ -0,0 +1,92 @@ +# RUN: yaml2obj %s | llvm-dwarfdump --statistics - | FileCheck %s + +## Check that we are covering the situation when +## sum of bytes in scope is a huge (uint64_t) number. +## +## The yaml represents this DWARF: +## +## DW_TAG_compile_unit +## DW_AT_low_pc (0x0000000000000000) +## DW_AT_high_pc (0x000000000000000b) +## +## DW_TAG_subprogram +## DW_AT_low_pc (0x0000000000000000) +## DW_AT_high_pc (0x00000000ffffffff) +## DW_TAG_variable +## DW_AT_location (0x00000023: +## [0x0000000000000003, 0x0000000000000005): DW_OP_reg2 RCX) +## DW_TAG_subprogram +## DW_AT_low_pc (0x0000000000000000) +## DW_AT_high_pc (0x00000000ffffffff) +## DW_TAG_variable +## DW_AT_location (0x00000023: +## [0x0000000000000003, 0x0000000000000005): DW_OP_reg2 RCX) + +# CHECK: "version": 9, +# CHECK: "sum_all_variables(#bytes in parent scope)": 8589934590 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_loc + Type: SHT_PROGBITS + AddressAlign: 0x01 + Content: '00000000000000000600000000000000010055000000000000000000000000000000000300000000000000050000000000000001005200000000000000000000000000000000' + - Name: .debug_ranges + Type: SHT_PROGBITS + AddressAlign: 0x01 + Content: '000000000000000003000000000000000500000000000000080000000000000000000000000000000000000000000000' +DWARF: + debug_abbrev: + - Table: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Code: 2 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Code: 3 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_sec_offset + debug_info: + - Version: 4 + AbbrOffset: 0x00 + Entries: + - AbbrCode: 1 ## DW_TAG_compile_unit + Values: + - Value: 0x00 ## DW_AT_low_pc + - Value: 0x0b ## DW_AT_high_pc + - AbbrCode: 2 ## DW_TAG_subprogram + Values: + - Value: 0x00 ## DW_AT_low_pc + - Value: 0xFFFFFFFF ## DW_AT_high_pc + - AbbrCode: 3 ## DW_TAG_variable + Values: + - Value: 0x23 ## DW_AT_sec_offset + - AbbrCode: 0 ## NULL + - AbbrCode: 2 ## DW_TAG_subprogram + Values: + - Value: 0x00 ## DW_AT_low_pc + - Value: 0xFFFFFFFF ## DW_AT_high_pc + - AbbrCode: 3 ## DW_TAG_variable + Values: + - Value: 0x23 ## DW_AT_sec_offset + - AbbrCode: 0 ## NULL + - AbbrCode: 0 ## NULL Index: llvm/test/tools/llvm-dwarfdump/X86/locstats-bytes-overflow.yaml =================================================================== --- /dev/null +++ llvm/test/tools/llvm-dwarfdump/X86/locstats-bytes-overflow.yaml @@ -0,0 +1,90 @@ +# RUN: yaml2obj %s | llvm-dwarfdump --statistics - 2>&1 | FileCheck %s + +## Check that we are covering the situation when a stat field overflows. +## +## The yaml represents this DWARF: +## +## DW_TAG_compile_unit +## DW_AT_low_pc (0x0000000000000000) +## DW_AT_high_pc (0x000000000000000b) +## +## DW_TAG_subprogram +## DW_AT_low_pc (0x0000000000000000) +## DW_AT_high_pc (0xffffffffffffffff) +## DW_TAG_variable +## DW_AT_location (0x00000023: +## [0x0000000000000003, 0x0000000000000005): DW_OP_reg2 RCX) +## DW_TAG_subprogram +## DW_AT_low_pc (0x0000000000000000) +## DW_AT_high_pc (0xffffffffffffffff) +## DW_TAG_variable +## DW_AT_location (0x00000023: +## [0x0000000000000003, 0x0000000000000005): DW_OP_reg2 RCX) + +# CHECK: "sum_all_variables(#bytes in parent scope)": "overflowed" + +--- !ELF +FileHeader: + Class: ELFCLASS[[BITS=64]] + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_loc + Type: SHT_PROGBITS + AddressAlign: 0x01 + Content: '00000000000000000600000000000000010055000000000000000000000000000000000300000000000000050000000000000001005200000000000000000000000000000000' + - Name: .debug_ranges + Type: SHT_PROGBITS + AddressAlign: 0x01 + Content: '000000000000000003000000000000000500000000000000080000000000000000000000000000000000000000000000' +DWARF: + debug_abbrev: + - Table: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Code: 2 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data8 + - Code: 3 + Tag: DW_TAG_variable + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_sec_offset + debug_info: + - Version: 4 + AbbrOffset: 0x00 + Entries: + - AbbrCode: 1 ## DW_TAG_compile_unit + Values: + - Value: 0x00 ## DW_AT_low_pc + - Value: 0x0b ## DW_AT_high_pc + - AbbrCode: 2 ## DW_TAG_subprogram + Values: + - Value: 0x00 ## DW_AT_low_pc + - Value: 0xFFFFFFFFFFFFFFFF ## DW_AT_high_pc + - AbbrCode: 3 ## DW_TAG_variable + Values: + - Value: 0x23 ## DW_AT_sec_offset + - AbbrCode: 0 ## NULL + - AbbrCode: 2 ## DW_TAG_subprogram + Values: + - Value: 0x00 ## DW_AT_low_pc + - Value: 0xFFFFFFFFFFFFFFFF ## DW_AT_high_pc + - AbbrCode: 3 ## DW_TAG_variable + Values: + - Value: 0x23 ## DW_AT_sec_offset + - AbbrCode: 0 ## NULL + - AbbrCode: 0 ## NULL Index: llvm/test/tools/llvm-dwarfdump/X86/locstats-for-absctract-origin-vars.yaml =================================================================== --- llvm/test/tools/llvm-dwarfdump/X86/locstats-for-absctract-origin-vars.yaml +++ llvm/test/tools/llvm-dwarfdump/X86/locstats-for-absctract-origin-vars.yaml @@ -120,7 +120,7 @@ ## DW_TAG_subprogram ## DW_AT_abstract_origin (0x000000f0) -# CHECK: "version": 8, +# CHECK: "version": 9, # CHECK: "#variables processed by location statistics": 17, # CHECK: "#variables with 0% of parent scope covered by DW_AT_location": 13, # CHECK: "#variables with 100% of parent scope covered by DW_AT_location": 4, Index: llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test =================================================================== --- llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test +++ llvm/test/tools/llvm-dwarfdump/X86/statistics-dwo.test @@ -69,7 +69,7 @@ # } # -CHECK: "version": 8, +CHECK: "version": 9, CHECK: "#functions": 3, CHECK: "#functions with location": 3, CHECK: "#inlined functions": 7, Index: llvm/test/tools/llvm-dwarfdump/X86/statistics-v3.test =================================================================== --- llvm/test/tools/llvm-dwarfdump/X86/statistics-v3.test +++ llvm/test/tools/llvm-dwarfdump/X86/statistics-v3.test @@ -64,7 +64,7 @@ # } # -CHECK: "version": 8, +CHECK: "version": 9, CHECK: "#functions": 3, CHECK: "#functions with location": 3, CHECK: "#inlined functions": 8, Index: llvm/test/tools/llvm-dwarfdump/X86/statistics.ll =================================================================== --- llvm/test/tools/llvm-dwarfdump/X86/statistics.ll +++ llvm/test/tools/llvm-dwarfdump/X86/statistics.ll @@ -1,6 +1,6 @@ ; RUN: llc -O0 %s -o - -filetype=obj \ ; RUN: | llvm-dwarfdump -statistics - | FileCheck %s -; CHECK: "version": 8, +; CHECK: "version": 9, ; namespace test { ; extern int a; Index: llvm/test/tools/llvm-dwarfdump/X86/stats-scope-bytes-covered.yaml =================================================================== --- llvm/test/tools/llvm-dwarfdump/X86/stats-scope-bytes-covered.yaml +++ llvm/test/tools/llvm-dwarfdump/X86/stats-scope-bytes-covered.yaml @@ -33,7 +33,7 @@ ## DW_AT_location (0x00000023: ## [0x0000000000000003, 0x0000000000000005): DW_OP_reg2 RCX) -# CHECK: "version": 8, +# CHECK: "version": 9, # CHECK: "sum_all_variables(#bytes in parent scope)": 12, # CHECK: "sum_all_variables(#bytes in any scope covered by DW_AT_location)": 8 # CHECK: "sum_all_variables(#bytes in parent scope covered by DW_AT_location)": 4 Index: llvm/tools/llvm-dwarfdump/Statistics.cpp =================================================================== --- llvm/tools/llvm-dwarfdump/Statistics.cpp +++ llvm/tools/llvm-dwarfdump/Statistics.cpp @@ -36,22 +36,44 @@ /// This represents function DIE offsets containing an abstract_origin. using FunctionsWithAbstractOriginTy = llvm::SmallVector; +/// This represents a data type for the stats and it helps us to +/// detect an overflow. The UINT64_MAX is used as an indication of +/// the overflow. +/// NOTE: This can be implemented as a template if there is an another type +/// needing this. +struct SaturatingUINT64 { + /// Number that represents the stats. + uint64_t Value; + + SaturatingUINT64(uint64_t Value_) : Value(Value_) {} + + void operator++(int) { return *this += 1; } + void operator+=(uint64_t Value_) { + if (Value != UINT64_MAX) { + if (Value < UINT64_MAX - Value_) + Value += Value_; + else + Value = UINT64_MAX; + } + } +}; + /// Holds statistics for one function (or other entity that has a PC range and /// contains variables, such as a compile unit). struct PerFunctionStats { /// Number of inlined instances of this function. - unsigned NumFnInlined = 0; + uint64_t NumFnInlined = 0; /// Number of out-of-line instances of this function. - unsigned NumFnOutOfLine = 0; + uint64_t NumFnOutOfLine = 0; /// Number of inlined instances that have abstract origins. - unsigned NumAbstractOrigins = 0; + uint64_t NumAbstractOrigins = 0; /// Number of variables and parameters with location across all inlined /// instances. - unsigned TotalVarWithLoc = 0; + uint64_t TotalVarWithLoc = 0; /// Number of constants with location across all inlined instances. - unsigned ConstantMembers = 0; + uint64_t ConstantMembers = 0; /// Number of arificial variables, parameters or members across all instances. - unsigned NumArtificial = 0; + uint64_t NumArtificial = 0; /// List of all Variables and parameters in this function. StringSet<> VarsInFunction; /// Compile units also cover a PC range, but have this flag set to false. @@ -59,63 +81,63 @@ /// Function has source location information. bool HasSourceLocation = false; /// Number of function parameters. - unsigned NumParams = 0; + uint64_t NumParams = 0; /// Number of function parameters with source location. - unsigned NumParamSourceLocations = 0; + uint64_t NumParamSourceLocations = 0; /// Number of function parameters with type. - unsigned NumParamTypes = 0; + uint64_t NumParamTypes = 0; /// Number of function parameters with a DW_AT_location. - unsigned NumParamLocations = 0; + uint64_t NumParamLocations = 0; /// Number of local variables. - unsigned NumLocalVars = 0; + uint64_t NumLocalVars = 0; /// Number of local variables with source location. - unsigned NumLocalVarSourceLocations = 0; + uint64_t NumLocalVarSourceLocations = 0; /// Number of local variables with type. - unsigned NumLocalVarTypes = 0; + uint64_t NumLocalVarTypes = 0; /// Number of local variables with DW_AT_location. - unsigned NumLocalVarLocations = 0; + uint64_t NumLocalVarLocations = 0; }; /// Holds accumulated global statistics about DIEs. struct GlobalStats { /// Total number of PC range bytes covered by DW_AT_locations. - unsigned TotalBytesCovered = 0; + SaturatingUINT64 TotalBytesCovered = 0; /// Total number of parent DIE PC range bytes covered by DW_AT_Locations. - unsigned ScopeBytesCovered = 0; + SaturatingUINT64 ScopeBytesCovered = 0; /// Total number of PC range bytes in each variable's enclosing scope. - unsigned ScopeBytes = 0; + SaturatingUINT64 ScopeBytes = 0; /// Total number of PC range bytes covered by DW_AT_locations with /// the debug entry values (DW_OP_entry_value). - unsigned ScopeEntryValueBytesCovered = 0; + SaturatingUINT64 ScopeEntryValueBytesCovered = 0; /// Total number of PC range bytes covered by DW_AT_locations of /// formal parameters. - unsigned ParamScopeBytesCovered = 0; + SaturatingUINT64 ParamScopeBytesCovered = 0; /// Total number of PC range bytes in each parameter's enclosing scope. - unsigned ParamScopeBytes = 0; + SaturatingUINT64 ParamScopeBytes = 0; /// Total number of PC range bytes covered by DW_AT_locations with /// the debug entry values (DW_OP_entry_value) (only for parameters). - unsigned ParamScopeEntryValueBytesCovered = 0; + SaturatingUINT64 ParamScopeEntryValueBytesCovered = 0; /// Total number of PC range bytes covered by DW_AT_locations (only for local /// variables). - unsigned LocalVarScopeBytesCovered = 0; + SaturatingUINT64 LocalVarScopeBytesCovered = 0; /// Total number of PC range bytes in each local variable's enclosing scope. - unsigned LocalVarScopeBytes = 0; + SaturatingUINT64 LocalVarScopeBytes = 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). - unsigned LocalVarScopeEntryValueBytesCovered = 0; + SaturatingUINT64 LocalVarScopeEntryValueBytesCovered = 0; /// Total number of call site entries (DW_AT_call_file & DW_AT_call_line). - unsigned CallSiteEntries = 0; + SaturatingUINT64 CallSiteEntries = 0; /// Total number of call site DIEs (DW_TAG_call_site). - unsigned CallSiteDIEs = 0; + SaturatingUINT64 CallSiteDIEs = 0; /// Total number of call site parameter DIEs (DW_TAG_call_site_parameter). - unsigned CallSiteParamDIEs = 0; + SaturatingUINT64 CallSiteParamDIEs = 0; /// Total byte size of concrete functions. This byte size includes /// inline functions contained in the concrete functions. - unsigned FunctionSize = 0; + SaturatingUINT64 FunctionSize = 0; /// Total byte size of inlined functions. This is the total number of bytes /// for the top inline functions within concrete functions. This can help /// tune the inline settings when compiling to match user expectations. - unsigned InlineFunctionSize = 0; + SaturatingUINT64 InlineFunctionSize = 0; }; /// Holds accumulated debug location statistics about local variables and @@ -126,37 +148,37 @@ /// of variables with the no debug location at all, but the last element /// in the vector represents the number of fully covered variables within /// its scope. - std::vector VarParamLocStats{ - std::vector(NumOfCoverageCategories, 0)}; + std::vector VarParamLocStats{ + std::vector(NumOfCoverageCategories, 0)}; /// Map non debug entry values coverage. - std::vector VarParamNonEntryValLocStats{ - std::vector(NumOfCoverageCategories, 0)}; + std::vector VarParamNonEntryValLocStats{ + std::vector(NumOfCoverageCategories, 0)}; /// The debug location statistics for formal parameters. - std::vector ParamLocStats{ - std::vector(NumOfCoverageCategories, 0)}; + std::vector ParamLocStats{ + std::vector(NumOfCoverageCategories, 0)}; /// Map non debug entry values coverage for formal parameters. - std::vector ParamNonEntryValLocStats{ - std::vector(NumOfCoverageCategories, 0)}; + std::vector ParamNonEntryValLocStats{ + std::vector(NumOfCoverageCategories, 0)}; /// The debug location statistics for local variables. - std::vector LocalVarLocStats{ - std::vector(NumOfCoverageCategories, 0)}; + std::vector LocalVarLocStats{ + std::vector(NumOfCoverageCategories, 0)}; /// Map non debug entry values coverage for local variables. - std::vector LocalVarNonEntryValLocStats{ - std::vector(NumOfCoverageCategories, 0)}; + std::vector LocalVarNonEntryValLocStats{ + std::vector(NumOfCoverageCategories, 0)}; /// Total number of local variables and function parameters processed. - unsigned NumVarParam = 0; + SaturatingUINT64 NumVarParam = 0; /// Total number of formal parameters processed. - unsigned NumParam = 0; + SaturatingUINT64 NumParam = 0; /// Total number of local variables processed. - unsigned NumVar = 0; + SaturatingUINT64 NumVar = 0; }; } // namespace /// Collect debug location statistics for one DIE. static void collectLocStats(uint64_t ScopeBytesCovered, uint64_t BytesInScope, - std::vector &VarParamLocStats, - std::vector &ParamLocStats, - std::vector &LocalVarLocStats, + std::vector &VarParamLocStats, + std::vector &ParamLocStats, + std::vector &LocalVarLocStats, bool IsParam, bool IsLocalVar) { auto getCoverageBucket = [ScopeBytesCovered, BytesInScope]() -> unsigned { // No debug location at all for the variable. @@ -173,11 +195,11 @@ unsigned CoverageBucket = getCoverageBucket(); - VarParamLocStats[CoverageBucket]++; + VarParamLocStats[CoverageBucket].Value++; if (IsParam) - ParamLocStats[CoverageBucket]++; + ParamLocStats[CoverageBucket].Value++; else if (IsLocalVar) - LocalVarLocStats[CoverageBucket]++; + LocalVarLocStats[CoverageBucket].Value++; } /// Construct an identifier for a given DIE from its Prefix, Name, DeclFileName @@ -350,11 +372,11 @@ // Calculate the debug location statistics. if (BytesInScope && !DeferLocStats) { - LocStats.NumVarParam++; + LocStats.NumVarParam.Value++; if (IsParam) - LocStats.NumParam++; + LocStats.NumParam.Value++; else if (IsLocalVar) - LocStats.NumVar++; + LocStats.NumVar.Value++; collectLocStats(ScopeBytesCovered, BytesInScope, LocStats.VarParamLocStats, LocStats.ParamLocStats, LocStats.LocalVarLocStats, IsParam, @@ -389,7 +411,7 @@ GlobalStats.LocalVarScopeEntryValueBytesCovered += BytesEntryValuesCovered; } - assert(GlobalStats.ScopeBytesCovered <= GlobalStats.ScopeBytes); + assert(GlobalStats.ScopeBytesCovered.Value <= GlobalStats.ScopeBytes.Value); } if (IsConstantMember) { @@ -603,45 +625,79 @@ /// Print human-readable output. /// \{ static void printDatum(json::OStream &J, const char *Key, json::Value Value) { - J.attribute(Key, Value); + // We defined the UINT64_MAX as an overflow indication. + if (Value == UINT64_MAX) + J.attribute(Key, "overflowed"); + else + J.attribute(Key, Value); + LLVM_DEBUG(llvm::dbgs() << Key << ": " << Value << '\n'); } static void printLocationStats(json::OStream &J, const char *Key, - std::vector &LocationStats) { - J.attribute( - (Twine(Key) + " with 0% of parent scope covered by DW_AT_location").str(), - LocationStats[0]); + std::vector &LocationStats) { + if (LocationStats[0].Value == UINT64_MAX) + J.attribute((Twine(Key) + + " with (0%,10%) of parent scope covered by DW_AT_location") + .str(), + "overflowed"); + else + J.attribute( + (Twine(Key) + " with 0% of parent scope covered by DW_AT_location") + .str(), + LocationStats[0].Value); LLVM_DEBUG( llvm::dbgs() << Key << " with 0% of parent scope covered by DW_AT_location: \\" - << LocationStats[0] << '\n'); - J.attribute( - (Twine(Key) + " with (0%,10%) of parent scope covered by DW_AT_location") - .str(), - LocationStats[1]); + << LocationStats[0].Value << '\n'); + + if (LocationStats[1].Value == UINT64_MAX) + J.attribute((Twine(Key) + + " with (0%,10%) of parent scope covered by DW_AT_location") + .str(), + "overflowed"); + else + J.attribute((Twine(Key) + + " with (0%,10%) of parent scope covered by DW_AT_location") + .str(), + LocationStats[1].Value); LLVM_DEBUG(llvm::dbgs() << Key << " with (0%,10%) of parent scope covered by DW_AT_location: " - << LocationStats[1] << '\n'); + << LocationStats[1].Value << '\n'); + for (unsigned i = 2; i < NumOfCoverageCategories - 1; ++i) { - J.attribute((Twine(Key) + " with [" + Twine((i - 1) * 10) + "%," + - Twine(i * 10) + "%) of parent scope covered by DW_AT_location") - .str(), - LocationStats[i]); + if (LocationStats[i].Value == UINT64_MAX) + J.attribute((Twine(Key) + " with [" + Twine((i - 1) * 10) + "%," + + Twine(i * 10) + + "%) of parent scope covered by DW_AT_location") + .str(), + "overflowed"); + else + J.attribute((Twine(Key) + " with [" + Twine((i - 1) * 10) + "%," + + Twine(i * 10) + + "%) of parent scope covered by DW_AT_location") + .str(), + LocationStats[i].Value); LLVM_DEBUG(llvm::dbgs() << Key << " with [" << (i - 1) * 10 << "%," << i * 10 << "%) of parent scope covered by DW_AT_location: " - << LocationStats[i]); + << LocationStats[i].Value); } - J.attribute( - (Twine(Key) + " with 100% of parent scope covered by DW_AT_location") - .str(), - LocationStats[NumOfCoverageCategories - 1]); + if (LocationStats[NumOfCoverageCategories - 1].Value == UINT64_MAX) + J.attribute( + (Twine(Key) + " with 100% of parent scope covered by DW_AT_location") + .str(), + "overflowed"); + else + J.attribute( + (Twine(Key) + " with 100% of parent scope covered by DW_AT_location") + .str(), + LocationStats[NumOfCoverageCategories - 1].Value); LLVM_DEBUG( llvm::dbgs() << Key << " with 100% of parent scope covered by DW_AT_location: " - << LocationStats[NumOfCoverageCategories - 1]); + << LocationStats[NumOfCoverageCategories - 1].Value); } static void printSectionSizes(json::OStream &J, const SectionSizes &Sizes) { @@ -750,31 +806,31 @@ /// The version number should be increased every time the algorithm is changed /// (including bug fixes). New metrics may be added without increasing the /// version. - unsigned Version = 8; - unsigned VarParamTotal = 0; - unsigned VarParamUnique = 0; - unsigned VarParamWithLoc = 0; - unsigned NumFunctions = 0; - unsigned NumInlinedFunctions = 0; - unsigned NumFuncsWithSrcLoc = 0; - unsigned NumAbstractOrigins = 0; - unsigned ParamTotal = 0; - unsigned ParamWithType = 0; - unsigned ParamWithLoc = 0; - unsigned ParamWithSrcLoc = 0; - unsigned LocalVarTotal = 0; - unsigned LocalVarWithType = 0; - unsigned LocalVarWithSrcLoc = 0; - unsigned LocalVarWithLoc = 0; + unsigned Version = 9; + SaturatingUINT64 VarParamTotal = 0; + SaturatingUINT64 VarParamUnique = 0; + SaturatingUINT64 VarParamWithLoc = 0; + SaturatingUINT64 NumFunctions = 0; + SaturatingUINT64 NumInlinedFunctions = 0; + SaturatingUINT64 NumFuncsWithSrcLoc = 0; + SaturatingUINT64 NumAbstractOrigins = 0; + SaturatingUINT64 ParamTotal = 0; + SaturatingUINT64 ParamWithType = 0; + SaturatingUINT64 ParamWithLoc = 0; + SaturatingUINT64 ParamWithSrcLoc = 0; + SaturatingUINT64 LocalVarTotal = 0; + SaturatingUINT64 LocalVarWithType = 0; + SaturatingUINT64 LocalVarWithSrcLoc = 0; + SaturatingUINT64 LocalVarWithLoc = 0; for (auto &Entry : Statistics) { PerFunctionStats &Stats = Entry.getValue(); - unsigned TotalVars = Stats.VarsInFunction.size() * + uint64_t TotalVars = Stats.VarsInFunction.size() * (Stats.NumFnInlined + Stats.NumFnOutOfLine); // Count variables in global scope. if (!Stats.IsFunction) TotalVars = Stats.NumLocalVars + Stats.ConstantMembers + Stats.NumArtificial; - unsigned Constants = Stats.ConstantMembers; + uint64_t Constants = Stats.ConstantMembers; VarParamWithLoc += Stats.TotalVarWithLoc + Constants; VarParamTotal += TotalVars; VarParamUnique += Stats.VarsInFunction.size(); @@ -806,70 +862,72 @@ printDatum(J, "file", Filename.str()); printDatum(J, "format", FormatName); - printDatum(J, "#functions", NumFunctions); - printDatum(J, "#functions with location", NumFuncsWithSrcLoc); - printDatum(J, "#inlined functions", NumInlinedFunctions); - printDatum(J, "#inlined functions with abstract origins", NumAbstractOrigins); + printDatum(J, "#functions", NumFunctions.Value); + printDatum(J, "#functions with location", NumFuncsWithSrcLoc.Value); + printDatum(J, "#inlined functions", NumInlinedFunctions.Value); + printDatum(J, "#inlined functions with abstract origins", + NumAbstractOrigins.Value); // This includes local variables and formal parameters. - printDatum(J, "#unique source variables", VarParamUnique); - printDatum(J, "#source variables", VarParamTotal); - printDatum(J, "#source variables with location", VarParamWithLoc); + printDatum(J, "#unique source variables", VarParamUnique.Value); + printDatum(J, "#source variables", VarParamTotal.Value); + printDatum(J, "#source variables with location", VarParamWithLoc.Value); - printDatum(J, "#call site entries", GlobalStats.CallSiteEntries); - printDatum(J, "#call site DIEs", GlobalStats.CallSiteDIEs); - printDatum(J, "#call site parameter DIEs", GlobalStats.CallSiteParamDIEs); + printDatum(J, "#call site entries", GlobalStats.CallSiteEntries.Value); + printDatum(J, "#call site DIEs", GlobalStats.CallSiteDIEs.Value); + printDatum(J, "#call site parameter DIEs", + GlobalStats.CallSiteParamDIEs.Value); printDatum(J, "sum_all_variables(#bytes in parent scope)", - GlobalStats.ScopeBytes); + GlobalStats.ScopeBytes.Value); printDatum(J, "sum_all_variables(#bytes in any scope covered by DW_AT_location)", - GlobalStats.TotalBytesCovered); + GlobalStats.TotalBytesCovered.Value); printDatum(J, "sum_all_variables(#bytes in parent scope covered by " "DW_AT_location)", - GlobalStats.ScopeBytesCovered); + GlobalStats.ScopeBytesCovered.Value); printDatum(J, "sum_all_variables(#bytes in parent scope covered by " "DW_OP_entry_value)", - GlobalStats.ScopeEntryValueBytesCovered); + GlobalStats.ScopeEntryValueBytesCovered.Value); printDatum(J, "sum_all_params(#bytes in parent scope)", - GlobalStats.ParamScopeBytes); + GlobalStats.ParamScopeBytes.Value); printDatum(J, "sum_all_params(#bytes in parent scope covered by DW_AT_location)", - GlobalStats.ParamScopeBytesCovered); + GlobalStats.ParamScopeBytesCovered.Value); printDatum(J, "sum_all_params(#bytes in parent scope covered by " "DW_OP_entry_value)", - GlobalStats.ParamScopeEntryValueBytesCovered); + GlobalStats.ParamScopeEntryValueBytesCovered.Value); printDatum(J, "sum_all_local_vars(#bytes in parent scope)", - GlobalStats.LocalVarScopeBytes); + GlobalStats.LocalVarScopeBytes.Value); printDatum(J, "sum_all_local_vars(#bytes in parent scope covered by " "DW_AT_location)", - GlobalStats.LocalVarScopeBytesCovered); + GlobalStats.LocalVarScopeBytesCovered.Value); printDatum(J, "sum_all_local_vars(#bytes in parent scope covered by " "DW_OP_entry_value)", - GlobalStats.LocalVarScopeEntryValueBytesCovered); + GlobalStats.LocalVarScopeEntryValueBytesCovered.Value); - printDatum(J, "#bytes within functions", GlobalStats.FunctionSize); + printDatum(J, "#bytes within functions", GlobalStats.FunctionSize.Value); printDatum(J, "#bytes within inlined functions", - GlobalStats.InlineFunctionSize); + GlobalStats.InlineFunctionSize.Value); // Print the summary for formal parameters. - printDatum(J, "#params", ParamTotal); - printDatum(J, "#params with source location", ParamWithSrcLoc); - printDatum(J, "#params with type", ParamWithType); - printDatum(J, "#params with binary location", ParamWithLoc); + printDatum(J, "#params", ParamTotal.Value); + printDatum(J, "#params with source location", ParamWithSrcLoc.Value); + printDatum(J, "#params with type", ParamWithType.Value); + printDatum(J, "#params with binary location", ParamWithLoc.Value); // Print the summary for local variables. - printDatum(J, "#local vars", LocalVarTotal); - printDatum(J, "#local vars with source location", LocalVarWithSrcLoc); - printDatum(J, "#local vars with type", LocalVarWithType); - printDatum(J, "#local vars with binary location", LocalVarWithLoc); + printDatum(J, "#local vars", LocalVarTotal.Value); + printDatum(J, "#local vars with source location", LocalVarWithSrcLoc.Value); + printDatum(J, "#local vars with type", LocalVarWithType.Value); + printDatum(J, "#local vars with binary location", LocalVarWithLoc.Value); // Print the debug section sizes. printSectionSizes(J, Sizes); @@ -877,32 +935,34 @@ // Print the location statistics for variables (includes local variables // and formal parameters). printDatum(J, "#variables processed by location statistics", - LocStats.NumVarParam); + LocStats.NumVarParam.Value); printLocationStats(J, "#variables", LocStats.VarParamLocStats); printLocationStats(J, "#variables - entry values", LocStats.VarParamNonEntryValLocStats); // Print the location statistics for formal parameters. - printDatum(J, "#params processed by location statistics", LocStats.NumParam); + printDatum(J, "#params processed by location statistics", + LocStats.NumParam.Value); printLocationStats(J, "#params", LocStats.ParamLocStats); printLocationStats(J, "#params - entry values", LocStats.ParamNonEntryValLocStats); // Print the location statistics for local variables. printDatum(J, "#local vars processed by location statistics", - LocStats.NumVar); + LocStats.NumVar.Value); printLocationStats(J, "#local vars", LocStats.LocalVarLocStats); printLocationStats(J, "#local vars - entry values", LocStats.LocalVarNonEntryValLocStats); J.objectEnd(); OS << '\n'; - LLVM_DEBUG( - llvm::dbgs() << "Total Availability: " - << (int)std::round((VarParamWithLoc * 100.0) / VarParamTotal) - << "%\n"; - llvm::dbgs() << "PC Ranges covered: " - << (int)std::round((GlobalStats.ScopeBytesCovered * 100.0) / - GlobalStats.ScopeBytes) - << "%\n"); + LLVM_DEBUG(llvm::dbgs() << "Total Availability: " + << (int)std::round((VarParamWithLoc.Value * 100.0) / + VarParamTotal.Value) + << "%\n"; + llvm::dbgs() << "PC Ranges covered: " + << (int)std::round( + (GlobalStats.ScopeBytesCovered.Value * 100.0) / + GlobalStats.ScopeBytes.Value) + << "%\n"); return true; }