aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Grosse <grosse@chromium.org>2013-07-25 14:34:41 -0700
committerRobert Grosse <grosse@chromium.org>2013-07-25 14:34:41 -0700
commit7b390888fd9f3886d966ab072c328f4fbd9c64b4 (patch)
tree61d7d80f47627e5736931a1ae488377c92594f4c
parent0adde5bbb53bfb2aadcb566c514efd3e218bf0bc (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.td2
-rw-r--r--include/clang/Driver/Options.td2
-rw-r--r--include/clang/Frontend/CodeGenOptions.def3
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp22
-rw-r--r--lib/Driver/Tools.cpp5
-rw-r--r--lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--test/CodeGen/instrument-functions-size.c28
-rw-r--r--test/CodeGen/instrument-functions.c8
-rw-r--r--test/CodeGenCXX/instrument-functions-size.cpp28
-rw-r--r--test/CodeGenCXX/instrument-functions.cpp8
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;
}