diff options
author | Chris Lattner <sabre@nondot.org> | 2010-06-22 00:03:40 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-06-22 00:03:40 +0000 |
commit | 7255a2d997b15beae82e627052fdb1b2474495c2 (patch) | |
tree | 63ef52287521415eca80d519c06a565f6fd0ba1a /lib/CodeGen/CodeGenFunction.cpp | |
parent | 43dec6bbde2d0a16c35978983761c8b7030c8e18 (diff) |
implement support for -finstrument-functions, patch by Nelson
Elhage!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106507 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | lib/CodeGen/CodeGenFunction.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index af062356f6..8a0b41a7ca 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -20,7 +20,9 @@ #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/StmtCXX.h" +#include "clang/Frontend/CodeGenOptions.h" #include "llvm/Target/TargetData.h" +#include "llvm/Intrinsics.h" using namespace clang; using namespace CodeGen; @@ -127,6 +129,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { // Emit function epilog (to return). EmitReturnBlock(); + EmitFunctionInstrumentation("__cyg_profile_func_exit"); + // Emit debug descriptor for function end. if (CGDebugInfo *DI = getDebugInfo()) { DI->setLocation(EndLoc); @@ -159,6 +163,41 @@ 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) + return false; + if (CurFuncDecl->hasAttr<NoInstrumentFunctionAttr>()) + return false; + return true; +} + +/// 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) { + if (!ShouldInstrumentFunction()) + return; + + const llvm::FunctionType *FunctionTy; + std::vector<const llvm::Type*> ProfileFuncArgs; + + ProfileFuncArgs.push_back(CurFn->getType()); + ProfileFuncArgs.push_back(llvm::Type::getInt8PtrTy(VMContext)); + FunctionTy = llvm::FunctionType::get( + llvm::Type::getVoidTy(VMContext), + ProfileFuncArgs, false); + + llvm::Constant *F = CGM.CreateRuntimeFunction(FunctionTy, Fn); + llvm::CallInst *CallSite = Builder.CreateCall( + CGM.getIntrinsic(llvm::Intrinsic::returnaddress, 0, 0), + llvm::ConstantInt::get(llvm::Type::getInt32Ty(VMContext), 0), + "callsite"); + + Builder.CreateCall2(F, CurFn, CallSite); +} + void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, llvm::Function *Fn, const FunctionArgList &Args, @@ -208,6 +247,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, DI->EmitFunctionStart(GD, FnType, CurFn, Builder); } + EmitFunctionInstrumentation("__cyg_profile_func_enter"); + // FIXME: Leaked. // CC info is ignored, hopefully? CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args, |