34void lto::DTLTO::cleanup() {
37 auto removeFile = [](StringRef FileName) ->
void {
40 EC != std::make_error_code(std::errc::no_such_file_or_directory))
41 errs() <<
"warning: could not remove the file '" << FileName
42 <<
"': " <<
EC.message() <<
"\n";
45 TimeTraceScope JobScope(
"Remove DTLTO temporary files");
46 for (
const auto &Name : CleanupList)
55Error lto::DTLTO::performThinLink() {
56 size_t NumTasks = getMaxTasks();
57 SummaryIndexFiles.resize(NumTasks);
58 ImportsFilesList.resize(NumTasks);
59 CacheKeysList.resize(NumTasks);
61 lto::Config &Cfg = getConfig();
63 [&](
size_t task) -> std::unique_ptr<raw_svector_ostream> {
64 return std::make_unique<raw_svector_ostream>(SummaryIndexFiles[task]);
67 return CacheKeysList[task];
70 [&](
size_t task) -> std::vector<std::string> & {
71 return ImportsFilesList[task];
73 return Base::run(AddStreamFunc, {});
80 AddStreamFunc = AddStream;
81 Cache = std::move(CacheParam);
85 if (
Error Err = performThinLink())
88 ThinLTOTaskOffset =
RegularLTO.ParallelCodeGenParallelismLevel;
89 DistributorParams.TargetTriple =
RegularLTO.CombinedModule->getTargetTriple();
91 if (
Error Err = prepareDtltoJobs())
93 if (
Error Err = serializeLTOInputs())
95 if (
Error Err = performCodegen())
97 if (
Error Err = addObjectFilesToLink())
103Error lto::DTLTO::checkCacheHit(Job &J) {
104 if (!Cache.isValid())
107 auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);
108 if (
Error Err = CacheAddStreamExp.takeError())
113 if (!CacheAddStream) {
115 CachedJobs.fetch_add(1);
120 J.CacheAddStream = std::move(CacheAddStream);
126Error lto::DTLTO::prepareDtltoJob(StringRef ModulePath,
unsigned Task) {
127 assert(Task >= ThinLTOTaskOffset && Task - ThinLTOTaskOffset < Jobs.size() &&
128 "Task index out of range for Jobs");
129 assert(Task < SummaryIndexFiles.size() &&
"Task index out of range");
131 SString ObjFilePath =
134 itostr(Task) +
"." + UID +
".native.o");
136 SString SummaryIndexPathStr = ObjFilePath;
137 SummaryIndexPathStr +=
".thinlto.bc";
138 SString ImportsPathStr = ModulePath;
139 ImportsPathStr +=
".imports";
141 Job &J = Jobs[Task - ThinLTOTaskOffset];
144 Saver.save(ObjFilePath.str()),
145 Saver.save(SummaryIndexPathStr.str()),
146 Saver.save(ImportsPathStr.str()),
147 ImportsFilesList[Task],
152 if (
Error Err = checkCacheHit(J))
155 TimeTraceScope JobScope(
"Emit individual index for DTLTO",
157 if (
Error Err = save(SummaryIndexFiles[Task], J.SummaryIndexPath))
161 OnIndexWriteCb(J.SummaryIndexPath.str());
163 if (ShouldEmitImportFiles)
164 if (
Error Err = save(
join(J.ImportsFilesList,
"\n"), J.ImportsPath))
169 addToCleanup(J.NativeObjectPath.str());
170 if (!ShouldEmitIndexFiles)
171 addToCleanup(J.SummaryIndexPath.str());
172 if (!ShouldEmitImportFiles)
173 addToCleanup(J.ImportsPath.str());
180void lto::DTLTO::buildCommonRemoteCompilerOptions() {
181 const lto::Config &
C = getConfig();
182 auto &
Ops = DistributorParams.CodegenOptions;
184 Ops.push_back(Saver.save(
"-O" + Twine(
C.OptLevel)));
186 if (
C.Options.EmitAddrsig)
187 Ops.push_back(
"-faddrsig");
188 if (
C.Options.FunctionSections)
189 Ops.push_back(
"-ffunction-sections");
190 if (
C.Options.DataSections)
191 Ops.push_back(
"-fdata-sections");
195 if (!DistributorParams.TargetTriple.isOSBinFormatCOFF())
196 Ops.push_back(
"-fpic");
200 if (!
C.PGOWarnMismatch) {
201 Ops.push_back(
"-mllvm");
202 Ops.push_back(
"-no-pgo-warn-mismatch");
207 if (!
C.SampleProfile.empty()) {
208 Ops.push_back(Saver.save(
"-fprofile-sample-use=" + Twine(
C.SampleProfile)));
209 DistributorParams.CommonInputs.insert(
C.SampleProfile);
213 Ops.push_back(
"-Wno-unused-command-line-argument");
216 if (!DistributorParams.RemoteCompilerArgs.empty())
217 for (
auto &a : DistributorParams.RemoteCompilerArgs)
222Error lto::DTLTO::prepareDtltoJobs() {
224 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
226 if (ModuleMap.empty())
229 Jobs.resize(ModuleMap.size());
232 if (
Error E = prepareDtltoJob(
Mod.first, ThinLTOTaskOffset +
I))
239Error lto::DTLTO::performCodegen() {
243 buildCommonRemoteCompilerOptions();
246 [&](StringRef S) { addToCleanup(S); });
248 if (CachedJobs.load() < Jobs.size()) {
249 if (
Error E = Distributor())
256Error lto::DTLTO::addObjectFilesToLink() {
257 TimeTraceScope FilesScope(
"Add DTLTO files to the link");
258 for (
auto &Job : Jobs) {
259 if (!Job.CacheKey.empty() && Job.Cached) {
265 auto ObjFileMbOrErr =
268 if (std::error_code EC = ObjFileMbOrErr.getError())
270 BCError +
"cannot open native object file: " + Job.NativeObjectPath +
274 MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();
275 if (Cache.isValid()) {
278 assert(Job.CacheAddStream);
280 auto CachedFileStreamOrErr = Job.CacheAddStream(Job.Task, Job.ModuleID);
281 if (!CachedFileStreamOrErr)
283 CachedFileStreamOrErr.takeError(),
285 "Cannot get a cache file stream: %s",
286 Job.NativeObjectPath.data()));
288 auto &CacheStream = *(CachedFileStreamOrErr->get());
289 *(CacheStream.OS) << ObjFileMbRef.
getBuffer();
290 if (
Error Err = CacheStream.commit())
294 AddBuffer(Job.Task, Job.ModuleID, std::move(ObjFileMbOrErr.get()));
296 auto StreamOrErr = AddStreamFunc(Job.Task, Job.ModuleID);
297 if (
Error Err = StreamOrErr.takeError())
299 auto &Stream = *StreamOrErr->get();
301 if (
Error Err = Stream.commit())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void cleanup(BlockFrequencyInfoImplBase &BFI)
Clear all memory not needed downstream.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Provides a library for accessing information about this process and other processes on the operating ...
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallString class.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
StringRef getBuffer() const
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
virtual LLVM_ABI Error run(AddStreamFn AddStream, FileCache Cache={}) override
Runs the DTLTO pipeline.
struct llvm::lto::LTO::RegularLTOState RegularLTO
static LLVM_ABI Pid getProcessId()
Get the process's identifier.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
LLVM_ABI StringRef stem(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get stem.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Mod
The access may modify the value stored in memory.
std::string join(IteratorT Begin, IteratorT End, StringRef Separator)
Joins the strings in the range [Begin, End), adding Separator between the elements.
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.
std::string itostr(int64_t X)
This type represents a file cache system that manages caching of files.
std::function< std::string &(size_t Task)> GetCacheKeyOutputString
Called by WriteIndexesThinBackend when it needs to store a bitcode module's cache key.
std::function< std::vector< std::string > &(size_t Task)> GetImportsListOutputArray
Called by WriteIndexesThinBackend when it needs to store a bitcode module's imports list.
std::function< std::unique_ptr< raw_pwrite_stream >(size_t Task)> GetSummaryIndexOutputStream
Called by WriteIndexesThinBackend when it needs to write a bitcode module's summary index.