Ilod created this revision.
Ilod added a subscriber: cfe-commits.

Add two flags (-finline-implicit-hint and -fno-inline-implicit-hint) to allow 
to add InlineHint on implicitly inline functions (constexpr and member 
functions of class that was defined in the class body).
This is needed to add support for /Ob1 flag on clang-cl, which inlines only 
hinted functions, but considers implicitly inline functions as hinted (as per 
C++ standard).

http://reviews.llvm.org/D20647

Files:
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.def
  lib/CodeGen/CodeGenFunction.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGenCXX/inline-hint.cpp

Index: test/CodeGenCXX/inline-hint.cpp
===================================================================
--- test/CodeGenCXX/inline-hint.cpp
+++ test/CodeGenCXX/inline-hint.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -fno-inline-implicit-hint -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=EXPLICIT
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-implicit-hint -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=IMPLICIT
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-implicit-hint -fno-inline -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=NOINLINE
+
+// Force non-trivial implicit constructors/destructors/operators for B by having explicit ones for A
+struct A {
+  A() {}
+  A(const A&) {}
+  A& operator=(const A&) { return *this; }
+  ~A() {}
+};
+
+struct B {
+  A member;
+  int implicitFunction(int a) { return a + a; }
+  inline int explicitFunction(int a);
+  int noHintFunction(int a);
+  __attribute__((optnone)) int optNoneFunction(int a) { return a + a; }
+};
+
+int B::explicitFunction(int a) { return a + a; }
+// CHECK: @_ZN1B14noHintFunctionEi({{.*}}) [[NOHINT_ATTR:#[0-9]+]]
+int B::noHintFunction(int a) { return a + a; }
+
+constexpr int constexprFunction(int a) { return a + a; }
+
+void foo()
+{
+// CHECK: @_ZN1BC1Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR:#[0-9]+]]
+  B b1;
+// CHECK: @_ZN1BC1ERKS_({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
+  B b2(b1);
+// CHECK: @_ZN1BaSERKS_({{.*}}) [[IMPLICIT_CONSTR_ATTR]]
+  b2 = b1;
+// CHECK: @_ZN1B16implicitFunctionEi({{.*}}) [[IMPLICIT_ATTR:#[0-9]+]]
+  b2.implicitFunction(1);
+// CHECK: @_ZN1B16explicitFunctionEi({{.*}}) [[EXPLICIT_ATTR:#[0-9]+]]
+  b2.explicitFunction(2);
+  b2.noHintFunction(3);
+// CHECK: @_ZN1B15optNoneFunctionEi({{.*}}) [[OPTNONE_ATTR:#[0-9]+]]
+  b2.optNoneFunction(4);
+// CHECK: @_Z17constexprFunctioni({{.*}}) [[IMPLICIT_ATTR]]
+  constexprFunction(5);
+// CHECK: @_ZN1BD2Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
+}
+
+// EXPLICIT-NOT: attributes [[NOHINT_ATTR]] = { {{.*}}inlinehint{{.*}} }
+// IMPLICIT-NOT: attributes [[NOHINT_ATTR]] = { {{.*}}inlinehint{{.*}} }
+// NOINLINE-DAG: attributes [[NOHINT_ATTR]] = { noinline{{.*}} }
+
+// EXPLICIT-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}inlinehint{{.*}} }
+// IMPLICIT-DAG: attributes [[IMPLICIT_ATTR]] = { inlinehint{{.*}} }
+// NOINLINE-DAG: attributes [[IMPLICIT_ATTR]] = { noinline{{.*}} }
+
+// EXPLICIT-DAG: attributes [[IMPLICIT_CONSTR_ATTR]] = { inlinehint{{.*}} }
+// IMPLICIT-DAG: attributes [[IMPLICIT_CONSTR_ATTR]] = { inlinehint{{.*}} }
+// NOINLINE-DAG: attributes [[IMPLICIT_CONSTR_ATTR]] = { noinline{{.*}} }
+
+// EXPLICIT-DAG: attributes [[EXPLICIT_ATTR]] = { inlinehint{{.*}} }
+// IMPLICIT-DAG: attributes [[EXPLICIT_ATTR]] = { inlinehint{{.*}} }
+// NOINLINE-DAG: attributes [[EXPLICIT_ATTR]] = { noinline{{.*}} }
+
+// CHECK-DAG: attributes [[OPTNONE_ATTR]] = { noinline{{.*}} }
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -447,6 +447,8 @@
       InlineArg->getOption().matches(options::OPT_finline_functions) ?
         CodeGenOptions::NormalInlining : CodeGenOptions::OnlyAlwaysInlining);
   }
+  Opts.ImplicitInlineHint = Args.hasFlag(OPT_finline_implicit_hint,
+                                         OPT_fno_inline_implicit_hint, false);
 
   if (Arg *A = Args.getLastArg(OPT_fveclib)) {
     StringRef Name = A->getValue();
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -699,12 +699,14 @@
     Fn->addFnAttr(llvm::Attribute::SafeStack);
 
   // Pass inline keyword to optimizer if it appears explicitly on any
-  // declaration. Also, in the case of -fno-inline attach NoInline
-  // attribute to all function that are not marked AlwaysInline.
+  // declaration, or implicitly in the case of -finline-implicit-hint.
+  // Also, in the case of -fno-inline attach NoInline attribute to all
+  // function that are not marked AlwaysInline.
   if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
     if (!CGM.getCodeGenOpts().NoInline) {
       for (auto RI : FD->redecls())
-        if (RI->isInlineSpecified()) {
+        if (RI->isInlineSpecified() ||
+            (CGM.getCodeGenOpts().ImplicitInlineHint && RI->isInlined())) {
           Fn->addFnAttr(llvm::Attribute::InlineHint);
           break;
         }
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ include/clang/Frontend/CodeGenOptions.def
@@ -99,6 +99,9 @@
 CODEGENOPT(ReciprocalMath    , 1, 0) ///< Allow FP divisions to be reassociated.
 CODEGENOPT(NoInline          , 1, 0) ///< Set when -fno-inline is enabled.
                                      ///< Disables use of the inline keyword.
+CODEGENOPT(ImplicitInlineHint, 1, 0) ///< Set when -finline-implicit-hint is enabled.
+                                     ///< Add inline hint on implicitly inline
+                                     ///< functions.
 CODEGENOPT(NoNaNsFPMath      , 1, 0) ///< Assume FP arguments, results not NaN.
 CODEGENOPT(NoZeroInitializedInBSS , 1, 0) ///< -fno-zero-initialized-in-bss.
 /// \brief Method of Objective-C dispatch to use.
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -742,6 +742,8 @@
 def filelist : Separate<["-"], "filelist">, Flags<[LinkerInput]>;
 def : Flag<["-"], "findirect-virtual-calls">, Alias<fapple_kext>;
 def finline_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>;
+def finline_implicit_hint: Flag<["-"], "finline-implicit-hint">, Group<f_clang_Group>, Flags<[CC1Option]>;
+def fno_inline_implicit_hint: Flag<["-"], "fno-inline-implicit-hint">, Group<f_clang_Group>, Flags<[CC1Option]>;
 def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>;
 def finput_charset_EQ : Joined<["-"], "finput-charset=">, Group<f_Group>;
 def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to