Author: honggyu.kim Date: Thu Sep 1 06:29:21 2016 New Revision: 280355 URL: http://llvm.org/viewvc/llvm-project?rev=280355&view=rev Log: [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 Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp cfe/trunk/test/CodeGen/mcount.c cfe/trunk/test/Frontend/gnu-mcount.c Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=280355&r1=280354&r2=280355&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Thu Sep 1 06:29:21 2016 @@ -428,14 +428,6 @@ void CodeGenFunction::EmitFunctionInstru 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 @@ void CodeGenFunction::StartFunction(Glob 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. Modified: cfe/trunk/test/CodeGen/mcount.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/mcount.c?rev=280355&r1=280354&r2=280355&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/mcount.c (original) +++ cfe/trunk/test/CodeGen/mcount.c Thu Sep 1 06:29:21 2016 @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -pg -triple i386-unknown-unknown -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -pg -triple i386-unknown-unknown -emit-llvm -O2 -o - %s | FileCheck %s // RUN: %clang_cc1 -pg -triple powerpc-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s // RUN: %clang_cc1 -pg -triple powerpc64-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s // RUN: %clang_cc1 -pg -triple powerpc64le-unknown-gnu-linux -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s @@ -12,7 +13,20 @@ // RUN: %clang_cc1 -pg -triple powerpc64le-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s // RUN: %clang_cc1 -pg -triple sparc-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s // RUN: %clang_cc1 -pg -triple sparc64-netbsd -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-PREFIXED %s -void foo(void) { -// CHECK: call void @mcount() -// CHECK-PREFIXED: call void @_mcount() +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s -check-prefix=NO-MCOUNT + +int bar(void) { + return 0; } + +int foo(void) { + return bar(); +} + +int main(void) { + return foo(); +} + +// CHECK: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-PREFIXED: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="_mcount"{{.*}} } +// NO-MCOUNT-NOT: attributes #{{[0-9]}} = { {{.*}}"counting-function"={{.*}} } Modified: cfe/trunk/test/Frontend/gnu-mcount.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/gnu-mcount.c?rev=280355&r1=280354&r2=280355&view=diff ============================================================================== --- cfe/trunk/test/Frontend/gnu-mcount.c (original) +++ cfe/trunk/test/Frontend/gnu-mcount.c Thu Sep 1 06:29:21 2016 @@ -44,35 +44,35 @@ int f() { } // CHECK-LABEL: f -// CHECK-ARM-IOS-NOT: call void @_mcount() -// CHECK-ARM-IOS-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM-EABI: call void @"\01mcount"() -// CHECK-ARM-EABI-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM64-EABI: call void @mcount() -// CHECK-ARM64-EABI-MEABI-GNU: call void @"\01_mcount"() -// CHECK-ARM64-EABI-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM-EABI-FREEBSD: call void @__mcount() -// CHECK-ARM-EABI-FREEBSD-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM64-EABI-FREEBSD: call void @.mcount() -// CHECK-ARM64-EABI-FREEBSD-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM-EABI-NETBSD: call void @_mcount() -// CHECK-ARM-EABI-NETBSD-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM-EABI-OPENBSD: call void @__mcount() -// CHECK-ARM-EABI-OPENBSD-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM64-EABI-OPENBSD: call void @mcount() -// CHECK-ARM64-EABI-OPENBSD-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM-EABI-MEABI-GNU-NOT: call void @mcount() -// CHECK-ARM-EABI-MEABI-GNU: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM-EABI-BITRIG: call void @__mcount() -// CHECK-ARM-EABI-BITRIG-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM54-EABI-BITRIG: call void @mcount() -// CHECK-ARM54-EABI-BITRIG-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM-EABI-RTEMS: call void @mcount() -// CHECK-ARM-EABI-RTEMS-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM64-EABI-RTEMS: call void @mcount() -// CHECK-ARM64-EABI-RTEMS-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM-EABI-CLOUDABI: call void @mcount() -// CHECK-ARM-EABI-CLOUDABI-NOT: call void @"\01__gnu_mcount_nc"() -// CHECK-ARM64-EABI-CLOUDABI: call void @mcount() -// CHECK-ARM64-EABI-CLOUDABI-NOT: call void @"\01__gnu_mcount_nc"() +// CHECK-ARM-IOS-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="_mcount"{{.*}} } +// CHECK-ARM-IOS-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM-EABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01mcount"{{.*}} } +// CHECK-ARM-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM64-EABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-ARM64-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01_mcount"{{.*}} } +// CHECK-ARM64-EABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM-EABI-FREEBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} } +// CHECK-ARM-EABI-FREEBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM64-EABI-FREEBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"=".mcount"{{.*}} } +// CHECK-ARM64-EABI-FREEBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM-EABI-NETBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="_mcount"{{.*}} } +// CHECK-ARM-EABI-NETBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} } +// CHECK-ARM-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM64-EABI-OPENBSD: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-ARM64-EABI-OPENBSD-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM-EABI-MEABI-GNU-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-ARM-EABI-MEABI-GNU: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM-EABI-BITRIG: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="__mcount"{{.*}} } +// CHECK-ARM-EABI-BITRIG-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM54-EABI-BITRIG: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-ARM54-EABI-BITRIG-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM-EABI-RTEMS: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-ARM-EABI-RTEMS-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM64-EABI-RTEMS: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-ARM64-EABI-RTEMS-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM-EABI-CLOUDABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-ARM-EABI-CLOUDABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } +// CHECK-ARM64-EABI-CLOUDABI: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="mcount"{{.*}} } +// CHECK-ARM64-EABI-CLOUDABI-NOT: attributes #{{[0-9]+}} = { {{.*}}"counting-function"="\01__gnu_mcount_nc"{{.*}} } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits