[lld] [llvm] [DTLTO] Add DTLTO time traces (and llvm-lto2 time tracing to test) (PR #171600)
Ben Dunbobbin via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 10 03:02:28 PST 2025
https://github.com/bd1976bris created https://github.com/llvm/llvm-project/pull/171600
The primary goal of this patch is to add a comprehensive set of DTLTO time traces.
I also have implemented support for time traces in llvm-lto2, to allow for adding a test via Lit.
>From 919c2dc80057ff035c56b9bb60c29d767a8c65d9 Mon Sep 17 00:00:00 2001
From: Ben <ben.dunbobbin at sony.com>
Date: Thu, 27 Nov 2025 01:58:04 +0000
Subject: [PATCH 1/5] Add scopes without changing indentation
---
llvm/lib/LTO/LTO.cpp | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index a02af59600c44..47abeb4a2a8b0 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -2289,13 +2289,13 @@ class OutOfProcessThinBackend : public CGThinBackend {
const FunctionImporter::ExportSetTy &ExportList,
const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
&ResolvedODR) {
-
- llvm::TimeTraceScope timeScope(
- "Run ThinLTO backend thread (out-of-process)", J.ModuleID);
-
+ {
+ TimeTraceScope TimeScope("Emit individual index for DTLTO",
+ J.SummaryIndexPath);
if (auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
J.SummaryIndexPath, J.ImportsFiles))
return E;
+ }
if (!Cache.isValid() || !CombinedIndex.modulePaths().count(J.ModuleID) ||
all_of(CombinedIndex.getModuleHash(J.ModuleID),
@@ -2304,6 +2304,7 @@ class OutOfProcessThinBackend : public CGThinBackend {
// no module hash.
return Error::success();
+ TimeTraceScope TimeScope("Check cache for DTLTO", J.SummaryIndexPath);
const GVSummaryMapTy &DefinedGlobals =
ModuleToDefinedGVSummaries.find(J.ModuleID)->second;
@@ -2363,6 +2364,10 @@ class OutOfProcessThinBackend : public CGThinBackend {
const FunctionImporter::ExportSetTy &ExportList,
const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>
&ResolvedODR) {
+ if (LLVM_ENABLE_THREADS && Conf.TimeTraceEnabled)
+ timeTraceProfilerInitialize(
+ Conf.TimeTraceGranularity,
+ "Emit individual index and check cache for DTLTO");
Error E =
runThinLTOBackendThread(J, ImportList, ExportList, ResolvedODR);
if (E) {
@@ -2372,6 +2377,8 @@ class OutOfProcessThinBackend : public CGThinBackend {
else
Err = std::move(E);
}
+ if (LLVM_ENABLE_THREADS && Conf.TimeTraceEnabled)
+ timeTraceProfilerFinishThread();
},
std::ref(J), std::ref(ImportList), std::ref(ExportList),
std::ref(ResolvedODR));
@@ -2520,6 +2527,7 @@ class OutOfProcessThinBackend : public CGThinBackend {
return std::move(*Err);
auto CleanPerJobFiles = llvm::make_scope_exit([&] {
+ llvm::TimeTraceScope TimeScope("Remove DTLTO temporary files");
if (!SaveTemps)
for (auto &Job : Jobs) {
removeFile(Job.NativeObjectPath);
@@ -2533,17 +2541,23 @@ class OutOfProcessThinBackend : public CGThinBackend {
buildCommonRemoteCompilerOptions();
SString JsonFile = sys::path::parent_path(LinkerOutputFile);
+ {
+ llvm::TimeTraceScope TimeScope("Emit DTLTO JSON");
sys::path::append(JsonFile, sys::path::stem(LinkerOutputFile) + "." + UID +
".dist-file.json");
if (!emitDistributorJson(JsonFile))
return make_error<StringError>(
BCError + "failed to generate distributor JSON script: " + JsonFile,
inconvertibleErrorCode());
+ }
auto CleanJson = llvm::make_scope_exit([&] {
if (!SaveTemps)
removeFile(JsonFile);
});
+ {
+ llvm::TimeTraceScope TimeScope("Execute DTLTO distributor",
+ DistributorPath);
// Checks if we have any jobs that don't have corresponding cache entries.
if (CachedJobs.load() < Jobs.size()) {
SmallVector<StringRef, 3> Args = {DistributorPath};
@@ -2560,7 +2574,10 @@ class OutOfProcessThinBackend : public CGThinBackend {
inconvertibleErrorCode());
}
}
+ }
+ {
+ llvm::TimeTraceScope FilesScope("Add DTLTO files to the link");
for (auto &Job : Jobs) {
if (!Job.CacheKey.empty() && Job.Cached) {
assert(Cache.isValid());
@@ -2605,6 +2622,7 @@ class OutOfProcessThinBackend : public CGThinBackend {
report_fatal_error(std::move(Err));
}
}
+ }
return Error::success();
}
};
>From 73576ff12378b37d62b06f242664e43629e55bb3 Mon Sep 17 00:00:00 2001
From: Ben <ben.dunbobbin at sony.com>
Date: Thu, 27 Nov 2025 02:01:05 +0000
Subject: [PATCH 2/5] Apply clang-format
---
llvm/lib/LTO/LTO.cpp | 135 ++++++++++++++++++++++---------------------
1 file changed, 68 insertions(+), 67 deletions(-)
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp
index 47abeb4a2a8b0..32bb415ccd518 100644
--- a/llvm/lib/LTO/LTO.cpp
+++ b/llvm/lib/LTO/LTO.cpp
@@ -2292,9 +2292,9 @@ class OutOfProcessThinBackend : public CGThinBackend {
{
TimeTraceScope TimeScope("Emit individual index for DTLTO",
J.SummaryIndexPath);
- if (auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
- J.SummaryIndexPath, J.ImportsFiles))
- return E;
+ if (auto E = emitFiles(ImportList, J.ModuleID, J.ModuleID.str(),
+ J.SummaryIndexPath, J.ImportsFiles))
+ return E;
}
if (!Cache.isValid() || !CombinedIndex.modulePaths().count(J.ModuleID) ||
@@ -2543,12 +2543,12 @@ class OutOfProcessThinBackend : public CGThinBackend {
SString JsonFile = sys::path::parent_path(LinkerOutputFile);
{
llvm::TimeTraceScope TimeScope("Emit DTLTO JSON");
- sys::path::append(JsonFile, sys::path::stem(LinkerOutputFile) + "." + UID +
- ".dist-file.json");
- if (!emitDistributorJson(JsonFile))
- return make_error<StringError>(
- BCError + "failed to generate distributor JSON script: " + JsonFile,
- inconvertibleErrorCode());
+ sys::path::append(JsonFile, sys::path::stem(LinkerOutputFile) + "." +
+ UID + ".dist-file.json");
+ if (!emitDistributorJson(JsonFile))
+ return make_error<StringError>(
+ BCError + "failed to generate distributor JSON script: " + JsonFile,
+ inconvertibleErrorCode());
}
auto CleanJson = llvm::make_scope_exit([&] {
if (!SaveTemps)
@@ -2558,71 +2558,72 @@ class OutOfProcessThinBackend : public CGThinBackend {
{
llvm::TimeTraceScope TimeScope("Execute DTLTO distributor",
DistributorPath);
- // Checks if we have any jobs that don't have corresponding cache entries.
- if (CachedJobs.load() < Jobs.size()) {
- SmallVector<StringRef, 3> Args = {DistributorPath};
- llvm::append_range(Args, DistributorArgs);
- Args.push_back(JsonFile);
- std::string ErrMsg;
- if (sys::ExecuteAndWait(Args[0], Args,
- /*Env=*/std::nullopt, /*Redirects=*/{},
- /*SecondsToWait=*/0, /*MemoryLimit=*/0,
- &ErrMsg)) {
- return make_error<StringError>(
- BCError + "distributor execution failed" +
- (!ErrMsg.empty() ? ": " + ErrMsg + Twine(".") : Twine(".")),
- inconvertibleErrorCode());
+ // Checks if we have any jobs that don't have corresponding cache entries.
+ if (CachedJobs.load() < Jobs.size()) {
+ SmallVector<StringRef, 3> Args = {DistributorPath};
+ llvm::append_range(Args, DistributorArgs);
+ Args.push_back(JsonFile);
+ std::string ErrMsg;
+ if (sys::ExecuteAndWait(Args[0], Args,
+ /*Env=*/std::nullopt, /*Redirects=*/{},
+ /*SecondsToWait=*/0, /*MemoryLimit=*/0,
+ &ErrMsg)) {
+ return make_error<StringError>(
+ BCError + "distributor execution failed" +
+ (!ErrMsg.empty() ? ": " + ErrMsg + Twine(".") : Twine(".")),
+ inconvertibleErrorCode());
+ }
}
}
- }
{
llvm::TimeTraceScope FilesScope("Add DTLTO files to the link");
- for (auto &Job : Jobs) {
- if (!Job.CacheKey.empty() && Job.Cached) {
- assert(Cache.isValid());
- continue;
- }
- // Load the native object from a file into a memory buffer
- // and store its contents in the output buffer.
- auto ObjFileMbOrErr =
- MemoryBuffer::getFile(Job.NativeObjectPath, /*IsText=*/false,
- /*RequiresNullTerminator=*/false);
- if (std::error_code EC = ObjFileMbOrErr.getError())
- return make_error<StringError>(
- BCError + "cannot open native object file: " +
- Job.NativeObjectPath + ": " + EC.message(),
- inconvertibleErrorCode());
-
- MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();
- if (Cache.isValid()) {
- // Cache hits are taken care of earlier. At this point, we could only
- // have cache misses.
- assert(Job.CacheAddStream);
- // Obtain a file stream for a storing a cache entry.
- auto CachedFileStreamOrErr = Job.CacheAddStream(Job.Task, Job.ModuleID);
- if (!CachedFileStreamOrErr)
- return joinErrors(
- CachedFileStreamOrErr.takeError(),
- createStringError(inconvertibleErrorCode(),
- "Cannot get a cache file stream: %s",
- Job.NativeObjectPath.data()));
- // Store a file buffer into the cache stream.
- auto &CacheStream = *(CachedFileStreamOrErr->get());
- *(CacheStream.OS) << ObjFileMbRef.getBuffer();
- if (Error Err = CacheStream.commit())
- return Err;
- } else {
- auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
- if (Error Err = StreamOrErr.takeError())
- report_fatal_error(std::move(Err));
- auto &Stream = *StreamOrErr->get();
- *Stream.OS << ObjFileMbRef.getBuffer();
- if (Error Err = Stream.commit())
- report_fatal_error(std::move(Err));
+ for (auto &Job : Jobs) {
+ if (!Job.CacheKey.empty() && Job.Cached) {
+ assert(Cache.isValid());
+ continue;
+ }
+ // Load the native object from a file into a memory buffer
+ // and store its contents in the output buffer.
+ auto ObjFileMbOrErr =
+ MemoryBuffer::getFile(Job.NativeObjectPath, /*IsText=*/false,
+ /*RequiresNullTerminator=*/false);
+ if (std::error_code EC = ObjFileMbOrErr.getError())
+ return make_error<StringError>(
+ BCError + "cannot open native object file: " +
+ Job.NativeObjectPath + ": " + EC.message(),
+ inconvertibleErrorCode());
+
+ MemoryBufferRef ObjFileMbRef = ObjFileMbOrErr->get()->getMemBufferRef();
+ if (Cache.isValid()) {
+ // Cache hits are taken care of earlier. At this point, we could only
+ // have cache misses.
+ assert(Job.CacheAddStream);
+ // Obtain a file stream for a storing a cache entry.
+ auto CachedFileStreamOrErr =
+ Job.CacheAddStream(Job.Task, Job.ModuleID);
+ if (!CachedFileStreamOrErr)
+ return joinErrors(
+ CachedFileStreamOrErr.takeError(),
+ createStringError(inconvertibleErrorCode(),
+ "Cannot get a cache file stream: %s",
+ Job.NativeObjectPath.data()));
+ // Store a file buffer into the cache stream.
+ auto &CacheStream = *(CachedFileStreamOrErr->get());
+ *(CacheStream.OS) << ObjFileMbRef.getBuffer();
+ if (Error Err = CacheStream.commit())
+ return Err;
+ } else {
+ auto StreamOrErr = AddStream(Job.Task, Job.ModuleID);
+ if (Error Err = StreamOrErr.takeError())
+ report_fatal_error(std::move(Err));
+ auto &Stream = *StreamOrErr->get();
+ *Stream.OS << ObjFileMbRef.getBuffer();
+ if (Error Err = Stream.commit())
+ report_fatal_error(std::move(Err));
+ }
}
}
- }
return Error::success();
}
};
>From 2d6432ca4e01af29005eea7a9d71c80eccff935e Mon Sep 17 00:00:00 2001
From: Ben <ben.dunbobbin at sony.com>
Date: Thu, 27 Nov 2025 02:02:52 +0000
Subject: [PATCH 3/5] Add Lit test
---
lld/test/ELF/dtlto/timetrace.test | 70 +++++++++++++++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 lld/test/ELF/dtlto/timetrace.test
diff --git a/lld/test/ELF/dtlto/timetrace.test b/lld/test/ELF/dtlto/timetrace.test
new file mode 100644
index 0000000000000..8b6ff80d1647a
--- /dev/null
+++ b/lld/test/ELF/dtlto/timetrace.test
@@ -0,0 +1,70 @@
+REQUIRES: x86
+
+## Test that the LLD produces expected time trace output for DTLTO.
+
+RUN: rm -rf %t && split-file %s %t && cd %t
+
+RUN: sed 's/@t1/@t2/g' t1.ll > t2.ll
+
+## Generate ThinLTO bitcode files.
+RUN: opt -thinlto-bc t1.ll -o t1.bc
+RUN: opt -thinlto-bc t2.ll -o t2.bc
+
+## Generate object files for mock.py to return.
+RUN: llc t1.ll --filetype=obj -o t1.o
+RUN: llc t2.ll --filetype=obj -o t2.o
+
+## Link and generate a time trace.
+## Note: mock.py doesn’t compile; it copies the specified object files to the
+## outputs in job order.
+RUN: ld.lld t1.bc t2.bc -o my.elf \
+RUN: --thinlto-distributor=%python \
+RUN: --thinlto-distributor-arg=%llvm_src_root/utils/dtlto/mock.py \
+RUN: --thinlto-distributor-arg=t1.o --thinlto-distributor-arg=t2.o \
+RUN: --time-trace-granularity=0 --time-trace=%t.json
+RUN: %python filter_order_and_pprint.py %t.json | FileCheck %s
+
+## Check that DTLTO events are recorded.
+CHECK-NOT: "name"
+CHECK: "name": "Add DTLTO files to the link"
+CHECK-SAME: "pid": [[#PID:]],
+CHECK-NEXT: "name": "Emit DTLTO JSON"
+CHECK-NEXT: "name": "Emit individual index for DTLTO"
+CHECK-SAME: t1.1.[[#PID]].native.o.thinlto.bc"
+CHECK-NEXT: "name": "Emit individual index for DTLTO"
+CHECK-SAME: t2.2.[[#PID]].native.o.thinlto.bc"
+CHECK-NEXT: "name": "Execute DTLTO distributor", "{{.*}}"
+CHECK-NEXT: "name": "Remove DTLTO temporary files"
+CHECK-NEXT: "name": "Total Add DTLTO files to the link"
+CHECK-SAME: "count": 1,
+CHECK-NEXT: "name": "Total Emit DTLTO JSON"
+CHECK-SAME: "count": 1,
+CHECK-NEXT: "name": "Total Emit individual index for DTLTO"
+CHECK-SAME: "count": 2,
+CHECK-NEXT: "name": "Total Execute DTLTO distributor"
+CHECK-SAME: "count": 1,
+CHECK-NEXT: "name": "Total Remove DTLTO temporary files"
+CHECK-SAME: "count": 1,
+CHECK-NOT: "name"
+
+#--- t1.ll
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @t1() {
+ ret void
+}
+
+#--- filter_order_and_pprint.py
+import json, sys
+
+data = json.load(open(sys.argv[1], "r", encoding="utf-8"))
+
+# Get DTLTO events.
+events = [e for e in data["traceEvents"] if "DTLTO" in e["name"]]
+events.sort(key=lambda e: (e["name"], str(e.get("args", {}).get("detail", ""))))
+
+# Print an event per line. Ensure 'name' is the first key.
+for ev in events:
+ name = ev.pop("name")
+ print(json.dumps({"name": name, **ev}))
>From c2e58b76c5ace9a59c6e0f94a65aaedc33d25c20 Mon Sep 17 00:00:00 2001
From: Ben <ben.dunbobbin at sony.com>
Date: Wed, 10 Dec 2025 10:49:14 +0000
Subject: [PATCH 4/5] [DTLTO] Add llvm-lto2 time tracing and test DTLTO time
traces
---
.../test/ThinLTO/X86/dtlto/timetrace.ll | 43 +++++++++++--------
llvm/tools/llvm-lto2/llvm-lto2.cpp | 34 ++++++++++++++-
2 files changed, 57 insertions(+), 20 deletions(-)
rename lld/test/ELF/dtlto/timetrace.test => llvm/test/ThinLTO/X86/dtlto/timetrace.ll (62%)
diff --git a/lld/test/ELF/dtlto/timetrace.test b/llvm/test/ThinLTO/X86/dtlto/timetrace.ll
similarity index 62%
rename from lld/test/ELF/dtlto/timetrace.test
rename to llvm/test/ThinLTO/X86/dtlto/timetrace.ll
index 8b6ff80d1647a..cab9fa04a3bb9 100644
--- a/lld/test/ELF/dtlto/timetrace.test
+++ b/llvm/test/ThinLTO/X86/dtlto/timetrace.ll
@@ -1,27 +1,23 @@
-REQUIRES: x86
-
-## Test that the LLD produces expected time trace output for DTLTO.
+; Test that the LLD produces expected time trace output for DTLTO.
RUN: rm -rf %t && split-file %s %t && cd %t
-RUN: sed 's/@t1/@t2/g' t1.ll > t2.ll
-
-## Generate ThinLTO bitcode files.
+; Generate bitcode files with summary.
RUN: opt -thinlto-bc t1.ll -o t1.bc
RUN: opt -thinlto-bc t2.ll -o t2.bc
-## Generate object files for mock.py to return.
-RUN: llc t1.ll --filetype=obj -o t1.o
-RUN: llc t2.ll --filetype=obj -o t2.o
+; Generate fake object files for mock.py to return.
+RUN: touch t1.o t2.o
-## Link and generate a time trace.
-## Note: mock.py doesn’t compile; it copies the specified object files to the
-## outputs in job order.
-RUN: ld.lld t1.bc t2.bc -o my.elf \
-RUN: --thinlto-distributor=%python \
-RUN: --thinlto-distributor-arg=%llvm_src_root/utils/dtlto/mock.py \
-RUN: --thinlto-distributor-arg=t1.o --thinlto-distributor-arg=t2.o \
-RUN: --time-trace-granularity=0 --time-trace=%t.json
+; Perform DTLTO and generate a time trace. mock.py does not do any compilation,
+; instead it simply writes the contents of the object files supplied on the
+; command line into the output object files in job order.
+RUN: llvm-lto2 run t1.bc t2.bc -o t.o \
+RUN: -dtlto-distributor=%python \
+RUN: -dtlto-distributor-arg=%llvm_src_root/utils/dtlto/mock.py,t1.o,t2.o \
+RUN: --time-trace --time-trace-granularity=0 --time-trace-file=%t.json \
+RUN: -r=t1.bc,t1,px \
+RUN: -r=t2.bc,t2,px
RUN: %python filter_order_and_pprint.py %t.json | FileCheck %s
## Check that DTLTO events are recorded.
@@ -47,14 +43,22 @@ CHECK-NEXT: "name": "Total Remove DTLTO temporary files"
CHECK-SAME: "count": 1,
CHECK-NOT: "name"
-#--- t1.ll
-target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+;--- t1.ll
target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
define void @t1() {
ret void
}
+;--- t2.ll
+target triple = "x86_64-unknown-linux-gnu"
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
+
+define void @t2() {
+ ret void
+}
+
#--- filter_order_and_pprint.py
import json, sys
@@ -68,3 +72,4 @@ events.sort(key=lambda e: (e["name"], str(e.get("args", {}).get("detail", ""))))
for ev in events:
name = ev.pop("name")
print(json.dumps({"name": name, **ev}))
+
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index 399306f39daeb..c437f1448b763 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -15,6 +15,7 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ScopeExit.h"
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/IR/DiagnosticPrinter.h"
@@ -28,6 +29,7 @@
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Threading.h"
+#include "llvm/Support/TimeProfiler.h"
#include <atomic>
using namespace llvm;
@@ -232,6 +234,19 @@ static cl::opt<bool>
AllVtablesHaveTypeInfos("all-vtables-have-type-infos", cl::Hidden,
cl::desc("All vtables have type infos"));
+static cl::opt<bool> TimeTrace("time-trace", cl::desc("Record time trace"));
+
+static cl::opt<unsigned> TimeTraceGranularity(
+ "time-trace-granularity",
+ cl::desc(
+ "Minimum time granularity (in microseconds) traced by time profiler"),
+ cl::init(500), cl::Hidden);
+
+static cl::opt<std::string>
+ TimeTraceFile("time-trace-file",
+ cl::desc("Specify time trace file destination"),
+ cl::value_desc("filename"));
+
static void check(Error E, std::string Msg) {
if (!E)
return;
@@ -267,6 +282,20 @@ static int usage() {
static int run(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, "Resolution-based LTO test harness");
+ if (TimeTrace)
+ timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]);
+ auto TimeTraceScopeExit = make_scope_exit([]() {
+ if (TimeTrace) {
+ if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
+ handleAllErrors(std::move(E), [&](const StringError &SE) {
+ errs() << SE.getMessage() << "\n";
+ });
+ return;
+ }
+ timeTraceProfilerCleanup();
+ }
+ });
+
// FIXME: Workaround PR30396 which means that a symbol can appear
// more than once if it is defined in module-level assembly and
// has a GV declaration. We allow (file, symbol) pairs to have multiple
@@ -304,7 +333,10 @@ static int run(int argc, char **argv) {
std::vector<std::unique_ptr<MemoryBuffer>> MBs;
Config Conf;
-
+ if (TimeTrace) {
+ Conf.TimeTraceEnabled = TimeTrace;
+ Conf.TimeTraceGranularity = TimeTraceGranularity;
+ }
Conf.CPU = codegen::getMCPU();
Conf.Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple());
Conf.MAttrs = codegen::getMAttrs();
>From 6762e05014941a03692e173bdbcd828af6c21973 Mon Sep 17 00:00:00 2001
From: Ben <ben.dunbobbin at sony.com>
Date: Wed, 10 Dec 2025 10:56:02 +0000
Subject: [PATCH 5/5] Use llvm-lto2 error handling helpers to simplify
---
llvm/tools/llvm-lto2/llvm-lto2.cpp | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/llvm/tools/llvm-lto2/llvm-lto2.cpp b/llvm/tools/llvm-lto2/llvm-lto2.cpp
index c437f1448b763..ca6864cbf9b91 100644
--- a/llvm/tools/llvm-lto2/llvm-lto2.cpp
+++ b/llvm/tools/llvm-lto2/llvm-lto2.cpp
@@ -286,12 +286,8 @@ static int run(int argc, char **argv) {
timeTraceProfilerInitialize(TimeTraceGranularity, argv[0]);
auto TimeTraceScopeExit = make_scope_exit([]() {
if (TimeTrace) {
- if (auto E = timeTraceProfilerWrite(TimeTraceFile, OutputFilename)) {
- handleAllErrors(std::move(E), [&](const StringError &SE) {
- errs() << SE.getMessage() << "\n";
- });
- return;
- }
+ check(timeTraceProfilerWrite(TimeTraceFile, OutputFilename),
+ "timeTraceProfilerWrite failed");
timeTraceProfilerCleanup();
}
});
More information about the llvm-commits
mailing list