diff options
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,  | 
