Introduce LABEL_REF_LABEL
[platform/upstream/gcc.git] / gcc / alias.c
index f8e7760..a098cb7 100644 (file)
@@ -42,12 +42,12 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "df.h"
 #include "tree-ssa-alias.h"
-#include "pointer-set.h"
 #include "internal-fn.h"
 #include "gimple-expr.h"
 #include "is-a.h"
 #include "gimple.h"
 #include "gimple-ssa.h"
+#include "rtl-iter.h"
 
 /* The aliasing API provided here solves related but different problems:
 
@@ -157,7 +157,6 @@ static rtx find_base_value (rtx);
 static int mems_in_disjoint_alias_sets_p (const_rtx, const_rtx);
 static int insert_subset_children (splay_tree_node, void*);
 static alias_set_entry get_alias_set_entry (alias_set_type);
-static bool nonoverlapping_component_refs_p (const_rtx, const_rtx);
 static tree decl_for_component_ref (tree);
 static int write_dependence_p (const_rtx,
                               const_rtx, enum machine_mode, rtx,
@@ -303,10 +302,9 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
       && ! is_global_var (base)
       && cfun->gimple_df->decls_to_pointers != NULL)
     {
-      void *namep;
-      namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
+      tree *namep = cfun->gimple_df->decls_to_pointers->get (base);
       if (namep)
-       ref->base = build_simple_mem_ref (*(tree *)namep);
+       ref->base = build_simple_mem_ref (*namep);
     }
 
   ref->ref_alias_set = MEM_ALIAS_SET (mem);
@@ -341,9 +339,10 @@ ao_ref_from_mem (ao_ref *ref, const_rtx mem)
   if (MEM_EXPR (mem) != get_spill_slot_decl (false)
       && (ref->offset < 0
          || (DECL_P (ref->base)
-             && (!tree_fits_uhwi_p (DECL_SIZE (ref->base))
-                 || (tree_to_uhwi (DECL_SIZE (ref->base))
-                     < (unsigned HOST_WIDE_INT) (ref->offset + ref->size))))))
+             && (DECL_SIZE (ref->base) == NULL_TREE
+                 || TREE_CODE (DECL_SIZE (ref->base)) != INTEGER_CST
+                 || wi::ltu_p (wi::to_offset (DECL_SIZE (ref->base)),
+                               ref->offset + ref->size)))))
     return false;
 
   return true;
@@ -944,7 +943,7 @@ record_alias_subset (alias_set_type superset, alias_set_type subset)
     {
       /* Create an entry for the SUPERSET, so that we have a place to
         attach the SUBSET.  */
-      superset_entry = ggc_alloc_cleared_alias_set_entry_d ();
+      superset_entry = ggc_cleared_alloc<alias_set_entry_d> ();
       superset_entry->alias_set = superset;
       superset_entry->children
        = splay_tree_new_ggc (splay_tree_compare_ints,
@@ -1522,7 +1521,7 @@ rtx_equal_for_memref_p (const_rtx x, const_rtx y)
       return REGNO (x) == REGNO (y);
 
     case LABEL_REF:
-      return XEXP (x, 0) == XEXP (y, 0);
+      return LABEL_REF_LABEL (x) == LABEL_REF_LABEL (y);
 
     case SYMBOL_REF:
       return XSTR (x, 0) == XSTR (y, 0);
@@ -1533,9 +1532,7 @@ rtx_equal_for_memref_p (const_rtx x, const_rtx y)
 
     case VALUE:
     CASE_CONST_UNIQUE:
-      /* There's no need to compare the contents of CONST_DOUBLEs or
-        CONST_INTs because pointer equality is a good enough
-        comparison for these nodes.  */
+      /* Pointer equality guarantees equality for these nodes.  */
       return 0;
 
     default:
@@ -1855,27 +1852,18 @@ base_alias_check (rtx x, rtx x_base, rtx y, rtx y_base,
   return 1;
 }
 
-/* Callback for for_each_rtx, that returns 1 upon encountering a VALUE
-   whose UID is greater than the int uid that D points to.  */
-
-static int
-refs_newer_value_cb (rtx *x, void *d)
-{
-  if (GET_CODE (*x) == VALUE && CSELIB_VAL_PTR (*x)->uid > *(int *)d)
-    return 1;
-
-  return 0;
-}
-
 /* Return TRUE if EXPR refers to a VALUE whose uid is greater than
    that of V.  */
 
 static bool
-refs_newer_value_p (rtx expr, rtx v)
+refs_newer_value_p (const_rtx expr, rtx v)
 {
   int minuid = CSELIB_VAL_PTR (v)->uid;
-
-  return for_each_rtx (&expr, refs_newer_value_cb, &minuid);
+  subrtx_iterator::array_type array;
+  FOR_EACH_SUBRTX (iter, array, expr, NONCONST)
+    if (GET_CODE (*iter) == VALUE && CSELIB_VAL_PTR (*iter)->uid > minuid)
+      return true;
+  return false;
 }
 
 /* Convert the address X into something we can use.  This is done by returning
@@ -2248,68 +2236,6 @@ read_dependence (const_rtx mem, const_rtx x)
   return false;
 }
 
-/* Return true if we can determine that the fields referenced cannot
-   overlap for any pair of objects.  */
-
-static bool
-nonoverlapping_component_refs_p (const_rtx rtlx, const_rtx rtly)
-{
-  const_tree x = MEM_EXPR (rtlx), y = MEM_EXPR (rtly);
-  const_tree fieldx, fieldy, typex, typey, orig_y;
-
-  if (!flag_strict_aliasing
-      || !x || !y
-      || TREE_CODE (x) != COMPONENT_REF
-      || TREE_CODE (y) != COMPONENT_REF)
-    return false;
-
-  do
-    {
-      /* The comparison has to be done at a common type, since we don't
-        know how the inheritance hierarchy works.  */
-      orig_y = y;
-      do
-       {
-         fieldx = TREE_OPERAND (x, 1);
-         typex = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldx));
-
-         y = orig_y;
-         do
-           {
-             fieldy = TREE_OPERAND (y, 1);
-             typey = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldy));
-
-             if (typex == typey)
-               goto found;
-
-             y = TREE_OPERAND (y, 0);
-           }
-         while (y && TREE_CODE (y) == COMPONENT_REF);
-
-         x = TREE_OPERAND (x, 0);
-       }
-      while (x && TREE_CODE (x) == COMPONENT_REF);
-      /* Never found a common type.  */
-      return false;
-
-    found:
-      /* If we're left with accessing different fields of a structure, then no
-        possible overlap, unless they are both bitfields.  */
-      if (TREE_CODE (typex) == RECORD_TYPE && fieldx != fieldy)
-       return !(DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy));
-
-      /* The comparison on the current field failed.  If we're accessing
-        a very nested structure, look at the next outer level.  */
-      x = TREE_OPERAND (x, 0);
-      y = TREE_OPERAND (y, 0);
-    }
-  while (x && y
-        && TREE_CODE (x) == COMPONENT_REF
-        && TREE_CODE (y) == COMPONENT_REF);
-
-  return false;
-}
-
 /* Look at the bottom of the COMPONENT_REF list for a DECL, and return it.  */
 
 static tree
@@ -2338,15 +2264,22 @@ adjust_offset_for_component_ref (tree x, bool *known_p,
     {
       tree xoffset = component_ref_field_offset (x);
       tree field = TREE_OPERAND (x, 1);
+      if (TREE_CODE (xoffset) != INTEGER_CST)
+       {
+         *known_p = false;
+         return;
+       }
 
-      if (! tree_fits_uhwi_p (xoffset))
+      offset_int woffset
+       = (wi::to_offset (xoffset)
+          + wi::lrshift (wi::to_offset (DECL_FIELD_BIT_OFFSET (field)),
+                         LOG2_BITS_PER_UNIT));
+      if (!wi::fits_uhwi_p (woffset))
        {
          *known_p = false;
          return;
        }
-      *offset += (tree_to_uhwi (xoffset)
-                 + (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
-                    / BITS_PER_UNIT));
+      *offset += woffset.to_uhwi ();
 
       x = TREE_OPERAND (x, 0);
     }
@@ -2585,9 +2518,6 @@ true_dependence_1 (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
   if (nonoverlapping_memrefs_p (mem, x, false))
     return 0;
 
-  if (nonoverlapping_component_refs_p (mem, x))
-    return 0;
-
   return rtx_refs_may_alias_p (x, mem, true);
 }
 
@@ -2900,7 +2830,8 @@ init_alias_analysis (void)
   int changed, pass;
   int i;
   unsigned int ui;
-  rtx insn, val;
+  rtx_insn *insn;
+  rtx val;
   int rpo_cnt;
   int *rpo;