This is an archive of the discontinued LLVM Phabricator instance.

[LLD] Add --lto-CGO[0-3] option
ClosedPublic

Authored by scott.linder on Jan 17 2023, 2:51 PM.

Details

Summary

Allow controlling the CodeGenOpt::Level independent of the LTO
optimization level in LLD via new options for the COFF, ELF, MachO, and
wasm frontends to lld. Most are spelled as --lto-CGO[0-3], but COFF is
spelled as -opt:lldltocgo=[0-3].

See D57422 for discussion surrounding the issue of how to set the CG opt
level. The ultimate goal is to let each function control its CG opt
level, but until then the current default means it is impossible to
specify a CG opt level lower than 2 while using LTO. This option gives
the user a means to control it for as long as it is not handled on a
per-function basis.

Diff Detail

Event Timeline

scott.linder created this revision.Jan 17 2023, 2:51 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald Transcript
Herald added a reviewer: Restricted Project. · View Herald Transcript
Herald added subscribers: pmatos, asb, ormris and 8 others. · View Herald Transcript
scott.linder requested review of this revision.Jan 17 2023, 2:51 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 17 2023, 2:51 PM

Correct MetaVarName for macho option (actually uncertain if this
needs to be changed; is it just for help text?)

Actually correct MetaVarName

yaxunl added inline comments.Jan 19 2023, 9:32 AM
lld/MachO/Arch/ARM.cpp
32 ↗(On Diff #490322)

this change seems not related to the patch. same as below

scott.linder added inline comments.Jan 20 2023, 11:24 AM
lld/MachO/Arch/ARM.cpp
32 ↗(On Diff #490322)

Right, it is just a side-effect of not being able to forward-declare CodeGenOpt::Level in lld/MachO/Config.h, and the coincidence that llvm/Support/CodeGen.h also defines a type called Reloc.

I can move it into another NFC patch if that is preferrable.

pcc added inline comments.Jan 20 2023, 11:49 AM
lld/Common/Args.cpp
20

This is still the preferred approach.

lld/ELF/Driver.cpp
1143

It looks like this is setting the CG opt level based on the LTO opt level, which is undesirable for the reasons mentioned in D57422. Let's keep the existing logic for determining the default CG opt level.

llvm/include/llvm/ADT/Unwrap.h
1 ↗(On Diff #490322)

It doesn't look like you're using this?

scott.linder added inline comments.Jan 20 2023, 1:05 PM
lld/Common/Args.cpp
20

I can move the comment, I just wasn't sure where to should go now.

lld/ELF/Driver.cpp
1143

Right, but the existing lld::args::getCGOptLevel is also setting the CG opt level based on the LTO opt level, just in a surprising manner (i.e. not 1:1). I saw this same concern in a comment on D57422 by @mehdi_amini but didn't see any response.

I find it confusing that a new user of LTO would start with a command-line like this and observe that they got CodeGenOpt::None:

$ echo 'int main() {}' | build/bin/clang -### -x c -O0 -
"clang" "-cc1" "-emit-obj" "-O0" ...
"ld.lld" ...

And that by adding just -flto they would still see command-lines for CC1 and the linker that would indicate the same would be true:

$ echo 'int main() {}' | build/bin/clang -### -x c -O0 - -flto
"clang" "-cc1" "-emit-llvm-bc" "-O0" ...
"ld.lld" "-plugin-opt=O0" ...

And yet somehow they get CodeGenOpt::Default behavior (and before this patch would have no recourse to correct this).

It isn't obvious to me (and I assume a typical user of Clang) that the internal behavior when adding "-flto" is that the CG opt level cannot ever fall below Default.

If we really need to retain the special behavior in the linkers themselves, could we instead teach Clang to start passing the new option, so the above becomes:

$ echo 'int main() {}' | build/bin/clang -### -x c -O0 - -flto
"clang" "-cc1" "-emit-llvm-bc" "-O0" ...
"ld.lld" "-plugin-opt=O0" "--lto-CGO0" ...

?

pcc added inline comments.Jan 20 2023, 1:53 PM
lld/ELF/Driver.cpp
1143

I think that the default is a separate issue from making the CG opt level configurable. Let's just keep this patch about making it configurable for now.

I agree that the default CG opt level is somewhat unintuitive, but the goal was to match the opt level used at compile time. Ideally it would be based on the information in the .bc file, but in the absence of such information, we have to "guess" which opt level was used, and the logic that was implemented was the most reasonable guess that we could come up with at the time.

arsenm added inline comments.Jan 20 2023, 2:25 PM
lld/ELF/Driver.cpp
1143

I maintain that the optimization level of a translation unit is not semantics and should not matter. The optimization level for the final codegen invocation is what should matter

scott.linder added inline comments.Jan 20 2023, 2:35 PM
llvm/include/llvm/ADT/Unwrap.h
1 ↗(On Diff #490322)

Whoops, this was a sketch I left in my working directory and missed when I commited, I'll remove it, sorry for the noise!

Restore default behavior (CG never defaults to anything below -O2)

scott.linder edited the summary of this revision. (Show Details)

Update commit message

The summary just states what this patch adds, but does not state the motivation. It seems that @pcc is fine with an option, it is fine with me, too.
If you want to reference D57422, update the summary to mention it.

scott.linder edited the summary of this revision. (Show Details)

Update commit message with rationale

  • Forward declare llvm::CodeGenOpt::Level when possible.
  • Add missing assertions.
MaskRay requested changes to this revision.Jan 30 2023, 3:33 PM
MaskRay added inline comments.
lld/COFF/Driver.cpp
1768

s.consume_front(...) then just use s below

lld/COFF/LTO.cpp
93

This introduces a crash in an assertion build if ltoo is larger than 3.
A proper error message like existing invalid optimization level should be used.

lld/wasm/Driver.cpp
429

This introduces a crash in an assertion build if ltoo is larger than 3.
A proper error message like existing invalid optimization level should be used.

This revision now requires changes to proceed.Jan 30 2023, 3:33 PM
scott.linder marked an inline comment as done.Jan 31 2023, 12:50 PM
scott.linder added inline comments.
lld/COFF/Driver.cpp
1768

Done as part of rebasing

lld/wasm/Driver.cpp
429

This doesn't add a new assert, it moves it from LTO.cpp to Driver.cpp and incorporates an option to control the input directly.

I avoided changing the behavior from an assert to an error to limit the tail of the refactor, but I can add a patch preceding this one to so.

scott.linder marked an inline comment as done.Feb 1 2023, 9:59 AM
scott.linder added inline comments.
lld/wasm/Driver.cpp
429

Ah, my mistake, I didn't see the call to checkOptions that I was hoisting the assert over. Like you say, this is adding an assert incorrectly. I will update the patch to handle the error in checkOptions instead.

scott.linder updated this revision to Diff 494089.EditedFeb 1 2023, 3:30 PM

Replace asserts added in previous version of patch with true diagnostic errors.
The only excpetion is COFF, where the parsing still deals in integral values
and ensures they fall in the right range, which the Driver assumes/asserts.

Also note that this actually changes the behavior for the ltoo error for macho. It seems like macho doesn't abort after building its config (i.e. it doesn't check errorCount() again after all modifications to config) and some tests rely on this behavior. I wasn't sure if this is needed to emulate some other linker, or if it is an oversight, but I tentatively moved only the ltoo/ltocgo setup before the errorCount() check.

MaskRay accepted this revision as: MaskRay.Feb 1 2023, 5:02 PM

Remove [Clang] from the subject.

Give #lld-macho a chance to review as well.

lld/COFF/Config.h
166

ltoCgo

lld/MachO/Config.h
172

ltoCgo ditto elsewhere

int3 accepted this revision.Feb 1 2023, 5:46 PM
int3 added a subscriber: int3.

Mach-O changes lgtm

This revision is now accepted and ready to land.Feb 1 2023, 5:46 PM
scott.linder retitled this revision from [Clang][LLD] Add --lto-CGO[0-3] option to [LLD] Add --lto-CGO[0-3] option.
  • Drop [Clang] from commit message.
  • ltocgo -> ltoCgo
MaskRay accepted this revision.Feb 2 2023, 3:50 PM
This revision was automatically updated to reflect the committed changes.