diff mbox series

Improve alias info on incomplete ODR pointers

Message ID 20190601163555.ywo3r2jvesevmgxi@kam.mff.cuni.cz
State New
Headers show
Series Improve alias info on incomplete ODR pointers | expand

Commit Message

Jan Hubicka June 1, 2019, 4:35 p.m. UTC
Hi,
while looking at the cases disambiguated by access path and not by alias simple
alias set lookup I noticed that there are number of accesses to pointers of
different type which we consider as possible equivalent.

For example

struct a *a;
struct b *b;

is currently considered aliasing with LTO if one of the structures is
incomplete.  For C++ sources we could fix this by looking up the complete
variant via ODR type hash.

Note that this is also safe WRT subset construction for aggregates because
we glob all pointers to void * with LTO prior calling get_alias_set (so 
currently any two structures containing pointer conflict with each other).

This quite simple patch saves about 5% of void * globbing when compiling
cc1plus with LTO.

Stats change from:

Alias oracle query stats:                                                       
  refs_may_alias_p: 39482421 disambiguations, 47760976 queries                  
  ref_maybe_used_by_call_p: 58817 disambiguations, 40085376 queries             
  call_may_clobber_ref_p: 5579 disambiguations, 8373 queries                    
  aliasing_component_ref_p: 99652 disambiguations, 285661 queries               
  TBAA oracle: 11408132 disambiguations 35099843 queries                        
               14285452 are in alias set 0                                      
               5370901 queries asked about the same object                      
               147 queries asked about the same alias set                       
               0 access volatile                                                
               1721512 are dependent in the DAG                                 
               2313699 are aritificially in conflict with void *                
                                                                                
PTA query stats:                                                                
  pt_solution_includes: 474714 disambiguations, 7173966 queries                 
  pt_solutions_intersect: 390271 disambiguations, 7304940 queries               

To:

Alias oracle query stats:                                                       
  refs_may_alias_p: 39461257 disambiguations, 47717872 queries                  
  ref_maybe_used_by_call_p: 58819 disambiguations, 40064384 queries             
  call_may_clobber_ref_p: 5579 disambiguations, 8373 queries                    
  aliasing_component_ref_p: 91509 disambiguations, 277156 queries               
  TBAA oracle: 11436147 disambiguations 34996771 queries                        
               14283553 are in alias set 0                                      
               5389241 queries asked about the same object                      
               147 queries asked about the same alias set                       
               0 access volatile                                                
               1694396 are dependent in the DAG                                 
               2193287 are aritificially in conflict with void *                
                                                                                
PTA query stats:                                                                
  pt_solution_includes: 474052 disambiguations, 7165766 queries                 
  pt_solutions_intersect: 389420 disambiguations, 7268793 queries               

Bootstrapped/regtested x86_64-linux, comitted.

Honza

	* alias.c: Include ipa-utils.h.
	(get_alias_set): Try to complete ODR type via ODR type hash lookup.
	* ipa-devirt.c (prevailing_odr_type): New.
	* ipa-utils.h (previaling_odr_type): Declare.

	* g++.dg/lto/alias-1_0.C: New testcase.
	* g++.dg/lto/alias-1_1.C: New testcase.
diff mbox series

Patch

Index: alias.c
===================================================================
--- alias.c	(revision 271836)
+++ alias.c	(working copy)
@@ -39,6 +39,7 @@  along with GCC; see the file COPYING3.
 #include "cfganal.h"
 #include "rtl-iter.h"
 #include "cgraph.h"
+#include "ipa-utils.h"
 
 /* The aliasing API provided here solves related but different problems:
 
@@ -1008,6 +1009,14 @@  get_alias_set (tree t)
 	}
       p = TYPE_MAIN_VARIANT (p);
 
+      /* In LTO for C++ programs we can turn in complete types to complete
+	 using ODR name lookup.  */
+      if (in_lto_p && TYPE_STRUCTURAL_EQUALITY_P (p) && odr_type_p (p))
+	{
+	  p = prevailing_odr_type (p);
+	  gcc_checking_assert (TYPE_MAIN_VARIANT (p) == p);
+	}
+
       /* Make void * compatible with char * and also void **.
 	 Programs are commonly violating TBAA by this.
 
Index: ipa-devirt.c
===================================================================
--- ipa-devirt.c	(revision 271836)
+++ ipa-devirt.c	(working copy)
@@ -2170,6 +2170,20 @@  get_odr_type (tree type, bool insert)
   return val;
 }
 
+/* Return type that in ODR type hash prevailed TYPE.  Be careful and punt
+   on ODR violations.  */
+
+tree
+prevailing_odr_type (tree type)
+{
+  odr_type t = get_odr_type (type, false);
+  if (!t || t->odr_violated)
+    return type;
+  return t->type;
+}
+
+/* Return true if we reported some ODR violation on TYPE.  */
+
 bool
 odr_type_violation_reported_p (tree type)
 {
Index: ipa-utils.h
===================================================================
--- ipa-utils.h	(revision 271836)
+++ ipa-utils.h	(working copy)
@@ -92,6 +92,7 @@  void warn_types_mismatch (tree t1, tree
 bool odr_or_derived_type_p (const_tree t);
 bool odr_types_equivalent_p (tree type1, tree type2);
 bool odr_type_violation_reported_p (tree type);
+tree prevailing_odr_type (tree type);
 
 /* Return vector containing possible targets of polymorphic call E.
    If COMPLETEP is non-NULL, store true if the list is complete. 
Index: testsuite/g++.dg/lto/alias-1_0.C
===================================================================
--- testsuite/g++.dg/lto/alias-1_0.C	(nonexistent)
+++ testsuite/g++.dg/lto/alias-1_0.C	(working copy)
@@ -0,0 +1,31 @@ 
+/* { dg-lto-do run } */
+/* { dg-lto-options { { -O2 -flto } } } */
+
+/* With LTO we consider all pointers to incomplete types to be possibly
+   aliasing.  This makes *bptr to alias with aptr.
+   However with C++ ODR rule we can turn incomplete pointers to complete
+   dragging in info from alias-1_1.C.  */
+
+#include <string.h>
+
+typedef int (*fnptr) ();
+
+__attribute__ ((used))
+struct a *aptr;
+
+__attribute__ ((used))
+struct b **bptr = (struct b**)&aptr;
+extern void init ();
+extern void inline_me_late (int);
+
+
+int
+main (int argc, char **argv)
+{
+  init ();
+  aptr = 0;
+  inline_me_late (argc);
+  if (!__builtin_constant_p (aptr == 0))
+    __builtin_abort ();
+  return (size_t)aptr;
+}
Index: testsuite/g++.dg/lto/alias-1_1.C
===================================================================
--- testsuite/g++.dg/lto/alias-1_1.C	(nonexistent)
+++ testsuite/g++.dg/lto/alias-1_1.C	(working copy)
@@ -0,0 +1,16 @@ 
+#include <string.h>
+struct a {int a;} a;
+struct b {short b;} b;
+extern struct b **bptr;
+void
+inline_me_late (int argc)
+{
+  if (argc == -1)
+    *bptr = (struct b *)(size_t)1;
+}
+void
+init()
+{
+  a.a=1;
+  b.b=2;
+}