diff options
author | Robert Grosse <grosse@chromium.org> | 2013-07-25 14:34:41 -0700 |
---|---|---|
committer | Robert Grosse <grosse@chromium.org> | 2013-07-25 14:34:41 -0700 |
commit | 7b390888fd9f3886d966ab072c328f4fbd9c64b4 (patch) | |
tree | 61d7d80f47627e5736931a1ae488377c92594f4c | |
parent | 0adde5bbb53bfb2aadcb566c514efd3e218bf0bc (diff) |
Add a -finstrument-functions-size=n option to control basic block
filtering. If omitted entirely, the original behavior is restored.
This also undos the string and __pnacl_profile stuff from the previous
CL. Finally, it fixes and updates the -finstrument-function tests.
BUG=none
R=bradnelson@google.com, dschuff@chromium.org
Review URL: https://codereview.chromium.org/19793007
-rw-r--r-- | include/clang/Driver/CC1Options.td | 2 | ||||
-rw-r--r-- | include/clang/Driver/Options.td | 2 | ||||
-rw-r--r-- | include/clang/Frontend/CodeGenOptions.def | 3 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 22 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 5 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 2 | ||||
-rw-r--r-- | test/CodeGen/instrument-functions-size.c | 28 | ||||
-rw-r--r-- | test/CodeGen/instrument-functions.c | 8 | ||||
-rw-r--r-- | test/CodeGenCXX/instrument-functions-size.cpp | 28 | ||||
-rw-r--r-- | test/CodeGenCXX/instrument-functions.cpp | 8 |
10 files changed, 94 insertions, 14 deletions
diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 96a50fc5c6..eaa67ab1db 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -456,6 +456,8 @@ def fdeprecated_macro : Flag<["-"], "fdeprecated-macro">, HelpText<"Defines the __DEPRECATED macro">; def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, HelpText<"Undefines the __DEPRECATED macro">; +def finstrument_functions_size : Separate<["-"], "finstrument-functions-size">, + HelpText<"Minimum size of functions to instrument">; //===----------------------------------------------------------------------===// // Header Search Options diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 3a5358a7e3..fea7ba3c00 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -484,6 +484,8 @@ def finline_functions : Flag<["-"], "finline-functions">, Group<clang_ignored_f_ def finline : Flag<["-"], "finline">, Group<clang_ignored_f_Group>; def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>, HelpText<"Generate calls to instrument function entry and exit">; +def finstrument_functions_size_EQ : Joined<["-"], "finstrument-functions-size=">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Set a minimum number of basic blocks for function instrumentation">; def fkeep_inline_functions : Flag<["-"], "fkeep-inline-functions">, Group<clang_ignored_f_Group>; def flat__namespace : Flag<["-"], "flat_namespace">; def flax_vector_conversions : Flag<["-"], "flax-vector-conversions">, Group<f_Group>; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index f6e2472cb9..63516e8684 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -62,6 +62,9 @@ CODEGENOPT(HiddenWeakVTables , 1, 0) ///< Emit weak vtables, RTTI, and thunks wi ///< hidden visibility. CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is ///< enabled. +VALUE_CODEGENOPT(InstrumentFunctionsSize, 32, 0) ///< If set, only functions with + ///< at least this many basic + ///< blocks are instrumented. CODEGENOPT(InstrumentForProfiling , 1, 0) ///< Set when -pg is enabled. CODEGENOPT(LessPreciseFPMAD , 1, 0) ///< Enable less precise MAD instructions to ///< be generated. diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 75c60edbba..a3c39649b7 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -222,8 +222,18 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { // Emit function epilog (to return). EmitReturnBlock(); - if (ShouldInstrumentFunction()) - EmitFunctionInstrumentation("__cyg_profile_func_exit"); + if (ShouldInstrumentFunction()) { + // The size of the function isn't known during StartFunction, so in order + // to instrument selectively based on function size, we need to wait + // until the end and insert both the entry and exit instrumentation + llvm::BasicBlock *CurBlock = Builder.GetInsertBlock(); + llvm::BasicBlock *BeginBlock = &CurFn->getEntryBlock(); + + Builder.SetInsertPoint(BeginBlock, BeginBlock->begin()); + EmitFunctionInstrumentation("__cyg_profile_func_enter"); + Builder.SetInsertPoint(CurBlock); + EmitFunctionInstrumentation("__cyg_profile_func_exit"); + } // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) { @@ -274,7 +284,10 @@ bool CodeGenFunction::ShouldInstrumentFunction() { return false; if (!CurFuncDecl || CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>()) return false; - return true; + + // If not specified, defaults to 0. + int Size = CGM.getCodeGenOpts().InstrumentFunctionsSize; + return CurFn->getBasicBlockList().size() >= Size; } /// EmitFunctionInstrumentation - Emit LLVM code to call the specified @@ -541,9 +554,6 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, DI->EmitFunctionStart(GD, FnType, CurFn, Builder); } - if (ShouldInstrumentFunction()) - EmitFunctionInstrumentation("__cyg_profile_func_enter"); - if (CGM.getCodeGenOpts().InstrumentForProfiling) EmitMCountInstrumentation(); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index aba1fe4d2d..c04fc13b23 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -2462,6 +2462,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions); + if (Arg *A = Args.getLastArg(options::OPT_finstrument_functions_size_EQ)) { + CmdArgs.push_back("-finstrument-functions-size"); + CmdArgs.push_back(A->getValue()); + } + if (Args.hasArg(options::OPT_ftest_coverage) || Args.hasArg(options::OPT_coverage)) CmdArgs.push_back("-femit-coverage-notes"); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 42ea96f0f2..06d8b12e6c 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -407,6 +407,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions); + Opts.InstrumentFunctionsSize = + Args.getLastArgIntValue(OPT_finstrument_functions_size, 0); Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); Opts.EmitOpenCLArgMetadata = Args.hasArg(OPT_cl_kernel_arg_info); Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); diff --git a/test/CodeGen/instrument-functions-size.c b/test/CodeGen/instrument-functions-size.c new file mode 100644 index 0000000000..d7905a9ed0 --- /dev/null +++ b/test/CodeGen/instrument-functions-size.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions -finstrument-functions-size 2 | FileCheck %s + +// CHECK: define i32 @test1 +int test1(int x) { +// CHECK-NOT: __cyg_profile_func_enter +// CHECK-NOT: __cyg_profile_func_exit +// CHECK: ret i32 + return x; +} + +// CHECK: define i32 @test2 +int test2(int) __attribute__((no_instrument_function)); +int test2(int x) { + if(x) {test1(x);} +// CHECK-NOT: __cyg_profile_func_enter +// CHECK-NOT: __cyg_profile_func_exit +// CHECK: ret i32 + return x; +} + +// CHECK: define i32 @test3 +int test3(int x) { + if(x) {test1(x);} +// CHECK: __cyg_profile_func_enter +// CHECK: __cyg_profile_func_exit +// CHECK: ret i32 + return x; +} diff --git a/test/CodeGen/instrument-functions.c b/test/CodeGen/instrument-functions.c index d80385e223..41275c76dc 100644 --- a/test/CodeGen/instrument-functions.c +++ b/test/CodeGen/instrument-functions.c @@ -1,18 +1,18 @@ // RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s -// CHECK: @test1 +// CHECK: define i32 @test1 int test1(int x) { // CHECK: __cyg_profile_func_enter // CHECK: __cyg_profile_func_exit -// CHECK: ret +// CHECK: ret i32 return x; } -// CHECK: @test2 +// CHECK: define i32 @test2 int test2(int) __attribute__((no_instrument_function)); int test2(int x) { // CHECK-NOT: __cyg_profile_func_enter // CHECK-NOT: __cyg_profile_func_exit -// CHECK: ret +// CHECK: ret i32 return x; } diff --git a/test/CodeGenCXX/instrument-functions-size.cpp b/test/CodeGenCXX/instrument-functions-size.cpp new file mode 100644 index 0000000000..6fcb839ca1 --- /dev/null +++ b/test/CodeGenCXX/instrument-functions-size.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions -finstrument-functions-size 2 | FileCheck %s + +// CHECK: define i32 @_Z5test1i +int test1(int x) { +// CHECK-NOT: __cyg_profile_func_enter +// CHECK-NOT: __cyg_profile_func_exit +// CHECK: ret i32 + return x; +} + +// CHECK: define i32 @_Z5test2i +int test2(int) __attribute__((no_instrument_function)); +int test2(int x) { + if(x) {test1(x);} +// CHECK-NOT: __cyg_profile_func_enter +// CHECK-NOT: __cyg_profile_func_exit +// CHECK: ret i32 + return x; +} + +// CHECK: define i32 @_Z5test3i +int test3(int x) { + if(x) {test1(x);} +// CHECK: __cyg_profile_func_enter +// CHECK: __cyg_profile_func_exit +// CHECK: ret i32 + return x; +} diff --git a/test/CodeGenCXX/instrument-functions.cpp b/test/CodeGenCXX/instrument-functions.cpp index 253e096108..35d35dd1c9 100644 --- a/test/CodeGenCXX/instrument-functions.cpp +++ b/test/CodeGenCXX/instrument-functions.cpp @@ -1,19 +1,19 @@ // RUN: %clang_cc1 -S -emit-llvm -o - %s -finstrument-functions | FileCheck %s -// CHECK: @_Z5test1i +// CHECK: define i32 @_Z5test1i int test1(int x) { // CHECK: __cyg_profile_func_enter // CHECK: __cyg_profile_func_exit -// CHECK: ret +// CHECK: ret i32 return x; } -// CHECK: @_Z5test2i +// CHECK: define i32 @_Z5test2i int test2(int) __attribute__((no_instrument_function)); int test2(int x) { // CHECK-NOT: __cyg_profile_func_enter // CHECK-NOT: __cyg_profile_func_exit -// CHECK: ret +// CHECK: ret i32 return x; } |