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