Index: lib/Analysis/ModuleSummaryAnalysis.cpp =================================================================== --- lib/Analysis/ModuleSummaryAnalysis.cpp +++ lib/Analysis/ModuleSummaryAnalysis.cpp @@ -49,6 +49,7 @@ #include "llvm/Object/SymbolicFile.h" #include "llvm/Pass.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" #include #include #include @@ -58,6 +59,13 @@ #define DEBUG_TYPE "module-summary-analysis" +// Option to force edges cold which will block importing when the +// -import-cold-multiplier is set to 0. Useful for debugging. +bool ForceSummaryEdgesCold = false; +cl::opt FSEC( + "force-summary-edges-cold", cl::Hidden, cl::location(ForceSummaryEdgesCold), + cl::desc("Force all edges in the function summary to cold")); + // Walk through the operands of a given User via worklist iteration and populate // the set of GlobalValue references encountered. Invoked either on an // Instruction or a GlobalVariable (which walks its initializer). @@ -268,6 +276,8 @@ auto ScaledCount = PSI->getProfileCount(&I, BFI); auto Hotness = ScaledCount ? getHotness(ScaledCount.getValue(), PSI) : CalleeInfo::HotnessType::Unknown; + if (ForceSummaryEdgesCold) + Hotness = CalleeInfo::HotnessType::Cold; // Use the original CalledValue, in case it was an alias. We want // to record the call edge to the alias in that case. Eventually @@ -318,7 +328,8 @@ // sample PGO, to enable the same inlines as the profiled optimized binary. for (auto &I : F.getImportGUIDs()) CallGraphEdges[Index.getOrInsertValueInfo(I)].updateHotness( - CalleeInfo::HotnessType::Critical); + ForceSummaryEdgesCold ? CalleeInfo::HotnessType::Cold + : CalleeInfo::HotnessType::Critical); bool NonRenamableLocal = isNonRenamableLocal(F); bool NotEligibleForImport = Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -89,6 +89,9 @@ cl::opt WriteRelBFToSummary( "write-relbf-to-summary", cl::Hidden, cl::init(false), cl::desc("Write relative block frequency to function summary ")); + +extern bool ForceSummaryEdgesCold; + namespace { /// These are manifest constants used by the bitcode writer. They do not need to @@ -3436,7 +3439,7 @@ for (auto &RI : FS->refs()) NameVals.push_back(VE.getValueID(RI.getValue())); - bool HasProfileData = F.hasProfileData(); + bool HasProfileData = F.hasProfileData() || ForceSummaryEdgesCold; for (auto &ECI : FS->calls()) { NameVals.push_back(getValueId(ECI.first)); if (HasProfileData) Index: lib/Transforms/IPO/FunctionImport.cpp =================================================================== --- lib/Transforms/IPO/FunctionImport.cpp +++ lib/Transforms/IPO/FunctionImport.cpp @@ -303,6 +303,8 @@ const auto NewThreshold = Threshold * GetBonusMultiplier(Edge.second.getHotness()); + DEBUG(dbgs() << " edge -> " << VI.getGUID() << " NewThreshold:" << NewThreshold + << " Hotness: " << (int)Edge.second.getHotness() << "\n"); auto *CalleeSummary = selectCallee(Index, VI.getSummaryList(), NewThreshold, Summary.modulePath()); if (!CalleeSummary) { Index: test/Transforms/FunctionImport/Inputs/funcimport_forcecold.ll =================================================================== --- /dev/null +++ test/Transforms/FunctionImport/Inputs/funcimport_forcecold.ll @@ -0,0 +1,4 @@ +define void @foo() { +entry: + ret void +} Index: test/Transforms/FunctionImport/funcimport_forcecold.ll =================================================================== --- /dev/null +++ test/Transforms/FunctionImport/funcimport_forcecold.ll @@ -0,0 +1,29 @@ +; Test to ensure that building summary with -force-summary-edges-cold=true +; blocks importing as expected. + +; "-stats" and "-debug-only" require +Asserts. +; REQUIRES: asserts + +; First do with default options, which should import +; RUN: opt -module-summary %s -o %t.bc +; RUN: opt -module-summary %p/Inputs/funcimport_forcecold.ll -o %t2.bc +; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc +; RUN: opt -function-import -stats -print-imports -summary-file %t3.thinlto.bc %t.bc -S 2>&1 | FileCheck %s --check-prefix=IMPORT + +; Next rebuild caller module summary with edges forced cold. +; Make sure we don't import. +; RUN: opt -force-summary-edges-cold=true -module-summary %s -o %t.bc +; RUN: llvm-lto -thinlto -o %t3 %t.bc %t2.bc +; RUN: opt -function-import -stats -print-imports -summary-file %t3.thinlto.bc %t.bc -S 2>&1 | FileCheck %s --check-prefix=NOIMPORT + +define i32 @main() #0 { +entry: + call void @foo() + ret i32 0 +} + +; IMPORT: Import foo +; NOIMPORT-NOT: Import foo +; IMPORT: define available_externally void @foo() +; NOIMPORT: declare void @foo() +declare void @foo()