hans created this revision.
This adds two flags:
-fno-cygprofile-exit Don't insert any calls for function exit.
-fno-cygprofile-args Don't pass any arguments to the cygprofile functions (the
implementer has to figure out the caller address themselves)
These are useful for reducing the size and run-time overhead of the
instrumentation.
https://reviews.llvm.org/D39331
Files:
include/clang/Driver/Options.td
include/clang/Frontend/CodeGenOptions.def
lib/CodeGen/CodeGenFunction.cpp
lib/CodeGen/CodeGenFunction.h
lib/Driver/ToolChains/Clang.cpp
lib/Frontend/CompilerInvocation.cpp
test/CodeGen/instrument-functions.c
Index: test/CodeGen/instrument-functions.c
===================================================================
--- test/CodeGen/instrument-functions.c
+++ test/CodeGen/instrument-functions.c
@@ -1,18 +1,27 @@
-// RUN: %clang_cc1 -S -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-functions | FileCheck %s
+// RUN: %clang_cc1 -S -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-functions | FileCheck --check-prefix=DEFAULT --check-prefix=CHECK %s
+// RUN: %clang_cc1 -S -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-functions -fno-cygprofile-exit | FileCheck --check-prefix=NOEXIT --check-prefix=CHECK %s
+// RUN: %clang_cc1 -S -debug-info-kind=standalone -emit-llvm -o - %s -finstrument-functions -fno-cygprofile-args | FileCheck --check-prefix=NOARGS --check-prefix=CHECK %s
-// CHECK: @test1
+// CHECK-LABEL: @test1
int test1(int x) {
-// CHECK: call void @__cyg_profile_func_enter({{.*}}, !dbg
-// CHECK: call void @__cyg_profile_func_exit({{.*}}, !dbg
-// CHECK: ret
+// DEFAULT: call void @__cyg_profile_func_enter(i8*{{.*}}, i8*{{.*}}){{.*}}, !dbg
+// DEFAULT: call void @__cyg_profile_func_exit(i8*{{.*}}, i8*{{.*}}){{.*}}, !dbg
+
+// NOEXIT: call void @__cyg_profile_func_enter(i8*{{.*}}, i8*{{.*}}){{.*}}, !dbg
+// NOEXIT-NOT: @__cyg_profile_func_exit
+
+// NOARGS: call void @__cyg_profile_func_enter(){{.*}}, !dbg
+// NOARGS: call void @__cyg_profile_func_exit(){{.*}}, !dbg
+
+// CHECK: ret i32 %0
return x;
}
-// CHECK: @test2
+// CHECK-LABEL: @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 %0
return x;
}
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -776,6 +776,8 @@
Opts.PreserveVec3Type = Args.hasArg(OPT_fpreserve_vec3_type);
Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
+ Opts.CygProfileExit = !Args.hasArg(OPT_fno_cygprofile_exit);
+ Opts.CygProfileArgs = !Args.hasArg(OPT_fno_cygprofile_args);
Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument);
Opts.XRayInstructionThreshold =
getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -3553,6 +3553,8 @@
CmdArgs.push_back("-fno-unique-section-names");
Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
+ Args.AddAllArgs(CmdArgs, options::OPT_fno_cygprofile_exit);
+ Args.AddAllArgs(CmdArgs, options::OPT_fno_cygprofile_args);
addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -1773,17 +1773,20 @@
void EnterDtorCleanups(const CXXDestructorDecl *Dtor, CXXDtorType Type);
/// ShouldInstrumentFunction - Return true if the current function should be
- /// instrumented with __cyg_profile_func_* calls
- bool ShouldInstrumentFunction();
+ /// instrumented with __cyg_profile_func_* calls. If true, sets CygProfileExit
+ /// and CygProfileArgs to indicate whether function exit should be
+ /// instrumented and whether the __cyg_profile calls take arguments,
+ /// respectively.
+ bool ShouldInstrumentFunction(bool *CygProfileExit, bool *CygProfileArgs);
/// ShouldXRayInstrument - Return true if the current function should be
/// instrumented with XRay nop sleds.
bool ShouldXRayInstrumentFunction() const;
/// EmitFunctionInstrumentation - Emit LLVM code to call the specified
- /// instrumentation function with the current function and the call site, if
- /// function instrumentation is enabled.
- void EmitFunctionInstrumentation(const char *Fn);
+ /// instrumentation function with the current function and the call site.
+ /// If CygProfileArgs is false, don't pass any arguments to the function.
+ void EmitFunctionInstrumentation(const char *Fn, bool CygProfileArgs);
/// EmitMCountInstrumentation - Emit call to .mcount.
void EmitMCountInstrumentation();
Index: lib/CodeGen/CodeGenFunction.cpp
===================================================================
--- lib/CodeGen/CodeGenFunction.cpp
+++ lib/CodeGen/CodeGenFunction.cpp
@@ -352,8 +352,9 @@
// Emit function epilog (to return).
llvm::DebugLoc Loc = EmitReturnBlock();
- if (ShouldInstrumentFunction())
- EmitFunctionInstrumentation("__cyg_profile_func_exit");
+ bool CygProfileExit, CygProfileArgs;
+ if (ShouldInstrumentFunction(&CygProfileExit, &CygProfileArgs) && CygProfileExit)
+ EmitFunctionInstrumentation("__cyg_profile_func_exit", CygProfileArgs);
// Emit debug descriptor for function end.
if (CGDebugInfo *DI = getDebugInfo())
@@ -423,11 +424,16 @@
/// ShouldInstrumentFunction - Return true if the current function should be
/// instrumented with __cyg_profile_func_* calls
-bool CodeGenFunction::ShouldInstrumentFunction() {
+bool CodeGenFunction::ShouldInstrumentFunction(bool *CygProfileExit,
+ bool *CygProfileArgs) {
if (!CGM.getCodeGenOpts().InstrumentFunctions)
return false;
if (!CurFuncDecl || CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>())
return false;
+
+ *CygProfileExit = CGM.getCodeGenOpts().CygProfileExit;
+ *CygProfileArgs = CGM.getCodeGenOpts().CygProfileArgs;
+
return true;
}
@@ -477,8 +483,18 @@
/// EmitFunctionInstrumentation - Emit LLVM code to call the specified
/// instrumentation function with the current function and the call site, if
/// function instrumentation is enabled.
-void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) {
+void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn,
+ bool CygProfileArgs) {
auto NL = ApplyDebugLocation::CreateArtificial(*this);
+
+ if (!CygProfileArgs) {
+ // Call the function without passing any arguments.
+ llvm::FunctionType *FunctionTy = llvm::FunctionType::get(VoidTy, false);
+ llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn);
+ EmitNounwindRuntimeCall(F);
+ return;
+ }
+
// void __cyg_profile_func_{enter,exit} (void *this_fn, void *call_site);
llvm::PointerType *PointerTy = Int8PtrTy;
llvm::Type *ProfileFuncArgs[] = { PointerTy, PointerTy };
@@ -987,8 +1003,9 @@
DI->EmitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, Builder);
}
- if (ShouldInstrumentFunction())
- EmitFunctionInstrumentation("__cyg_profile_func_enter");
+ bool CygProfileExit, CygProfileArgs;
+ if (ShouldInstrumentFunction(&CygProfileExit, &CygProfileArgs))
+ EmitFunctionInstrumentation("__cyg_profile_func_enter", CygProfileArgs);
// Since emitting the mcount call here impacts optimizations such as function
// inlining, we just add an attribute to insert a mcount call in backend.
Index: include/clang/Frontend/CodeGenOptions.def
===================================================================
--- include/clang/Frontend/CodeGenOptions.def
+++ include/clang/Frontend/CodeGenOptions.def
@@ -76,7 +76,11 @@
CODEGENOPT(FunctionSections , 1, 0) ///< Set when -ffunction-sections is enabled.
CODEGENOPT(InstrumentFunctions , 1, 0) ///< Set when -finstrument-functions is
///< enabled.
-
+CODEGENOPT(CygProfileExit , 1, 1) ///< Whether to instrument function exits
+ ///< when using InstrumentFunctions.
+CODEGENOPT(CygProfileArgs , 1, 1) ///< Whether to pass arguments to the
+ ///< __cyg_profile* functions when using
+ ///< InstrumentFunctions.
CODEGENOPT(XRayInstrumentFunctions , 1, 0) ///< Set when -fxray-instrument is
///< enabled.
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -1025,6 +1025,10 @@
def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
def finstrument_functions : Flag<["-"], "finstrument-functions">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Generate calls to instrument function entry and exit">;
+def fno_cygprofile_exit : Flag<["-"], "fno-cygprofile-exit">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"When using -finstrument-functions, don't instrument function exit">;
+def fno_cygprofile_args : Flag<["-"], "fno-cygprofile-args">, Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"When using -finstrument-functions, don't pass any arguments to the __cyg_profile* functions">;
def fxray_instrument : Flag<["-"], "fxray-instrument">, Group<f_Group>,
Flags<[CC1Option]>,
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits