This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix flow-insensitive alias computation
On Thu, 17 Apr 2008, Daniel Berlin wrote:
> On Thu, Apr 17, 2008 at 11:48 AM, Richard Guenther <rguenther@suse.de> wrote:
> >
> > Eventually
> >
> > if (may_aliases2 && !bitmap_empty_p (may_aliases2))
> > {
> > union_alias_set_into (tag1, may_aliases2);
> > }
>
> Errr, this was not added at some point to fix anything, AFAIK. The
> code there was simply transformed from a loop over the aliases into a
> bitmap or :)
Heh, you are right. All of the above code was added effectively with
r87515.
To clarify what I mean with the symmetry problem consider
struct X {
int i;
double x;
} s;
int test3 (struct X *p1, int *p2, double *p3)
{
p1->i = 1;
*p2 = 2;
*p3 = 3;
return p1->i;
}
where we at the moment do
test3 (struct X * p1, int * p2, double * p3)
{
int D.1572;
<bb 2>:
# SMT.30_9 = VDEF <SMT.30_6(D)>
# SMT.31_10 = VDEF <SMT.31_7(D)>
# SMT.32_11 = VDEF <SMT.32_8(D)>
p1_1(D)->i = 1;
# SMT.30_12 = VDEF <SMT.30_9>
# SMT.31_13 = VDEF <SMT.31_10>
*p2_2(D) = 2;
# SMT.30_14 = VDEF <SMT.30_12>
# SMT.32_15 = VDEF <SMT.32_11>
*p3_3(D) = 3.0e+0;
# VUSE <SMT.30_14, SMT.31_13, SMT.32_15>
D.1572_4 = p1_1(D)->i;
return D.1572_4;
}
which is ok for the accesses through the pointers *p2 and *p3 but
unnecessarily includes the SMT for double in the access of p1->i.
This is caused by several places, one flow insensitive alias
computation being symmetric, another find_what_p_points_to
calling merge_smts_into for pt_anything pointers and that
adding all subsets to the solution (which gets merged back
to the SMT aliases in flow sensitive alias compuation). It's
all a little bit of a twisted maze and the problem can be
at least worked around in access_can_touch_variable (as I
proposed once before). It can also be "fixed" by treating
pt_anything pointers like PTR_IS_REF_ALL pointers, but I belive
we are just overly conservative in what we add to the solution.
So I believe the following should be in principle correct modulo
latent bugs elsewhere...
Richard.
2008-04-18 Richard Guenther <rguenther@suse.de>
* tree-ssa-structalias.c (merge_smts_into): Only merge the
SMTs aliases and the tag itself into the solution.
* tree-ssa-alias.c (compute_flow_sensitive_aliasing): Do not
merge the points-to solution back into the SMT aliases.
(may_alias_p): Use alias_set_subset_of instead of
aliases_conflict_p.
Index: tree-ssa-structalias.c
===================================================================
*** tree-ssa-structalias.c (revision 134383)
--- tree-ssa-structalias.c (working copy)
*************** set_used_smts (void)
*** 4862,4869 ****
static void
merge_smts_into (tree p, bitmap solution)
{
- unsigned int i;
- bitmap_iterator bi;
tree smt;
bitmap aliases;
tree var = p;
--- 4862,4867 ----
*************** merge_smts_into (tree p, bitmap solution
*** 4874,4893 ****
smt = var_ann (var)->symbol_mem_tag;
if (smt)
{
! alias_set_type smtset = get_alias_set (TREE_TYPE (smt));
!
! /* Need to set the SMT subsets first before this
! will work properly. */
bitmap_set_bit (solution, DECL_UID (smt));
- EXECUTE_IF_SET_IN_BITMAP (used_smts, 0, i, bi)
- {
- tree newsmt = referenced_var (i);
- tree newsmttype = TREE_TYPE (newsmt);
-
- if (alias_set_subset_of (get_alias_set (newsmttype),
- smtset))
- bitmap_set_bit (solution, i);
- }
aliases = MTAG_ALIASES (smt);
if (aliases)
--- 4872,4879 ----
smt = var_ann (var)->symbol_mem_tag;
if (smt)
{
! /* The smt itself isn't included in its aliases. */
bitmap_set_bit (solution, DECL_UID (smt));
aliases = MTAG_ALIASES (smt);
if (aliases)
Index: tree-ssa-alias.c
===================================================================
*** tree-ssa-alias.c (revision 134383)
--- tree-ssa-alias.c (working copy)
*************** compute_flow_sensitive_aliasing (struct
*** 2354,2360 ****
for (i = 0; VEC_iterate (tree, ai->processed_ptrs, i, ptr); i++)
{
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
- tree tag = symbol_mem_tag (SSA_NAME_VAR (ptr));
/* Set up aliasing information for PTR's name memory tag (if it has
one). Note that only pointers that have been dereferenced will
--- 2354,2359 ----
*************** compute_flow_sensitive_aliasing (struct
*** 2362,2379 ****
if (pi->name_mem_tag && pi->pt_vars)
{
if (!bitmap_empty_p (pi->pt_vars))
! {
! union_alias_set_into (pi->name_mem_tag, pi->pt_vars);
! union_alias_set_into (tag, pi->pt_vars);
! bitmap_clear_bit (MTAG_ALIASES (tag), DECL_UID (tag));
!
! /* It may be the case that this the tag uid was the only
! bit we had set in the aliases list, and in this case,
! we don't want to keep an empty bitmap, as this
! asserts in tree-ssa-operands.c . */
! if (bitmap_empty_p (MTAG_ALIASES (tag)))
! BITMAP_FREE (MTAG_ALIASES (tag));
! }
}
}
timevar_pop (TV_FLOW_SENSITIVE);
--- 2361,2367 ----
if (pi->name_mem_tag && pi->pt_vars)
{
if (!bitmap_empty_p (pi->pt_vars))
! union_alias_set_into (pi->name_mem_tag, pi->pt_vars);
}
}
timevar_pop (TV_FLOW_SENSITIVE);
*************** may_alias_p (tree ptr, alias_set_type me
*** 2869,2875 ****
alias_stats.tbaa_queries++;
/* If the alias sets don't conflict then MEM cannot alias VAR. */
! if (!alias_sets_conflict_p (mem_alias_set, var_alias_set))
{
alias_stats.alias_noalias++;
alias_stats.tbaa_resolved++;
--- 2857,2864 ----
alias_stats.tbaa_queries++;
/* If the alias sets don't conflict then MEM cannot alias VAR. */
! if (mem_alias_set != var_alias_set
! && !alias_set_subset_of (mem_alias_set, var_alias_set))
{
alias_stats.alias_noalias++;
alias_stats.tbaa_resolved++;