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::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.
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    */
77   void run();
78 
79   /**
80    * Return the "in memory" binaries produced by the code generator.
81    */
getProducedBinaries()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.
setCacheDir(std::string Path)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.
setCachePruningInterval(int Interval)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.
setCacheEntryExpiration(unsigned Expiration)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    */
setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage)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.
setSaveTempsDir(std::string Path)157   void setSaveTempsDir(std::string Path) { SaveTempsDir = std::move(Path); }
158 
159   /// CPU to use to initialize the TargetMachine
setCpu(std::string Cpu)160   void setCpu(std::string Cpu) { TMBuilder.MCpu = std::move(Cpu); }
161 
162   /// Subtarget attributes
setAttr(std::string MAttr)163   void setAttr(std::string MAttr) { TMBuilder.MAttr = std::move(MAttr); }
164 
165   /// TargetMachine options
setTargetOptions(TargetOptions Options)166   void setTargetOptions(TargetOptions Options) {
167     TMBuilder.Options = std::move(Options);
168   }
169 
170   /// CodeModel
setCodePICModel(Optional<Reloc::Model> Model)171   void setCodePICModel(Optional<Reloc::Model> Model) {
172     TMBuilder.RelocModel = Model;
173   }
174 
175   /// CodeGen optimization level
setCodeGenOptLevel(CodeGenOpt::Level CGOptLevel)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.
disableCodeGen(bool Disable)182   void disableCodeGen(bool Disable) { DisableCodeGen = Disable; }
183 
184   /// Perform CodeGen only: disable all other stages.
setCodeGenOnly(bool CGOnly)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 
243 private:
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