diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 50 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 5 | ||||
-rw-r--r-- | clang/lib/Driver/ToolChains/Clang.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 2 |
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); |