This is an archive of the discontinued LLVM Phabricator instance.

[Clang] Add option to allow marking pass-by-value args as noalias.
ClosedPublic

Authored by fhahn on Aug 6 2020, 1:31 PM.

Details

Summary

After the recent discussion on cfe-dev 'Can indirect class parameters be
noalias?' [1], it seems like using using noalias is problematic for
current C++, but should be allowed for C-only code.

This patch introduces a new option to let the user indicate that it is
safe to mark indirect class parameters as noalias. Note that this also
applies to external callers, e.g. it might not be safe to use this flag
for C functions that are called by C++ functions.

In targets that allocate indirect arguments in the called function, this
enables more agressive optimizations with respect to memory operations
and brings a ~1% - 2% codesize reduction for some programs.

I am not sure about the best name for the option and description. I
would appreciate any feedback.

[1] : http://lists.llvm.org/pipermail/cfe-dev/2020-July/066353.html

Diff Detail

Event Timeline

fhahn created this revision.Aug 6 2020, 1:31 PM
Herald added a project: Restricted Project. · View Herald TranscriptAug 6 2020, 1:31 PM
fhahn requested review of this revision.Aug 6 2020, 1:31 PM
smeenai added a subscriber: smeenai.Aug 6 2020, 4:03 PM
rsmith added inline comments.Aug 6 2020, 11:17 PM
clang/include/clang/Basic/LangOptions.def
371–374 ↗(On Diff #283720)

Per the comment at the top of the file, the description should be a single noun phrase; we use this in diagnostics such as "AST file was built with %0 enabled but it is currently disabled". Something like "assumption that by-value parameters do not alias any other values" maybe?

clang/include/clang/Driver/Options.td
4325–4328

This should be in Group<f_Group>.

fhahn updated this revision to Diff 283837.Aug 7 2020, 1:23 AM

Thanks for taking a look!

I adjusted the LangOpts description and added the flag to f_Group, as suggested.

Is it acceptable to leave this as a -cc1 option while we're pursuing this with the language committee? Do we have any intent to pursue this with the language committee?

clang/include/clang/Basic/LangOptions.def
372 ↗(On Diff #283837)

This should be a code-gen option, I think. I can't really imagine how this would affect language processing.

clang/include/clang/Driver/Options.td
4325–4328

The "Note" clause seems to muddy more than it clarifies. Maybe "has no effect on non-trivially-copyable classes in C++"? Or add proper documentation somewhere instead of trying to jam this into the help text.

clang/lib/CodeGen/CGCall.cpp
2207

This definitely can't be added unconditionally to all types; you need to rule out non-trivial C++ class types, as well as types with ObjC weak references.

fhahn updated this revision to Diff 290504.Sep 8 2020, 9:19 AM
fhahn marked an inline comment as done.

Change to codegen option, adjust description for option, limit to trivially copyable types in C++, add corresponding test cases.

fhahn added inline comments.Sep 8 2020, 9:21 AM
clang/include/clang/Driver/Options.td
4325–4328

I've added the clarification, thanks!

clang/lib/CodeGen/CGCall.cpp
2207

Updated to rule out non trivially-copyable types.

I am not sure how to best handle types with weak references. I did not manage to find any helpers that traverse a whole type to check if it contains weak references.

I added clang/test/CodeGenObjC/pass-by-value-noalias.m and IIUC noalias should not be added for that case.

fhahn updated this revision to Diff 291083.Sep 10 2020, 2:24 PM

Also restrict to types that are isNonTrivialToPrimitiveCopy, so we do not add noalias for problematic types, like ObjC structs with weak references.

rjmccall added inline comments.
clang/lib/CodeGen/CGCall.cpp
2207

The restriction should not be by triviality but by whether indirectness is forced semantically. That may currently only be available on RecordDecl (as RecordDecl::getArgPassingRestrictions), but you could definitely add an accessor to Type which checked for a RecordType and otherwise returned that there are no passing constraints. Tagging Akira, who worked on this.

fhahn updated this revision to Diff 291176.Sep 11 2020, 3:55 AM

Update code to limit adding noalias to types with getArgPassingRestrictions() == RecordDecl::APK_CanPassInRegs. This rules out problematic types, like ones with non-trivial constructors or ObjC structs with weak pointers. Thanks @rjmccall

I also added the escape cases shared on cfe-dev by @rsmith

fhahn marked an inline comment as done.Sep 11 2020, 3:56 AM
fhahn added inline comments.
clang/lib/CodeGen/CGCall.cpp
2207

Thanks John, that does indeed exactly what we need I think. I updated the code to use getAsRecordDecl here. I can also add a helper to Type if it is useful beyond here.

fhahn updated this revision to Diff 291183.Sep 11 2020, 4:35 AM
fhahn marked an inline comment as done.

Add check lines for escape examples. Note that for return-by-value we already add noalias to the pointer unconditionally.

rjmccall accepted this revision.Sep 11 2020, 11:46 AM

Just a minor tweak and then LGTM.

clang/include/clang/Driver/Options.td
4325–4328

Oh, you need a space after the period.

This revision is now accepted and ready to land.Sep 11 2020, 11:46 AM
This revision was landed with ongoing or failed builds.Sep 12 2020, 6:56 AM
This revision was automatically updated to reflect the committed changes.
fhahn added inline comments.Sep 12 2020, 6:57 AM
clang/include/clang/Driver/Options.td
4325–4328

Done, thanks!