This is an archive of the discontinued LLVM Phabricator instance.

[lld-macho] Add support for LTO optimization level
ClosedPublic

Authored by lgrey on Jun 30 2021, 12:35 PM.

Details

Summary

Everything (including test) modified from ELF/COFF. Using the same syntax (--lto-O3, etc) as ELF.

Diff Detail

Event Timeline

lgrey created this revision.Jun 30 2021, 12:35 PM
Herald added a reviewer: gkm. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
lgrey requested review of this revision.Jun 30 2021, 12:35 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 30 2021, 12:35 PM
thakis accepted this revision.Jun 30 2021, 12:38 PM
thakis added a subscriber: thakis.

Nice!

lld/MachO/Config.h
129

Is this the same default ld64 seems to use?

This revision is now accepted and ready to land.Jun 30 2021, 12:38 PM
lgrey added inline comments.Jun 30 2021, 12:53 PM
lld/MachO/Config.h
129

AFAICT, it doesn't optimize.

$ cat opt_check.c
void foo() {
    return;
}

int main(int argc, char** argv) {
    foo();
    return 0;
}
$ clang -flto=thin opt_check.c && nm -pa a.out
0000000100003f80 t _foo
0000000100000000 T __mh_execute_header
0000000100003f90 T _main
                 U dyld_stub_binder

Should we change it to 0 for compat?

int3 added inline comments.Jun 30 2021, 1:07 PM
lld/MachO/Config.h
129

ld64 has an undocumented -flto-codegen-only flag. I haven't looked into what exactly it does, but it seems relevant...

thakis added inline comments.Jun 30 2021, 1:34 PM
lld/MachO/Config.h
129

Should we change it to 0 for compat?

Yes, I think so.

-flto-codegen-only

I think that's probably something else. That ends up calling thinlto_codegen_set_codegen_only() in llvm/tools/lto/lto.cpp.

…but lto_file.cpp in ld64 doesn't seem to pass an optimization flag, and OptLevel in lto.cpp defaults to 2. Strange that ld64 doesn't get an opt level of 2 then…

Does this test -O2 or --lto-O2? Do you need two files for checking lto, i.e. it inlines foo across two TUs?

lgrey added a comment.Jul 1 2021, 7:35 AM

Does this test -O2 or --lto-O2? Do you need two files for checking lto, i.e. it inlines foo across two TUs?

Effectively both, since what it really wants to test is the passthrough, but I don't think there's a way to sense for that directly. This just adapts lld/test/COFF/lto-opt-level.ll, but if there's some way to mock lto::LTO and assert things about its config, that seems like it would be good. Is there?

I think two files aren't necessary since the single file inlining is enough to demonstrate the flag was passed.

lld/MachO/Config.h
129

Maybe the legacy LTO implementation bitrotted? The docs bake optimization in:

% clang -flto=thin -O2 file1.c file2.c -c
% clang -flto=thin -O2 file1.o file2.o -o a.out

I tried changing to 0, but this breaks existing behavior, since the default appears to be 2 when omitting opt level from the config. Are we OK with that?

steven_wu added inline comments.Jul 1 2021, 9:29 AM
lld/MachO/Config.h
129

You cannot control optimization level for ld64. It is always on and the pipeline is configured in libLTO.
-flto-codegen-only will turn off all the optimization on LLVM IR and only run the code generation pipeline with all optimization on. This is only used for debugging or apple bitcode.

-O flag will control how much local optimization is done for each individual .o file (bitcode) before passing to linker for LTO.

This revision was automatically updated to reflect the committed changes.
thakis added a comment.EditedJul 1 2021, 12:05 PM

Thanks for chiming in, Steven! Sounds like this is all good as-is then, so landed :)