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 TimeTraceScope TimeScope(
"Check cache for DTLTO", J.SummaryIndexPath);
109 auto CacheAddStreamExp = Cache(J.Task, J.CacheKey, J.ModuleID);
110 if (
Error Err = CacheAddStreamExp.takeError())
115 if (!CacheAddStream) {
117 CachedJobs.fetch_add(1);
122 J.CacheAddStream = std::move(CacheAddStream);
128Error lto::DTLTO::prepareDtltoJob(StringRef ModulePath,
unsigned Task) {
129 assert(Task >= ThinLTOTaskOffset && Task - ThinLTOTaskOffset < Jobs.size() &&
130 "Task index out of range for Jobs");
131 assert(Task < SummaryIndexFiles.size() &&
"Task index out of range");
133 SString ObjFilePath =
136 itostr(Task) +
"." + UID +
".native.o");
138 SString SummaryIndexPathStr = ObjFilePath;
139 SummaryIndexPathStr +=
".thinlto.bc";
140 SString ImportsPathStr = ModulePath;
141 ImportsPathStr +=
".imports";
143 Job &J = Jobs[Task - ThinLTOTaskOffset];
146 Saver.save(ObjFilePath.str()),
147 Saver.save(SummaryIndexPathStr.str()),
148 Saver.save(ImportsPathStr.str()),
149 ImportsFilesList[Task],
154 if (
Error Err = checkCacheHit(J))
157 TimeTraceScope JobScope(
"Emit individual index for DTLTO",
159 if (
Error Err = save(SummaryIndexFiles[Task], J.SummaryIndexPath))
163 OnIndexWriteCb(J.SummaryIndexPath.str());
165 if (ShouldEmitImportFiles)
166 if (
Error Err = save(
join(J.ImportsFilesList,
"\n"), J.ImportsPath))
171 addToCleanup(J.NativeObjectPath.str());
172 if (!ShouldEmitIndexFiles)
173 addToCleanup(J.SummaryIndexPath.str());
174 if (!ShouldEmitImportFiles)
175 addToCleanup(J.ImportsPath.str());
182void lto::DTLTO::buildCommonRemoteCompilerOptions() {
183 const lto::Config &
C = getConfig();
184 auto &
Ops = DistributorParams.CodegenOptions;
186 Ops.push_back(Saver.save(
"-O" + Twine(
C.OptLevel)));
188 if (
C.Options.EmitAddrsig)
189 Ops.push_back(
"-faddrsig");
190 if (
C.Options.FunctionSections)
191 Ops.push_back(
"-ffunction-sections");
192 if (
C.Options.DataSections)
193 Ops.push_back(
"-fdata-sections");
197 if (!DistributorParams.TargetTriple.isOSBinFormatCOFF())
198 Ops.push_back(
"-fpic");
202 if (!
C.PGOWarnMismatch) {
203 Ops.push_back(
"-mllvm");
204 Ops.push_back(
"-no-pgo-warn-mismatch");
209 if (!
C.SampleProfile.empty()) {
210 Ops.push_back(Saver.save(
"-fprofile-sample-use=" + Twine(
C.SampleProfile)));
211 DistributorParams.CommonInputs.insert(
C.SampleProfile);
215 Ops.push_back(
"-Wno-unused-command-line-argument");
218 if (!DistributorParams.RemoteCompilerArgs.empty())
219 for (
auto &a : DistributorParams.RemoteCompilerArgs)
224Error lto::DTLTO::prepareDtltoJobs() {
226 ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap;
228 if (ModuleMap.empty())
231 Jobs.resize(ModuleMap.size());
234 if (
Error E = prepareDtltoJob(
Mod.first, ThinLTOTaskOffset +
I))
241Error lto::DTLTO::performCodegen() {
245 buildCommonRemoteCompilerOptions();
248 [&](StringRef S) { addToCleanup(S); });
250 if (CachedJobs.load() < Jobs.size()) {
251 if (
Error E = Distributor())
258Error lto::DTLTO::addObjectFilesToLink() {
259 TimeTraceScope FilesScope(
"Add DTLTO files to the link");
260 for (
auto &Job : Jobs) {
261 if (!Job.CacheKey.empty() && Job.Cached) {
267 auto ObjFileMbOrErr =
270 if (std::error_code EC = ObjFileMbOrErr.getError())
272 BCError +
"cannot open native object file: " + Job.NativeObjectPath +
276 MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();
277 if (Cache.isValid()) {
280 assert(Job.CacheAddStream);
282 auto CachedFileStreamOrErr = Job.CacheAddStream(Job.Task, Job.ModuleID);
283 if (!CachedFileStreamOrErr)
285 CachedFileStreamOrErr.takeError(),
287 "Cannot get a cache file stream: %s",
288 Job.NativeObjectPath.data()));
290 auto &CacheStream = *(CachedFileStreamOrErr->get());
291 *(CacheStream.OS) << ObjFileMbRef.
getBuffer();
292 if (
Error Err = CacheStream.commit())
296 AddBuffer(Job.Task, Job.ModuleID, std::move(ObjFileMbOrErr.get()));
298 auto StreamOrErr = AddStreamFunc(Job.Task, Job.ModuleID);
299 if (
Error Err = StreamOrErr.takeError())
301 auto &Stream = *StreamOrErr->get();
303 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,...
The TimeTraceScope is a helper class to call the begin and end functions of the time trace profiler.
virtual 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.