LLVM: lib/Transforms/IPO/FunctionImport.cpp File Reference (original) (raw)

Go to the source code of this file.

Classes
class GlobalsImporter
Import globals referenced by a function or other globals that are being imported, if importing such global is possible. More...
class ModuleImportsManager
Determine the list of imports and exports for each module. More...
class WorkloadImportsManager
A ModuleImportsManager that operates based on a workload definition (see -thinlto-workload-def). More...
struct ImportStatistics
Namespaces
namespace llvm
This is an optimization pass for GlobalISel generic memory operations.
Functions
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")
static std::unique_ptr< Module > loadFile (const std::string &FileName, LLVMContext &Context)
static bool shouldSkipLocalInAnotherModule (const GlobalValueSummary *RefSummary, size_t NumDefs, StringRef ImporterModule)
static auto qualifyCalleeCandidates (const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, StringRef CallerModulePath)
Given a list of possible callee implementation for a call site, qualify the legality of importing each.
static const GlobalValueSummary * selectCallee (const ModuleSummaryIndex &Index, ArrayRef< std::unique_ptr< GlobalValueSummary > > CalleeSummaryList, unsigned Threshold, StringRef CallerModulePath, const GlobalValueSummary *&TooLargeOrNoInlineSummary, FunctionImporter::ImportFailureReason &Reason)
Given a list of possible callee implementation for a call site, select one that fits the Threshold for function definition import.
static const char * getFailureName (FunctionImporter::ImportFailureReason Reason)
static void computeImportForFunction (const FunctionSummary &Summary, const ModuleSummaryIndex &Index, const unsigned Threshold, const GVSummaryMapTy &DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, SmallVectorImpl< EdgeInfo > &Worklist, GlobalsImporter &GVImporter, FunctionImporter::ImportMapTy &ImportList, DenseMap< StringRef, FunctionImporter::ExportSetTy > *ExportLists, FunctionImporter::ImportThresholdsTy &ImportThresholds)
Compute the list of functions to import for a given caller.
static bool isGlobalVarSummary (const ModuleSummaryIndex &Index, ValueInfo VI)
static bool isGlobalVarSummary (const ModuleSummaryIndex &Index, GlobalValue::GUID G)
static unsigned numGlobalVarSummaries (const ModuleSummaryIndex &Index, FunctionImporter::ExportSetTy &ExportSet)
static DenseMap< StringRef, ImportStatistics > collectImportStatistics (const ModuleSummaryIndex &Index, const FunctionImporter::ImportMapTy &ImportList)
static bool checkVariableImport (const ModuleSummaryIndex &Index, FunctionImporter::ImportListsTy &ImportLists, DenseMap< StringRef, FunctionImporter::ExportSetTy > &ExportLists)
static void dumpImportListForModule (const ModuleSummaryIndex &Index, StringRef ModulePath, FunctionImporter::ImportMapTy &ImportList)
static void ComputeCrossModuleImportForModuleForTest (StringRef ModulePath, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Compute all the imports for the given module using the Index.
static void ComputeCrossModuleImportForModuleFromIndexForTest (StringRef ModulePath, const ModuleSummaryIndex &Index, FunctionImporter::ImportMapTy &ImportList)
Mark all external summaries in Index for import into the given module.
void updateValueInfoForIndirectCalls (ModuleSummaryIndex &Index, FunctionSummary *FS)
static Function * replaceAliasWithAliasee (Module *SrcModule, GlobalAlias *GA)
Make alias a clone of its aliasee.
static void internalizeGVsAfterImport (Module &M)
static bool doImportingForModuleForTest (Module &M, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Variables
static cl::opt< unsigned > ImportInstrLimit ("import-instr-limit", cl::init(100), cl::Hidden, cl::value_desc("N"), cl::desc("Only import functions with less than N instructions"))
Limit on instruction count of imported functions.
static cl::opt< int > ImportCutoff ("import-cutoff", cl::init(-1), cl::Hidden, cl::value_desc("N"), cl::desc("Only import first N functions if N>=0 (default -1)"))
static cl::opt< bool > ForceImportAll ("force-import-all", cl::init(false), cl::Hidden, cl::desc("Import functions with noinline attribute"))
static cl::opt< float > ImportInstrFactor ("import-instr-evolution-factor", cl::init(0.7), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
static cl::opt< float > ImportHotInstrFactor ("import-hot-evolution-factor", cl::init(1.0), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions called from hot callsite, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions"))
static cl::opt< float > ImportHotMultiplier ("import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for hot callsites"))
static cl::opt< float > ImportCriticalMultiplier ("import-critical-multiplier", cl::init(100.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for critical callsites"))
static cl::opt< float > ImportColdMultiplier ("import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"), cl::desc("Multiply the `import-instr-limit` threshold for cold callsites"))
static cl::opt< bool > PrintImports ("print-imports", cl::init(false), cl::Hidden, cl::desc("Print imported functions"))
static cl::opt< bool > PrintImportFailures ("print-import-failures", cl::init(false), cl::Hidden, cl::desc("Print information for functions rejected for importing"))
static cl::opt< bool > ComputeDead ("compute-dead", cl::init(true), cl::Hidden, cl::desc("Compute dead symbols"))
static cl::opt< bool > EnableImportMetadata ("enable-import-metadata", cl::init(false), cl::Hidden, cl::desc("Enable import metadata like 'thinlto_src_module' and " "'thinlto_src_file'"))
static cl::opt< std::string > SummaryFile ("summary-file", cl::desc("The summary file to use for function importing."))
Summary file to use for function importing when using -function-import from the command line.
static cl::opt< bool > ImportAllIndex ("import-all-index", cl::desc("Import all external functions in index."))
Used when testing importing from distributed indexes via opt.
static cl::opt< bool > ImportDeclaration ("import-declaration", cl::init(false), cl::Hidden, cl::desc("If true, import function declaration as fallback if the function " "definition is not imported."))
This is a test-only option.
static cl::opt< std::string > WorkloadDefinitions ("thinlto-workload-def", cl::desc("Pass a workload definition. This is a file containing a JSON " "dictionary. The keys are root functions, the values are lists of " "functions to import in the module defining the root. It is " "assumed -funique-internal-linkage-names was used, to ensure " "local linkage functions have unique names. For example: \n" "{\n" " \"rootFunction_1\": [\"function_to_import_1\", " "\"function_to_import_2\"], \n" " \"rootFunction_2\": [\"function_to_import_3\", " "\"function_to_import_4\"] \n" "}"), cl::Hidden)
Pass a workload description file - an example of workload would be the functions executed to satisfy a RPC request.
cl::opt< std::string > UseCtxProfile

DEBUG_TYPE

#define DEBUG_TYPE "function-import"

checkVariableImport()

collectImportStatistics()

ComputeCrossModuleImportForModuleForTest()

ComputeCrossModuleImportForModuleFromIndexForTest()

computeImportForFunction()

static void computeImportForFunction ( const FunctionSummary & Summary, const ModuleSummaryIndex & Index, const unsigned Threshold, const GVSummaryMapTy & DefinedGVSummaries, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing, SmallVectorImpl< EdgeInfo > & Worklist, GlobalsImporter & GVImporter, FunctionImporter::ImportMapTy & ImportList, DenseMap< StringRef, FunctionImporter::ExportSetTy > * ExportLists, FunctionImporter::ImportThresholdsTy & ImportThresholds ) static

Compute the list of functions to import for a given caller.

Mark these imported functions and the symbols they reference in their source module as exported from their source module.

Definition at line 833 of file FunctionImport.cpp.

References llvm::FunctionImporter::ImportMapTy::addDefinition(), llvm::FunctionSummary::FFlags::AlwaysInline, assert(), llvm::CalleeInfo::Cold, llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::count(), llvm::CalleeInfo::Critical, llvm::dbgs(), llvm::SmallVectorImpl< T >::emplace_back(), llvm::errs(), llvm::FunctionSummary::fflags(), ForceImportAll, getFailureName(), llvm::CalleeInfo::Hot, ImportColdMultiplier, ImportCriticalMultiplier, ImportCutoff, ImportDeclaration, ImportHotInstrFactor, ImportHotMultiplier, ImportInstrFactor, llvm::DenseMapBase< DerivedT, KeyT, ValueT, KeyInfoT, BucketT >::insert(), llvm::FunctionSummary::instCount(), IT, LLVM_DEBUG, llvm::logAllUnhandledErrors(), llvm::make_error_code(), llvm::FunctionImporter::ImportMapTy::maybeAddDeclaration(), llvm::GlobalValueSummary::modulePath(), llvm::FunctionImporter::ImportMapTy::NoChange, llvm::not_supported, GlobalsImporter::onImportingSummary(), PrintImportFailures, and selectCallee().

Referenced by ModuleImportsManager::computeImportForModule().

doImportingForModuleForTest()

Definition at line 1988 of file FunctionImport.cpp.

References ComputeCrossModuleImportForModuleForTest(), ComputeCrossModuleImportForModuleFromIndexForTest(), llvm::errs(), llvm::GlobalValue::ExternalLinkage, llvm::getModuleSummaryIndexForFile(), I, ImportAllIndex, llvm::FunctionImporter::importFunctions(), llvm::GlobalValue::isLocalLinkage(), loadFile(), llvm::logAllUnhandledErrors(), llvm::renameModuleForThinLTO(), llvm::report_fatal_error(), SummaryFile, and llvm::Expected< T >::takeError().

Referenced by llvm::FunctionImportPass::run().

dumpImportListForModule()

getFailureName()

internalizeGVsAfterImport()

static void internalizeGVsAfterImport ( Module & M) static

isGlobalVarSummary() [1/2]

isGlobalVarSummary() [2/2]

loadFile()

numGlobalVarSummaries()

qualifyCalleeCandidates()

replaceAliasWithAliasee()

selectCallee()

Given a list of possible callee implementation for a call site, select one that fits the Threshold for function definition import.

If none are found, the Reason will give the last reason for the failure (last, in the order of CalleeSummaryList entries). While looking for a callee definition, sets TooLargeOrNoInlineSummary to the last seen too-large or noinline candidate; other modules may want to know the function summary or declaration even if a definition is not needed.

FIXME: select "best" instead of first that fits. But what is "best"?

Definition at line 292 of file FunctionImport.cpp.

References ForceImportAll, and qualifyCalleeCandidates().

Referenced by computeImportForFunction().

shouldSkipLocalInAnotherModule()

STATISTIC() [1/9]

STATISTIC ( NumDeadSymbols ,
"Number of dead stripped symbols in index"
)

STATISTIC() [2/9]

STATISTIC ( NumImportedCriticalFunctionsThinLink ,
"Number of critical functions thin link decided to import"
)

STATISTIC() [3/9]

STATISTIC ( NumImportedFunctions ,
"Number of functions imported in backend"
)

STATISTIC() [4/9]

STATISTIC ( NumImportedFunctionsThinLink ,
"Number of functions thin link decided to import"
)

STATISTIC() [5/9]

STATISTIC ( NumImportedGlobalVars ,
"Number of global variables imported in backend"
)

STATISTIC() [6/9]

STATISTIC ( NumImportedGlobalVarsThinLink ,
"Number of global variables thin link decided to import"
)

STATISTIC() [7/9]

STATISTIC ( NumImportedHotFunctionsThinLink ,
"Number of hot functions thin link decided to import"
)

STATISTIC() [8/9]

STATISTIC ( NumImportedModules ,
"Number of modules imported from"
)

STATISTIC() [9/9]

STATISTIC ( NumLiveSymbols ,
"Number of live symbols in index"
)

updateValueInfoForIndirectCalls()

ComputeDead

cl::opt< bool > ComputeDead("compute-dead", cl::init(true), cl::Hidden, cl::desc("Compute dead symbols")) ( "compute-dead" , cl::init(true) , cl::Hidden , cl::desc("Compute dead symbols") ) static

EnableImportMetadata

cl::opt< bool > EnableImportMetadata("enable-import-metadata", cl::init(false), cl::Hidden, cl::desc("Enable import metadata like 'thinlto_src_module' and " "'thinlto_src_file'")) ( "enable-import-metadata" , cl::init(false) , cl::Hidden , cl::desc("Enable import metadata like 'thinlto_src_module' and " "'thinlto_src_file'") ) static

ForceImportAll

cl::opt< bool > ForceImportAll("force-import-all", cl::init(false), cl::Hidden, cl::desc("Import functions with noinline attribute")) ( "force-import-all" , cl::init(false) , cl::Hidden , cl::desc("Import functions with noinline attribute") ) static

ImportAllIndex

ImportColdMultiplier

cl::opt< float > ImportColdMultiplier("import-cold-multiplier", cl::init(0), cl::Hidden, cl::value_desc("N"), cl::desc("Multiply the `import-instr-limit` threshold for cold callsites")) ( "import-cold-multiplier" , cl::init(0) , cl::Hidden , cl::value_desc("N") , cl::desc("Multiply the `import-instr-limit` threshold for cold callsites") ) static

ImportCriticalMultiplier

cl::opt< float > ImportCriticalMultiplier("import-critical-multiplier", cl::init(100.0), cl::Hidden, cl::value_desc("x"), cl::desc( "Multiply the `import-instr-limit` threshold for critical callsites")) ( "import-critical-multiplier" , cl::init(100.0) , cl::Hidden , cl::value_desc("x") , cl::desc( "Multiply the `import-instr-limit` threshold for critical callsites") ) static

ImportCutoff

ImportDeclaration

cl::opt< bool > ImportDeclaration("import-declaration", cl::init(false), cl::Hidden, cl::desc("If true, import function declaration as fallback if the function " "definition is not imported.")) ( "import-declaration" , cl::init(false) , cl::Hidden , cl::desc("If true, import function declaration as fallback if the function " "definition is not imported.") ) static

This is a test-only option.

If this option is enabled, the ThinLTO indexing step will import each function declaration as a fallback. In a real build this may increase ram usage of the indexing step unnecessarily. TODO: Implement selective import (based on combined summary analysis) to ensure the imported function has a use case in the postlink pipeline.

Referenced by computeImportForFunction().

ImportHotInstrFactor

cl::opt< float > ImportHotInstrFactor("import-hot-evolution-factor", cl::init(1.0), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions called from hot callsite, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions")) ( "import-hot-evolution-factor" , cl::init(1.0) , cl::Hidden , cl::value_desc("x") , cl::desc("As we import functions called from hot callsite, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions") ) static

ImportHotMultiplier

cl::opt< float > ImportHotMultiplier("import-hot-multiplier", cl::init(10.0), cl::Hidden, cl::value_desc("x"), cl::desc("Multiply the `import-instr-limit` threshold for hot callsites")) ( "import-hot-multiplier" , cl::init(10.0) , cl::Hidden , cl::value_desc("x") , cl::desc("Multiply the `import-instr-limit` threshold for hot callsites") ) static

ImportInstrFactor

cl::opt< float > ImportInstrFactor("import-instr-evolution-factor", cl::init(0.7), cl::Hidden, cl::value_desc("x"), cl::desc("As we import functions, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions")) ( "import-instr-evolution-factor" , cl::init(0.7) , cl::Hidden , cl::value_desc("x") , cl::desc("As we import functions, multiply the " "`import-instr-limit` threshold by this factor " "before processing newly imported functions") ) static

ImportInstrLimit

PrintImportFailures

cl::opt< bool > PrintImportFailures("print-import-failures", cl::init(false), cl::Hidden, cl::desc("Print information for functions rejected for importing")) ( "print-import-failures" , cl::init(false) , cl::Hidden , cl::desc("Print information for functions rejected for importing") ) static

PrintImports

cl::opt< bool > PrintImports("print-imports", cl::init(false), cl::Hidden, cl::desc("Print imported functions")) ( "print-imports" , cl::init(false) , cl::Hidden , cl::desc("Print imported functions") ) static

SummaryFile

UseCtxProfile

WorkloadDefinitions

cl::opt< std::string > WorkloadDefinitions("thinlto-workload-def", cl::desc("Pass a workload definition. This is a file containing a JSON " "dictionary. The keys are root functions, the values are lists of " "functions to import in the module defining the root. It is " "assumed -funique-internal-linkage-names was used, to ensure " "local linkage functions have unique names. For example: \n" "{\n" " \"rootFunction_1\": [\"function_to_import_1\", " "\"function_to_import_2\"], \n" " \"rootFunction_2\": [\"function_to_import_3\", " "\"function_to_import_4\"] \n" "}"), cl::Hidden) ( "thinlto-workload-def" , cl::desc("Pass a workload definition. This is a file containing a JSON " "dictionary. The keys are root functions, the values are lists of " "functions to import in the module defining the root. It is " "assumed -funique-internal-linkage-names was used, to ensure " "local linkage functions have unique names. For example: \n" "{\n" " \"rootFunction_1\": [\"function_to_import_1\", " "\"function_to_import_2\"], \n" " \"rootFunction_2\": [\"function_to_import_3\", " "\"function_to_import_4\"] \n" "}") , cl::Hidden ) static

Pass a workload description file - an example of workload would be the functions executed to satisfy a RPC request.

A workload is defined by a root function and the list of functions that are (frequently) needed to satisfy it. The module that defines the root will have all those functions imported. The file contains a JSON dictionary. The keys are root functions, the values are lists of functions to import in the module defining the root. It is assumed -funique-internal-linkage-names was used, thus ensuring function names are unique even for local linkage ones.

Referenced by ModuleImportsManager::create(), and WorkloadImportsManager::WorkloadImportsManager().