Fix alias.c wrt aliases and anchors

Uros Bizjak ubizjak@gmail.com
Mon Dec 28 12:16:00 GMT 2015


Hello!

>> Yeah, I think handling anchors is a good thing.  It just seems that
>> logically the correctness fix is to replace:
>>
>>  /* Label and normal symbol are never the same. */
>>    if (x_decl != y_decl)
>>    return 0;
>>  return offset_overlap_p (c, xsize, ysize);
>>
>> with something like:
>>
>>  if (XSTR (x, 0) == XSTR (y, 0))
>>    return offset_overlap_p (c, xsize, ysize);
>>  /* Symbols might conflict.  */
>>  return -1;
>>
>> Handling anchors would then be a very useful optimisation on top of that.
>
> Ah, OK, now I get your point :)
> Yep, I have no problem beling conservative for non-anchor cases !SYMBOL_REF_DECL case.
> Pretty much all cases that matter are IMO either anchors or SYMBOL_REF_DECL != NULL.
> (i.e. user variables).
>
> I will update the patch and also look into the Alpha AND issues.

I have another version of the patch that deals with AND addresses in
testing, please see attached. The difference from the previous patch
is:

@@ -2339,6 +2337,12 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, r
       /* If both decls are the same, decide by offsets.  */
       if (cmp == 1)
         return offset_overlap_p (c, xsize, ysize);
+      /* Assume a potential overlap for symbolic addresses that went
+        through alignment adjustments (i.e., that have negative
+        sizes), because we can't know how far they are from each
+        other.  */
+      if (xsize < 0 || ysize < 0)
+       return -1;
       /* If decls are different or we know by offsets that there is no overlap,
         we win.  */
       if (!cmp || !offset_overlap_p (c, xsize, ysize))

So, we simply return unknown from memrefs_conflict_p when realignment
is in play.

(We still need early return for AND addresses in base_alias_check, though).

Uros.
-------------- next part --------------
Index: alias.c
===================================================================
--- alias.c	(revision 231971)
+++ alias.c	(working copy)
@@ -2046,8 +2046,6 @@ compare_base_decls (tree base1, tree base2)
 
   ret = symtab_node::get_create (base1)->equal_address_to
 		 (symtab_node::get_create (base2), true);
-  if (ret == 2)
-    return -1;
   return ret;
 }
 
@@ -2088,17 +2086,6 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_
   if (rtx_equal_p (x_base, y_base))
     return 1;
 
-  if (GET_CODE (x_base) == SYMBOL_REF && GET_CODE (y_base) == SYMBOL_REF)
-    {
-      tree x_decl = SYMBOL_REF_DECL (x_base);
-      tree y_decl = SYMBOL_REF_DECL (y_base);
-
-      /* We can assume that no stores are made to labels.  */
-      if (!x_decl || !y_decl)
-	return 0;
-      return compare_base_decls (x_decl, y_decl) != 0;
-    }
-
   /* The base addresses are different expressions.  If they are not accessed
      via AND, there is no conflict.  We can bring knowledge of object
      alignment into play here.  For example, on alpha, "char a, b;" can
@@ -2117,6 +2104,17 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_
 	  || (int) GET_MODE_UNIT_SIZE (x_mode) < -INTVAL (XEXP (y, 1))))
     return 1;
 
+  if (GET_CODE (x_base) == SYMBOL_REF && GET_CODE (y_base) == SYMBOL_REF)
+    {
+      tree x_decl = SYMBOL_REF_DECL (x_base);
+      tree y_decl = SYMBOL_REF_DECL (y_base);
+
+      /* We can assume that no stores are made to labels.  */
+      if (!x_decl || !y_decl)
+	return 0;
+      return compare_base_decls (x_decl, y_decl) != 0;
+    }
+
   /* Differing symbols not accessed via AND never alias.  */
   if (GET_CODE (x_base) != ADDRESS && GET_CODE (y_base) != ADDRESS)
     return 0;
@@ -2339,6 +2337,12 @@ memrefs_conflict_p (int xsize, rtx x, int ysize, r
       /* If both decls are the same, decide by offsets.  */
       if (cmp == 1)
         return offset_overlap_p (c, xsize, ysize);
+      /* Assume a potential overlap for symbolic addresses that went
+	 through alignment adjustments (i.e., that have negative
+	 sizes), because we can't know how far they are from each
+	 other.  */
+      if (xsize < 0 || ysize < 0)
+	return -1;
       /* If decls are different or we know by offsets that there is no overlap,
 	 we win.  */
       if (!cmp || !offset_overlap_p (c, xsize, ysize))
Index: symtab.c
===================================================================
--- symtab.c	(revision 231971)
+++ symtab.c	(working copy)
@@ -1877,7 +1877,7 @@ symtab_node::nonzero_address ()
 
 /* Return 0 if symbol is known to have different address than S2,
    Return 1 if symbol is known to have same address as S2,
-   return 2 otherwise.  
+   return -1 otherwise.  
 
    If MEMORY_ACCESSED is true, assume that both memory pointer to THIS
    and S2 is going to be accessed.  This eliminates the situations when
@@ -1941,7 +1941,7 @@ symtab_node::equal_address_to (symtab_node *s2, bo
   /* If both symbols may resolve to NULL, we can not really prove them
      different.  */
   if (!memory_accessed && !nonzero_address () && !s2->nonzero_address ())
-    return 2;
+    return -1;
 
   /* Except for NULL, functions and variables never overlap.  */
   if (TREE_CODE (decl) != TREE_CODE (s2->decl))
@@ -1949,7 +1949,7 @@ symtab_node::equal_address_to (symtab_node *s2, bo
 
   /* If one of the symbols is unresolved alias, punt.  */
   if (rs1->alias || rs2->alias)
-    return 2;
+    return -1;
 
   /* If we have a non-interposale definition of at least one of the symbols
      and the other symbol is different, we know other unit can not interpose
@@ -1976,7 +1976,7 @@ symtab_node::equal_address_to (symtab_node *s2, bo
      We probably should be consistent and use this fact here, too, but for
      the moment return false only when we are called from the alias oracle.  */
 
-  return memory_accessed && rs1 != rs2 ? 0 : 2;
+  return memory_accessed && rs1 != rs2 ? 0 : -1;
 }
 
 /* Worker for call_for_symbol_and_aliases.  */


More information about the Gcc-patches mailing list