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 | 3c77a355e0850ba09c868850870663d6e1a3bc3c (patch) | |
| tree | b187bba6508fa661db2f1a57ec53fdeaa58c6223 /clang/lib/CodeGen/CodeGenFunction.cpp | |
| parent | b2c4a99d522bd8851b36b13809ce67be16a81bdb (diff) | |
| download | llvm-3c77a355e0850ba09c868850870663d6e1a3bc3c.zip llvm-3c77a355e0850ba09c868850870663d6e1a3bc3c.tar.gz llvm-3c77a355e0850ba09c868850870663d6e1a3bc3c.tar.bz2 | |
implement support for -finstrument-functions, patch by Nelson
Elhage!
llvm-svn: 106507
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index af06235..8a0b41a 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/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, |
