ThinLTOCodeGenerator.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-ThinLTOCodeGenerator.h - LLVM Link Time Optimizer -------------------===//
  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. //
  14. // This file declares the ThinLTOCodeGenerator class, similar to the
  15. // LTOCodeGenerator but for the ThinLTO scheme. It provides an interface for
  16. // linker plugin.
  17. //
  18. //===----------------------------------------------------------------------===//
  19. #ifndef LLVM_LTO_LEGACY_THINLTOCODEGENERATOR_H
  20. #define LLVM_LTO_LEGACY_THINLTOCODEGENERATOR_H
  21. #include "llvm-c/lto.h"
  22. #include "llvm/ADT/StringSet.h"
  23. #include "llvm/ADT/Triple.h"
  24. #include "llvm/IR/ModuleSummaryIndex.h"
  25. #include "llvm/LTO/LTO.h"
  26. #include "llvm/Support/CachePruning.h"
  27. #include "llvm/Support/CodeGen.h"
  28. #include "llvm/Support/MemoryBuffer.h"
  29. #include "llvm/Target/TargetOptions.h"
  30. #include <string>
  31. namespace llvm {
  32. class StringRef;
  33. class TargetMachine;
  34. /// Helper to gather options relevant to the target machine creation
  35. struct TargetMachineBuilder {
  36. Triple TheTriple;
  37. std::string MCpu;
  38. std::string MAttr;
  39. TargetOptions Options;
  40. std::optional<Reloc::Model> RelocModel;
  41. CodeGenOpt::Level CGOptLevel = CodeGenOpt::Aggressive;
  42. std::unique_ptr<TargetMachine> create() const;
  43. };
  44. /// This class define an interface similar to the LTOCodeGenerator, but adapted
  45. /// for ThinLTO processing.
  46. /// The ThinLTOCodeGenerator is not intended to be reuse for multiple
  47. /// compilation: the model is that the client adds modules to the generator and
  48. /// ask to perform the ThinLTO optimizations / codegen, and finally destroys the
  49. /// codegenerator.
  50. class ThinLTOCodeGenerator {
  51. public:
  52. /// Add given module to the code generator.
  53. void addModule(StringRef Identifier, StringRef Data);
  54. /**
  55. * Adds to a list of all global symbols that must exist in the final generated
  56. * code. If a symbol is not listed there, it will be optimized away if it is
  57. * inlined into every usage.
  58. */
  59. void preserveSymbol(StringRef Name);
  60. /**
  61. * Adds to a list of all global symbols that are cross-referenced between
  62. * ThinLTO files. If the ThinLTO CodeGenerator can ensure that every
  63. * references from a ThinLTO module to this symbol is optimized away, then
  64. * the symbol can be discarded.
  65. */
  66. void crossReferenceSymbol(StringRef Name);
  67. /**
  68. * Process all the modules that were added to the code generator in parallel.
  69. *
  70. * Client can access the resulting object files using getProducedBinaries(),
  71. * unless setGeneratedObjectsDirectory() has been called, in which case
  72. * results are available through getProducedBinaryFiles().
  73. */
  74. void run();
  75. /**
  76. * Return the "in memory" binaries produced by the code generator. This is
  77. * filled after run() unless setGeneratedObjectsDirectory() has been
  78. * called, in which case results are available through
  79. * getProducedBinaryFiles().
  80. */
  81. std::vector<std::unique_ptr<MemoryBuffer>> &getProducedBinaries() {
  82. return ProducedBinaries;
  83. }
  84. /**
  85. * Return the "on-disk" binaries produced by the code generator. This is
  86. * filled after run() when setGeneratedObjectsDirectory() has been
  87. * called, in which case results are available through getProducedBinaries().
  88. */
  89. std::vector<std::string> &getProducedBinaryFiles() {
  90. return ProducedBinaryFiles;
  91. }
  92. /**
  93. * \defgroup Options setters
  94. * @{
  95. */
  96. /**
  97. * \defgroup Cache controlling options
  98. *
  99. * These entry points control the ThinLTO cache. The cache is intended to
  100. * support incremental build, and thus needs to be persistent accross build.
  101. * The client enabled the cache by supplying a path to an existing directory.
  102. * The code generator will use this to store objects files that may be reused
  103. * during a subsequent build.
  104. * To avoid filling the disk space, a few knobs are provided:
  105. * - The pruning interval limit the frequency at which the garbage collector
  106. * will try to scan the cache directory to prune it from expired entries.
  107. * Setting to -1 disable the pruning (default). Setting to 0 will force
  108. * pruning to occur.
  109. * - The pruning expiration time indicates to the garbage collector how old
  110. * an entry needs to be to be removed.
  111. * - Finally, the garbage collector can be instructed to prune the cache till
  112. * the occupied space goes below a threshold.
  113. * @{
  114. */
  115. struct CachingOptions {
  116. std::string Path; // Path to the cache, empty to disable.
  117. CachePruningPolicy Policy;
  118. };
  119. /// Provide a path to a directory where to store the cached files for
  120. /// incremental build.
  121. void setCacheDir(std::string Path) { CacheOptions.Path = std::move(Path); }
  122. /// Cache policy: interval (seconds) between two prunes of the cache. Set to a
  123. /// negative value to disable pruning. A value of 0 will force pruning to
  124. /// occur.
  125. void setCachePruningInterval(int Interval) {
  126. if(Interval < 0)
  127. CacheOptions.Policy.Interval.reset();
  128. else
  129. CacheOptions.Policy.Interval = std::chrono::seconds(Interval);
  130. }
  131. /// Cache policy: expiration (in seconds) for an entry.
  132. /// A value of 0 will be ignored.
  133. void setCacheEntryExpiration(unsigned Expiration) {
  134. if (Expiration)
  135. CacheOptions.Policy.Expiration = std::chrono::seconds(Expiration);
  136. }
  137. /**
  138. * Sets the maximum cache size that can be persistent across build, in terms
  139. * of percentage of the available space on the disk. Set to 100 to indicate
  140. * no limit, 50 to indicate that the cache size will not be left over
  141. * half the available space. A value over 100 will be reduced to 100, and a
  142. * value of 0 will be ignored.
  143. *
  144. *
  145. * The formula looks like:
  146. * AvailableSpace = FreeSpace + ExistingCacheSize
  147. * NewCacheSize = AvailableSpace * P/100
  148. *
  149. */
  150. void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) {
  151. if (Percentage)
  152. CacheOptions.Policy.MaxSizePercentageOfAvailableSpace = Percentage;
  153. }
  154. /// Cache policy: the maximum size for the cache directory in bytes. A value
  155. /// over the amount of available space on the disk will be reduced to the
  156. /// amount of available space. A value of 0 will be ignored.
  157. void setCacheMaxSizeBytes(uint64_t MaxSizeBytes) {
  158. if (MaxSizeBytes)
  159. CacheOptions.Policy.MaxSizeBytes = MaxSizeBytes;
  160. }
  161. /// Cache policy: the maximum number of files in the cache directory. A value
  162. /// of 0 will be ignored.
  163. void setCacheMaxSizeFiles(unsigned MaxSizeFiles) {
  164. if (MaxSizeFiles)
  165. CacheOptions.Policy.MaxSizeFiles = MaxSizeFiles;
  166. }
  167. /**@}*/
  168. /// Set the path to a directory where to save temporaries at various stages of
  169. /// the processing.
  170. void setSaveTempsDir(std::string Path) { SaveTempsDir = std::move(Path); }
  171. /// Set the path to a directory where to save generated object files. This
  172. /// path can be used by a linker to request on-disk files instead of in-memory
  173. /// buffers. When set, results are available through getProducedBinaryFiles()
  174. /// instead of getProducedBinaries().
  175. void setGeneratedObjectsDirectory(std::string Path) {
  176. SavedObjectsDirectoryPath = std::move(Path);
  177. }
  178. /// CPU to use to initialize the TargetMachine
  179. void setCpu(std::string Cpu) { TMBuilder.MCpu = std::move(Cpu); }
  180. /// Subtarget attributes
  181. void setAttr(std::string MAttr) { TMBuilder.MAttr = std::move(MAttr); }
  182. /// TargetMachine options
  183. void setTargetOptions(TargetOptions Options) {
  184. TMBuilder.Options = std::move(Options);
  185. }
  186. /// Enable the Freestanding mode: indicate that the optimizer should not
  187. /// assume builtins are present on the target.
  188. void setFreestanding(bool Enabled) { Freestanding = Enabled; }
  189. /// CodeModel
  190. void setCodePICModel(std::optional<Reloc::Model> Model) {
  191. TMBuilder.RelocModel = Model;
  192. }
  193. /// CodeGen optimization level
  194. void setCodeGenOptLevel(CodeGenOpt::Level CGOptLevel) {
  195. TMBuilder.CGOptLevel = CGOptLevel;
  196. }
  197. /// IR optimization level: from 0 to 3.
  198. void setOptLevel(unsigned NewOptLevel) {
  199. OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel;
  200. }
  201. /// Enable or disable debug output for the new pass manager.
  202. void setDebugPassManager(unsigned Enabled) { DebugPassManager = Enabled; }
  203. /// Disable CodeGen, only run the stages till codegen and stop. The output
  204. /// will be bitcode.
  205. void disableCodeGen(bool Disable) { DisableCodeGen = Disable; }
  206. /// Perform CodeGen only: disable all other stages.
  207. void setCodeGenOnly(bool CGOnly) { CodeGenOnly = CGOnly; }
  208. /**@}*/
  209. /**
  210. * \defgroup Set of APIs to run individual stages in isolation.
  211. * @{
  212. */
  213. /**
  214. * Produce the combined summary index from all the bitcode files:
  215. * "thin-link".
  216. */
  217. std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex();
  218. /**
  219. * Perform promotion and renaming of exported internal functions,
  220. * and additionally resolve weak and linkonce symbols.
  221. * Index is updated to reflect linkage changes from weak resolution.
  222. */
  223. void promote(Module &Module, ModuleSummaryIndex &Index,
  224. const lto::InputFile &File);
  225. /**
  226. * Compute and emit the imported files for module at \p ModulePath.
  227. */
  228. void emitImports(Module &Module, StringRef OutputName,
  229. ModuleSummaryIndex &Index,
  230. const lto::InputFile &File);
  231. /**
  232. * Perform cross-module importing for the module identified by
  233. * ModuleIdentifier.
  234. */
  235. void crossModuleImport(Module &Module, ModuleSummaryIndex &Index,
  236. const lto::InputFile &File);
  237. /**
  238. * Compute the list of summaries needed for importing into module.
  239. */
  240. void gatherImportedSummariesForModule(
  241. Module &Module, ModuleSummaryIndex &Index,
  242. std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex,
  243. const lto::InputFile &File);
  244. /**
  245. * Perform internalization. Index is updated to reflect linkage changes.
  246. */
  247. void internalize(Module &Module, ModuleSummaryIndex &Index,
  248. const lto::InputFile &File);
  249. /**
  250. * Perform post-importing ThinLTO optimizations.
  251. */
  252. void optimize(Module &Module);
  253. /**
  254. * Write temporary object file to SavedObjectDirectoryPath, write symlink
  255. * to Cache directory if needed. Returns the path to the generated file in
  256. * SavedObjectsDirectoryPath.
  257. */
  258. std::string writeGeneratedObject(int count, StringRef CacheEntryPath,
  259. const MemoryBuffer &OutputBuffer);
  260. /**@}*/
  261. private:
  262. /// Helper factory to build a TargetMachine
  263. TargetMachineBuilder TMBuilder;
  264. /// Vector holding the in-memory buffer containing the produced binaries, when
  265. /// SavedObjectsDirectoryPath isn't set.
  266. std::vector<std::unique_ptr<MemoryBuffer>> ProducedBinaries;
  267. /// Path to generated files in the supplied SavedObjectsDirectoryPath if any.
  268. std::vector<std::string> ProducedBinaryFiles;
  269. /// Vector holding the input buffers containing the bitcode modules to
  270. /// process.
  271. std::vector<std::unique_ptr<lto::InputFile>> Modules;
  272. /// Set of symbols that need to be preserved outside of the set of bitcode
  273. /// files.
  274. StringSet<> PreservedSymbols;
  275. /// Set of symbols that are cross-referenced between bitcode files.
  276. StringSet<> CrossReferencedSymbols;
  277. /// Control the caching behavior.
  278. CachingOptions CacheOptions;
  279. /// Path to a directory to save the temporary bitcode files.
  280. std::string SaveTempsDir;
  281. /// Path to a directory to save the generated object files.
  282. std::string SavedObjectsDirectoryPath;
  283. /// Flag to enable/disable CodeGen. When set to true, the process stops after
  284. /// optimizations and a bitcode is produced.
  285. bool DisableCodeGen = false;
  286. /// Flag to indicate that only the CodeGen will be performed, no cross-module
  287. /// importing or optimization.
  288. bool CodeGenOnly = false;
  289. /// Flag to indicate that the optimizer should not assume builtins are present
  290. /// on the target.
  291. bool Freestanding = false;
  292. /// IR Optimization Level [0-3].
  293. unsigned OptLevel = 3;
  294. /// Flag to indicate whether debug output should be enabled for the new pass
  295. /// manager.
  296. bool DebugPassManager = false;
  297. };
  298. }
  299. #endif
  300. #ifdef __GNUC__
  301. #pragma GCC diagnostic pop
  302. #endif