Initialize type_warnings::dyn_count with a default value (PR ipa/83054).

Message ID 122d5108-88c6-4d73-c533-f22e4114e15b@suse.cz
State New
Headers show
Series
  • Initialize type_warnings::dyn_count with a default value (PR ipa/83054).
Related show

Commit Message

Martin Liška Jan. 12, 2018, 8:40 a.m.
Hi.

There's an example of zero initialized profile_count. Instead I guess we want
to initialize it to profile_count::zero.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin

Comments

Jan Hubicka Jan. 12, 2018, 8:46 a.m. | #1
> Hi.
> 
> There's an example of zero initialized profile_count. Instead I guess we want
> to initialize it to profile_count::zero.
> 
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
> 
> Ready to be installed?
> Martin

> >From 0cb1501005429cc7ef1083bfc279d7be2a6197aa Mon Sep 17 00:00:00 2001
> From: marxin <mliska@suse.cz>
> Date: Wed, 10 Jan 2018 15:30:33 +0100
> Subject: [PATCH] Initialize type_warnings::dyn_count with a default value (PR
>  ipa/83054).
> 
> gcc/ChangeLog:
> 
> 2018-01-10  Martin Liska  <mliska@suse.cz>
> 
> 	PR ipa/83054
> 	* ipa-devirt.c (final_warning_record::grow_type_warnings):
> 	New function.
> 	(possible_polymorphic_call_targets): Use it.
> 	(ipa_devirt): Likewise.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-01-10  Martin Liska  <mliska@suse.cz>
> 
> 	* g++.dg/warn/pr83054.C: New test.

OK,
thanks!

Honza
> ---
>  gcc/ipa-devirt.c                    | 25 +++++++++++++++++-----
>  gcc/testsuite/g++.dg/warn/pr83054.C | 41 +++++++++++++++++++++++++++++++++++++
>  2 files changed, 61 insertions(+), 5 deletions(-)
>  create mode 100644 gcc/testsuite/g++.dg/warn/pr83054.C
> 
> diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
> index 8de004fef63..cc551d636fd 100644
> --- a/gcc/ipa-devirt.c
> +++ b/gcc/ipa-devirt.c
> @@ -2901,10 +2901,27 @@ struct decl_warn_count
>  
>  struct final_warning_record
>  {
> +  /* If needed grow type_warnings vector and initialize new decl_warn_count
> +     to have dyn_count set to profile_count::zero ().  */
> +  void grow_type_warnings (unsigned newlen);
> +
>    profile_count dyn_count;
>    auto_vec<odr_type_warn_count> type_warnings;
>    hash_map<tree, decl_warn_count> decl_warnings;
>  };
> +
> +void
> +final_warning_record::grow_type_warnings (unsigned newlen)
> +{
> +  unsigned len = type_warnings.length ();
> +  if (newlen > len)
> +    {
> +      type_warnings.safe_grow_cleared (newlen);
> +      for (unsigned i = len; i < newlen; i++)
> +	type_warnings[i].dyn_count = profile_count::zero ();
> +    }
> +}
> +
>  struct final_warning_record *final_warning_records;
>  
>  /* Return vector containing possible targets of polymorphic call of type
> @@ -3176,9 +3193,8 @@ possible_polymorphic_call_targets (tree otr_type,
>  		      && warn_suggest_final_types
>  		      && !outer_type->derived_types.length ())
>  		    {
> -		      if (outer_type->id >= (int)final_warning_records->type_warnings.length ())
> -			final_warning_records->type_warnings.safe_grow_cleared
> -			  (odr_types.length ());
> +		      final_warning_records->grow_type_warnings
> +			(outer_type->id);
>  		      final_warning_records->type_warnings[outer_type->id].count++;
>  		      if (!final_warning_records->type_warnings
>  				[outer_type->id].dyn_count.initialized_p ())
> @@ -3545,8 +3561,7 @@ ipa_devirt (void)
>      {
>        final_warning_records = new (final_warning_record);
>        final_warning_records->dyn_count = profile_count::zero ();
> -      final_warning_records->type_warnings.safe_grow_cleared
> -						 (odr_types.length ());
> +      final_warning_records->grow_type_warnings (odr_types.length ());
>        free_polymorphic_call_targets_hash ();
>      }
>  
> diff --git a/gcc/testsuite/g++.dg/warn/pr83054.C b/gcc/testsuite/g++.dg/warn/pr83054.C
> new file mode 100644
> index 00000000000..506c9609b90
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/warn/pr83054.C
> @@ -0,0 +1,41 @@
> +// PR ipa/83054
> +// { dg-options "-O3 -Wsuggest-final-types" }
> +// { dg-do compile }
> +
> +extern "C" int printf (const char *, ...);
> +struct foo // { dg-warning "final would enable devirtualization of 5 calls" }
> +{
> +  static int count;
> +  void print (int i, int j) { printf ("foo[%d][%d] = %d\n", i, j, x); }
> +  int x;
> +  foo () {
> +    x = count++;
> +    printf("this %d = %x\n", x, (void *)this);
> +  }
> +  virtual ~foo () {
> +    printf("this %d = %x\n", x, (void *)this);
> +    --count;
> +  }
> +};
> +int foo::count;
> +
> +
> +int main ()
> +{
> +  {
> +    foo array[3][3];
> +    for (int i = 0; i < 3; i++)
> +      {
> +	for (int j = 0; j < 3; j++)
> +	  {
> +	    printf("&a[%d][%d] = %x\n", i, j, (void *)&array[i][j]);
> +	  }
> +      }
> +      // The count should be nine, if not, fail the test.
> +      if (foo::count != 9)
> +	return 1;
> +  }
> +  if (foo::count != 0)
> +    return 1;
> +  return 0;
> +}
> -- 
> 2.14.3
>

Patch

From 0cb1501005429cc7ef1083bfc279d7be2a6197aa Mon Sep 17 00:00:00 2001
From: marxin <mliska@suse.cz>
Date: Wed, 10 Jan 2018 15:30:33 +0100
Subject: [PATCH] Initialize type_warnings::dyn_count with a default value (PR
 ipa/83054).

gcc/ChangeLog:

2018-01-10  Martin Liska  <mliska@suse.cz>

	PR ipa/83054
	* ipa-devirt.c (final_warning_record::grow_type_warnings):
	New function.
	(possible_polymorphic_call_targets): Use it.
	(ipa_devirt): Likewise.

gcc/testsuite/ChangeLog:

2018-01-10  Martin Liska  <mliska@suse.cz>

	* g++.dg/warn/pr83054.C: New test.
---
 gcc/ipa-devirt.c                    | 25 +++++++++++++++++-----
 gcc/testsuite/g++.dg/warn/pr83054.C | 41 +++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 5 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/warn/pr83054.C

diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
index 8de004fef63..cc551d636fd 100644
--- a/gcc/ipa-devirt.c
+++ b/gcc/ipa-devirt.c
@@ -2901,10 +2901,27 @@  struct decl_warn_count
 
 struct final_warning_record
 {
+  /* If needed grow type_warnings vector and initialize new decl_warn_count
+     to have dyn_count set to profile_count::zero ().  */
+  void grow_type_warnings (unsigned newlen);
+
   profile_count dyn_count;
   auto_vec<odr_type_warn_count> type_warnings;
   hash_map<tree, decl_warn_count> decl_warnings;
 };
+
+void
+final_warning_record::grow_type_warnings (unsigned newlen)
+{
+  unsigned len = type_warnings.length ();
+  if (newlen > len)
+    {
+      type_warnings.safe_grow_cleared (newlen);
+      for (unsigned i = len; i < newlen; i++)
+	type_warnings[i].dyn_count = profile_count::zero ();
+    }
+}
+
 struct final_warning_record *final_warning_records;
 
 /* Return vector containing possible targets of polymorphic call of type
@@ -3176,9 +3193,8 @@  possible_polymorphic_call_targets (tree otr_type,
 		      && warn_suggest_final_types
 		      && !outer_type->derived_types.length ())
 		    {
-		      if (outer_type->id >= (int)final_warning_records->type_warnings.length ())
-			final_warning_records->type_warnings.safe_grow_cleared
-			  (odr_types.length ());
+		      final_warning_records->grow_type_warnings
+			(outer_type->id);
 		      final_warning_records->type_warnings[outer_type->id].count++;
 		      if (!final_warning_records->type_warnings
 				[outer_type->id].dyn_count.initialized_p ())
@@ -3545,8 +3561,7 @@  ipa_devirt (void)
     {
       final_warning_records = new (final_warning_record);
       final_warning_records->dyn_count = profile_count::zero ();
-      final_warning_records->type_warnings.safe_grow_cleared
-						 (odr_types.length ());
+      final_warning_records->grow_type_warnings (odr_types.length ());
       free_polymorphic_call_targets_hash ();
     }
 
diff --git a/gcc/testsuite/g++.dg/warn/pr83054.C b/gcc/testsuite/g++.dg/warn/pr83054.C
new file mode 100644
index 00000000000..506c9609b90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/pr83054.C
@@ -0,0 +1,41 @@ 
+// PR ipa/83054
+// { dg-options "-O3 -Wsuggest-final-types" }
+// { dg-do compile }
+
+extern "C" int printf (const char *, ...);
+struct foo // { dg-warning "final would enable devirtualization of 5 calls" }
+{
+  static int count;
+  void print (int i, int j) { printf ("foo[%d][%d] = %d\n", i, j, x); }
+  int x;
+  foo () {
+    x = count++;
+    printf("this %d = %x\n", x, (void *)this);
+  }
+  virtual ~foo () {
+    printf("this %d = %x\n", x, (void *)this);
+    --count;
+  }
+};
+int foo::count;
+
+
+int main ()
+{
+  {
+    foo array[3][3];
+    for (int i = 0; i < 3; i++)
+      {
+	for (int j = 0; j < 3; j++)
+	  {
+	    printf("&a[%d][%d] = %x\n", i, j, (void *)&array[i][j]);
+	  }
+      }
+      // The count should be nine, if not, fail the test.
+      if (foo::count != 9)
+	return 1;
+  }
+  if (foo::count != 0)
+    return 1;
+  return 0;
+}
-- 
2.14.3