[clang] [lld] [llvm] [llvm][lld][clang] Delay initializing TargetOptions in LTO builds until a Triple is available (PR #179509)
Paul Kirth via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 10 09:56:46 PST 2026
================
@@ -46,47 +46,52 @@ static std::string getThinLTOOutputFile(Ctx &ctx, StringRef modulePath) {
static lto::Config createConfig(Ctx &ctx) {
lto::Config c;
- // LLD supports the new relocations and address-significance tables.
- c.Options = initTargetOptionsFromCodeGenFlags();
- c.Options.EmitAddrsig = true;
- for (StringRef C : ctx.arg.mllvmOpts)
- c.MllvmArgs.emplace_back(C.str());
-
- // Always emit a section per function/datum with LTO.
- c.Options.FunctionSections = true;
- c.Options.DataSections = true;
-
- // Check if basic block sections must be used.
- // Allowed values for --lto-basic-block-sections are "all",
- // "<file name specifying basic block ids>", or none. This is the equivalent
- // of -fbasic-block-sections= flag in clang.
- if (!ctx.arg.ltoBasicBlockSections.empty()) {
- if (ctx.arg.ltoBasicBlockSections == "all") {
- c.Options.BBSections = BasicBlockSection::All;
- } else if (ctx.arg.ltoBasicBlockSections == "labels") {
- c.Options.BBAddrMap = true;
- Warn(ctx)
- << "'--lto-basic-block-sections=labels' is deprecated; Please use "
- "'--lto-basic-block-address-map' instead";
- } else if (ctx.arg.ltoBasicBlockSections == "none") {
- c.Options.BBSections = BasicBlockSection::None;
- } else {
- ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
- MemoryBuffer::getFile(ctx.arg.ltoBasicBlockSections.str());
- if (!MBOrErr) {
- ErrAlways(ctx) << "cannot open " << ctx.arg.ltoBasicBlockSections << ":"
- << MBOrErr.getError().message();
+ // Set up the callback to modify TargetOptions.
+ c.ModifyTargetOptions = [&](TargetOptions &Options) -> void {
+ // LLD supports the new relocations and address-significance tables.
+ Options.EmitAddrsig = true;
+ // Always emit a section per function/datum with LTO.
+ Options.FunctionSections = true;
+ Options.DataSections = true;
+
+ // Check if basic block sections must be used.
+ // Allowed values for --lto-basic-block-sections are "all",
+ // "<file name specifying basic block ids>", or none. This is the
+ // equivalent of -fbasic-block-sections= flag in clang.
+ if (!ctx.arg.ltoBasicBlockSections.empty()) {
+ if (ctx.arg.ltoBasicBlockSections == "all") {
+ Options.BBSections = BasicBlockSection::All;
+ } else if (ctx.arg.ltoBasicBlockSections == "labels") {
+ Options.BBAddrMap = true;
+ Warn(ctx)
+ << "'--lto-basic-block-sections=labels' is deprecated; Please use "
+ "'--lto-basic-block-address-map' instead";
+ } else if (ctx.arg.ltoBasicBlockSections == "none") {
+ Options.BBSections = BasicBlockSection::None;
} else {
- c.Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+ MemoryBuffer::getFile(ctx.arg.ltoBasicBlockSections.str());
----------------
ilovepi wrote:
I'm pretty sure we always only call the callback once. I also tried just duping the conditional block w/ all the options above the lambda. That almost works, but something in the move capture is breaking and I don't understand what the issue is, since i just did` [MB = std::move(*MBOrErr), ...]`, which (AFAIK) is the only way to move `std::unique_ptr<T>` into a closure.
```console
/usr/local/google/home/paulkirth/llvm-fork/lld/ELF/LTO.cpp:94:41: error: no viable overloaded '='
94 | options.BBSectionsFuncListBuf = std::move(MB);
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~
/usr/local/google/home/paulkirth/fuchsia/prebuilt/third_party/clang/linux-x64/bin/../include/c++/v1/__memory/shared_ptr.h:504:42: note: candidate function not viable: no known conversion from '__libcpp_remove_reference_t<const std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>> &>' (aka 'const std::unique_ptr<llvm::MemoryBuffer>') to 'const shared_ptr<llvm::MemoryBuffer>' for 1st argument
504 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(const shared_ptr& __r) _NOEXCEPT {
| ^ ~~~~~~~~~~~~~~~~~~~~~
/usr/local/google/home/paulkirth/fuchsia/prebuilt/third_party/clang/linux-x64/bin/../include/c++/v1/__memory/shared_ptr.h:515:42: note: candidate function not viable: no known conversion from '__libcpp_remove_reference_t<const std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>> &>' (aka 'const std::unique_ptr<llvm::MemoryBuffer>') to 'shared_ptr<llvm::MemoryBuffer>' for 1st argument
515 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr&& __r) _NOEXCEPT {
| ^ ~~~~~~~~~~~~~~~~
/usr/local/google/home/paulkirth/fuchsia/prebuilt/third_party/clang/linux-x64/bin/../include/c++/v1/__memory/shared_ptr.h:510:42: note: candidate template ignored: could not match 'shared_ptr' against 'std::unique_ptr'
510 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(const shared_ptr<_Yp>& __r) _NOEXCEPT {
| ^
/usr/local/google/home/paulkirth/fuchsia/prebuilt/third_party/clang/linux-x64/bin/../include/c++/v1/__memory/shared_ptr.h:521:42: note: candidate template ignored: could not match 'shared_ptr' against 'std::unique_ptr'
521 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(shared_ptr<_Yp>&& __r) {
| ^
/usr/local/google/home/paulkirth/fuchsia/prebuilt/third_party/clang/linux-x64/bin/../include/c++/v1/__memory/shared_ptr.h:541:42: note: candidate template ignored: deduced type 'unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>>' of 1st parameter does not match adjusted type '__libcpp_remove_reference_t<const std::unique_ptr<llvm::MemoryBuffer, std::default_delete<llvm::MemoryBuffer>> &>' (aka 'const std::unique_ptr<llvm::MemoryBuffer>') of argument [with _Yp = llvm::MemoryBuffer, _Dp = std::default_delete<llvm::MemoryBuffer>, $2 = 0]
541 | _LIBCPP_HIDE_FROM_ABI shared_ptr<_Tp>& operator=(unique_ptr<_Yp, _Dp>&& __r) {
| ^
```
Maybe something odd with `__libcpp_remove_ref`?
https://github.com/llvm/llvm-project/pull/179509
More information about the cfe-commits
mailing list