[PATCH] Always emit function declaration when generating profile instrumentation

Alex L arphaman at gmail.com
Wed May 28 16:35:19 PDT 2014


I've fixed the style, added the tests and utilized CodeGenerator::
HandleInlineMethodDefinition() instead of EmitTopLevelDecl. Please see the
attached patch:

-------------- next part --------------
Index: lib/CodeGen/CodeGenModule.cpp
===================================================================
--- lib/CodeGen/CodeGenModule.cpp    (revision 209778)
+++ lib/CodeGen/CodeGenModule.cpp    (working copy)
@@ -1083,6 +1083,9 @@
   if (LangOpts.EmitAllDecls)
     return false;

+  // Always emit declarations when instrumenting.
+  if (CodeGenOpts.ProfileInstrGenerate && isa<FunctionDecl>(Global))
+    return false;
   return !getContext().DeclMustBeEmitted(Global);
 }

Index: lib/CodeGen/ModuleBuilder.cpp
===================================================================
--- lib/CodeGen/ModuleBuilder.cpp    (revision 209778)
+++ lib/CodeGen/ModuleBuilder.cpp    (working copy)
@@ -90,7 +90,9 @@
       // We may have member functions that need to be emitted at this
point.
       if (!D->isDependentContext() &&
           (D->hasAttr<UsedAttr>() || D->hasAttr<ConstructorAttr>() ||
-           D->hasAttr<DLLExportAttr>())) {
+           D->hasAttr<DLLExportAttr>() ||
+           // Always emit methods when instrumenting.
+           CodeGenOpts.ProfileInstrGenerate)) {
         Builder->EmitTopLevelDecl(D);
       }
     }
Index: test/Profile/c-general.c
===================================================================
--- test/Profile/c-general.c    (revision 209778)
+++ test/Profile/c-general.c    (working copy)
@@ -14,8 +14,8 @@
 // PGOGEN: @[[BOC:__llvm_profile_counters_boolean_operators]] = hidden
global [8 x i64] zeroinitializer
 // PGOGEN: @[[BLC:__llvm_profile_counters_boolop_loops]] = hidden global
[9 x i64] zeroinitializer
 // PGOGEN: @[[COC:__llvm_profile_counters_conditional_operator]] = hidden
global [3 x i64] zeroinitializer
+// PGOGEN: @[[STC:__llvm_profile_counters_static_func]] = internal global
[2 x i64] zeroinitializer
 // PGOGEN: @[[MAC:__llvm_profile_counters_main]] = hidden global [1 x i64]
zeroinitializer
-// PGOGEN: @[[STC:__llvm_profile_counters_static_func]] = internal global
[2 x i64] zeroinitializer

 // PGOGEN-LABEL: @simple_loops()
 // PGOUSE-LABEL: @simple_loops()
Index: test/Profile/c-unused-static-functions.c
===================================================================
--- test/Profile/c-unused-static-functions.c    (revision 0)
+++ test/Profile/c-unused-static-functions.c    (working copy)
@@ -0,0 +1,12 @@
+// Check that the unused static functions still emit the counters
+
+// RUN: %clang_cc1 %s -O2 -triple x86_64-apple-macosx10.9 -main-file-name
c-unused-static-functions.cpp -o - -emit-llvm -fprofile-instr-generate |
FileCheck %s
+
+// CHECK: @__llvm_profile_counters_static_func = internal global [1 x i64]
zeroinitializer
+
+static void static_func() {
+}
+
+int main(int argc, const char *argv[]) {
+  return 0;
+}
Index: test/Profile/cxx-unused-methods.cpp
===================================================================
--- test/Profile/cxx-unused-methods.cpp    (revision 0)
+++ test/Profile/cxx-unused-methods.cpp    (working copy)
@@ -0,0 +1,42 @@
+// Check that the unused methods defined inside a class body
+// and inline methods defined outside of the class body
+// still emit the counters
+
+// RUN: %clang_cc1 -x c++ %s -O2 -triple x86_64-apple-macosx10.9
-main-file-name cxx-unused-methods.cpp -o - -emit-llvm
-fprofile-instr-generate | FileCheck %s
+
+// CHECK: @__llvm_profile_counters__ZN5Outer6methodEv = linkonce_odr
hidden global [1 x i64] zeroinitializer
+// CHECK: @__llvm_profile_counters__ZN5Outer13inline_methodEv =
linkonce_odr hidden global [1 x i64] zeroinitializer
+// CHECK: @__llvm_profile_counters__ZN5Outer5Inner6methodEv = linkonce_odr
hidden global [1 x i64] zeroinitializer
+// CHECK: @__llvm_profile_counters__ZN5Outer5Inner13inline_methodEv =
linkonce_odr hidden global [1 x i64] zeroinitializer
+
+class Outer {
+  int Member;
+public:
+
+  Outer(int M) : Member(M) {
+  }
+
+  ~Outer() {
+  }
+
+  void method() {
+  }
+
+  inline void inline_method() {
+  }
+
+  struct Inner {
+
+    void method() {
+    }
+
+    void inline_method();
+  };
+};
+
+inline void Outer::Inner::inline_method() {
+}
+
+int main(int argc, const char *argv[]) {
+  return 0;
+}



2014-05-28 16:11 GMT-07:00 Eric Christopher <echristo at gmail.com>:

> On Wed, May 28, 2014 at 4:08 PM, Duncan P. N. Exon Smith
> <dexonsmith at apple.com> wrote:
> >
> >> On 2014-May-28, at 15:55, Eric Christopher <echristo at gmail.com> wrote:
> >>
> >> ... I'll bite.
> >>
> >> Why do you want to know "this function wasn't instrumented" versus
> >> "this had no calls" for coverage? If it's not instrumented it's
> >> definitely not called. Otherwise you need to do this for all functions
> >> (and who knows what chaos with special member functions that you
> >> didn't have to create... :)
> >
> > I can think of two scenarios:
> >
> >  1. The error/warning messages should be different: "profile out of
> date" vs.
> >     "foo() has no coverage".
>
> This seems ok I guess. Though if you've got a binary you should be
> able to say "this code doesn't exist".
>
> >
> >  2. All you have is source and the profile data (i.e., a gcov-like flow,
> >     without an AST), and you want to output the list of functions with no
> >     coverage.
>
> You could just take the ones that you do have coverage info for and
> it's the inverse?
>
> In general I think forcing emission of things that aren't normally
> emitted is probably going to be a bit of a problem.
>
> -erc
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140528/da18cb99/attachment.html>


More information about the cfe-commits mailing list