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

Florian Hahn via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 6 13:31:32 PDT 2020


fhahn created this revision.
fhahn added reviewers: rjmccall, rsmith, hfinkel, jfb.
Herald added subscribers: dang, dexonsmith.
Herald added a project: clang.
fhahn requested review of this revision.

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


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85473

Files:
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/lib/CodeGen/CGCall.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/pass-by-value-noalias.c


Index: clang/test/CodeGen/pass-by-value-noalias.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/pass-by-value-noalias.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fpass-by-value-noalias -triple arm64-apple-iphoneos -emit-llvm -disable-llvm-optzns %s -o - 2>&1 | FileCheck --check-prefix=WITH_NOALIAS %s
+// RUN: %clang_cc1 -triple arm64-apple-iphoneos -emit-llvm -disable-llvm-optzns %s -o - 2>&1 | FileCheck --check-prefix=NO_NOALIAS %s
+
+struct Foo {
+  int a;
+  int b;
+  int c;
+  int d;
+  int e;
+  int f;
+};
+
+// WITH_NOALIAS: define void @take(%struct.Foo* noalias %arg)
+// NO_NOALIAS: define void @take(%struct.Foo* %arg)
+void take(struct Foo arg) {}
Index: clang/lib/Frontend/CompilerInvocation.cpp
===================================================================
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -3419,6 +3419,7 @@
   Opts.PCHInstantiateTemplates = Args.hasArg(OPT_fpch_instantiate_templates);
 
   Opts.MatrixTypes = Args.hasArg(OPT_fenable_matrix);
+  Opts.PassByValueNoAlias = Args.hasArg(OPT_fpass_by_value_noalias);
 
   Opts.MaxTokens = getLastArgIntValue(Args, OPT_fmax_tokens_EQ, 0, Diags);
 
Index: clang/lib/CodeGen/CGCall.cpp
===================================================================
--- clang/lib/CodeGen/CGCall.cpp
+++ clang/lib/CodeGen/CGCall.cpp
@@ -2184,6 +2184,11 @@
       if (AI.getIndirectByVal())
         Attrs.addByValAttr(getTypes().ConvertTypeForMem(ParamType));
 
+      if (getLangOpts().PassByValueNoAlias)
+        // When calling the function, the pointer passed in will be the only
+        // reference to the underlying object. Mark it accordingly.
+        Attrs.addAttribute(llvm::Attribute::NoAlias);
+
       CharUnits Align = AI.getIndirectAlign();
 
       // In a byval argument, it is important that the required
Index: clang/include/clang/Driver/Options.td
===================================================================
--- clang/include/clang/Driver/Options.td
+++ clang/include/clang/Driver/Options.td
@@ -4284,6 +4284,10 @@
 def fcompatibility_qualified_id_block_param_type_checking : Flag<["-"], "fcompatibility-qualified-id-block-type-checking">,
   HelpText<"Allow using blocks with parameters of more specific type than "
            "the type system guarantees when a parameter is qualified id">;
+def fpass_by_value_noalias: Flag<["-"], "fpass-by-value-noalias">,
+  HelpText<"Allows assuming no references to passed by value escape before "
+           "transferring execution to the called function. Note that this "
+           "does not hold for C++">;
 
 // FIXME: Remove these entirely once functionality/tests have been excised.
 def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>,
Index: clang/include/clang/Basic/LangOptions.def
===================================================================
--- clang/include/clang/Basic/LangOptions.def
+++ clang/include/clang/Basic/LangOptions.def
@@ -368,6 +368,10 @@
 LANGOPT(RegisterStaticDestructors, 1, 1, "Register C++ static destructors")
 
 LANGOPT(MatrixTypes, 1, 0, "Enable or disable the builtin matrix type")
+LANGOPT(PassByValueNoAlias, 1, 0, "Allows assuming no references to passed by "
+                                  "value escape before transferring execution "
+                                  "to the called function. Note that this does "
+                                  "not hold for C++")
 
 COMPATIBLE_VALUE_LANGOPT(MaxTokens, 32, 0, "Max number of tokens per TU or 0")
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D85473.283720.patch
Type: text/x-patch
Size: 3570 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200806/d796db6a/attachment-0001.bin>


More information about the cfe-commits mailing list