LLVM 24.0.0git
DTLTO.h
Go to the documentation of this file.
1//===- DTLTO.h - Integrated Distributed ThinLTO implementation ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// \file
10// Declarations for Integrated Distributed ThinLTO, including the DTLTO class
11// and the distribution driver. The implementation focuses on preparing input
12// files for distribution.
13//
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_DTLTO_DTLTO_H
17#define LLVM_DTLTO_DTLTO_H
18
19#include "llvm/ADT/DenseSet.h"
21#include "llvm/LTO/LTO.h"
24
25#include <functional>
26#include <string>
27#include <utility>
28#include <vector>
29
30namespace llvm {
31namespace lto {
32
33/// Prepares inputs for Distributed ThinLTO so that backend compilations use
34/// individual bitcode paths and consistent module IDs.
35///
36/// Each input must exist as an individual bitcode file on disk and be loadable
37/// via its ModuleID. Archive members and FatLTO objects do not satisfy this
38/// requirement. For these inputs, this class extracts the individual bitcode
39/// to an individual temporary file, and updates ModuleID to that path. On
40/// Windows, module IDs are normalized to remove short 8.3 path components
41/// that are machine-local and break distribution; other normalization is left
42/// to DTLTO distributors.
43///
44/// Input files are kept alive until the pipeline has determined per-module
45/// ThinLTO participation and cache status, see addInput() for details.
46class LLVM_ABI DTLTO : public LTO {
47 using Base = LTO;
48
49public:
50 DTLTO(Config Conf, unsigned ParallelCodeGenParallelismLevel, LTOKind LTOMode,
51 IndexWriteCallback OnWrite, bool EmitIndexFiles, bool EmitImportsFiles,
52 StringRef LinkerOutputFile, StringRef Distributor,
53 ArrayRef<StringRef> DistributorArgs, StringRef RemoteCompiler,
54 ArrayRef<StringRef> RemoteCompilerPrependArgs,
55 ArrayRef<StringRef> RemoteCompilerArgs, AddBufferFn AddBufferArg,
56 bool SaveTempsArg)
58 ParallelCodeGenParallelismLevel, LTOMode),
59 AddBuffer(AddBufferArg), SaveTemps(SaveTempsArg),
60 ShouldEmitIndexFiles(EmitIndexFiles),
61 ShouldEmitImportFiles(EmitImportsFiles), OnIndexWriteCb(OnWrite),
62 DistributorParams{Distributor, DistributorArgs,
63 RemoteCompiler, RemoteCompilerPrependArgs,
64 RemoteCompilerArgs, LinkerOutputFile} {
65 assert(!LinkerOutputFile.empty() && "expected a valid linker output file");
67 }
68
69 // Create an instance of WriteIndexesBackend class.
72 "", true, nullptr, nullptr);
73 }
74
75 /// Add an input file and prepare it for distribution.
76 ///
77 /// This function performs the following tasks:
78 /// 1. Add the input file to the LTO object's list of input files.
79 /// 2. For individual bitcode file inputs on Windows only, overwrite the
80 /// module ID with a normalized path to remove short 8.3 form components.
81 /// 3. For thin archive members, overwrite the module ID with the path
82 /// (normalized on Windows) to the member file on disk.
83 /// 4. For archive members and FatLTO objects, overwrite the module ID with a
84 /// unique path (normalized on Windows) naming a file that will contain the
85 /// content. The file is created/populated later (see extractLTOInputs()).
87 addInput(std::unique_ptr<InputFile> InputPtr) override;
88
89 /// Runs the DTLTO pipeline. This function calls the supplied AddStream
90 /// function to add native object files to the link.
91 ///
92 /// The Cache parameter is optional. If supplied, it will be used to cache
93 /// native object files and add them to the link.
94 ///
95 /// The client will receive at most one callback (via either AddStream or
96 /// Cache) for each task identifier.
97 virtual Error run(AddStreamFn AddStream, FileCache Cache = {}) override;
98
99 /// Wait for LTO cleanup. Clients may call this after run() once subsequent
100 /// linking work that can overlap with cleanup is complete. Cleanup may emit
101 /// time trace events, so this must be called before time trace data is
102 /// finalized.
103 void waitForCleanup() override;
104
105private:
106 /// DTLTO archive support.
107 ///
108 /// Save the contents of ThinLTO-enabled input files that must be extracted
109 /// for distribution, such as archive members and FatLTO objects, to
110 /// individual bitcode files named after the module ID.
111 ///
112 /// Must be called after all input files are added and cache hits are known,
113 /// but before optimization begins. Existing files are overwritten because
114 /// they are likely leftovers from a previously terminated linker process and
115 /// can be safely replaced.
116 LLVM_ABI Error extractLTOInputs();
117
118 // Remove temporary files created to enable distribution.
119 void cleanup() override;
120
121public:
122 // Mutable and const accessors to the LTO configuration object.
123 Config &getConfig() { return Conf; }
124 const Config &getConfig() const { return Conf; }
125
126private:
127 // Bump allocator for saving updated module IDs.
128 BumpPtrAllocator PtrAlloc;
129 // String saver backed by PtrAlloc.
130 StringSaver Saver{PtrAlloc};
131
132 using SString = SmallString<128>;
133
134 // Function pointer that defines the callback to add a pre-existing file.
135 AddBufferFn AddBuffer;
136 // Count of jobs that hit the cache.
137 std::atomic<size_t> CachedJobs{0};
138 // Normalized output directory from LinkerOutputFile.
139 SString LinkerOutputDir;
140 // Keep temporary files when true.
141 bool SaveTemps = false;
142
143 // Saves the content of Buffer to Path overwriting any existing file.
144 static Error save(StringRef Buffer, StringRef Path);
145
146public:
147 struct Job {
148 // Task index (combines RegularLTO parallel codegen offset with module
149 // index).
150 unsigned Task;
151 // Module identifier (bitcode path) for the ThinLTO module.
153 // Native object path.
155 // Per-module summary index path.
157 // Per-module imports list path.
159 // Bitcode files from which this module imports.
161 // Cache key from thin link.
162 std::string CacheKey;
163 // On cache miss, stream used to store the compiled object in the cache.
165 // Set when the object was already supplied via the cache callback.
166 bool Cached = false;
167 };
168
169private:
170 // Backend compilation jobs, one per module.
171 SmallVector<Job> Jobs;
172 // Input module IDs that must be extracted to individual files.
173 DenseSet<StringRef> InputModuleIDsToExtract;
174 // Task index offset for first ThinLTO job.
175 unsigned ThinLTOTaskOffset;
176 // Optional cache for native objects.
177 FileCache Cache;
178 // Keep summary index files when true.
179 bool ShouldEmitIndexFiles = false;
180 // Keep summary import files when true.
181 bool ShouldEmitImportFiles = false;
182 // On index file write callback.
183 IndexWriteCallback OnIndexWriteCb;
184
185 /// Probes the LTO cache for a compiled native object for the given job.
186 ///
187 /// If no cache is configured (Cache.isValid() is false), returns immediately
188 /// without modifying the job.
189 ///
190 /// Otherwise, looks up the cache using J.CacheKey. On a cache hit, the cached
191 /// object has already been passed to the linker via the Cache callback, so
192 /// J.Cached is set to true, CachedJobs is incremented, and the distributor
193 /// can skip this job. On a cache miss, the cache returns an AddStreamFn; we
194 /// store it in J.CacheAddStream for use when storing the freshly compiled
195 /// object after the distributor runs.
196 ///
197 /// \param J The job to check. Must have Task, CacheKey, and ModuleID set.
198 /// On return, J.Cached and J.CacheAddStream may be updated.
199 ///
200 /// \returns Error::success() on success, or an Error from the cache lookup.
201 Error checkCacheHit(Job &J);
202
203 /// Prepares a single DTLTO backend compilation job for a ThinLTO module.
204 ///
205 /// Called once per module during performCodegen(). This function:
206 ///
207 /// 1. Computes output paths for the native object and summary index files.
208 /// Both are placed in the linker output directory with names of the form
209 /// stem.Task.UID.native.o and stem.Task.UID.thinlto.bc, where stem is
210 /// derived from ModulePath.
211 ///
212 /// 2. Initializes the Job struct with Task, ModuleID (ModulePath), paths,
213 /// ImportsFilesList and CacheKey from thin link results, and default
214 /// values for CacheAddStream and Cached.
215 ///
216 /// 3. Calls checkCacheHit() to probe the cache. On a cache hit, J.Cached is
217 /// set and the cached object has already been passed to the linker; the
218 /// distributor will skip this job. On a cache miss, J.CacheAddStream is
219 /// set for later use when storing the compiled object.
220 ///
221 /// 4. Records the module ID and imported module IDs that must be extracted
222 /// to individual files.
223 ///
224 /// 5. Writes the per-module summary index to disk only on cache miss. The
225 /// remote compiler will read this via -fthinlto-index=.
226 ///
227 /// 6. Registers the job's temporary files for removal on abnormal process
228 /// exit when SaveTemps is false (only for files that will be created).
229 ///
230 /// \param ModulePath The module identifier (bitcode path) for the ThinLTO
231 /// module.
232 /// \param Task The task index (combines RegularLTO.ParallelCodeGen
233 /// parallelism offset with the module index).
234 ///
235 /// \returns Error::success() on success, or an Error from saveBuffer() or
236 /// checkCacheHit().
237 Error prepareDtltoJob(StringRef ModulePath, unsigned Task);
238
239 /// Initializes DTLTO state and prepares a job for each ThinLTO module.
240 ///
241 /// Sets task offset, target triple, UID, and Jobs. For each module, calls
242 /// prepareDtltoJob() to assign output paths, check the cache, and write
243 /// summary index shards to disk when needed.
244 ///
245 /// \returns Error::success() on success, or an Error from prepareDtltoJob.
246 Error prepareDtltoJobs();
247
248 /// Runs the DTLTO code generation phase. Must be invoked after thinLink().
249 ///
250 /// Builds Clang options, emits a JSON manifest describing compilation jobs,
251 /// and invokes the distributor to compile ThinLTO modules remotely. Cache
252 /// hits are skipped; the distributor runs only when there are uncached jobs.
253 ///
254 /// \returns Error::success() on success, or an Error on manifest or
255 /// distributor failure.
256 Error performCodegen();
257
258 /// Adds compiled object files to the link for each non-cached job.
259 ///
260 /// Loads each native object from disk, then either writes it to the cache
261 /// (which adds it to the link via the cache callback) or passes it to
262 /// AddStreamFunc directly when caching is disabled.
263 ///
264 /// \returns Error::success() on success, or an Error if a file cannot be read
265 /// or a cache stream cannot be obtained.
266 Error addObjectFilesToLink();
267
268 // Determines if a file at the given path is a thin archive file.
269 //
270 // Uses a cache to avoid repeatedly reading the same file; reads only the
271 // header (magic bytes) to identify the archive type.
272 Expected<bool> isThinArchive(const StringRef ArchivePath);
273
274 // Unique ID for this link (process ID as string).
275 std::string UID;
276
277 // Input files registered for this link (same order as addInput).
278 std::vector<std::shared_ptr<lto::InputFile>> InputFiles;
279 // Cache for isThinArchive() results keyed by archive path.
280 StringMap<bool> ArchiveIsThinCache;
281 // Callback used by run() to add native objects to the link.
282 AddStreamFn AddStreamFunc = nullptr;
283 // Per-task summary index shards from the thin link (in-memory buffers).
284 std::vector<SmallString<0>> SummaryIndexFiles;
285 // Per-task imported bitcode paths from the thin link.
286 std::vector<std::vector<std::string>> ImportsFilesList;
287 // Per-task cache keys for incremental builds from the thin link.
288 std::vector<std::string> CacheKeysList;
289
290 /// Runs the DTLTO thin link phase, producing per-module summary indices,
291 /// import lists, and cache keys for distribution.
292 ///
293 /// This function configures a WriteIndexesThinBackend and invokes the base
294 /// LTO run, which performs the thin link. The thin link resolves cross-module
295 /// references and produces:
296 ///
297 /// - SummaryIndexFiles: per-module summary index shards (in-memory buffers)
298 /// - ImportsFilesList: per-module lists of imported bitcode files
299 /// - CacheKeysList: per-module cache keys for incremental builds
300 /// - ModuleNames: per-module identifiers
301 ///
302 /// The Config callbacks (GetSummaryIndexStreamFunc, GetCacheKeysListRefFunc,
303 /// GetImportsListRefFunc) are installed so the WriteIndexesThinBackend
304 /// populates these arrays. performCodegen() later uses them to prepare
305 /// backend jobs.
306 ///
307 /// \returns Error::success() if the thin link completes, or an Error from
308 /// Base::run().
309 Error performThinLink();
310
311 /// Derive a set of Clang options that will be shared/common for all DTLTO
312 /// backend compilations. We are intentionally minimal here as these options
313 /// must remain synchronized with the behavior of Clang. DTLTO does not
314 /// support all the features available with in-process LTO. More features are
315 /// expected to be added over time. Users can specify Clang options directly
316 /// if a feature is not supported. Note that explicitly specified options that
317 /// imply additional input or output file dependencies must be communicated to
318 /// the distribution system, potentially by setting extra options on the
319 /// distributor program.
320 void buildCommonRemoteCompilerOptions();
321
322public:
323 // Parameters and shared state for DistributorDriver class.
325
328 ArrayRef<StringRef> DistributorArgsArg,
329 StringRef RemoteCompilerArg,
330 ArrayRef<StringRef> RemoteCompilerPrependArgsArg,
331 ArrayRef<StringRef> RemoteCompilerArgsArg,
332 StringRef LinkerOutputFileArg)
333 : LinkerOutputFile(LinkerOutputFileArg),
334 DistributorPath(DistributorArg), DistributorArgs(DistributorArgsArg),
335 RemoteCompiler(RemoteCompilerArg),
336 RemoteCompilerPrependArgs(RemoteCompilerPrependArgsArg),
337 RemoteCompilerArgs(RemoteCompilerArgsArg) {}
338
339 // Output linker file path.
341 // Path to the distributor executable.
343 // Arguments passed to the distributor.
345 // Compiler executabl invoked by the distributor (e.g., Clang).
347 // Options prepended to remote compiler args.
349 // User-supplied options passed to remote compiler.
351
352 // Common Clang options for all compilation jobs.
354 // Input paths shared across compilation jobs.
356 // Target triple for compilations.
358 };
359
360private:
361 // Distributor configuration class instance.
362 DistributionDriverParams DistributorParams;
363
364 // Cleanup files list.
365 std::vector<std::string> CleanupList;
366
367 // There can be many temporary files to remove. Performing deletion in the
368 // background can save a few seconds on Windows hosts.
369 struct BackgroundDeletion : DefaultThreadPool {
370 BackgroundDeletion();
371 ~BackgroundDeletion();
372
373 void removeFiles(std::vector<std::string> &&Files, const Config &Conf);
374 void waitForTasks();
375
376 std::vector<std::string> Warnings;
377 };
378
379 BackgroundDeletion BackgroundDeleter;
380
381 // Record a file for cleanup and register signal-time removal if requested.
382 void addToCleanup(StringRef Filename) {
383 CleanupList.push_back(Filename.str());
385 }
386};
387
388namespace {
389constexpr StringRef BCError = "DTLTO backend compilation: ";
390}
391
393public:
395 ArrayRef<DTLTO::Job> JobsArg, bool SaveTempsArg,
396 std::function<void(StringRef)> AddToClenupArg)
397 : Params{ParamsArg}, SaveTemps{SaveTempsArg},
398 AddToCleanup{AddToClenupArg}, Jobs{JobsArg} {};
399
400private:
402 // Keep temporary files when true.
403 bool SaveTemps = false;
404 std::function<void(StringRef)> AddToCleanup;
406 SmallString<128> DistributorJsonFile;
407
408 // Generates a JSON file describing the compilations
409 Error emitJson();
410 // Saves JSON file on a filesystem.
411 Error saveJson();
412
413public:
414 /// Invokes the distributor to compile bitcode modules remotely.
415 ///
416 /// Runs the distributor with the
417 /// JSON manifest path; the distributor spawns remote compiler processes.
418 ///
419 /// \returns Error::success() on success, or an Error if the distributor
420 /// fails.
422};
423
424} // namespace lto
425} // namespace llvm
426
427#endif // LLVM_DTLTO_DTLTO_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void cleanup(BlockFrequencyInfoImplBase &BFI)
Clear all memory not needed downstream.
#define LLVM_ABI
Definition Compiler.h:215
This file defines the DenseSet and SmallDenseSet classes.
static constexpr StringLiteral Filename
This file defines the SmallString class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
Tagged union holding either a T or a Error.
Definition Error.h:485
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings",...
Definition StringMap.h:128
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
Saves strings in the provided stable storage and returns a StringRef with a stable character pointer.
Definition StringSaver.h:22
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
const Config & getConfig() const
Definition DTLTO.h:124
Config & getConfig()
Definition DTLTO.h:123
static lto::ThinBackend writeIndexesBackendInstance()
Definition DTLTO.h:70
DTLTO(Config Conf, unsigned ParallelCodeGenParallelismLevel, LTOKind LTOMode, IndexWriteCallback OnWrite, bool EmitIndexFiles, bool EmitImportsFiles, StringRef LinkerOutputFile, StringRef Distributor, ArrayRef< StringRef > DistributorArgs, StringRef RemoteCompiler, ArrayRef< StringRef > RemoteCompilerPrependArgs, ArrayRef< StringRef > RemoteCompilerArgs, AddBufferFn AddBufferArg, bool SaveTempsArg)
Definition DTLTO.h:50
DistributionDriver(DTLTO::DistributionDriverParams &ParamsArg, ArrayRef< DTLTO::Job > JobsArg, bool SaveTempsArg, std::function< void(StringRef)> AddToClenupArg)
Definition DTLTO.h:394
LLVM_ABI Error operator()()
Invokes the distributor to compile bitcode modules remotely.
LTO(Config Conf, ThinBackend Backend={}, unsigned ParallelCodeGenParallelismLevel=1, LTOKind LTOMode=LTOK_Default)
Create an LTO object.
Definition LTO.cpp:694
Config Conf
Definition LTO.h:466
LTOKind
Unified LTO modes.
Definition LTO.h:396
@ LTOK_UnifiedThin
ThinLTO, with Unified LTO enabled.
Definition LTO.h:404
LTOKind LTOMode
Definition LTO.h:647
std::function< void(const std::string &)> IndexWriteCallback
Definition LTO.h:245
LLVM_ABI ThinBackend createWriteIndexesThinBackend(ThreadPoolStrategy Parallelism, std::string OldPrefix, std::string NewPrefix, std::string NativeObjectPrefix, bool ShouldEmitImportsFiles, raw_fd_ostream *LinkedObjectsFile, IndexWriteCallback OnWrite)
This ThinBackend writes individual module indexes to files, instead of running the individual backend...
Definition LTO.cpp:2043
LLVM_ABI bool RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg=nullptr)
This function registers signal handlers to ensure that if a signal gets delivered that the named file...
This is an optimization pass for GlobalISel generic memory operations.
ThreadPoolStrategy hardware_concurrency(unsigned ThreadCount=0)
Returns a default thread strategy where all available hardware resources are to be used,...
Definition Threading.h:190
std::function< void(unsigned Task, const Twine &ModuleName, std::unique_ptr< MemoryBuffer > MB)> AddBufferFn
This type defines the callback to add a pre-existing file (e.g.
Definition Caching.h:107
SingleThreadExecutor DefaultThreadPool
Definition ThreadPool.h:262
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
std::function< Expected< std::unique_ptr< CachedFileStream > >( unsigned Task, const Twine &ModuleName)> AddStreamFn
This type defines the callback to add a file that is generated on the fly.
Definition Caching.h:58
LLVM_ABI Error EmitImportsFiles(StringRef ModulePath, StringRef OutputFilename, const ModuleToSummariesForIndexTy &ModuleToSummariesForIndex)
Emit into OutputFilename the files module ModulePath will import from.
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
This type represents a file cache system that manages caching of files.
Definition Caching.h:84
LTO configuration.
Definition Config.h:43
ArrayRef< StringRef > DistributorArgs
Definition DTLTO.h:344
ArrayRef< StringRef > RemoteCompilerArgs
Definition DTLTO.h:350
SmallVector< StringRef, 0 > CodegenOptions
Definition DTLTO.h:353
DistributionDriverParams(StringRef DistributorArg, ArrayRef< StringRef > DistributorArgsArg, StringRef RemoteCompilerArg, ArrayRef< StringRef > RemoteCompilerPrependArgsArg, ArrayRef< StringRef > RemoteCompilerArgsArg, StringRef LinkerOutputFileArg)
Definition DTLTO.h:327
DenseSet< StringRef > CommonInputs
Definition DTLTO.h:355
ArrayRef< StringRef > RemoteCompilerPrependArgs
Definition DTLTO.h:348
StringRef SummaryIndexPath
Definition DTLTO.h:156
AddStreamFn CacheAddStream
Definition DTLTO.h:164
StringRef NativeObjectPath
Definition DTLTO.h:154
StringRef ModuleID
Definition DTLTO.h:152
ArrayRef< std::string > ImportsFilesList
Definition DTLTO.h:160
StringRef ImportsPath
Definition DTLTO.h:158
std::string CacheKey
Definition DTLTO.h:162
This type defines the behavior following the thin-link phase during ThinLTO.
Definition LTO.h:320