Improve alias info on incomplete ODR pointers
Jan Hubicka
hubicka@ucw.cz
Sat Jun 1 16:36:00 GMT 2019
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.
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;
+}
More information about the Gcc-patches
mailing list