Line data Source code
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/CachePruning.h"
24 : #include "llvm/Support/CodeGen.h"
25 : #include "llvm/Support/MemoryBuffer.h"
26 : #include "llvm/Target/TargetOptions.h"
27 :
28 : #include <string>
29 :
30 : namespace llvm {
31 : class StringRef;
32 : class LLVMContext;
33 : class TargetMachine;
34 :
35 : /// Wrapper around MemoryBufferRef, owning the identifier
36 525 : class ThinLTOBuffer {
37 : std::string OwnedIdentifier;
38 : StringRef Buffer;
39 :
40 : public:
41 : ThinLTOBuffer(StringRef Buffer, StringRef Identifier)
42 300 : : OwnedIdentifier(Identifier), Buffer(Buffer) {}
43 :
44 : MemoryBufferRef getMemBuffer() const {
45 : return MemoryBufferRef(Buffer,
46 352 : {OwnedIdentifier.c_str(), OwnedIdentifier.size()});
47 : }
48 0 : StringRef getBuffer() const { return Buffer; }
49 : StringRef getBufferIdentifier() const { return OwnedIdentifier; }
50 : };
51 :
52 : /// Helper to gather options relevant to the target machine creation
53 : struct TargetMachineBuilder {
54 : Triple TheTriple;
55 : std::string MCpu;
56 : std::string MAttr;
57 : TargetOptions Options;
58 : Optional<Reloc::Model> RelocModel;
59 : CodeGenOpt::Level CGOptLevel = CodeGenOpt::Aggressive;
60 :
61 : std::unique_ptr<TargetMachine> create() const;
62 : };
63 :
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
69 : /// codegenerator.
70 : class ThinLTOCodeGenerator {
71 : public:
72 : /// Add given module to the code generator.
73 : void addModule(StringRef Identifier, StringRef Data);
74 :
75 : /**
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.
79 : */
80 : void preserveSymbol(StringRef Name);
81 :
82 : /**
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.
87 : */
88 : void crossReferenceSymbol(StringRef Name);
89 :
90 : /**
91 : * Process all the modules that were added to the code generator in parallel.
92 : *
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().
96 : */
97 : void run();
98 :
99 : /**
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().
104 : */
105 : std::vector<std::unique_ptr<MemoryBuffer>> &getProducedBinaries() {
106 2 : return ProducedBinaries;
107 : }
108 :
109 : /**
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().
113 : */
114 : std::vector<std::string> &getProducedBinaryFiles() {
115 : return ProducedBinaryFiles;
116 : }
117 :
118 : /**
119 : * \defgroup Options setters
120 : * @{
121 : */
122 :
123 : /**
124 : * \defgroup Cache controlling options
125 : *
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
135 : * pruning to occur.
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.
140 : * @{
141 : */
142 :
143 : struct CachingOptions {
144 : std::string Path; // Path to the cache, empty to disable.
145 : CachePruningPolicy Policy;
146 : };
147 :
148 : /// Provide a path to a directory where to store the cached files for
149 : /// incremental build.
150 102 : void setCacheDir(std::string Path) { CacheOptions.Path = std::move(Path); }
151 :
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
154 : /// occur.
155 : void setCachePruningInterval(int Interval) {
156 102 : if(Interval < 0)
157 : CacheOptions.Policy.Interval.reset();
158 : else
159 : CacheOptions.Policy.Interval = std::chrono::seconds(Interval);
160 : }
161 :
162 : /// Cache policy: expiration (in seconds) for an entry.
163 : /// A value of 0 will be ignored.
164 : void setCacheEntryExpiration(unsigned Expiration) {
165 102 : if (Expiration)
166 102 : CacheOptions.Policy.Expiration = std::chrono::seconds(Expiration);
167 : }
168 :
169 : /**
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.
175 : *
176 : *
177 : * The formula looks like:
178 : * AvailableSpace = FreeSpace + ExistingCacheSize
179 : * NewCacheSize = AvailableSpace * P/100
180 : *
181 : */
182 : void setMaxCacheSizeRelativeToAvailableSpace(unsigned Percentage) {
183 : if (Percentage)
184 : CacheOptions.Policy.MaxSizePercentageOfAvailableSpace = Percentage;
185 : }
186 :
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 0 : void setCacheMaxSizeBytes(uint64_t MaxSizeBytes) {
191 102 : if (MaxSizeBytes)
192 2 : CacheOptions.Policy.MaxSizeBytes = MaxSizeBytes;
193 0 : }
194 :
195 : /// Cache policy: the maximum number of files in the cache directory. A value
196 : /// of 0 will be ignored.
197 0 : void setCacheMaxSizeFiles(unsigned MaxSizeFiles) {
198 102 : if (MaxSizeFiles)
199 102 : CacheOptions.Policy.MaxSizeFiles = MaxSizeFiles;
200 0 : }
201 :
202 : /**@}*/
203 :
204 : /// Set the path to a directory where to save temporaries at various stages of
205 : /// the processing.
206 3 : void setSaveTempsDir(std::string Path) { SaveTempsDir = std::move(Path); }
207 :
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 3 : SavedObjectsDirectoryPath = std::move(Path);
214 : }
215 :
216 : /// CPU to use to initialize the TargetMachine
217 : void setCpu(std::string Cpu) { TMBuilder.MCpu = std::move(Cpu); }
218 :
219 : /// Subtarget attributes
220 : void setAttr(std::string MAttr) { TMBuilder.MAttr = std::move(MAttr); }
221 :
222 : /// TargetMachine options
223 : void setTargetOptions(TargetOptions Options) {
224 102 : TMBuilder.Options = std::move(Options);
225 : }
226 :
227 : /// Enable the Freestanding mode: indicate that the optimizer should not
228 : /// assume builtins are present on the target.
229 102 : void setFreestanding(bool Enabled) { Freestanding = Enabled; }
230 :
231 : /// CodeModel
232 : void setCodePICModel(Optional<Reloc::Model> Model) {
233 : TMBuilder.RelocModel = Model;
234 : }
235 :
236 : /// CodeGen optimization level
237 : void setCodeGenOptLevel(CodeGenOpt::Level CGOptLevel) {
238 : TMBuilder.CGOptLevel = CGOptLevel;
239 : }
240 :
241 : /// IR optimization level: from 0 to 3.
242 : void setOptLevel(unsigned NewOptLevel) {
243 : OptLevel = (NewOptLevel > 3) ? 3 : NewOptLevel;
244 : }
245 :
246 : /// Disable CodeGen, only run the stages till codegen and stop. The output
247 : /// will be bitcode.
248 : void disableCodeGen(bool Disable) { DisableCodeGen = Disable; }
249 :
250 : /// Perform CodeGen only: disable all other stages.
251 2 : void setCodeGenOnly(bool CGOnly) { CodeGenOnly = CGOnly; }
252 :
253 : /**@}*/
254 :
255 : /**
256 : * \defgroup Set of APIs to run individual stages in isolation.
257 : * @{
258 : */
259 :
260 : /**
261 : * Produce the combined summary index from all the bitcode files:
262 : * "thin-link".
263 : */
264 : std::unique_ptr<ModuleSummaryIndex> linkCombinedIndex();
265 :
266 : /**
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.
270 : */
271 : void promote(Module &Module, ModuleSummaryIndex &Index);
272 :
273 : /**
274 : * Compute and emit the imported files for module at \p ModulePath.
275 : */
276 : static void emitImports(StringRef ModulePath, StringRef OutputName,
277 : ModuleSummaryIndex &Index);
278 :
279 : /**
280 : * Perform cross-module importing for the module identified by
281 : * ModuleIdentifier.
282 : */
283 : void crossModuleImport(Module &Module, ModuleSummaryIndex &Index);
284 :
285 : /**
286 : * Compute the list of summaries needed for importing into module.
287 : */
288 : static void gatherImportedSummariesForModule(
289 : StringRef ModulePath, ModuleSummaryIndex &Index,
290 : std::map<std::string, GVSummaryMapTy> &ModuleToSummariesForIndex);
291 :
292 : /**
293 : * Perform internalization. Index is updated to reflect linkage changes.
294 : */
295 : void internalize(Module &Module, ModuleSummaryIndex &Index);
296 :
297 : /**
298 : * Perform post-importing ThinLTO optimizations.
299 : */
300 : void optimize(Module &Module);
301 :
302 : /**@}*/
303 :
304 : private:
305 : /// Helper factory to build a TargetMachine
306 : TargetMachineBuilder TMBuilder;
307 :
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;
311 :
312 : /// Path to generated files in the supplied SavedObjectsDirectoryPath if any.
313 : std::vector<std::string> ProducedBinaryFiles;
314 :
315 : /// Vector holding the input buffers containing the bitcode modules to
316 : /// process.
317 : std::vector<ThinLTOBuffer> Modules;
318 :
319 : /// Set of symbols that need to be preserved outside of the set of bitcode
320 : /// files.
321 : StringSet<> PreservedSymbols;
322 :
323 : /// Set of symbols that are cross-referenced between bitcode files.
324 : StringSet<> CrossReferencedSymbols;
325 :
326 : /// Control the caching behavior.
327 : CachingOptions CacheOptions;
328 :
329 : /// Path to a directory to save the temporary bitcode files.
330 : std::string SaveTempsDir;
331 :
332 : /// Path to a directory to save the generated object files.
333 : std::string SavedObjectsDirectoryPath;
334 :
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;
338 :
339 : /// Flag to indicate that only the CodeGen will be performed, no cross-module
340 : /// importing or optimization.
341 : bool CodeGenOnly = false;
342 :
343 : /// Flag to indicate that the optimizer should not assume builtins are present
344 : /// on the target.
345 : bool Freestanding = false;
346 :
347 : /// IR Optimization Level [0-3].
348 : unsigned OptLevel = 3;
349 : };
350 : }
351 : #endif
|