FunctionImport.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/Transforms/IPO/FunctionImport.h - ThinLTO importing -*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
  14. #define LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
  15. #include "llvm/ADT/DenseSet.h"
  16. #include "llvm/ADT/StringMap.h"
  17. #include "llvm/ADT/StringRef.h"
  18. #include "llvm/IR/GlobalValue.h"
  19. #include "llvm/IR/ModuleSummaryIndex.h"
  20. #include "llvm/IR/PassManager.h"
  21. #include "llvm/Support/Error.h"
  22. #include <functional>
  23. #include <map>
  24. #include <memory>
  25. #include <string>
  26. #include <system_error>
  27. #include <unordered_set>
  28. #include <utility>
  29. namespace llvm {
  30. class Module;
  31. /// The function importer is automatically importing function from other modules
  32. /// based on the provided summary informations.
  33. class FunctionImporter {
  34. public:
  35. /// Set of functions to import from a source module. Each entry is a set
  36. /// containing all the GUIDs of all functions to import for a source module.
  37. using FunctionsToImportTy = std::unordered_set<GlobalValue::GUID>;
  38. /// The different reasons selectCallee will chose not to import a
  39. /// candidate.
  40. enum ImportFailureReason {
  41. None,
  42. // We can encounter a global variable instead of a function in rare
  43. // situations with SamplePGO. See comments where this failure type is
  44. // set for more details.
  45. GlobalVar,
  46. // Found to be globally dead, so we don't bother importing.
  47. NotLive,
  48. // Instruction count over the current threshold.
  49. TooLarge,
  50. // Don't import something with interposable linkage as we can't inline it
  51. // anyway.
  52. InterposableLinkage,
  53. // Generally we won't end up failing due to this reason, as we expect
  54. // to find at least one summary for the GUID that is global or a local
  55. // in the referenced module for direct calls.
  56. LocalLinkageNotInModule,
  57. // This corresponds to the NotEligibleToImport being set on the summary,
  58. // which can happen in a few different cases (e.g. local that can't be
  59. // renamed or promoted because it is referenced on a llvm*.used variable).
  60. NotEligible,
  61. // This corresponds to NoInline being set on the function summary,
  62. // which will happen if it is known that the inliner will not be able
  63. // to inline the function (e.g. it is marked with a NoInline attribute).
  64. NoInline
  65. };
  66. /// Information optionally tracked for candidates the importer decided
  67. /// not to import. Used for optional stat printing.
  68. struct ImportFailureInfo {
  69. // The ValueInfo corresponding to the candidate. We save an index hash
  70. // table lookup for each GUID by stashing this here.
  71. ValueInfo VI;
  72. // The maximum call edge hotness for all failed imports of this candidate.
  73. CalleeInfo::HotnessType MaxHotness;
  74. // most recent reason for failing to import (doesn't necessarily correspond
  75. // to the attempt with the maximum hotness).
  76. ImportFailureReason Reason;
  77. // The number of times we tried to import candidate but failed.
  78. unsigned Attempts;
  79. ImportFailureInfo(ValueInfo VI, CalleeInfo::HotnessType MaxHotness,
  80. ImportFailureReason Reason, unsigned Attempts)
  81. : VI(VI), MaxHotness(MaxHotness), Reason(Reason), Attempts(Attempts) {}
  82. };
  83. /// Map of callee GUID considered for import into a given module to a pair
  84. /// consisting of the largest threshold applied when deciding whether to
  85. /// import it and, if we decided to import, a pointer to the summary instance
  86. /// imported. If we decided not to import, the summary will be nullptr.
  87. using ImportThresholdsTy =
  88. DenseMap<GlobalValue::GUID,
  89. std::tuple<unsigned, const GlobalValueSummary *,
  90. std::unique_ptr<ImportFailureInfo>>>;
  91. /// The map contains an entry for every module to import from, the key being
  92. /// the module identifier to pass to the ModuleLoader. The value is the set of
  93. /// functions to import.
  94. using ImportMapTy = StringMap<FunctionsToImportTy>;
  95. /// The set contains an entry for every global value the module exports.
  96. using ExportSetTy = DenseSet<ValueInfo>;
  97. /// A function of this type is used to load modules referenced by the index.
  98. using ModuleLoaderTy =
  99. std::function<Expected<std::unique_ptr<Module>>(StringRef Identifier)>;
  100. /// Create a Function Importer.
  101. FunctionImporter(const ModuleSummaryIndex &Index, ModuleLoaderTy ModuleLoader,
  102. bool ClearDSOLocalOnDeclarations)
  103. : Index(Index), ModuleLoader(std::move(ModuleLoader)),
  104. ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) {}
  105. /// Import functions in Module \p M based on the supplied import list.
  106. Expected<bool> importFunctions(Module &M, const ImportMapTy &ImportList);
  107. private:
  108. /// The summaries index used to trigger importing.
  109. const ModuleSummaryIndex &Index;
  110. /// Factory function to load a Module for a given identifier
  111. ModuleLoaderTy ModuleLoader;
  112. /// See the comment of ClearDSOLocalOnDeclarations in
  113. /// Utils/FunctionImportUtils.h.
  114. bool ClearDSOLocalOnDeclarations;
  115. };
  116. /// The function importing pass
  117. class FunctionImportPass : public PassInfoMixin<FunctionImportPass> {
  118. public:
  119. PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
  120. };
  121. /// Compute all the imports and exports for every module in the Index.
  122. ///
  123. /// \p ModuleToDefinedGVSummaries contains for each Module a map
  124. /// (GUID -> Summary) for every global defined in the module.
  125. ///
  126. /// \p ImportLists will be populated with an entry for every Module we are
  127. /// importing into. This entry is itself a map that can be passed to
  128. /// FunctionImporter::importFunctions() above (see description there).
  129. ///
  130. /// \p ExportLists contains for each Module the set of globals (GUID) that will
  131. /// be imported by another module, or referenced by such a function. I.e. this
  132. /// is the set of globals that need to be promoted/renamed appropriately.
  133. void ComputeCrossModuleImport(
  134. const ModuleSummaryIndex &Index,
  135. const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
  136. StringMap<FunctionImporter::ImportMapTy> &ImportLists,
  137. StringMap<FunctionImporter::ExportSetTy> &ExportLists);
  138. /// Compute all the imports for the given module using the Index.
  139. ///
  140. /// \p ImportList will be populated with a map that can be passed to
  141. /// FunctionImporter::importFunctions() above (see description there).
  142. void ComputeCrossModuleImportForModule(
  143. StringRef ModulePath, const ModuleSummaryIndex &Index,
  144. FunctionImporter::ImportMapTy &ImportList);
  145. /// Mark all external summaries in \p Index for import into the given module.
  146. /// Used for distributed builds using a distributed index.
  147. ///
  148. /// \p ImportList will be populated with a map that can be passed to
  149. /// FunctionImporter::importFunctions() above (see description there).
  150. void ComputeCrossModuleImportForModuleFromIndex(
  151. StringRef ModulePath, const ModuleSummaryIndex &Index,
  152. FunctionImporter::ImportMapTy &ImportList);
  153. /// PrevailingType enum used as a return type of callback passed
  154. /// to computeDeadSymbolsAndUpdateIndirectCalls. Yes and No values used when
  155. /// status explicitly set by symbols resolution, otherwise status is Unknown.
  156. enum class PrevailingType { Yes, No, Unknown };
  157. /// Update call edges for indirect calls to local functions added from
  158. /// SamplePGO when needed. Normally this is done during
  159. /// computeDeadSymbolsAndUpdateIndirectCalls, but can be called standalone
  160. /// when that is not called (e.g. during testing).
  161. void updateIndirectCalls(ModuleSummaryIndex &Index);
  162. /// Compute all the symbols that are "dead": i.e these that can't be reached
  163. /// in the graph from any of the given symbols listed in
  164. /// \p GUIDPreservedSymbols. Non-prevailing symbols are symbols without a
  165. /// prevailing copy anywhere in IR and are normally dead, \p isPrevailing
  166. /// predicate returns status of symbol.
  167. /// Also update call edges for indirect calls to local functions added from
  168. /// SamplePGO when needed.
  169. void computeDeadSymbolsAndUpdateIndirectCalls(
  170. ModuleSummaryIndex &Index,
  171. const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
  172. function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing);
  173. /// Compute dead symbols and run constant propagation in combined index
  174. /// after that.
  175. void computeDeadSymbolsWithConstProp(
  176. ModuleSummaryIndex &Index,
  177. const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols,
  178. function_ref<PrevailingType(GlobalValue::GUID)> isPrevailing,
  179. bool ImportEnabled);
  180. /// Converts value \p GV to declaration, or replaces with a declaration if
  181. /// it is an alias. Returns true if converted, false if replaced.
  182. bool convertToDeclaration(GlobalValue &GV);
  183. /// Compute the set of summaries needed for a ThinLTO backend compilation of
  184. /// \p ModulePath.
  185. //
  186. /// This includes summaries from that module (in case any global summary based
  187. /// optimizations were recorded) and from any definitions in other modules that
  188. /// should be imported.
  189. //
  190. /// \p ModuleToSummariesForIndex will be populated with the needed summaries
  191. /// from each required module path. Use a std::map instead of StringMap to get
  192. /// stable order for bitcode emission.
  193. void gatherImportedSummariesForModule(
  194. StringRef ModulePath,
  195. const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries,
  196. const FunctionImporter::ImportMapTy &ImportList,
  197. std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
  198. /// Emit into \p OutputFilename the files module \p ModulePath will import from.
  199. std::error_code EmitImportsFiles(
  200. StringRef ModulePath, StringRef OutputFilename,
  201. const std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
  202. /// Based on the information recorded in the summaries during global
  203. /// summary-based analysis:
  204. /// 1. Resolve prevailing symbol linkages and constrain visibility (CanAutoHide
  205. /// and consider visibility from other definitions for ELF) in \p TheModule
  206. /// 2. (optional) Apply propagated function attributes to \p TheModule if
  207. /// PropagateAttrs is true
  208. void thinLTOFinalizeInModule(Module &TheModule,
  209. const GVSummaryMapTy &DefinedGlobals,
  210. bool PropagateAttrs);
  211. /// Internalize \p TheModule based on the information recorded in the summaries
  212. /// during global summary-based analysis.
  213. void thinLTOInternalizeModule(Module &TheModule,
  214. const GVSummaryMapTy &DefinedGlobals);
  215. } // end namespace llvm
  216. #endif // LLVM_TRANSFORMS_IPO_FUNCTIONIMPORT_H
  217. #ifdef __GNUC__
  218. #pragma GCC diagnostic pop
  219. #endif