Message ID | 20150520221319.GA91616@kam.mff.cuni.cz |
---|---|
State | New |
Headers | show |
On May 21, 2015 12:13:19 AM GMT+02:00, Jan Hubicka <hubicka@ucw.cz> wrote: >Hi, >this patch extends statistics from tree-ssa-alias to also cover TBAA >oracle. >This is useful to keep track of aliasing effectivity. For example the >hack >in alias.c putting globbing all pointers to one costs about 20% of all >answers on firefox. I.e. from 15500978 disambiguations/23744267 >querries >(with the hack removed) to 12932078 disambiguations/27256455 querries. > >Bootstrapped x86_64-linux, OK? s/quaries/queries/ Thanks,
On Thu, 21 May 2015, Jan Hubicka wrote: > Hi, > this patch extends statistics from tree-ssa-alias to also cover TBAA oracle. > This is useful to keep track of aliasing effectivity. For example the hack > in alias.c putting globbing all pointers to one costs about 20% of all > answers on firefox. I.e. from 15500978 disambiguations/23744267 querries > (with the hack removed) to 12932078 disambiguations/27256455 querries. > > Bootstrapped x86_64-linux, OK? Ok with the spelling fix and the same_type_for_tbaa hunk. Thanks, Richard. > Honza > > * alias.c (alias_stats): New static var. > (alias_sets_conflict_p, alias_sets_must_conflict_p): Update stats. > (dump_alias_stats_in_alias_c): New function. > * alias.h (dump_alias_stats_in_alias_c): Declare. > * tree-ssa-alias.c (dump_alias_stats): Call it. > Index: alias.c > =================================================================== > --- alias.c (revision 223444) > +++ alias.c (working copy) > @@ -213,6 +213,19 @@ static int write_dependence_p (const_rtx > > static void memory_modified_1 (rtx, const_rtx, void *); > > +/* Query statistics for the different low-level disambiguators. > + A high-level query may trigger multiple of them. */ > + > +static struct { > + unsigned long long num_alias_zero; > + unsigned long long num_same_alias_set; > + unsigned long long num_same_objects; > + unsigned long long num_volatile; > + unsigned long long num_dag; > + unsigned long long num_disambiguated; > +} alias_stats; > + > + > /* Set up all info needed to perform alias analysis on memory references. */ > > /* Returns the size in bytes of the mode of X. */ > @@ -471,13 +484,20 @@ alias_sets_conflict_p (alias_set_type se > ase = get_alias_set_entry (set1); > if (ase != 0 > && ase->children->get (set2)) > - return 1; > + { > + ++alias_stats.num_dag; > + return 1; > + } > > /* Now do the same, but with the alias sets reversed. */ > ase = get_alias_set_entry (set2); > if (ase != 0 > && ase->children->get (set1)) > - return 1; > + { > + ++alias_stats.num_dag; > + return 1; > + } > + ++alias_stats.num_disambiguated; > > /* The two alias sets are distinct and neither one is the > child of the other. Therefore, they cannot conflict. */ > @@ -489,8 +509,16 @@ alias_sets_conflict_p (alias_set_type se > int > alias_sets_must_conflict_p (alias_set_type set1, alias_set_type set2) > { > - if (set1 == 0 || set2 == 0 || set1 == set2) > - return 1; > + if (set1 == 0 || set2 == 0) > + { > + ++alias_stats.num_alias_zero; > + return 1; > + } > + if (set1 == set2) > + { > + ++alias_stats.num_same_alias_set; > + return 1; > + } > > return 0; > } > @@ -512,10 +540,17 @@ objects_must_conflict_p (tree t1, tree t > return 0; > > /* If they are the same type, they must conflict. */ > - if (t1 == t2 > - /* Likewise if both are volatile. */ > - || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2))) > - return 1; > + if (t1 == t2) > + { > + ++alias_stats.num_same_objects; > + return 1; > + } > + /* Likewise if both are volatile. */ > + if (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)) > + { > + ++alias_stats.num_volatile; > + return 1; > + } > > set1 = t1 ? get_alias_set (t1) : 0; > set2 = t2 ? get_alias_set (t2) : 0; > @@ -3043,4 +3051,21 @@ end_alias_analysis (void) > sbitmap_free (reg_known_equiv_p); > } > > +void > +dump_alias_stats_in_alias_c (FILE *s) > +{ > + fprintf (s, " TBAA oracle: %llu disambiguations %llu queries\n" > + " %llu are in alias set 0\n" > + " %llu queries asked about the same object\n" > + " %llu quaries asked about the same alias set\n" > + " %llu access volatile\n" > + " %llu are dependent in the DAG\n", > + alias_stats.num_disambiguated, > + alias_stats.num_alias_zero + alias_stats.num_same_alias_set > + + alias_stats.num_same_objects + alias_stats.num_volatile > + + alias_stats.num_dag, > + alias_stats.num_alias_zero, alias_stats.num_same_alias_set, > + + alias_stats.num_same_objects, alias_stats.num_volatile, > + + alias_stats.num_dag); > +} > #include "gt-alias.h" > Index: alias.h > =================================================================== > --- alias.h (revision 223444) > +++ alias.h (working copy) > @@ -41,6 +41,7 @@ extern int alias_sets_conflict_p (alias_ > extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type); > extern int objects_must_conflict_p (tree, tree); > extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool); > +extern void dump_alias_stats_in_alias_c (FILE *s); > tree reference_alias_ptr_type (tree); > bool alias_ptr_types_compatible_p (tree, tree); > > Index: tree-ssa-alias.c > =================================================================== > --- tree-ssa-alias.c (revision 223444) > +++ tree-ssa-alias.c (working copy) > @@ -163,6 +163,7 @@ dump_alias_stats (FILE *s) > alias_stats.call_may_clobber_ref_p_no_alias, > alias_stats.call_may_clobber_ref_p_no_alias > + alias_stats.call_may_clobber_ref_p_may_alias); > + dump_alias_stats_in_alias_c (s); > } > > > @@ -685,7 +686,12 @@ same_type_for_tbaa (tree type1, tree typ > /* If we would have to do structural comparison bail out. */ > if (TYPE_STRUCTURAL_EQUALITY_P (type1) > || TYPE_STRUCTURAL_EQUALITY_P (type2)) > - return -1; > + { > + /* The way LTO produces canonical types makes sure that everything > + that matters has TYPE_CANONICAL set. */ > + gcc_assert (!in_lto_p); > + return -1; > + } > > /* Compare the canonical types. */ > if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2)) > >
Index: alias.c =================================================================== --- alias.c (revision 223444) +++ alias.c (working copy) @@ -213,6 +213,19 @@ static int write_dependence_p (const_rtx static void memory_modified_1 (rtx, const_rtx, void *); +/* Query statistics for the different low-level disambiguators. + A high-level query may trigger multiple of them. */ + +static struct { + unsigned long long num_alias_zero; + unsigned long long num_same_alias_set; + unsigned long long num_same_objects; + unsigned long long num_volatile; + unsigned long long num_dag; + unsigned long long num_disambiguated; +} alias_stats; + + /* Set up all info needed to perform alias analysis on memory references. */ /* Returns the size in bytes of the mode of X. */ @@ -471,13 +484,20 @@ alias_sets_conflict_p (alias_set_type se ase = get_alias_set_entry (set1); if (ase != 0 && ase->children->get (set2)) - return 1; + { + ++alias_stats.num_dag; + return 1; + } /* Now do the same, but with the alias sets reversed. */ ase = get_alias_set_entry (set2); if (ase != 0 && ase->children->get (set1)) - return 1; + { + ++alias_stats.num_dag; + return 1; + } + ++alias_stats.num_disambiguated; /* The two alias sets are distinct and neither one is the child of the other. Therefore, they cannot conflict. */ @@ -489,8 +509,16 @@ alias_sets_conflict_p (alias_set_type se int alias_sets_must_conflict_p (alias_set_type set1, alias_set_type set2) { - if (set1 == 0 || set2 == 0 || set1 == set2) - return 1; + if (set1 == 0 || set2 == 0) + { + ++alias_stats.num_alias_zero; + return 1; + } + if (set1 == set2) + { + ++alias_stats.num_same_alias_set; + return 1; + } return 0; } @@ -512,10 +540,17 @@ objects_must_conflict_p (tree t1, tree t return 0; /* If they are the same type, they must conflict. */ - if (t1 == t2 - /* Likewise if both are volatile. */ - || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2))) - return 1; + if (t1 == t2) + { + ++alias_stats.num_same_objects; + return 1; + } + /* Likewise if both are volatile. */ + if (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2)) + { + ++alias_stats.num_volatile; + return 1; + } set1 = t1 ? get_alias_set (t1) : 0; set2 = t2 ? get_alias_set (t2) : 0; @@ -3043,4 +3051,21 @@ end_alias_analysis (void) sbitmap_free (reg_known_equiv_p); } +void +dump_alias_stats_in_alias_c (FILE *s) +{ + fprintf (s, " TBAA oracle: %llu disambiguations %llu queries\n" + " %llu are in alias set 0\n" + " %llu queries asked about the same object\n" + " %llu quaries asked about the same alias set\n" + " %llu access volatile\n" + " %llu are dependent in the DAG\n", + alias_stats.num_disambiguated, + alias_stats.num_alias_zero + alias_stats.num_same_alias_set + + alias_stats.num_same_objects + alias_stats.num_volatile + + alias_stats.num_dag, + alias_stats.num_alias_zero, alias_stats.num_same_alias_set, + + alias_stats.num_same_objects, alias_stats.num_volatile, + + alias_stats.num_dag); +} #include "gt-alias.h" Index: alias.h =================================================================== --- alias.h (revision 223444) +++ alias.h (working copy) @@ -41,6 +41,7 @@ extern int alias_sets_conflict_p (alias_ extern int alias_sets_must_conflict_p (alias_set_type, alias_set_type); extern int objects_must_conflict_p (tree, tree); extern int nonoverlapping_memrefs_p (const_rtx, const_rtx, bool); +extern void dump_alias_stats_in_alias_c (FILE *s); tree reference_alias_ptr_type (tree); bool alias_ptr_types_compatible_p (tree, tree); Index: tree-ssa-alias.c =================================================================== --- tree-ssa-alias.c (revision 223444) +++ tree-ssa-alias.c (working copy) @@ -163,6 +163,7 @@ dump_alias_stats (FILE *s) alias_stats.call_may_clobber_ref_p_no_alias, alias_stats.call_may_clobber_ref_p_no_alias + alias_stats.call_may_clobber_ref_p_may_alias); + dump_alias_stats_in_alias_c (s); } @@ -685,7 +686,12 @@ same_type_for_tbaa (tree type1, tree typ /* If we would have to do structural comparison bail out. */ if (TYPE_STRUCTURAL_EQUALITY_P (type1) || TYPE_STRUCTURAL_EQUALITY_P (type2)) - return -1; + { + /* The way LTO produces canonical types makes sure that everything + that matters has TYPE_CANONICAL set. */ + gcc_assert (!in_lto_p); + return -1; + } /* Compare the canonical types. */ if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))