]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/llvm/LTO/legacy/ThinLTOCodeGenerator.h
Vendor import of llvm trunk r290819:
[FreeBSD/FreeBSD.git] / include / llvm / LTO / legacy / ThinLTOCodeGenerator.h
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
29 namespace llvm {
30 class StringRef;
31 class LLVMContext;
32 class TargetMachine;
33
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   Optional<Reloc::Model> RelocModel;
41   CodeGenOpt::Level CGOptLevel = CodeGenOpt::Aggressive;
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.
52 class ThinLTOCodeGenerator {
53 public:
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    * unless setGeneratedObjectsDirectory() has been called, in which case
77    * results are available through getProducedBinaryFiles().
78    */
79   void run();
80
81   /**
82    * Return the "in memory" binaries produced by the code generator. This is
83    * filled after run() unless setGeneratedObjectsDirectory() has been
84    * called, in which case results are available through
85    * getProducedBinaryFiles().
86    */
87   std::vector<std::unique_ptr<MemoryBuffer>> &getProducedBinaries() {
88     return ProducedBinaries;
89   }
90
91   /**
92    * Return the "on-disk" binaries produced by the code generator. This is
93    * filled after run() when setGeneratedObjectsDirectory() has been
94    * called, in which case results are available through getProducedBinaries().
95    */
96   std::vector<std::string> &getProducedBinaryFiles() {
97     return ProducedBinaryFiles;
98   }
99
100   /**
101    * \defgroup Options setters
102    * @{
103    */
104
105   /**
106    * \defgroup Cache controlling options
107    *
108    * These entry points control the ThinLTO cache. The cache is intended to
109    * support incremental build, and thus needs to be persistent accross build.
110    * The client enabled the cache by supplying a path to an existing directory.
111    * The code generator will use this to store objects files that may be reused
112    * during a subsequent build.
113    * To avoid filling the disk space, a few knobs are provided:
114    *  - The pruning interval limit the frequency at which the garbage collector
115    *    will try to scan the cache directory to prune it from expired entries.
116    *    Setting to -1 disable the pruning (default).
117    *  - The pruning expiration time indicates to the garbage collector how old
118    *    an entry needs to be to be removed.
119    *  - Finally, the garbage collector can be instructed to prune the cache till
120    *    the occupied space goes below a threshold.
121    * @{
122    */
123
124   struct CachingOptions {
125     std::string Path;                    // Path to the cache, empty to disable.
126     int PruningInterval = 1200;          // seconds, -1 to disable pruning.
127     unsigned int Expiration = 7 * 24 * 3600;     // seconds (1w default).
128     unsigned MaxPercentageOfAvailableSpace = 75; // percentage.
129   };
130
131   /// Provide a path to a directory where to store the cached files for
132   /// incremental build.
133   void setCacheDir(std::string Path) { CacheOptions.Path = std::move(Path); }
134
135   /// Cache policy: interval (seconds) between two prune of the cache. Set to a
136   /// negative value (default) to disable pruning. A value of 0 will be ignored.
137   void setCachePruningInterval(int Interval) {
138     if (Interval)
139       CacheOptions.PruningInterval = Interval;
140   }
141
142   /// Cache policy: expiration (in seconds) for an entry.
143   /// A value of 0 will be ignored.
144   void setCacheEntryExpiration(unsigned Expiration) {
145     if (Expiration)
146       CacheOptions.Expiration = Expiration;
147   }
148
149   /**
150    * Sets the maximum cache size that can be persistent across build, in terms
151    * of percentage of the available space on the the disk. Set to 100 to
152    * indicate no limit, 50 to indicate that the cache size will not be left over
153    * half the available space. A value over 100 will be reduced to 100, and a
154    * value of 0 will be ignored.
155    *
156    *
157    * The formula looks like:
158    *  AvailableSpace = FreeSpace + ExistingCacheSize
159    *  NewCacheSize = AvailableSpace * P/100
160    *
161    */
162   void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) {
163     if (Percentage)
164       CacheOptions.MaxPercentageOfAvailableSpace = Percentage;
165   }
166
167   /**@}*/
168
169   /// Set the path to a directory where to save temporaries at various stages of
170   /// the processing.
171   void setSaveTempsDir(std::string Path) { SaveTempsDir = std::move(Path); }
172
173   /// Set the path to a directory where to save generated object files. This
174   /// path can be used by a linker to request on-disk files instead of in-memory
175   /// buffers. When set, results are available through getProducedBinaryFiles()
176   /// instead of getProducedBinaries().
177   void setGeneratedObjectsDirectory(std::string Path) {
178     SavedObjectsDirectoryPath = std::move(Path);
179   }
180
181   /// CPU to use to initialize the TargetMachine
182   void setCpu(std::string Cpu) { TMBuilder.MCpu = std::move(Cpu); }
183
184   /// Subtarget attributes
185   void setAttr(std::string MAttr) { TMBuilder.MAttr = std::move(MAttr); }
186
187   /// TargetMachine options
188   void setTargetOptions(TargetOptions Options) {
189     TMBuilder.Options = std::move(Options);
190   }
191
192   /// CodeModel
193   void setCodePICModel(Optional<Reloc::Model> Model) {
194     TMBuilder.RelocModel = Model;
195   }
196
197   /// CodeGen optimization level
198   void setCodeGenOptLevel(CodeGenOpt::Level CGOptLevel) {
199     TMBuilder.CGOptLevel = CGOptLevel;
200   }
201
202   /// IR optimization level: from 0 to 3.
203   void setOptLevel(unsigned NewOptLevel) {
204     OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel;
205   }
206
207   /// Disable CodeGen, only run the stages till codegen and stop. The output
208   /// will be bitcode.
209   void disableCodeGen(bool Disable) { DisableCodeGen = Disable; }
210
211   /// Perform CodeGen only: disable all other stages.
212   void setCodeGenOnly(bool CGOnly) { CodeGenOnly = CGOnly; }
213
214   /**@}*/
215
216   /**
217    * \defgroup Set of APIs to run individual stages in isolation.
218    * @{
219    */
220
221   /**
222    * Produce the combined summary index from all the bitcode files:
223    * "thin-link".
224    */
225   std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex();
226
227   /**
228    * Perform promotion and renaming of exported internal functions,
229    * and additionally resolve weak and linkonce symbols.
230    * Index is updated to reflect linkage changes from weak resolution.
231    */
232   void promote(Module &Module, ModuleSummaryIndex &Index);
233
234   /**
235    * Compute and emit the imported files for module at \p ModulePath.
236    */
237   static void emitImports(StringRef ModulePath, StringRef OutputName,
238                           ModuleSummaryIndex &Index);
239
240   /**
241    * Perform cross-module importing for the module identified by
242    * ModuleIdentifier.
243    */
244   void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
245
246   /**
247    * Compute the list of summaries needed for importing into module.
248    */
249   static void gatherImportedSummariesForModule(
250       StringRef ModulePath, ModuleSummaryIndex &Index,
251       std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
252
253   /**
254    * Perform internalization. Index is updated to reflect linkage changes.
255    */
256   void internalize(Module &Module, ModuleSummaryIndex &Index);
257
258   /**
259    * Perform post-importing ThinLTO optimizations.
260    */
261   void optimize(Module &Module);
262
263   /**
264    * Perform ThinLTO CodeGen.
265    */
266   std::unique_ptr<MemoryBuffer> codegen(Module &Module);
267
268   /**@}*/
269
270 private:
271   /// Helper factory to build a TargetMachine
272   TargetMachineBuilder TMBuilder;
273
274   /// Vector holding the in-memory buffer containing the produced binaries, when
275   /// SavedObjectsDirectoryPath isn't set.
276   std::vector<std::unique_ptr<MemoryBuffer>> ProducedBinaries;
277
278   /// Path to generated files in the supplied SavedObjectsDirectoryPath if any.
279   std::vector<std::string> ProducedBinaryFiles;
280
281   /// Vector holding the input buffers containing the bitcode modules to
282   /// process.
283   std::vector<MemoryBufferRef> Modules;
284
285   /// Set of symbols that need to be preserved outside of the set of bitcode
286   /// files.
287   StringSet<> PreservedSymbols;
288
289   /// Set of symbols that are cross-referenced between bitcode files.
290   StringSet<> CrossReferencedSymbols;
291
292   /// Control the caching behavior.
293   CachingOptions CacheOptions;
294
295   /// Path to a directory to save the temporary bitcode files.
296   std::string SaveTempsDir;
297
298   /// Path to a directory to save the generated object files.
299   std::string SavedObjectsDirectoryPath;
300
301   /// Flag to enable/disable CodeGen. When set to true, the process stops after
302   /// optimizations and a bitcode is produced.
303   bool DisableCodeGen = false;
304
305   /// Flag to indicate that only the CodeGen will be performed, no cross-module
306   /// importing or optimization.
307   bool CodeGenOnly = false;
308
309   /// IR Optimization Level [0-3].
310   unsigned OptLevel = 3;
311 };
312 }
313 #endif