r273440 - Add support for /Ob1 and -finline-hint-functions flags
Hans Wennborg via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 22 09:56:16 PDT 2016
Author: hans
Date: Wed Jun 22 11:56:16 2016
New Revision: 273440
URL: http://llvm.org/viewvc/llvm-project?rev=273440&view=rev
Log:
Add support for /Ob1 and -finline-hint-functions flags
Add support for /Ob1 (and equivalent -finline-hint-functions), which enable
inlining only for functions marked inline, either explicitly (via inline
keyword, for example), or implicitly (function definition in class body,
for example).
This works by enabling inlining pass, and adding noinline attribute to
every function not marked inline.
Patch by Rudy Pons <rudy.pons at ilod.org>!
Differential Revision: http://reviews.llvm.org/D20647
Added:
cfe/trunk/test/CodeGenCXX/inline-hint.cpp
Modified:
cfe/trunk/include/clang/Driver/CLCompatOptions.td
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/include/clang/Frontend/CodeGenOptions.h
cfe/trunk/lib/CodeGen/BackendUtil.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
cfe/trunk/lib/Driver/MSVCToolChain.cpp
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/test/CodeGen/inline-optim.c
cfe/trunk/test/Driver/cl-options.c
Modified: cfe/trunk/include/clang/Driver/CLCompatOptions.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CLCompatOptions.td?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CLCompatOptions.td (original)
+++ cfe/trunk/include/clang/Driver/CLCompatOptions.td Wed Jun 22 11:56:16 2016
@@ -291,7 +291,6 @@ def _SLASH_FS : CLIgnoredFlag<"FS">, Hel
def _SLASH_GF : CLIgnoredFlag<"GF">;
def _SLASH_kernel_ : CLIgnoredFlag<"kernel-">;
def _SLASH_nologo : CLIgnoredFlag<"nologo">;
-def _SLASH_Ob1 : CLIgnoredFlag<"Ob1">;
def _SLASH_Og : CLIgnoredFlag<"Og">;
def _SLASH_openmp_ : CLIgnoredFlag<"openmp-">;
def _SLASH_RTC : CLIgnoredJoined<"RTC">;
Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Wed Jun 22 11:56:16 2016
@@ -746,7 +746,10 @@ def fgnu_runtime : Flag<["-"], "fgnu-run
def fheinous_gnu_extensions : Flag<["-"], "fheinous-gnu-extensions">, Flags<[CC1Option]>;
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_functions : Flag<["-"], "finline-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Inline suitable functions">;
+def finline_hint_functions: Flag<["-"], "finline-hint-functions">, Group<f_clang_Group>, Flags<[CC1Option]>,
+ HelpText<"Inline functions wich are (explicitly or implicitly) marked inline">;
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>;
Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.h?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CodeGenOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/CodeGenOptions.h Wed Jun 22 11:56:16 2016
@@ -46,6 +46,7 @@ public:
enum InliningMethod {
NoInlining, // Perform no inlining whatsoever.
NormalInlining, // Use the standard function inlining pass.
+ OnlyHintInlining, // Inline only (implicitly) hinted functions.
OnlyAlwaysInlining // Only run the always inlining pass.
};
Modified: cfe/trunk/lib/CodeGen/BackendUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/BackendUtil.cpp?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/BackendUtil.cpp (original)
+++ cfe/trunk/lib/CodeGen/BackendUtil.cpp Wed Jun 22 11:56:16 2016
@@ -328,7 +328,8 @@ void EmitAssemblyHelper::CreatePasses(Mo
switch (Inlining) {
case CodeGenOptions::NoInlining:
break;
- case CodeGenOptions::NormalInlining: {
+ case CodeGenOptions::NormalInlining:
+ case CodeGenOptions::OnlyHintInlining: {
PMBuilder.Inliner =
createFunctionInliningPass(OptLevel, CodeGenOpts.OptimizeSize);
break;
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Jun 22 11:56:16 2016
@@ -686,14 +686,20 @@ void CodeGenFunction::StartFunction(Glob
// 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.
+ // attribute to all functions that are not marked AlwaysInline, or
+ // to all functions that are not marked inline or implicitly inline
+ // in the case of -finline-hint-functions.
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
- if (!CGM.getCodeGenOpts().NoInline) {
+ const CodeGenOptions& CodeGenOpts = CGM.getCodeGenOpts();
+ if (!CodeGenOpts.NoInline) {
for (auto RI : FD->redecls())
if (RI->isInlineSpecified()) {
Fn->addFnAttr(llvm::Attribute::InlineHint);
break;
}
+ if (CodeGenOpts.getInlining() == CodeGenOptions::OnlyHintInlining &&
+ !FD->isInlined() && !Fn->hasFnAttribute(llvm::Attribute::InlineHint))
+ Fn->addFnAttr(llvm::Attribute::NoInline);
} else if (!FD->hasAttr<AlwaysInlineAttr>())
Fn->addFnAttr(llvm::Attribute::NoInline);
if (CGM.getLangOpts().OpenMP && FD->hasAttr<OMPDeclareSimdDeclAttr>())
Modified: cfe/trunk/lib/Driver/MSVCToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/MSVCToolChain.cpp?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/MSVCToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/MSVCToolChain.cpp Wed Jun 22 11:56:16 2016
@@ -728,7 +728,7 @@ static void TranslateOptArg(Arg *A, llvm
DAL.AddFlagArg(A, Opts.getOption(options::OPT_fno_inline));
break;
case '1':
- // TODO: Inline calls to 'inline functions' only.
+ DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_hint_functions));
break;
case '2':
DAL.AddFlagArg(A, Opts.getOption(options::OPT_finline_functions));
Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Wed Jun 22 11:56:16 2016
@@ -5405,6 +5405,7 @@ void Clang::ConstructJob(Compilation &C,
CmdArgs.push_back("-fno-inline");
if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions,
+ options::OPT_finline_hint_functions,
options::OPT_fno_inline_functions))
InlineArg->render(Args, CmdArgs);
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Jun 22 11:56:16 2016
@@ -442,10 +442,15 @@ static bool ParseCodeGenArgs(CodeGenOpti
// -fno-inline-functions overrides OptimizationLevel > 1.
Opts.NoInline = Args.hasArg(OPT_fno_inline);
if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions,
+ options::OPT_finline_hint_functions,
options::OPT_fno_inline_functions)) {
- Opts.setInlining(
- InlineArg->getOption().matches(options::OPT_finline_functions) ?
- CodeGenOptions::NormalInlining : CodeGenOptions::OnlyAlwaysInlining);
+ const Option& InlineOpt = InlineArg->getOption();
+ if (InlineOpt.matches(options::OPT_finline_functions))
+ Opts.setInlining(CodeGenOptions::NormalInlining);
+ else if (InlineOpt.matches(options::OPT_finline_hint_functions))
+ Opts.setInlining(CodeGenOptions::OnlyHintInlining);
+ else
+ Opts.setInlining(CodeGenOptions::OnlyAlwaysInlining);
}
if (Arg *A = Args.getLastArg(OPT_fveclib)) {
Modified: cfe/trunk/test/CodeGen/inline-optim.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/inline-optim.c?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/inline-optim.c (original)
+++ cfe/trunk/test/CodeGen/inline-optim.c Wed Jun 22 11:56:16 2016
@@ -2,6 +2,7 @@
// RUN: %clang_cc1 -triple i686-pc-win32 -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
// RUN: %clang_cc1 -triple i686-pc-win32 -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s
+// RUN: %clang_cc1 -triple i686-pc-win32 -finline-hint-functions -emit-llvm %s -o - | FileCheck -check-prefix=HINT %s
// RUN: %clang_cc1 -triple i686-pc-win32 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s
inline int inline_hint(int a, int b) { return(a+b); }
@@ -13,14 +14,18 @@ inline __attribute__ ((__always_inline__
volatile int *pa = (int*) 0x1000;
void foo() {
// NOINLINE-LABEL: @foo
+// HINT-LABEL: @foo
// INLINE-LABEL: @foo
// NOINLINE: call i32 @inline_hint
+// HINT-NOT: call i32 @inline_hint
// INLINE-NOT: call i32 @inline_hint
pa[0] = inline_hint(pa[1],pa[2]);
// NOINLINE-NOT: call i32 @inline_always
+// HINT-NOT: call i32 @inline_always
// INLINE-NOT: call i32 @inline_always
pa[3] = inline_always(pa[4],pa[5]);
// NOINLINE: call i32 @inline_no_hint
+// HINT: call i32 @inline_no_hint
// INLINE-NOT: call i32 @inline_no_hint
pa[6] = inline_no_hint(pa[7], pa[8]);
}
Added: cfe/trunk/test/CodeGenCXX/inline-hint.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/inline-hint.cpp?rev=273440&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/inline-hint.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/inline-hint.cpp Wed Jun 22 11:56:16 2016
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=SUITABLE
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -finline-hint-functions -emit-llvm -disable-llvm-optzns -o - | FileCheck %s --check-prefix=CHECK --check-prefix=HINTED
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-linux -fno-inline -emit-llvm -disable-llvm-optzns -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; }
+ template<int N> int implicitTplFunction(int a) { return N + a; }
+ template<int N> inline int explicitTplFunction(int a) { return N + a; }
+ template<int N> int noHintTplFunction(int a);
+ template<int N> int explicitRedeclTplFunction(int a);
+};
+
+int B::explicitFunction(int a) { return a + a; }
+// CHECK: @_ZN1B14noHintFunctionEi({{.*}}) [[NOHINT_ATTR:#[0-9]+]]
+int B::noHintFunction(int a) { return a + a; }
+
+// CHECK: @_ZN1B19implicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::implicitTplFunction<0>(int a) { return a + a; }
+// CHECK: @_ZN1B19explicitTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::explicitTplFunction<0>(int a) { return a + a; }
+// CHECK: @_ZN1B17noHintTplFunctionILi0EEEii({{.*}}) [[NOHINT_ATTR]]
+template<> int B::noHintTplFunction<0>(int a) { return a + a; }
+template<> inline int B::implicitTplFunction<1>(int a) { return a; }
+template<> inline int B::explicitTplFunction<1>(int a) { return a; }
+template<> inline int B::noHintTplFunction<1>(int a) { return a; }
+template<int N> int B::noHintTplFunction(int a) { return N + a; }
+template<int N> inline int B::explicitRedeclTplFunction(int a) { return N + 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]+]]
+ b1.implicitFunction(1);
+// CHECK: @_ZN1B16explicitFunctionEi({{.*}}) [[EXPLICIT_ATTR:#[0-9]+]]
+ b1.explicitFunction(2);
+ b1.noHintFunction(3);
+// CHECK: @_ZN1B15optNoneFunctionEi({{.*}}) [[OPTNONE_ATTR:#[0-9]+]]
+ b1.optNoneFunction(4);
+// CHECK: @_Z17constexprFunctioni({{.*}}) [[IMPLICIT_ATTR]]
+ constexprFunction(5);
+ b1.implicitTplFunction<0>(6);
+// CHECK: @_ZN1B19implicitTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.implicitTplFunction<1>(7);
+// CHECK: @_ZN1B19implicitTplFunctionILi2EEEii({{.*}}) [[IMPLICIT_ATTR]]
+ b1.implicitTplFunction<2>(8);
+ b1.explicitTplFunction<0>(9);
+// CHECK: @_ZN1B19explicitTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitTplFunction<1>(10);
+// CHECK: @_ZN1B19explicitTplFunctionILi2EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitTplFunction<2>(11);
+ b1.noHintTplFunction<0>(12);
+// CHECK: @_ZN1B17noHintTplFunctionILi1EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.noHintTplFunction<1>(13);
+// CHECK: @_ZN1B17noHintTplFunctionILi2EEEii({{.*}}) [[NOHINT_ATTR]]
+ b1.noHintTplFunction<2>(14);
+// CHECK: @_ZN1B25explicitRedeclTplFunctionILi2EEEii({{.*}}) [[EXPLICIT_ATTR]]
+ b1.explicitRedeclTplFunction<2>(15);
+// CHECK: @_ZN1BD2Ev({{.*}}) unnamed_addr [[IMPLICIT_CONSTR_ATTR]]
+}
+
+// SUITABLE-NOT: attributes [[NOHINT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-DAG: attributes [[NOHINT_ATTR]] = { noinline{{.*}} }
+// NOINLINE-DAG: attributes [[NOHINT_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[IMPLICIT_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[IMPLICIT_CONSTR_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[IMPLICIT_CONSTR_ATTR]] = { noinline{{.*}} }
+
+// SUITABLE-NOT: attributes [[EXPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// HINTED-NOT: attributes [[IMPLICIT_ATTR]] = { {{.*}}noinline{{.*}} }
+// NOINLINE-DAG: attributes [[EXPLICIT_ATTR]] = { noinline{{.*}} }
+
+// CHECK-DAG: attributes [[OPTNONE_ATTR]] = { noinline{{.*}} }
Modified: cfe/trunk/test/Driver/cl-options.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cl-options.c?rev=273440&r1=273439&r2=273440&view=diff
==============================================================================
--- cfe/trunk/test/Driver/cl-options.c (original)
+++ cfe/trunk/test/Driver/cl-options.c Wed Jun 22 11:56:16 2016
@@ -113,6 +113,10 @@
// Ob2-NOT: warning: argument unused during compilation: '/O2'
// Ob2: -finline-functions
+// RUN: %clang_cl /Ob1 -### -- %s 2>&1 | FileCheck -check-prefix=Ob1 %s
+// RUN: %clang_cl /Odb1 -### -- %s 2>&1 | FileCheck -check-prefix=Ob1 %s
+// Ob1: -finline-hint-functions
+
// RUN: %clang_cl /Od -### -- %s 2>&1 | FileCheck -check-prefix=Od %s
// Od: -O0
@@ -280,7 +284,6 @@
// RUN: /GS- \
// RUN: /kernel- \
// RUN: /nologo \
-// RUN: /Ob1 \
// RUN: /openmp- \
// RUN: /RTC1 \
// RUN: /sdl \
More information about the cfe-commits
mailing list