From be4c8705e499b55548467eb7adaa23cbc6edfef9 Mon Sep 17 00:00:00 2001 From: Roman Divacky Date: Thu, 10 Feb 2011 16:52:03 +0000 Subject: [PATCH] Implement mcount profiling, enabled via -pg. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@125282 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/TargetInfo.h | 6 ++++++ include/clang/Driver/CC1Options.td | 1 + include/clang/Frontend/CodeGenOptions.h | 2 ++ lib/Basic/TargetInfo.cpp | 1 + lib/Basic/Targets.cpp | 19 +++++++++++++++++++ lib/CodeGen/CodeGenFunction.cpp | 12 ++++++++++++ lib/CodeGen/CodeGenFunction.h | 3 +++ lib/Driver/Tools.cpp | 12 +++++------- lib/Frontend/CompilerInvocation.cpp | 1 + 9 files changed, 50 insertions(+), 7 deletions(-) diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 57ddb91b1d..586680bbd0 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -76,6 +76,7 @@ protected: unsigned char LongLongWidth, LongLongAlign; const char *DescriptionString; const char *UserLabelPrefix; + const char *MCountName; const llvm::fltSemantics *FloatFormat, *DoubleFormat, *LongDoubleFormat; unsigned char RegParmMax, SSERegParmMax; TargetCXXABI CXXABI; @@ -243,6 +244,11 @@ public: return UserLabelPrefix; } + /// MCountName - This returns name of the mcount instrumentation function. + const char *getMCountName() const { + return MCountName; + } + bool useBitFieldTypeAlignment() const { return UseBitFieldTypeAlignment; } diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 3160e96339..fda194bb4a 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -191,6 +191,7 @@ def mms_bitfields : Flag<"-mms-bitfields">, HelpText<"Set the default structure layout to be compatible with the Microsoft compiler standard.">; def O : Joined<"-O">, HelpText<"Optimization level">; def Os : Flag<"-Os">, HelpText<"Optimize for size">; +def pg : Flag<"-pg">, HelpText<"Enable mcount instrumentation">; //===----------------------------------------------------------------------===// // Dependency Output Options diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index 66c9409fe5..ee85b655c2 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -58,6 +58,7 @@ public: /// hidden visibility. unsigned InstrumentFunctions : 1; /// Set when -finstrument-functions is /// enabled. + unsigned InstrumentForProfiling : 1; /// Set when -pg is enabled unsigned LessPreciseFPMAD : 1; /// Enable less precise MAD instructions to be /// generated. unsigned MergeAllConstants : 1; /// Merge identical constants. @@ -131,6 +132,7 @@ public: HiddenWeakTemplateVTables = 0; HiddenWeakVTables = 0; InstrumentFunctions = 0; + InstrumentForProfiling = 0; LessPreciseFPMAD = 0; MergeAllConstants = 1; NoCommon = 0; diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp index 17de01b4e1..a9eeb8b4cc 100644 --- a/lib/Basic/TargetInfo.cpp +++ b/lib/Basic/TargetInfo.cpp @@ -56,6 +56,7 @@ TargetInfo::TargetInfo(const std::string &T) : Triple(T) { DescriptionString = "E-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-" "i64:64:64-f32:32:32-f64:64:64-n32"; UserLabelPrefix = "_"; + MCountName = "mcount"; HasAlignMac68kSupport = false; // Default to no types using fpret. diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 6888117725..2af28d663c 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -210,6 +210,25 @@ public: FreeBSDTargetInfo(const std::string &triple) : OSTargetInfo(triple) { this->UserLabelPrefix = ""; + + llvm::Triple Triple(triple); + switch (Triple.getArch()) { + default: + case llvm::Triple::x86: + case llvm::Triple::x86_64: + this->MCountName = ".mcount"; + break; + case llvm::Triple::mips: + case llvm::Triple::mipsel: + case llvm::Triple::ppc: + case llvm::Triple::ppc64: + this->MCountName = "_mcount"; + break; + case llvm::Triple::arm: + this->MCountName = "__mcount"; + break; + } + } }; diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 66114c87a4..364f2697e6 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -210,6 +210,15 @@ void CodeGenFunction::EmitFunctionInstrumentation(const char *Fn) { CallSite); } +void CodeGenFunction::EmitMCountInstrumentation() { + llvm::FunctionType *FTy = + llvm::FunctionType::get(llvm::Type::getVoidTy(getLLVMContext()), false); + + llvm::Constant *MCountFn = CGM.CreateRuntimeFunction(FTy, + Target.getMCountName()); + Builder.CreateCall(MCountFn); +} + void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const FunctionArgList &Args, @@ -260,6 +269,9 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, EmitFunctionInstrumentation("__cyg_profile_func_enter"); + if (CGM.getCodeGenOpts().InstrumentForProfiling) + EmitMCountInstrumentation(); + // FIXME: Leaked. // CC info is ignored, hopefully? CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args, diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h index 19fbf5ca98..1fe1c3fda9 100644 --- a/lib/CodeGen/CodeGenFunction.h +++ b/lib/CodeGen/CodeGenFunction.h @@ -1087,6 +1087,9 @@ public: /// function instrumentation is enabled. void EmitFunctionInstrumentation(const char *Fn); + /// EmitMCountInstrumentation - Emit call to .mcount. + void EmitMCountInstrumentation(); + /// EmitFunctionProlog - Emit the target specific LLVM code to load the /// arguments for the given function. This is also responsible for naming the /// LLVM function arguments. diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index fdc2b82cb8..a1ae8b19a1 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1313,6 +1313,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls); Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions); Args.AddLastArg(CmdArgs, options::OPT_flimit_debug_info); + Args.AddLastArg(CmdArgs, options::OPT_pg); // -flax-vector-conversions is default. if (!Args.hasFlag(options::OPT_flax_vector_conversions, @@ -1743,13 +1744,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, C.addCommand(new Command(JA, *this, Exec, CmdArgs)); - // Explicitly warn that these options are unsupported, even though - // we are allowing compilation to continue. - for (arg_iterator it = Args.filtered_begin(options::OPT_pg), - ie = Args.filtered_end(); it != ie; ++it) { - (*it)->claim(); - D.Diag(clang::diag::warn_drv_clang_unsupported) << (*it)->getAsString(Args); - } + if (Arg *A = Args.getLastArg(options::OPT_pg)) + if (Args.hasArg(options::OPT_fomit_frame_pointer)) + D.Diag(clang::diag::err_drv_argument_not_allowed_with) + << "-fomit-frame-pointer" << A->getAsString(Args); // Claim some arguments which clang supports automatically. diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 3108477e3a..21038565e1 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -948,6 +948,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.VerifyModule = !Args.hasArg(OPT_disable_llvm_verifier); Opts.InstrumentFunctions = Args.hasArg(OPT_finstrument_functions); + Opts.InstrumentForProfiling = Args.hasArg(OPT_pg); if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { llvm::StringRef Name = A->getValue(Args); -- 2.40.0