[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