1 //===-ThinLTOCodeGenerator.h - LLVM Link Time Optimizer -------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file declares the ThinLTOCodeGenerator class, similar to the
11 // LTOCodeGenerator but for the ThinLTO scheme. It provides an interface for
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_LTO_THINLTOCODEGENERATOR_H
17 #define LLVM_LTO_THINLTOCODEGENERATOR_H
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/CachePruning.h"
24 #include "llvm/Support/CodeGen.h"
25 #include "llvm/Support/MemoryBuffer.h"
26 #include "llvm/Target/TargetOptions.h"
35 /// Wrapper around MemoryBufferRef, owning the identifier
37 std::string OwnedIdentifier;
41 ThinLTOBuffer(StringRef Buffer, StringRef Identifier)
42 : OwnedIdentifier(Identifier), Buffer(Buffer) {}
44 MemoryBufferRef getMemBuffer() const {
45 return MemoryBufferRef(Buffer,
46 {OwnedIdentifier.c_str(), OwnedIdentifier.size()});
48 StringRef getBuffer() const { return Buffer; }
49 StringRef getBufferIdentifier() const { return OwnedIdentifier; }
52 /// Helper to gather options relevant to the target machine creation
53 struct TargetMachineBuilder {
57 TargetOptions Options;
58 Optional<Reloc::Model> RelocModel;
59 CodeGenOpt::Level CGOptLevel = CodeGenOpt::Aggressive;
61 std::unique_ptr<TargetMachine> create() const;
64 /// This class define an interface similar to the LTOCodeGenerator, but adapted
65 /// for ThinLTO processing.
66 /// The ThinLTOCodeGenerator is not intended to be reuse for multiple
67 /// compilation: the model is that the client adds modules to the generator and
68 /// ask to perform the ThinLTO optimizations / codegen, and finally destroys the
70 class ThinLTOCodeGenerator {
72 /// Add given module to the code generator.
73 void addModule(StringRef Identifier, StringRef Data);
76 * Adds to a list of all global symbols that must exist in the final generated
77 * code. If a symbol is not listed there, it will be optimized away if it is
78 * inlined into every usage.
80 void preserveSymbol(StringRef Name);
83 * Adds to a list of all global symbols that are cross-referenced between
84 * ThinLTO files. If the ThinLTO CodeGenerator can ensure that every
85 * references from a ThinLTO module to this symbol is optimized away, then
86 * the symbol can be discarded.
88 void crossReferenceSymbol(StringRef Name);
91 * Process all the modules that were added to the code generator in parallel.
93 * Client can access the resulting object files using getProducedBinaries(),
94 * unless setGeneratedObjectsDirectory() has been called, in which case
95 * results are available through getProducedBinaryFiles().
100 * Return the "in memory" binaries produced by the code generator. This is
101 * filled after run() unless setGeneratedObjectsDirectory() has been
102 * called, in which case results are available through
103 * getProducedBinaryFiles().
105 std::vector<std::unique_ptr<MemoryBuffer>> &getProducedBinaries() {
106 return ProducedBinaries;
110 * Return the "on-disk" binaries produced by the code generator. This is
111 * filled after run() when setGeneratedObjectsDirectory() has been
112 * called, in which case results are available through getProducedBinaries().
114 std::vector<std::string> &getProducedBinaryFiles() {
115 return ProducedBinaryFiles;
119 * \defgroup Options setters
124 * \defgroup Cache controlling options
126 * These entry points control the ThinLTO cache. The cache is intended to
127 * support incremental build, and thus needs to be persistent accross build.
128 * The client enabled the cache by supplying a path to an existing directory.
129 * The code generator will use this to store objects files that may be reused
130 * during a subsequent build.
131 * To avoid filling the disk space, a few knobs are provided:
132 * - The pruning interval limit the frequency at which the garbage collector
133 * will try to scan the cache directory to prune it from expired entries.
134 * Setting to -1 disable the pruning (default). Setting to 0 will force
136 * - The pruning expiration time indicates to the garbage collector how old
137 * an entry needs to be to be removed.
138 * - Finally, the garbage collector can be instructed to prune the cache till
139 * the occupied space goes below a threshold.
143 struct CachingOptions {
144 std::string Path; // Path to the cache, empty to disable.
145 CachePruningPolicy Policy;
148 /// Provide a path to a directory where to store the cached files for
149 /// incremental build.
150 void setCacheDir(std::string Path) { CacheOptions.Path = std::move(Path); }
152 /// Cache policy: interval (seconds) between two prunes of the cache. Set to a
153 /// negative value to disable pruning. A value of 0 will force pruning to
155 void setCachePruningInterval(int Interval) {
157 CacheOptions.Policy.Interval.reset();
159 CacheOptions.Policy.Interval = std::chrono::seconds(Interval);
162 /// Cache policy: expiration (in seconds) for an entry.
163 /// A value of 0 will be ignored.
164 void setCacheEntryExpiration(unsigned Expiration) {
166 CacheOptions.Policy.Expiration = std::chrono::seconds(Expiration);
170 * Sets the maximum cache size that can be persistent across build, in terms
171 * of percentage of the available space on the disk. Set to 100 to indicate
172 * no limit, 50 to indicate that the cache size will not be left over
173 * half the available space. A value over 100 will be reduced to 100, and a
174 * value of 0 will be ignored.
177 * The formula looks like:
178 * AvailableSpace = FreeSpace + ExistingCacheSize
179 * NewCacheSize = AvailableSpace * P/100
182 void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) {
184 CacheOptions.Policy.MaxSizePercentageOfAvailableSpace = Percentage;
187 /// Cache policy: the maximum size for the cache directory in bytes. A value
188 /// over the amount of available space on the disk will be reduced to the
189 /// amount of available space. A value of 0 will be ignored.
190 void setCacheMaxSizeBytes(uint64_t MaxSizeBytes) {
192 CacheOptions.Policy.MaxSizeBytes = MaxSizeBytes;
195 /// Cache policy: the maximum number of files in the cache directory. A value
196 /// of 0 will be ignored.
197 void setCacheMaxSizeFiles(unsigned MaxSizeFiles) {
199 CacheOptions.Policy.MaxSizeFiles = MaxSizeFiles;
204 /// Set the path to a directory where to save temporaries at various stages of
206 void setSaveTempsDir(std::string Path) { SaveTempsDir = std::move(Path); }
208 /// Set the path to a directory where to save generated object files. This
209 /// path can be used by a linker to request on-disk files instead of in-memory
210 /// buffers. When set, results are available through getProducedBinaryFiles()
211 /// instead of getProducedBinaries().
212 void setGeneratedObjectsDirectory(std::string Path) {
213 SavedObjectsDirectoryPath = std::move(Path);
216 /// CPU to use to initialize the TargetMachine
217 void setCpu(std::string Cpu) { TMBuilder.MCpu = std::move(Cpu); }
219 /// Subtarget attributes
220 void setAttr(std::string MAttr) { TMBuilder.MAttr = std::move(MAttr); }
222 /// TargetMachine options
223 void setTargetOptions(TargetOptions Options) {
224 TMBuilder.Options = std::move(Options);
227 /// Enable the Freestanding mode: indicate that the optimizer should not
228 /// assume builtins are present on the target.
229 void setFreestanding(bool Enabled) { Freestanding = Enabled; }
232 void setCodePICModel(Optional<Reloc::Model> Model) {
233 TMBuilder.RelocModel = Model;
236 /// CodeGen optimization level
237 void setCodeGenOptLevel(CodeGenOpt::Level CGOptLevel) {
238 TMBuilder.CGOptLevel = CGOptLevel;
241 /// IR optimization level: from 0 to 3.
242 void setOptLevel(unsigned NewOptLevel) {
243 OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel;
246 /// Disable CodeGen, only run the stages till codegen and stop. The output
248 void disableCodeGen(bool Disable) { DisableCodeGen = Disable; }
250 /// Perform CodeGen only: disable all other stages.
251 void setCodeGenOnly(bool CGOnly) { CodeGenOnly = CGOnly; }
256 * \defgroup Set of APIs to run individual stages in isolation.
261 * Produce the combined summary index from all the bitcode files:
264 std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex();
267 * Perform promotion and renaming of exported internal functions,
268 * and additionally resolve weak and linkonce symbols.
269 * Index is updated to reflect linkage changes from weak resolution.
271 void promote(Module &Module, ModuleSummaryIndex &Index);
274 * Compute and emit the imported files for module at \p ModulePath.
276 void emitImports(Module &Module, StringRef OutputName,
277 ModuleSummaryIndex &Index);
280 * Perform cross-module importing for the module identified by
283 void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
286 * Compute the list of summaries needed for importing into module.
288 void gatherImportedSummariesForModule(
289 Module &Module, ModuleSummaryIndex &Index,
290 std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
293 * Perform internalization. Index is updated to reflect linkage changes.
295 void internalize(Module &Module, ModuleSummaryIndex &Index);
298 * Perform post-importing ThinLTO optimizations.
300 void optimize(Module &Module);
305 /// Helper factory to build a TargetMachine
306 TargetMachineBuilder TMBuilder;
308 /// Vector holding the in-memory buffer containing the produced binaries, when
309 /// SavedObjectsDirectoryPath isn't set.
310 std::vector<std::unique_ptr<MemoryBuffer>> ProducedBinaries;
312 /// Path to generated files in the supplied SavedObjectsDirectoryPath if any.
313 std::vector<std::string> ProducedBinaryFiles;
315 /// Vector holding the input buffers containing the bitcode modules to
317 std::vector<ThinLTOBuffer> Modules;
319 /// Set of symbols that need to be preserved outside of the set of bitcode
321 StringSet<> PreservedSymbols;
323 /// Set of symbols that are cross-referenced between bitcode files.
324 StringSet<> CrossReferencedSymbols;
326 /// Control the caching behavior.
327 CachingOptions CacheOptions;
329 /// Path to a directory to save the temporary bitcode files.
330 std::string SaveTempsDir;
332 /// Path to a directory to save the generated object files.
333 std::string SavedObjectsDirectoryPath;
335 /// Flag to enable/disable CodeGen. When set to true, the process stops after
336 /// optimizations and a bitcode is produced.
337 bool DisableCodeGen = false;
339 /// Flag to indicate that only the CodeGen will be performed, no cross-module
340 /// importing or optimization.
341 bool CodeGenOnly = false;
343 /// Flag to indicate that the optimizer should not assume builtins are present
345 bool Freestanding = false;
347 /// IR Optimization Level [0-3].
348 unsigned OptLevel = 3;