[PATCH] D20576: [Driver] Add support for -finline-functions and /Ob2 flags
Ilod created this revision. Ilod added a reviewer: hans. Ilod added a subscriber: cfe-commits. -finline-functions and /Ob2 are currently ignored by Clang. The only way to enable inlining is to use the global O flags, which also enable other options, or to emit LLVM bitcode using Clang, then running opt by hand with the inline pass. This patch allows to simply use the -finline-functions flag (same as GCC) or /Ob2 in clang-cl mode to enable inlining without other optimizations. This is the first patch of a serie to improve support for the /Ob flags. http://reviews.llvm.org/D20576 Files: include/clang/Driver/CLCompatOptions.td include/clang/Driver/Options.td lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/inline-optim.c test/Driver/cl-options.c test/Driver/clang_f_opts.c Index: test/Driver/clang_f_opts.c === --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -285,7 +285,6 @@ // RUN: -fexpensive-optimizations \ // RUN: -fno-expensive-optimizations \ // RUN: -fno-defer-pop\ -// RUN: -finline-functions\ // RUN: -fkeep-inline-functions \ // RUN: -fno-keep-inline-functions\ // RUN: -freorder-blocks \ @@ -353,7 +352,6 @@ // CHECK-WARNING-DAG: optimization flag '-fexpensive-optimizations' is not supported // CHECK-WARNING-DAG: optimization flag '-fno-expensive-optimizations' is not supported // CHECK-WARNING-DAG: optimization flag '-fno-defer-pop' is not supported -// CHECK-WARNING-DAG: optimization flag '-finline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-fkeep-inline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-fno-keep-inline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported Index: test/Driver/cl-options.c === --- test/Driver/cl-options.c +++ test/Driver/cl-options.c @@ -97,6 +97,9 @@ // RUN: %clang_cl /Ob0 -### -- %s 2>&1 | FileCheck -check-prefix=Ob0 %s // Ob0: -fno-inline +// RUN: %clang_cl /Ob2 -### -- %s 2>&1 | FileCheck -check-prefix=Ob2 %s +// Ob2: -finline-functions + // RUN: %clang_cl /Od -### -- %s 2>&1 | FileCheck -check-prefix=Od %s // Od: -O0 @@ -265,7 +268,6 @@ // RUN:/kernel- \ // RUN:/nologo \ // RUN:/Ob1 \ -// RUN:/Ob2 \ // RUN:/openmp- \ // RUN:/RTC1 \ // RUN:/sdl \ Index: test/CodeGen/inline-optim.c === --- test/CodeGen/inline-optim.c +++ test/CodeGen/inline-optim.c @@ -0,0 +1,26 @@ +// Make sure -finline-functions family flags are behaving correctly. + +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s +// RUN: %clang_cc1 -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s +// RUN: %clang_cc1 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s + +inline int inline_hint(int a, int b) { return(a+b); } + +int inline_no_hint(int a, int b) { return (a/b); } + +inline __attribute__ ((__always_inline__)) int inline_always(int a, int b) { return(a*b); } + +volatile int *pa = (int*) 0x1000; +void foo() { +// NOINLINE: @foo +// INLINE: @foo +// NOINLINE: inline_hint +// INLINE-NOT: inline_hint +pa[0] = inline_hint(pa[1],pa[2]); +// NOINLINE-NOT: inline_always +// INLINE-NOT: inline_always +pa[3] = inline_always(pa[4],pa[5]); +// NOINLINE: inline_no_hint +// INLINE-NOT: inline_no_hint +pa[6] = inline_no_hint(pa[7], pa[8]); +} Index: lib/Frontend/CompilerInvocation.cpp === --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -441,8 +441,10 @@ : CodeGenOptions::OnlyAlwaysInlining); // -fno-inline-functions overrides OptimizationLevel > 1. Opts.NoInline = Args.hasArg(OPT_fno_inline); - Opts.setInlining(Args.hasArg(OPT_fno_inline_functions) ? - CodeGenOptions::OnlyAlwaysInlining : Opts.getInlining()); + if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions, options::OPT_fno_inline_functions)) { +Opts.setInlining(InlineArg->getOption().matches(options::OPT_finline_functions) ? +CodeGenOptions::NormalInlining : CodeGenOptions::OnlyAlwaysInlining); + } if (Arg *A = Args.getLastArg(OPT_fveclib)) { StringRef Name = A->getValue(); Index: lib/Driver/Tools.cpp === --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -5332,8 +5332,10 @@ if
Re: [PATCH] D20576: [Driver] Add support for -finline-functions and /Ob2 flags
Ilod updated this revision to Diff 58302. Ilod added a comment. Thanks! Updated to respect the 80-columns limit. Updated the tests to have a clearer checks. (I don't know well the FileCheck, so I took example from test/CodeGen/noinline.c, but this is indeed more comprehensible). http://reviews.llvm.org/D20576 Files: include/clang/Driver/CLCompatOptions.td include/clang/Driver/Options.td lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/inline-optim.c test/Driver/cl-options.c test/Driver/clang_f_opts.c Index: test/Driver/clang_f_opts.c === --- test/Driver/clang_f_opts.c +++ test/Driver/clang_f_opts.c @@ -285,7 +285,6 @@ // RUN: -fexpensive-optimizations \ // RUN: -fno-expensive-optimizations \ // RUN: -fno-defer-pop\ -// RUN: -finline-functions\ // RUN: -fkeep-inline-functions \ // RUN: -fno-keep-inline-functions\ // RUN: -freorder-blocks \ @@ -353,7 +352,6 @@ // CHECK-WARNING-DAG: optimization flag '-fexpensive-optimizations' is not supported // CHECK-WARNING-DAG: optimization flag '-fno-expensive-optimizations' is not supported // CHECK-WARNING-DAG: optimization flag '-fno-defer-pop' is not supported -// CHECK-WARNING-DAG: optimization flag '-finline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-fkeep-inline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-fno-keep-inline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported Index: test/Driver/cl-options.c === --- test/Driver/cl-options.c +++ test/Driver/cl-options.c @@ -97,6 +97,9 @@ // RUN: %clang_cl /Ob0 -### -- %s 2>&1 | FileCheck -check-prefix=Ob0 %s // Ob0: -fno-inline +// RUN: %clang_cl /Ob2 -### -- %s 2>&1 | FileCheck -check-prefix=Ob2 %s +// Ob2: -finline-functions + // RUN: %clang_cl /Od -### -- %s 2>&1 | FileCheck -check-prefix=Od %s // Od: -O0 @@ -265,7 +268,6 @@ // RUN:/kernel- \ // RUN:/nologo \ // RUN:/Ob1 \ -// RUN:/Ob2 \ // RUN:/openmp- \ // RUN:/RTC1 \ // RUN:/sdl \ Index: test/CodeGen/inline-optim.c === --- test/CodeGen/inline-optim.c +++ test/CodeGen/inline-optim.c @@ -0,0 +1,26 @@ +// Make sure -finline-functions family flags are behaving correctly. + +// RUN: %clang_cc1 -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s +// RUN: %clang_cc1 -O3 -fno-inline-functions -emit-llvm %s -o - | FileCheck -check-prefix=NOINLINE %s +// RUN: %clang_cc1 -finline-functions -emit-llvm %s -o - | FileCheck -check-prefix=INLINE %s + +inline int inline_hint(int a, int b) { return(a+b); } + +int inline_no_hint(int a, int b) { return (a/b); } + +inline __attribute__ ((__always_inline__)) int inline_always(int a, int b) { return(a*b); } + +volatile int *pa = (int*) 0x1000; +void foo() { +// NOINLINE-LABEL: @foo +// INLINE-LABEL: @foo +// NOINLINE: call i32 @inline_hint +// INLINE-NOT: call i32 @inline_hint +pa[0] = inline_hint(pa[1],pa[2]); +// NOINLINE-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 +// INLINE-NOT: call i32 @inline_no_hint +pa[6] = inline_no_hint(pa[7], pa[8]); +} Index: lib/Frontend/CompilerInvocation.cpp === --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -441,8 +441,12 @@ : CodeGenOptions::OnlyAlwaysInlining); // -fno-inline-functions overrides OptimizationLevel > 1. Opts.NoInline = Args.hasArg(OPT_fno_inline); - Opts.setInlining(Args.hasArg(OPT_fno_inline_functions) ? - CodeGenOptions::OnlyAlwaysInlining : Opts.getInlining()); + if (Arg* InlineArg = Args.getLastArg(options::OPT_finline_functions, + options::OPT_fno_inline_functions)) { +Opts.setInlining( + InlineArg->getOption().matches(options::OPT_finline_functions) ? +CodeGenOptions::NormalInlining : CodeGenOptions::OnlyAlwaysInlining); + } if (Arg *A = Args.getLastArg(OPT_fveclib)) { StringRef Name = A->getValue(); Index: lib/Driver/Tools.cpp === --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -5332,8 +5332,9 @@ if (Args.hasArg(options::OPT_fno_inline)) CmdArgs.push_back("-fno-inline"); - if (Args.hasArg(options::OPT_fno_inline_functions)) -CmdArgs.push_ba
Re: [PATCH] D20576: [Driver] Add support for -finline-functions and /Ob2 flags
Ilod added a comment. I don't have commit access, so you can do it for me, thanks. http://reviews.llvm.org/D20576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20576: [Driver] Add support for -finline-functions and /Ob2 flags
Ilod added a comment. Hello, It seems the new test was commited as .cc instead of .c, which changes the name mangling, making // NOINLINE-LABEL: @foo fail. Either the file should be renamed, or -x c should be added to clang invocation, or LABEL check updated. Repository: rL LLVM http://reviews.llvm.org/D20576 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D20647: Add flag to add InlineHint attribute on implicitly inline functions
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(D)) { if (!CGM.getCodeGenO
Re: [PATCH] D20647: Add flag to add InlineHint attribute on implicitly inline functions
Ilod added a reviewer: rnk. Ilod updated this revision to Diff 61029. Ilod added a comment. Updated to head revision, and pinging this. 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(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: incl
Re: [PATCH] D20647: Add flag to add InlineHint attribute on implicitly inline functions
Ilod added a comment. I don't think weak linkage defines this. For example, in: struct A { inline int foo() { return 0; } int bar() { return 1; } int baz(); }; int A::baz() { return 2; } With /Ob1, we should inline foo and bar, but never baz. But baz doesn't have weak linkage, does it? But indeed, if in CodeGenFunctions.cpp, instead of adding InlineHint attribute when we have isInlined(), I add noinline attribute if we don't have it (with /Ob1 or equivalent clang flag), I could avoid the work I started to inline only hinted functions at http://reviews.llvm.org/D20603 http://reviews.llvm.org/D20647 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20647: Add flag to add InlineHint attribute on implicitly inline functions
Ilod updated this revision to Diff 61318. Ilod added a comment. New patch, which instead add NoInline to function not marked (implicitly or explicitly) inline, when we use the -finline-hint-functions flag (effectily inlining only implicitly and explicitly inline functions). Also adds support for /Ob1, since it's now an alias for it. There is no longer a flag to treat implicit and explicit inline functions exactly the same way, I don't kow if it's really useful (it can be if we want to use the threshold difference between InlineHint and standard functions). If it's wanted for other uses, I can re-add it. There is no flag to inline only explicitly marked inline functions, but it can be done by passing -finline-functions -mllvm -inline-threshold=-1000 (which will add InlineHint only to explicitly inline functions, and put a negative enough threshold for non-hinted functions to inline only the hinted ones). http://reviews.llvm.org/D20647 Files: include/clang/Driver/CLCompatOptions.td include/clang/Driver/Options.td include/clang/Frontend/CodeGenOptions.h lib/CodeGen/BackendUtil.cpp lib/CodeGen/CodeGenFunction.cpp lib/Driver/MSVCToolChain.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/inline-optim.c test/CodeGenCXX/inline-hint.cpp test/Driver/cl-options.c Index: test/Driver/cl-options.c === --- test/Driver/cl-options.c +++ test/Driver/cl-options.c @@ -280,7 +280,6 @@ // RUN:/GS- \ // RUN:/kernel- \ // RUN:/nologo \ -// RUN:/Ob1 \ // RUN:/openmp- \ // RUN:/RTC1 \ // RUN:/sdl \ Index: test/CodeGenCXX/inline-hint.cpp === --- test/CodeGenCXX/inline-hint.cpp +++ test/CodeGenCXX/inline-hint.cpp @@ -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 implicitTplFunction(int a) { return N + a; } + template inline int explicitTplFunction(int a) { return N + a; } + template int noHintTplFunction(int a); + template 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 B::noHintTplFunction(int a) { return N + a; } +template 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.explici
Re: [PATCH] D20647: Add support for /Ob1 and -finline-hint-functions flags
Ilod marked an inline comment as done. Comment at: test/Driver/cl-options.c:283 @@ -282,3 +282,2 @@ // RUN:/nologo \ -// RUN:/Ob1 \ // RUN:/openmp- \ hans wrote: > You're removing it from the ignored flags here, but I don't see any code > change or test for how clang-cl's supposed to handle it. What am I missing? Removing it from the ignored flags make if fallback to the generic /0 multi-param handling, in MSVCToolchain.cpp TranslateOptArg function. However I just checked that I forgot to forward the argument from the clang driver to cc1 in ConstructJob. Will add this (and a test for the driver) and submit a new patch. http://reviews.llvm.org/D20647 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20647: Add support for /Ob1 and -finline-hint-functions flags
Ilod updated this revision to Diff 61418. Ilod added a comment. Fixed passing argument from clang driver to cc1. Added driver tests. http://reviews.llvm.org/D20647 Files: include/clang/Driver/CLCompatOptions.td include/clang/Driver/Options.td include/clang/Frontend/CodeGenOptions.h lib/CodeGen/BackendUtil.cpp lib/CodeGen/CodeGenFunction.cpp lib/Driver/MSVCToolChain.cpp lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/inline-optim.c test/CodeGenCXX/inline-hint.cpp test/Driver/cl-options.c test/Driver/finline.c Index: test/Driver/finline.c === --- test/Driver/finline.c +++ test/Driver/finline.c @@ -0,0 +1,10 @@ +// Make sure the driver is correctly passing the -finline-functions family + +// RUN: %clang -target x86_64-apple-darwin10 -finline-functions -### -fsyntax-only %s 2>&1 | FileCheck -check-prefixes=INLINE,CHECK %s +// RUN: %clang -target x86_64-apple-darwin10 -finline-hint-functions -### -fsyntax-only %s 2>&1 | FileCheck -check-prefixes=HINT,CHECK %s +// RUN: %clang -target x86_64-apple-darwin10 -fno-inline-functions -### -fsyntax-only %s 2>&1 | FileCheck -check-prefixes=NOINLINE,CHECK %s + +// CHECK: clang +// INLINE: "-finline-functions" +// HINT: "-finline-hint-functions" +// NOINLINE: "-fno-inline-functions" Index: test/Driver/cl-options.c === --- test/Driver/cl-options.c +++ test/Driver/cl-options.c @@ -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 \ Index: test/CodeGenCXX/inline-hint.cpp === --- test/CodeGenCXX/inline-hint.cpp +++ test/CodeGenCXX/inline-hint.cpp @@ -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 implicitTplFunction(int a) { return N + a; } + template inline int explicitTplFunction(int a) { return N + a; } + template int noHintTplFunction(int a); + template 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 B::noHintTplFunction(int a) { return N + a; } +template 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: @_Z17constexprFuncti
Re: [PATCH] D20647: Add support for /Ob1 and -finline-hint-functions flags
Ilod marked 2 inline comments as done. Ilod added a comment. http://reviews.llvm.org/D20647 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D20647: Add support for /Ob1 and -finline-hint-functions flags
Ilod added a comment. Thanks. I will let you submit it for me if everything seems ok. http://reviews.llvm.org/D20647 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21385: Adjust Registry interface to not require plugins to export a registry
Ilod added a subscriber: Ilod. Ilod added a comment. Hello, When I tried your patch and added LLVM_EXPORT_SYMBOLS_FOR_PLUGINS=ON, I had multiple errors on your python scripts, like: File "utils/extract_symbols.py", line 399, in calling_convention_decoration = is_32bit_windows(libs[0]) File "utils/extract_symbols.py", line 88, in dumpbin_is_32bit_windows match = re.match('.+machine \((\S+)\)', line) File "C:\Program Files\Python35\lib\re.py", line 163, in match return _compile(pattern, flags).match(string) TypeError: cannot use a string pattern on a bytes-like object And after I fixed them by passing bytes-like object literals, I had the following error: File "utils/extract_symbols.py", line 488, in print >>outfile, str(k) TypeError: unsupported operand type(s) for >>: 'builtin_function_or_method' and '_io.TextIOWrapper' I gave up after this. I have Pyhton 3.5 64 bits, and was building clang 32-bits on Windows with Visual Studio 2015 Update 2. Looking at the patch: If I understand correctly, the pros/cons between your approach and the previous attempt are: - Your method allows to export the various symbols of the tool from the plugin, allowing mainly to access/modify global variables of it, instead of having another instance of it in the DLL (thus probably causing many bugs) - Previous attempt allowed to make a plugin which could be loaded by any tool, while yours need the plugin to be specific to a tool If that's all, I suppose it's better to have your limitation to plugin support rather than a full support which will bug if you call a function that accesses a static member. (By the way, the previous attempt works fine, it was reverted because of a mingw crash which can be fixed by the patch http://reviews.llvm.org/D18847) However, couldn't we enable by default LLVM_EXPORT_SYMBOLS_FOR_PLUGINS on the platforms/compilers which doesn't currently support the plugins? Having plugins only work on custom builds of clang seems to be against the main use of plugins. (If testing is the only problem, I would gladly test it on Windows with mingw, and maybe Mac if needed) Also, could you add in the documentation (cfe/trunk/docs/ClangPlugins.rst) what are the limitations/setup needed to make an out-of-tree plugin? Repository: rL LLVM http://reviews.llvm.org/D21385 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21385: Adjust Registry interface to not require plugins to export a registry
Ilod added a comment. In http://reviews.llvm.org/D21385#472268, @john.brawn wrote: > In http://reviews.llvm.org/D21385#471807, @Ilod wrote: > > > I gave up after this. I have Pyhton 3.5 64 bits, and was building clang > > 32-bits on Windows with Visual Studio 2015 Update 2. > > > python 3 isn't supported when building llvm/clang, according to llvm's > CMakeLists.txt. Oops, will try again tonight with Python 2. http://clang.llvm.org/get_started.html doesn't specify a version of Python, the LLVM webpage only say >= 2.7, and I ran the tests without any problem with Python 3 (but maybe some tests were automatically skipped?). Also, Python is also marked as only necessary to build the tests, which is no longer true with your script. Repository: rL LLVM http://reviews.llvm.org/D21385 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21385: Adjust Registry interface to not require plugins to export a registry
Ilod added a comment. The PrintFunctionNames plugin works fine, but not the SampleAnalyzerPlugin? The checker-plugins test fails. Not sure, but I suppose it's because the regitration method for checkers is different (a C method called clang_registerCheckers is retrieved in the DLL from the main program, then called with a CheckerRegistry - which is not related with the Registry class - on which a templated method addChecker is called). FAIL: Clang :: Analysis/checker-plugins.c (156 of 9493) TEST 'Clang :: Analysis/checker-plugins.c' FAILED Script: -- Debug/bin/clang.EXE -cc1 -internal-isystem Debug\bin\..\lib\clang\3.9.0\include -nostdsysteminc -load Debug/bin/SampleAnalyzerPlugin.dll -analyze -analyzer-checker='example.MainCallChecker' -verify tools\clang\test\Analysis\checker-plugins.c -- Exit Code: 1 Command Output (stdout): -- $ "Debug/bin/clang.EXE" "-cc1" "-internal-isystem" "Debug\bin\..\lib\clang\3.9.0\include" "-nostdsysteminc" "-load" "Debug/bin/SampleAnalyzerPlugin.dll" "-analyze" "-analyzer-checker=example.MainCallChecker" "-verify" "tools\clang\test\Analysis\checker-plugins.c" # command stderr: CUSTOMBUILD : error : 'error' diagnostics seen but not expected: (frontend): no analyzer checkers are associated with 'example.MainCallChecker' CUSTOMBUILD : error : 'warning' diagnostics expected but not seen: File tools\clang\test\Analysis\checker-plugins.c Line 9: call to main CUSTOMBUILD : error : 'note' diagnostics seen but not expected: (frontend): use -analyzer-disable-all-checks to disable all static analyzer checkers 3 errors generated. CUSTOMBUILD : error : command failed with exit status: 1 Repository: rL LLVM http://reviews.llvm.org/D21385 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21385: Adjust Registry interface to not require plugins to export a registry
Ilod added a comment. LGTM Plugins tests are still disabled by lit.cfg I think, as it only checks for enable_shared, which is disabled. I suppose we could wait for both this and the SampleAnalyzerPlugin to be patched before enabling plugins tests if we have LLVM_EXPORT_SYMBOLS_FOR_PLUGINS, as every plugin test should work after this. Repository: rL LLVM http://reviews.llvm.org/D21385 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21971: Explicitly export symbols from the sample analyzer plugin
Ilod added a comment. LGTM. Do you known if there is any good reason Analyzer plugins aren't using the Registry system (thus forcing plugin writers to manually export the functions)? Repository: rL LLVM http://reviews.llvm.org/D21971 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D21385: Adjust Registry interface to not require plugins to export a registry
Ilod added a comment. I don't have write access to SVN, so IIUC LLVM policy says I can't approve a patch. Repository: rL LLVM http://reviews.llvm.org/D21385 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits