Index: llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp +++ llvm/trunk/lib/Transforms/IPO/FunctionImport.cpp @@ -60,8 +60,17 @@ #define DEBUG_TYPE "function-import" -STATISTIC(NumImportedFunctions, "Number of functions imported"); -STATISTIC(NumImportedGlobalVars, "Number of global variables imported"); +STATISTIC(NumImportedFunctionsThinLink, + "Number of functions thin link decided to import"); +STATISTIC(NumImportedHotFunctionsThinLink, + "Number of hot functions thin link decided to import"); +STATISTIC(NumImportedCriticalFunctionsThinLink, + "Number of critical functions thin link decided to import"); +STATISTIC(NumImportedGlobalVarsThinLink, + "Number of global variables thin link decided to import"); +STATISTIC(NumImportedFunctions, "Number of functions imported in backend"); +STATISTIC(NumImportedGlobalVars, + "Number of global variables imported in backend"); STATISTIC(NumImportedModules, "Number of modules imported from"); STATISTIC(NumDeadSymbols, "Number of dead stripped symbols in index"); STATISTIC(NumLiveSymbols, "Number of live symbols in index"); @@ -281,7 +290,10 @@ !RefSummary->notEligibleToImport() && !GlobalValue::isInterposableLinkage(RefSummary->linkage()) && RefSummary->refs().empty()) { - ImportList[RefSummary->modulePath()].insert(VI.getGUID()); + auto ILI = ImportList[RefSummary->modulePath()].insert(VI.getGUID()); + // Only update stat if we haven't already imported this variable. + if (ILI.second) + NumImportedGlobalVarsThinLink++; if (ExportLists) (*ExportLists)[RefSummary->modulePath()].insert(VI.getGUID()); break; @@ -363,6 +375,11 @@ auto &CalleeSummary = std::get<1>(IT.first->second); auto &FailureInfo = std::get<2>(IT.first->second); + bool IsHotCallsite = + Edge.second.getHotness() == CalleeInfo::HotnessType::Hot; + bool IsCriticalCallsite = + Edge.second.getHotness() == CalleeInfo::HotnessType::Critical; + const FunctionSummary *ResolvedCalleeSummary = nullptr; if (CalleeSummary) { assert(PreviouslyVisited); @@ -434,6 +451,13 @@ // We previously decided to import this GUID definition if it was already // inserted in the set of imports from the exporting module. bool PreviouslyImported = !ILI.second; + if (!PreviouslyImported) { + NumImportedFunctionsThinLink++; + if (IsHotCallsite) + NumImportedHotFunctionsThinLink++; + if (IsCriticalCallsite) + NumImportedCriticalFunctionsThinLink++; + } // Make exports in the source module. if (ExportLists) { @@ -467,8 +491,6 @@ return Threshold * ImportInstrFactor; }; - bool IsHotCallsite = - Edge.second.getHotness() == CalleeInfo::HotnessType::Hot; const auto AdjThreshold = GetAdjustedThreshold(Threshold, IsHotCallsite); ImportCount++; Index: llvm/trunk/test/Transforms/FunctionImport/Inputs/import_stats.ll =================================================================== --- llvm/trunk/test/Transforms/FunctionImport/Inputs/import_stats.ll +++ llvm/trunk/test/Transforms/FunctionImport/Inputs/import_stats.ll @@ -0,0 +1,13 @@ +; ModuleID = 'import_stats2.ll' +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @hot() { + ret void +} +define void @critical() { + ret void +} +define void @none() { + ret void +} Index: llvm/trunk/test/Transforms/FunctionImport/import_stats.ll =================================================================== --- llvm/trunk/test/Transforms/FunctionImport/import_stats.ll +++ llvm/trunk/test/Transforms/FunctionImport/import_stats.ll @@ -0,0 +1,64 @@ +; Test to check thin link importing stats + +; RUN: opt -module-summary %s -o %t.bc +; RUN: opt -module-summary %p/Inputs/import_stats.ll -o %t2.bc + +; Test thin link stats with both new and old LTO +; RUN: llvm-lto -thinlto-action=run -stats %t.bc %t2.bc \ +; RUN: 2>&1 | FileCheck %s --check-prefix=THINLINKSTATS +; RUN: llvm-lto2 run -stats -o %t3 %t.bc %t2.bc \ +; RUN: -r %t.bc,hot_function,plx \ +; RUN: -r %t.bc,hot, \ +; RUN: -r %t.bc,critical, \ +; RUN: -r %t.bc,none, \ +; RUN: -r %t2.bc,hot,plx \ +; RUN: -r %t2.bc,critical,plx \ +; RUN: -r %t2.bc,none,plx \ +; RUN: 2>&1 | FileCheck %s --check-prefix=THINLINKSTATS + +; THINLINKSTATS-DAG: 1 function-import - Number of critical functions thin link decided to import +; THINLINKSTATS-DAG: 3 function-import - Number of functions thin link decided to import +; THINLINKSTATS-DAG: 1 function-import - Number of hot functions thin link decided to import + +; ModuleID = 'import_stats.ll' +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +; This function has a high profile count, so entry block is hot. +define void @hot_function(i1 %a) !prof !20 { +entry: + call void @hot() + call void @critical() + br i1 %a, label %None1, label %None2, !prof !42 +None1: ; half goes here + call void @none() + br label %exit +None2: ; half goes here + br label %exit +exit: + ret void +} + +declare void @hot() +declare void @none() +declare void @critical() + +!42 = !{!"branch_weights", i32 1, i32 1} + +!llvm.module.flags = !{!1} +!20 = !{!"function_entry_count", i64 100, i64 696010031887058302} + +!1 = !{i32 1, !"ProfileSummary", !2} +!2 = !{!3, !4, !5, !6, !7, !8, !9, !10} +!3 = !{!"ProfileFormat", !"InstrProf"} +!4 = !{!"TotalCount", i64 300} +!5 = !{!"MaxCount", i64 100} +!6 = !{!"MaxInternalCount", i64 100} +!7 = !{!"MaxFunctionCount", i64 100} +!8 = !{!"NumCounts", i64 4} +!9 = !{!"NumFunctions", i64 1} +!10 = !{!"DetailedSummary", !11} +!11 = !{!12, !13, !14} +!12 = !{i32 10000, i64 100, i32 1} +!13 = !{i32 999000, i64 100, i32 1} +!14 = !{i32 999999, i64 1, i32 4}