This is an archive of the discontinued LLVM Phabricator instance.

[Driver] Change multilib selection algorithm
ClosedPublic

Authored by michaelplatings on Jan 30 2023, 8:55 AM.

Details

Summary

The new algorithm is:

  1. Find all multilibs with flags that are a subset of the requested flags.
  2. If more than one multilib matches, choose the last.

In addition a new selection mechanism is permitted via an overload of
MultilibSet::select() for which multiple multilibs are returned.
This allows layering multilibs on top of each other.

Since multilibs are now ordered within a list, they no longer need a
Priority field.

The new algorithm is different to the old algorithm, but in practise
the old algorithm was always used in such a way that the effect is the
same.
The old algorithm was to find the set intersection of the requested
flags (with the first character of each removed) with each multilib's
flags (ditto), and for that intersection check whether the first
character matched. However, ignoring the first characters, the
requested flags were always a superset of all the multilibs flags.
Therefore the new algorithm can be used as a drop-in replacement.

The exception is Fuchsia, which needs adjusting slightly to set both
fexceptions and fno-exceptions flags.

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptJan 30 2023, 8:55 AM
michaelplatings requested review of this revision.Jan 30 2023, 8:55 AM
Herald added a project: Restricted Project. · View Herald TranscriptJan 30 2023, 8:55 AM

Set both fexceptions and fno-exceptions flags for Fuchsia multilib. Previously that tweak had slipped into D142878, which is now abandoned.

A couple of small stylisitic suggestions.

clang/include/clang/Driver/Multilib.h
33–34

would flags_set be a better name. I'm guessing we're using set as we want uniqueness and ordering?

If we don't need ordering then we may be able to use https://llvm.org/docs/ProgrammersManual.html#llvm-adt-stringset-h

112

Worth using multilib_list for consistency with the rest of the file?

Is this meant to be an overload for bool select below? I mention it as it has a different return type. Perhaps use selectCompatible?

michaelplatings marked an inline comment as done.

Apply improvements suggested by @peter.smith

michaelplatings added inline comments.Feb 7 2023, 7:25 AM
clang/include/clang/Driver/Multilib.h
33–34

Renamed to flag_set.

Yes, we want uniqueness and ordering. I don't think ordering matters in this change, but later changes rely on it.

112

Changed to use multilib_list now, thanks.

The overloading goes away in D143059.

Thanks for the updates, I'm happy with the changes and don't have any more comments. Happy to give my implicit approval.

Use [Driver] for pure driver patches.

MaskRay added inline comments.Feb 10 2023, 10:56 PM
clang/lib/Driver/Multilib.cpp
53

remove braces

99

remove braces

Mention MultilibSet::select in the summary.

michaelplatings marked 2 inline comments as done.

Remove braces as requested by @MaskRay

michaelplatings retitled this revision from Change multilib selection algorithm to [Driver] Change multilib selection algorithm.Feb 22 2023, 1:50 AM
michaelplatings edited the summary of this revision. (Show Details)
phosek added inline comments.Feb 23 2023, 12:49 AM
clang/include/clang/Driver/Multilib.h
42

This is just a suggestion, but GCC documentation refers to these as either "options" or "switches", not "args" so I think it might be helpful to use the same nomenclature. This would also avoid confusion since the term "args" is used extensively throughout the driver but refers to input arguments.

clang/lib/Driver/MultilibBuilder.cpp
87–90

If I understand this correctly, we might end up with duplicate arguments in the case when Flags contains duplicate elements. Is that desirable? Wouldn't it be better to construct the list of arguments from the set of fags inside Multilib?

michaelplatings marked 2 inline comments as done.
  • Rename args to options as suggested by @phosek
  • Add more comments to hopefully make the difference between flags and options clearer.
clang/include/clang/Driver/Multilib.h
42

OK, I've gone with "options" just because switch_list would be an unintuitive name.

clang/lib/Driver/MultilibBuilder.cpp
87–90

Yes, you can have duplicate options if you write code to do that. The Multilib class has never previously had any functionality to remove duplicate options so I'd rather not change that. Previously if you wrote code that added the same option twice then clang -print-multi-lib would reflect that. This behaviour remains unchanged.

No, you can't construct the list of options from the set of flags inside Multilib because Multilib's flags are not command line options. (They will typically look similar to command line options but there's no requirement for that to be the case). I've added comments here and for the flags() method to hopefully make this clearer. Hopefully the docs in D143587 will also make things clearer for anyone else trying to reason about the multilib system.

peter.smith accepted this revision.Mar 13 2023, 9:20 AM

I've set approved from the Arm side. Please leave some time for people in the US time zone to leave any final comments or ask for extensions. I've left a suggestion for a comment, but this can be applied prior to commit if you want to take it up.

clang/include/clang/Driver/Multilib.h
68

Would be good to reference the Multilib Design document's definition and examples of (what will be renamed in D145567 to tags).

This may require moving the design doc down the stack, probably not necessary if everything is committed at once.

This revision is now accepted and ready to land.Mar 13 2023, 9:20 AM
michaelplatings marked an inline comment as done.Mar 13 2023, 11:31 AM
michaelplatings added inline comments.
clang/include/clang/Driver/Multilib.h
68

I've changed D143587 to update the comment to reference the docs.

I have just one comment related to efficiency, but if it turns out to be too difficult to address, I'd be also fine landing this change as is and addressing that issue in a follow up change.

clang/lib/Driver/MultilibBuilder.cpp
91–97

I think we're optimizing for the wrong case here since PrintOptions is only needed for -print-multi-lib, which is infrequently used flag, but we always have pay the cost of constructing and keeping PrintOptions in memory, even when unused (which is going to vast majority of Driver uses). I think that constructing it lazily in getPrintOptions() (and using that in print()) would be more efficient.

michaelplatings updated this revision to Diff 505279.EditedMar 14 2023, 2:57 PM
michaelplatings marked an inline comment as done.

Calculate the output for -print-multi-lib lazily.
This necessitated returning to using std::vector to store flags to avoid reordering them.
In theory the big-O time to select a multilib is larger now but in practise the number of flags is small enough that it's now about 2 microseconds faster per clang invocation.

michaelplatings marked an inline comment as done.Mar 14 2023, 2:58 PM

fix typo in comment

phosek added inline comments.Mar 22 2023, 12:54 AM
clang/lib/Driver/MultilibBuilder.cpp
85

Would it be possible to move this method directly into Multilib to avoid having to pass around the callback?

michaelplatings marked an inline comment as done.

Add enum to Multilib class for how print options should be calculated.

Move change to print options into D146757

phosek accepted this revision.Mar 23 2023, 11:39 PM

LGTM

This revision was landed with ongoing or failed builds.Mar 23 2023, 11:59 PM
This revision was automatically updated to reflect the committed changes.