summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp50
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h5
-rw-r--r--clang/lib/Driver/ToolChains/Clang.cpp3
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp2
4 files changed, 22 insertions, 38 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 37d174dd663..8544da3da7f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -354,8 +354,12 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
// Emit function epilog (to return).
llvm::DebugLoc Loc = EmitReturnBlock();
- if (ShouldInstrumentFunction())
- EmitFunctionInstrumentation("__cyg_profile_func_exit");
+ if (ShouldInstrumentFunction()) {
+ CurFn->addFnAttr(!CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining
+ ? "instrument-function-exit"
+ : "instrument-function-exit-inlined",
+ "__cyg_profile_func_exit");
+ }
// Emit debug descriptor for function end.
if (CGDebugInfo *DI = getDebugInfo())
@@ -438,7 +442,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
/// ShouldInstrumentFunction - Return true if the current function should be
/// instrumented with __cyg_profile_func_* calls
bool CodeGenFunction::ShouldInstrumentFunction() {
- if (!CGM.getCodeGenOpts().InstrumentFunctions)
+ if (!CGM.getCodeGenOpts().InstrumentFunctions &&
+ !CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining)
return false;
if (!CurFuncDecl || CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>())
return false;
@@ -488,31 +493,6 @@ CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F,
"decoded_addr");
}
-/// 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) {
- auto NL = ApplyDebugLocation::CreateArtificial(*this);
- // void __cyg_profile_func_{enter,exit} (void *this_fn, void *call_site);
- llvm::PointerType *PointerTy = Int8PtrTy;
- llvm::Type *ProfileFuncArgs[] = { PointerTy, PointerTy };
- llvm::FunctionType *FunctionTy =
- llvm::FunctionType::get(VoidTy, ProfileFuncArgs, false);
-
- llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn);
- llvm::CallInst *CallSite = Builder.CreateCall(
- CGM.getIntrinsic(llvm::Intrinsic::returnaddress),
- llvm::ConstantInt::get(Int32Ty, 0),
- "callsite");
-
- llvm::Value *args[] = {
- llvm::ConstantExpr::getBitCast(CurFn, PointerTy),
- CallSite
- };
-
- EmitNounwindRuntimeCall(F, args);
-}
-
static void removeImageAccessQualifier(std::string& TyName) {
std::string ReadOnlyQual("__read_only");
std::string::size_type ReadOnlyPos = TyName.find(ReadOnlyQual);
@@ -1001,8 +981,12 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
DI->EmitFunctionStart(GD, Loc, StartLoc, FnType, CurFn, Builder);
}
- if (ShouldInstrumentFunction())
- EmitFunctionInstrumentation("__cyg_profile_func_enter");
+ if (ShouldInstrumentFunction()) {
+ Fn->addFnAttr(!CGM.getCodeGenOpts().InstrumentFunctionsAfterInlining
+ ? "instrument-function-entry"
+ : "instrument-function-entry-inlined",
+ "__cyg_profile_func_enter");
+ }
// Since emitting the mcount call here impacts optimizations such as function
// inlining, we just add an attribute to insert a mcount call in backend.
@@ -1012,8 +996,10 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
if (CGM.getCodeGenOpts().CallFEntry)
Fn->addFnAttr("fentry-call", "true");
else {
- if (!CurFuncDecl || !CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>())
- Fn->addFnAttr("counting-function", getTarget().getMCountName());
+ if (!CurFuncDecl || !CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>()) {
+ Fn->addFnAttr("instrument-function-entry-inlined",
+ getTarget().getMCountName());
+ }
}
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 0165e5f45df..6a2c8ab7800 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1784,11 +1784,6 @@ public:
/// 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);
-
/// Encode an address into a form suitable for use in a function prologue.
llvm::Constant *EncodeAddrForUseInPrologue(llvm::Function *F,
llvm::Constant *Addr);
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index ce901dac26f..8a2d6018655 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -3545,7 +3545,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_fno_unique_section_names, true))
CmdArgs.push_back("-fno-unique-section-names");
- Args.AddAllArgs(CmdArgs, options::OPT_finstrument_functions);
+ Args.AddLastArg(CmdArgs, options::OPT_finstrument_functions,
+ options::OPT_finstrument_functions_after_inlining);
addPGOAndCoverageFlags(C, D, Output, Args, CmdArgs);
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index ca1c65e95a4..41b6d1467f8 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -777,6 +777,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.PreserveVec3Type = Args.hasArg(OPT_fpreserve_vec3_type);
Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions);
+ Opts.InstrumentFunctionsAfterInlining =
+ Args.hasArg(OPT_finstrument_functions_after_inlining);
Opts.XRayInstrumentFunctions = Args.hasArg(OPT_fxray_instrument);
Opts.XRayInstructionThreshold =
getLastArgIntValue(Args, OPT_fxray_instruction_threshold_EQ, 200, Diags);
OpenPOWER on IntegriCloud