[Frontend] Fix mcount inlining bug

Since some profiling tools, such as gprof, ftrace, and uftrace, use
-pg option to generate a mcount function call at the entry of each
function. Function invocation can be detected by this hook function.

But mcount insertion is done before function inlining phase in clang,
sometime a function that already has a mcount call can be inlined in the
middle of another function.

This patch adds an attribute "counting-function" to each function
rather than emitting the mcount call directly in frontend so that this
attribute can be processed in backend. Then the mcount calls can be
properly inserted in backend after all the other optimizations are
completed.

Link: https://llvm.org/bugs/show_bug.cgi?id=28660

Reviewers: hans, rjmccall, hfinkel, rengolin, compnerd

Subscribers: shenhan, cfe-commits

Differential Revision: https://reviews.llvm.org/D22666

llvm-svn: 280355
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 94c9fd7..1cf068f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -428,14 +428,6 @@
   EmitNounwindRuntimeCall(F, args);
 }
 
-void CodeGenFunction::EmitMCountInstrumentation() {
-  llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
-
-  llvm::Constant *MCountFn =
-    CGM.CreateRuntimeFunction(FTy, getTarget().getMCountName());
-  EmitNounwindRuntimeCall(MCountFn);
-}
-
 // OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument
 // information in the program executable. The argument information stored
 // includes the argument name, its type, the address and access qualifiers used.
@@ -794,8 +786,12 @@
   if (ShouldInstrumentFunction())
     EmitFunctionInstrumentation("__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.
+  // The attribute "counting-function" is set to mcount function name which is
+  // architecture dependent.
   if (CGM.getCodeGenOpts().InstrumentForProfiling)
-    EmitMCountInstrumentation();
+    Fn->addFnAttr("counting-function", getTarget().getMCountName());
 
   if (RetTy->isVoidType()) {
     // Void type; nothing to return.