Index: llvm/test/tools/llvm-dwarfdump/X86/locstats.ll =================================================================== --- /dev/null +++ llvm/test/tools/llvm-dwarfdump/X86/locstats.ll @@ -0,0 +1,149 @@ +; RUN: llc -debug-entry-values %s -o - -filetype=obj \ +; RUN: | llvm-dwarfdump -statistics - | FileCheck %s +; +; CHECK: "constant members":0 +; CHECK: "variables with fully scope covered by debug locations":3 +; CHECK: "variables with fully scope covered by non entry value debug locations":1 +; CHECK: "variables with more than half scope covered by debug locations":2 +; CHECK: "variables with more than half scope covered by non entry value debug locations":2 +; CHECK: "entry value scope bytes covered":5 +; CHECK: "formal params scope bytes total":20 +; CHECK: "formal params scope bytes covered":20 +; CHECK: "formal params entry value scope bytes covered":5 +; CHECK: "vars scope bytes total":78 +; CHECK: "vars scope bytes covered":60 +; CHECK: "vars entry value scope bytes covered":0 +; CHECK: "formal params with fully scope covered by debug locations":2 +; CHECK: "formal params with fully scope covered by non entry value debug locations":1 +; CHECK: "formal params with more than half scope covered by debug locations":0 +; CHECK: "formal params with more than half scope covered by non entry value debug locations":0 +; CHECK: "vars with fully scope covered by debug locations":1 +; CHECK: "vars with fully scope covered by non entry value debug locations":0 +; CHECK: "vars with more than half scope covered by debug locations":2 +; CHECK: "vars with more than half scope covered by non entry value debug locations":2 +; +; The source code of the test case: +; extern void fn3(int *); +; extern void fn2 (int); +; __attribute__((noinline)) +; void +; fn1 (int x, int y) +; { +; int u = x + y; +; if (x > 1) +; u += 1; +; else +; u += 2; +; if (y > 4) +; u += x; +; int a = 7; +; fn2 (a); +; u --; +; } +; +; __attribute__((noinline)) +; int f() +; { +; int l, k; +; fn3(&l); +; fn3(&k); +; fn1 (l, k); +; return 0; +; } +; +; ModuleID = 'test.c' +source_filename = "test.c" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; Function Attrs: noinline nounwind uwtable +define dso_local void @fn1(i32 %x, i32 %y) local_unnamed_addr !dbg !16 { +entry: + call void @llvm.dbg.value(metadata i32 %x, metadata !20, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.value(metadata i32 %y, metadata !21, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.value(metadata i32 undef, metadata !22, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.value(metadata i32 undef, metadata !22, metadata !DIExpression()), !dbg !24 + call void @llvm.dbg.value(metadata i32 7, metadata !23, metadata !DIExpression()), !dbg !24 + tail call void @fn2(i32 7), !dbg !25 + call void @llvm.dbg.value(metadata i32 undef, metadata !22, metadata !DIExpression(DW_OP_constu, 1, DW_OP_minus, DW_OP_stack_value)), !dbg !24 + ret void, !dbg !26 +} + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) + +declare !dbg !4 dso_local void @fn2(i32) local_unnamed_addr + +; Function Attrs: argmemonly nounwind willreturn +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) + +; Function Attrs: noinline nounwind uwtable +define dso_local i32 @f() local_unnamed_addr !dbg !27 { +entry: + %l = alloca i32, align 4 + %k = alloca i32, align 4 + %0 = bitcast i32* %l to i8*, !dbg !33 + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0), !dbg !33 + %1 = bitcast i32* %k to i8*, !dbg !33 + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %1), !dbg !33 + call void @llvm.dbg.value(metadata i32* %l, metadata !31, metadata !DIExpression(DW_OP_deref)), !dbg !34 + call void @fn3(i32* nonnull %l), !dbg !35 + call void @llvm.dbg.value(metadata i32* %k, metadata !32, metadata !DIExpression(DW_OP_deref)), !dbg !34 + call void @fn3(i32* nonnull %k), !dbg !36 + %2 = load i32, i32* %l, align 4, !dbg !37 + call void @llvm.dbg.value(metadata i32 %2, metadata !31, metadata !DIExpression()), !dbg !34 + %3 = load i32, i32* %k, align 4, !dbg !37 + call void @llvm.dbg.value(metadata i32 %3, metadata !32, metadata !DIExpression()), !dbg !34 + call void @fn1(i32 %2, i32 %3), !dbg !37 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %1), !dbg !37 + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0), !dbg !37 + ret i32 0, !dbg !37 +} + +declare !dbg !8 dso_local void @fn3(i32*) local_unnamed_addr + +; Function Attrs: nounwind readnone speculatable willreturn +declare void @llvm.dbg.value(metadata, metadata, metadata) + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!12, !13, !14} +!llvm.ident = !{!15} + +!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, retainedTypes: !3, nameTableKind: None) +!1 = !DIFile(filename: "test.c", directory: "/") +!2 = !{} +!3 = !{!4, !8} +!4 = !DISubprogram(name: "fn2", scope: !1, file: !1, line: 2, type: !5, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!5 = !DISubroutineType(types: !6) +!6 = !{null, !7} +!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!8 = !DISubprogram(name: "fn3", scope: !1, file: !1, line: 1, type: !9, flags: DIFlagPrototyped, spFlags: DISPFlagOptimized, retainedNodes: !2) +!9 = !DISubroutineType(types: !10) +!10 = !{null, !11} +!11 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64) +!12 = !{i32 2, !"Dwarf Version", i32 4} +!13 = !{i32 2, !"Debug Info Version", i32 3} +!14 = !{i32 1, !"wchar_size", i32 4} +!15 = !{!"clang version 10.0.0"} +!16 = distinct !DISubprogram(name: "fn1", scope: !1, file: !1, line: 6, type: !17, scopeLine: 7, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !19) +!17 = !DISubroutineType(types: !18) +!18 = !{null, !7, !7} +!19 = !{!20, !21, !22, !23} +!20 = !DILocalVariable(name: "x", arg: 1, scope: !16, file: !1, line: 6, type: !7, flags: DIFlagArgumentNotModified) +!21 = !DILocalVariable(name: "y", arg: 2, scope: !16, file: !1, line: 6, type: !7, flags: DIFlagArgumentNotModified) +!22 = !DILocalVariable(name: "u", scope: !16, file: !1, line: 8, type: !7) +!23 = !DILocalVariable(name: "a", scope: !16, file: !1, line: 18, type: !7) +!24 = !DILocation(line: 0, scope: !16) +!25 = !DILocation(line: 20, column: 3, scope: !16) +!26 = !DILocation(line: 22, column: 1, scope: !16) +!27 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 25, type: !28, scopeLine: 26, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !30) +!28 = !DISubroutineType(types: !29) +!29 = !{!7} +!30 = !{!31, !32} +!31 = !DILocalVariable(name: "l", scope: !27, file: !1, line: 27, type: !7) +!32 = !DILocalVariable(name: "k", scope: !27, file: !1, line: 27, type: !7) +!33 = !DILocation(line: 27, column: 3, scope: !27) +!34 = !DILocation(line: 0, scope: !27) +!35 = !DILocation(line: 29, column: 3, scope: !27) +!36 = !DILocation(line: 30, column: 3, scope: !27) +!37 = !DILocation(line: 32, column: 8, scope: !27) Index: llvm/tools/llvm-dwarfdump/Statistics.cpp =================================================================== --- llvm/tools/llvm-dwarfdump/Statistics.cpp +++ llvm/tools/llvm-dwarfdump/Statistics.cpp @@ -43,10 +43,45 @@ unsigned NumVars = 0; /// Number of variables with source location. unsigned NumVarSourceLocations = 0; - /// Number of variables wtih type. + /// Number of variables with type. unsigned NumVarTypes = 0; - /// Number of variables wtih DW_AT_location. + /// Number of variables with DW_AT_location. unsigned NumVarLocations = 0; + /// Number of variables with fully covered debug location range of its scope. + unsigned NumVarParmFullyCoveredLoc = 0; + /// Number of variables with fully covered non entry value debug location + /// range of its scope. + unsigned NumVarParmFullyCoveredNonEntryValueLoc = 0; + /// Number of variables with more than 50% covered debug location range of its + /// scope. + unsigned NumVarParamMoreThanHalfScopeCoveredLoc = 0; + /// Number of variables with more than 50% covered non entry value debug + /// location range of its scope. + unsigned NumVarParamMoreThanHalfScopeNonEntryValCoveredLoc = 0; + /// Number of formal parameters with fully covered debug location range of its + /// scope. + unsigned NumParmFullyCoveredLoc = 0; + /// Number of formal parameters with fully covered non entry value debug + /// location range of its scope. + unsigned NumParmFullyCoveredNonEntryValueLoc = 0; + /// Number of formal parameters with more than 50% covered debug location + /// range of its scope. + unsigned NumParamMoreThanHalfScopeCoveredLoc = 0; + /// Number of formal parameters with more than 50% covered non entry value + /// debug location range of its scope. + unsigned NumParamMoreThanHalfScopeNonEntryValCoveredLoc = 0; + /// Number of local variables with fully covered debug location range of its + /// scope. + unsigned NumVarFullyCoveredLoc = 0; + /// Number of local variables with fully covered non entry value debug + /// location range of its scope. + unsigned NumVarFullyCoveredNonEntryValueLoc = 0; + /// Number of local variables with more than 50% covered debug location range + /// of its scope. + unsigned NumVarMoreThanHalfScopeCoveredLoc = 0; + /// Number of local variables with more than 50% covered non entry value debug + /// location range of its scope. + unsigned NumVarMoreThanHalfScopeNonEntryValCoveredLoc = 0; }; /// Holds accumulated global statistics about DIEs. @@ -56,6 +91,28 @@ /// Total number of PC range bytes in each variable's enclosing scope, /// starting from the first definition of the variable. unsigned ScopeBytesFromFirstDefinition = 0; + /// Total number of PC range bytes covered by DW_AT_locations with + /// the debug entry values (DW_OP_entry_value). + unsigned ScopeEntryValueBytesCovered = 0; + /// Total number of PC range bytes covered by DW_AT_locations of + /// formal parameters. + unsigned ParamScopeBytesCovered = 0; + /// Total number of PC range bytes in each variable's enclosing scope, + /// starting from the first definition of the variable (only for parameters). + unsigned ParamScopeBytesFromFirstDefinition = 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; + /// Total number of PC range bytes covered by DW_AT_locations (only for local + /// variables). + 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). + unsigned VarScopeEntryValueBytesCovered = 0; /// Total number of call site entries (DW_AT_call_file & DW_AT_call_line). unsigned CallSiteEntries = 0; /// Total number of call site DIEs (DW_TAG_call_site). @@ -95,7 +152,11 @@ bool HasType = false; bool IsArtificial = false; uint64_t BytesCovered = 0; + uint64_t BytesEntryValuesCovered = 0; uint64_t OffsetToFirstDefinition = 0; + auto &FnStats = FnStatMap[FnPrefix]; + bool IsParam = Die.getTag() == dwarf::DW_TAG_formal_parameter; + bool IsLocalVar = Die.getTag() == dwarf::DW_TAG_variable; if (Die.getTag() == dwarf::DW_TAG_call_site || Die.getTag() == dwarf::DW_TAG_GNU_call_site) { @@ -109,9 +170,7 @@ return; } - if (Die.getTag() != dwarf::DW_TAG_formal_parameter && - Die.getTag() != dwarf::DW_TAG_variable && - Die.getTag() != dwarf::DW_TAG_member) { + if (!IsParam && !IsLocalVar && Die.getTag() != dwarf::DW_TAG_member) { // Not a variable or constant member. return; } @@ -126,10 +185,28 @@ if (Die.find(dwarf::DW_AT_artificial)) IsArtificial = true; + auto IsEntryValue = [&](StringRef D) -> bool { + DWARFUnit *U = Die.getDwarfUnit(); + DataExtractor Data(D, Die.getDwarfUnit()->getContext().isLittleEndian(), 0); + DWARFExpression Expression(Data, U->getVersion(), U->getAddressByteSize()); + // Consider the expression containing the DW_OP_entry_value as + // an entry value. + return llvm::any_of(Expression, [](DWARFExpression::Operation &Op) { + return Op.getCode() == dwarf::DW_OP_entry_value || + Op.getCode() == dwarf::DW_OP_GNU_entry_value; + }); + }; + if (Die.find(dwarf::DW_AT_const_value)) { // This catches constant members *and* variables. HasLoc = true; BytesCovered = BytesInScope; + FnStats.NumVarParmFullyCoveredLoc++; + if (IsParam) { + FnStats.NumParmFullyCoveredLoc++; + } else if (IsLocalVar) { + FnStats.NumVarFullyCoveredLoc++; + } } else { if (Die.getTag() == dwarf::DW_TAG_member) { // Non-const member. @@ -143,8 +220,12 @@ if (auto DebugLocOffset = FormValue->getAsSectionOffset()) { auto *DebugLoc = Die.getDwarfUnit()->getContext().getDebugLoc(); if (auto List = DebugLoc->getLocationListAtOffset(*DebugLocOffset)) { - for (auto Entry : List->Entries) - BytesCovered += Entry.End - Entry.Begin; + for (auto Entry : List->Entries) { + uint64_t BytesEntryCovered = Entry.End - Entry.Begin; + BytesCovered += BytesEntryCovered; + if (IsEntryValue(Entry.Loc)) + BytesEntryValuesCovered += BytesEntryCovered; + } if (List->Entries.size()) { uint64_t FirstDef = List->Entries[0].Begin; uint64_t UnitOfs = getLowPC(Die.getDwarfUnit()->getUnitDIE()); @@ -157,15 +238,64 @@ } } assert(BytesInScope); + + // Calculate the total of variables with fully and more than half scope + // covered debug location range. + if (BytesCovered == BytesInScope) { + FnStats.NumVarParmFullyCoveredLoc++; + if (IsParam) { + FnStats.NumParmFullyCoveredLoc++; + } else if (IsLocalVar) { + FnStats.NumVarFullyCoveredLoc++; + } + } else { + int InScopeCovered = 100 * (double)BytesCovered / BytesInScope; + if (InScopeCovered > 50) { + FnStats.NumVarParamMoreThanHalfScopeCoveredLoc++; + if (IsParam) { + FnStats.NumParamMoreThanHalfScopeCoveredLoc++; + } else if (IsLocalVar) { + FnStats.NumVarMoreThanHalfScopeCoveredLoc++; + } + } + } + + // Calculate the total of variables with fully and more than half scope + // covered non entry value debug location range. + if (BytesCovered - BytesEntryValuesCovered == BytesInScope) { + FnStats.NumVarParmFullyCoveredNonEntryValueLoc++; + if (IsParam) { + FnStats.NumParmFullyCoveredNonEntryValueLoc++; + } else if (IsLocalVar) { + FnStats.NumVarFullyCoveredNonEntryValueLoc++; + } + } else { + int InScopeNonEntryValCovered = + 100 * (double)(BytesCovered - BytesEntryValuesCovered) / + BytesInScope; + if (InScopeNonEntryValCovered > 50) { + FnStats.NumVarParamMoreThanHalfScopeNonEntryValCoveredLoc++; + if (IsParam) { + FnStats.NumParamMoreThanHalfScopeNonEntryValCoveredLoc++; + } else if (IsLocalVar) { + FnStats.NumVarMoreThanHalfScopeNonEntryValCoveredLoc++; + } + } + } } else { // Assume the entire range is covered by a single location. BytesCovered = BytesInScope; + FnStats.NumVarParmFullyCoveredLoc++; + if (IsParam) { + FnStats.NumParmFullyCoveredLoc++; + } else if (IsLocalVar) { + FnStats.NumVarFullyCoveredLoc++; + } } } } // Collect PC range coverage data. - auto &FnStats = FnStatMap[FnPrefix]; if (DWARFDie D = Die.getAttributeValueAsReferencedDie(dwarf::DW_AT_abstract_origin)) Die = D; @@ -181,6 +311,17 @@ // Turns out we have a lot of ranges that extend past the lexical scope. GlobalStats.ScopeBytesCovered += std::min(BytesInScope, BytesCovered); GlobalStats.ScopeBytesFromFirstDefinition += BytesInScope; + GlobalStats.ScopeEntryValueBytesCovered += BytesEntryValuesCovered; + if (IsParam) { + GlobalStats.ParamScopeBytesCovered += + std::min(BytesInScope, BytesCovered); + GlobalStats.ParamScopeBytesFromFirstDefinition += BytesInScope; + GlobalStats.ParamScopeEntryValueBytesCovered += BytesEntryValuesCovered; + } else if (IsLocalVar) { + GlobalStats.VarScopeBytesCovered += std::min(BytesInScope, BytesCovered); + GlobalStats.VarScopeBytesFromFirstDefinition += BytesInScope; + GlobalStats.VarScopeEntryValueBytesCovered += BytesEntryValuesCovered; + } assert(GlobalStats.ScopeBytesCovered <= GlobalStats.ScopeBytesFromFirstDefinition); } else if (Die.getTag() == dwarf::DW_TAG_member) { @@ -189,7 +330,7 @@ FnStats.TotalVarWithLoc += (unsigned)HasLoc; } if (!IsArtificial) { - if (Die.getTag() == dwarf::DW_TAG_formal_parameter) { + if (IsParam) { FnStats.NumParams++; if (HasType) FnStats.NumParamTypes++; @@ -197,7 +338,7 @@ FnStats.NumParamSourceLocations++; if (HasLoc) FnStats.NumParamLocations++; - } else if (Die.getTag() == dwarf::DW_TAG_variable) { + } else if (IsLocalVar) { FnStats.NumVars++; if (HasType) FnStats.NumVarTypes++; @@ -342,6 +483,7 @@ unsigned Version = 3; unsigned VarParamTotal = 0; unsigned VarParamUnique = 0; + unsigned ConstMembers = 0; unsigned VarParamWithLoc = 0; unsigned NumFunctions = 0; unsigned NumInlinedFunctions = 0; @@ -355,6 +497,18 @@ unsigned VarWithType = 0; unsigned VarWithSrcLoc = 0; unsigned VarWithLoc = 0; + unsigned VarParamWithFullyCoveredLoc = 0; + unsigned VarParamWithFullyNonEntryValCoveredLoc = 0; + unsigned VarParamWithMoreThanHalfCoveredLoc = 0; + unsigned VarParamWithMoreThanHalfNonEntryValCoveredLoc = 0; + unsigned ParamWithFullyCoveredLoc = 0; + unsigned ParamWithFullyNonEntryValCoveredLoc = 0; + unsigned ParamWithMoreThanHalfCoveredLoc = 0; + unsigned ParamWithMoreThanHalfNonEntryValCoveredLoc = 0; + unsigned VarWithFullyCoveredLoc = 0; + unsigned VarWithFullyNonEntryValCoveredLoc = 0; + unsigned VarWithMoreThanHalfCoveredLoc = 0; + unsigned VarWithMoreThanHalfNonEntryValCoveredLoc = 0; for (auto &Entry : Statistics) { PerFunctionStats &Stats = Entry.getValue(); unsigned TotalVars = Stats.VarsInFunction.size() * Stats.NumFnInlined; @@ -362,6 +516,7 @@ if (Stats.HasPCAddresses || !Stats.IsFunction) TotalVars += Stats.VarsInFunction.size(); unsigned Constants = Stats.ConstantMembers; + ConstMembers += Constants; VarParamWithLoc += Stats.TotalVarWithLoc + Constants; VarParamTotal += TotalVars; VarParamUnique += Stats.VarsInFunction.size(); @@ -369,6 +524,26 @@ : Stats.VarsInFunction) llvm::dbgs() << Entry.getKey() << ": " << V.getKey() << "\n"); NumFunctions += Stats.IsFunction; + VarParamWithFullyCoveredLoc += Stats.NumVarParmFullyCoveredLoc; + VarParamWithFullyNonEntryValCoveredLoc += + Stats.NumVarParmFullyCoveredNonEntryValueLoc; + VarParamWithMoreThanHalfCoveredLoc += + Stats.NumVarParamMoreThanHalfScopeCoveredLoc; + VarParamWithMoreThanHalfNonEntryValCoveredLoc += + Stats.NumVarParamMoreThanHalfScopeNonEntryValCoveredLoc; + ParamWithFullyCoveredLoc += Stats.NumParmFullyCoveredLoc; + ParamWithFullyNonEntryValCoveredLoc += + Stats.NumParmFullyCoveredNonEntryValueLoc; + ParamWithMoreThanHalfCoveredLoc += + Stats.NumParamMoreThanHalfScopeCoveredLoc; + ParamWithMoreThanHalfNonEntryValCoveredLoc += + Stats.NumParamMoreThanHalfScopeNonEntryValCoveredLoc; + VarWithFullyCoveredLoc += Stats.NumVarFullyCoveredLoc; + VarWithFullyNonEntryValCoveredLoc += + Stats.NumVarFullyCoveredNonEntryValueLoc; + VarWithMoreThanHalfCoveredLoc += Stats.NumVarMoreThanHalfScopeCoveredLoc; + VarWithMoreThanHalfNonEntryValCoveredLoc += + Stats.NumVarMoreThanHalfScopeNonEntryValCoveredLoc; NumFuncsWithSrcLoc += Stats.HasSourceLocation; NumInlinedFunctions += Stats.IsFunction * Stats.NumFnInlined; NumAbstractOrigins += Stats.IsFunction * Stats.NumAbstractOrigins; @@ -395,23 +570,70 @@ printDatum(OS, "inlined funcs with abstract origins", NumAbstractOrigins); printDatum(OS, "unique source variables", VarParamUnique); printDatum(OS, "source variables", VarParamTotal); + printDatum(OS, "constant members", ConstMembers); printDatum(OS, "variables with location", VarParamWithLoc); + printDatum(OS, "variables with fully scope covered by debug locations", + VarParamWithFullyCoveredLoc); + printDatum( + OS, + "variables with fully scope covered by non entry value debug locations", + VarParamWithFullyNonEntryValCoveredLoc); + printDatum(OS, + "variables with more than half scope covered by debug locations", + VarParamWithMoreThanHalfCoveredLoc); + printDatum(OS, "variables with more than half scope covered by non entry " + "value debug locations", + VarParamWithMoreThanHalfNonEntryValCoveredLoc); printDatum(OS, "call site entries", GlobalStats.CallSiteEntries); printDatum(OS, "call site DIEs", GlobalStats.CallSiteDIEs); printDatum(OS, "call site parameter DIEs", GlobalStats.CallSiteParamDIEs); printDatum(OS, "scope bytes total", GlobalStats.ScopeBytesFromFirstDefinition); printDatum(OS, "scope bytes covered", GlobalStats.ScopeBytesCovered); + printDatum(OS, "entry value scope bytes covered", + GlobalStats.ScopeEntryValueBytesCovered); + printDatum(OS, "formal params scope bytes total", + GlobalStats.ParamScopeBytesFromFirstDefinition); + printDatum(OS, "formal params scope bytes covered", + GlobalStats.ParamScopeBytesCovered); + printDatum(OS, "formal params entry value scope bytes covered", + GlobalStats.ParamScopeEntryValueBytesCovered); + printDatum(OS, "vars scope bytes total", + GlobalStats.VarScopeBytesFromFirstDefinition); + printDatum(OS, "vars scope bytes covered", GlobalStats.VarScopeBytesCovered); + printDatum(OS, "vars entry value scope bytes covered", + GlobalStats.VarScopeEntryValueBytesCovered); printDatum(OS, "total function size", GlobalStats.FunctionSize); printDatum(OS, "total inlined function size", GlobalStats.InlineFunctionSize); printDatum(OS, "total formal params", ParamTotal); printDatum(OS, "formal params with source location", ParamWithSrcLoc); printDatum(OS, "formal params with type", ParamWithType); printDatum(OS, "formal params with binary location", ParamWithLoc); + printDatum(OS, "formal params with fully scope covered by debug locations", + ParamWithFullyCoveredLoc); + printDatum(OS, "formal params with fully scope covered by non entry value " + "debug locations", + ParamWithFullyNonEntryValCoveredLoc); + printDatum( + OS, "formal params with more than half scope covered by debug locations", + ParamWithMoreThanHalfCoveredLoc); + printDatum(OS, "formal params with more than half scope covered by non entry " + "value debug locations", + ParamWithMoreThanHalfNonEntryValCoveredLoc); printDatum(OS, "total vars", VarTotal); printDatum(OS, "vars with source location", VarWithSrcLoc); printDatum(OS, "vars with type", VarWithType); printDatum(OS, "vars with binary location", VarWithLoc); + printDatum(OS, "vars with fully scope covered by debug locations", + VarWithFullyCoveredLoc); + printDatum(OS, + "vars with fully scope covered by non entry value debug locations", + VarWithFullyNonEntryValCoveredLoc); + printDatum(OS, "vars with more than half scope covered by debug locations", + VarWithMoreThanHalfCoveredLoc); + printDatum(OS, "vars with more than half scope covered by non entry value " + "debug locations", + VarWithMoreThanHalfNonEntryValCoveredLoc); OS << "}\n"; LLVM_DEBUG( llvm::dbgs() << "Total Availability: "