OSDN Git Service

* ifcvt.c (noce_emit_cmove): If both of the values are SUBREGs, try
[pf3gnuchains/gcc-fork.git] / gcc / gimple.c
index 8453be0..fca7803 100644 (file)
@@ -36,19 +36,21 @@ along with GCC; see the file COPYING3.  If not see
 #include "flags.h"
 #include "alias.h"
 #include "demangle.h"
+#include "langhooks.h"
 
 /* Global type table.  FIXME lto, it should be possible to re-use some
    of the type hashing routines in tree.c (type_hash_canon, type_hash_lookup,
    etc), but those assume that types were built with the various
    build_*_type routines which is not the case with the streamer.  */
-static htab_t gimple_types;
-static struct pointer_map_t *type_hash_cache;
+static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node)))
+  htab_t gimple_types;
+static GTY((if_marked ("tree_int_map_marked_p"), param_is (struct tree_int_map)))
+  htab_t type_hash_cache;
 
-/* Global type comparison cache.  */
+/* Global type comparison cache.  This is by TYPE_UID for space efficiency
+   and thus cannot use and does not need GC.  */
 static htab_t gtc_visited;
 static struct obstack gtc_ob;
-static htab_t gtc_visited2;
-static struct obstack gtc_ob2;
 
 /* All the tuples have their operand vector (if present) at the very bottom
    of the structure.  Therefore, the offset required to find the
@@ -2401,24 +2403,25 @@ gimple_rhs_has_side_effects (const_gimple s)
   return false;
 }
 
-
 /* Helper for gimple_could_trap_p and gimple_assign_rhs_could_trap_p.
-   Return true if S can trap.  If INCLUDE_LHS is true and S is a
-   GIMPLE_ASSIGN, the LHS of the assignment is also checked.
-   Otherwise, only the RHS of the assignment is checked.  */
+   Return true if S can trap.  When INCLUDE_MEM is true, check whether
+   the memory operations could trap.  When INCLUDE_STORES is true and
+   S is a GIMPLE_ASSIGN, the LHS of the assignment is also checked.  */
 
-static bool
-gimple_could_trap_p_1 (gimple s, bool include_lhs)
+bool
+gimple_could_trap_p_1 (gimple s, bool include_mem, bool include_stores)
 {
-  unsigned i, start;
   tree t, div = NULL_TREE;
   enum tree_code op;
 
-  start = (is_gimple_assign (s) && !include_lhs) ? 1 : 0;
+  if (include_mem)
+    {
+      unsigned i, start = (is_gimple_assign (s) && !include_stores) ? 1 : 0;
 
-  for (i = start; i < gimple_num_ops (s); i++)
-    if (tree_could_trap_p (gimple_op (s, i)))
-      return true;
+      for (i = start; i < gimple_num_ops (s); i++)
+       if (tree_could_trap_p (gimple_op (s, i)))
+         return true;
+    }
 
   switch (gimple_code (s))
     {
@@ -2447,26 +2450,23 @@ gimple_could_trap_p_1 (gimple s, bool include_lhs)
     }
 
   return false;
-
 }
 
-
 /* Return true if statement S can trap.  */
 
 bool
 gimple_could_trap_p (gimple s)
 {
-  return gimple_could_trap_p_1 (s, true);
+  return gimple_could_trap_p_1 (s, true, true);
 }
 
-
 /* Return true if RHS of a GIMPLE_ASSIGN S can trap.  */
 
 bool
 gimple_assign_rhs_could_trap_p (gimple s)
 {
   gcc_assert (is_gimple_assign (s));
-  return gimple_could_trap_p_1 (s, false);
+  return gimple_could_trap_p_1 (s, true, false);
 }
 
 
@@ -3008,15 +3008,18 @@ get_base_address (tree t)
   while (handled_component_p (t))
     t = TREE_OPERAND (t, 0);
 
-  if (TREE_CODE (t) == MEM_REF
+  if ((TREE_CODE (t) == MEM_REF
+       || TREE_CODE (t) == TARGET_MEM_REF)
       && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR)
     t = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
 
-  if (SSA_VAR_P (t)
+  if (TREE_CODE (t) == SSA_NAME
+      || DECL_P (t)
       || TREE_CODE (t) == STRING_CST
       || TREE_CODE (t) == CONSTRUCTOR
       || INDIRECT_REF_P (t)
-      || TREE_CODE (t) == MEM_REF)
+      || TREE_CODE (t) == MEM_REF
+      || TREE_CODE (t) == TARGET_MEM_REF)
     return t;
   else
     return NULL_TREE;
@@ -3157,20 +3160,20 @@ static hashval_t gimple_type_hash (const void *);
 
 /* Structure used to maintain a cache of some type pairs compared by
    gimple_types_compatible_p when comparing aggregate types.  There are
-   four possible values for SAME_P:
+   three possible values for SAME_P:
 
        -2: The pair (T1, T2) has just been inserted in the table.
-       -1: The pair (T1, T2) is currently being compared.
         0: T1 and T2 are different types.
         1: T1 and T2 are the same type.
 
-   This table is only used when comparing aggregate types to avoid
-   infinite recursion due to self-referential types.  */
+   The two elements in the SAME_P array are indexed by the comparison
+   mode gtc_mode.  */
+
 struct type_pair_d
 {
   unsigned int uid1;
   unsigned int uid2;
-  int same_p;
+  signed char same_p[2];
 };
 typedef struct type_pair_d *type_pair_t;
 
@@ -3227,7 +3230,8 @@ lookup_type_pair (tree t1, tree t2, htab_t *visited_p, struct obstack *ob_p)
       p = XOBNEW (ob_p, struct type_pair_d);
       p->uid1 = TYPE_UID (t1);
       p->uid2 = TYPE_UID (t2);
-      p->same_p = -2;
+      p->same_p[0] = -2;
+      p->same_p[1] = -2;
       *slot = (void *) p;
     }
 
@@ -3246,7 +3250,7 @@ struct sccs
   bool on_sccstack;
   union {
     hashval_t hash;
-    int same_p;
+    signed char same_p;
   } u;
 };
 
@@ -3366,7 +3370,8 @@ gimple_compatible_complete_and_incomplete_subtype_p (tree t1, tree t2)
 }
 
 static bool
-gimple_types_compatible_p_1 (tree, tree, bool, VEC(type_pair_t, heap) **,
+gimple_types_compatible_p_1 (tree, tree, enum gtc_mode, type_pair_t,
+                            VEC(type_pair_t, heap) **,
                             struct pointer_map_t *, struct obstack *);
 
 /* DFS visit the edge from the callers type pair with state *STATE to
@@ -3376,7 +3381,7 @@ gimple_types_compatible_p_1 (tree, tree, bool, VEC(type_pair_t, heap) **,
    SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done.  */
 
 static bool
-gtc_visit (tree t1, tree t2, bool for_merging_p,
+gtc_visit (tree t1, tree t2, enum gtc_mode mode,
           struct sccs *state,
           VEC(type_pair_t, heap) **sccstack,
           struct pointer_map_t *sccstate,
@@ -3456,33 +3461,28 @@ gtc_visit (tree t1, tree t2, bool for_merging_p,
     return false;
 
   /* Allocate a new cache entry for this comparison.  */
-  p = lookup_type_pair (t1, t2,
-                       for_merging_p ? &gtc_visited : &gtc_visited2,
-                       for_merging_p ? &gtc_ob : &gtc_ob2);
-  if (p->same_p == 0 || p->same_p == 1)
+  p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob);
+  if (p->same_p[mode] == 0 || p->same_p[mode] == 1)
     {
       /* We have already decided whether T1 and T2 are the
         same, return the cached result.  */
-      return p->same_p == 1;
+      return p->same_p[mode] == 1;
     }
 
-  gcc_assert (p->same_p == -2);
-
   if ((slot = pointer_map_contains (sccstate, p)) != NULL)
     cstate = (struct sccs *)*slot;
   if (!cstate)
     {
       bool res;
       /* Not yet visited.  DFS recurse.  */
-      res = gimple_types_compatible_p_1 (t1, t2, for_merging_p,
+      res = gimple_types_compatible_p_1 (t1, t2, mode, p,
                                         sccstack, sccstate, sccstate_obstack);
       if (!cstate)
        cstate = (struct sccs *)* pointer_map_contains (sccstate, p);
       state->low = MIN (state->low, cstate->low);
       /* If the type is no longer on the SCC stack and thus is not part
-        of the parents SCC mix in its hash value.  Otherwise we will
-        ignore the type for hashing purposes and return the unaltered
-        hash value.  */
+        of the parents SCC, return its state.  Otherwise we will
+        ignore this pair and assume equality.  */
       if (!cstate->on_sccstack)
        return res;
     }
@@ -3498,19 +3498,15 @@ gtc_visit (tree t1, tree t2, bool for_merging_p,
    SCCSTACK, SCCSTATE and SCCSTATE_OBSTACK are state for the DFS walk done.  */
 
 static bool
-gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
+gimple_types_compatible_p_1 (tree t1, tree t2, enum gtc_mode mode,
+                            type_pair_t p,
                             VEC(type_pair_t, heap) **sccstack,
                             struct pointer_map_t *sccstate,
                             struct obstack *sccstate_obstack)
 {
-  type_pair_t p;
   struct sccs *state;
 
-  /* Allocate a new cache entry for this comparison.  */
-  p = lookup_type_pair (t1, t2,
-                       for_merging_p ? &gtc_visited : &gtc_visited2,
-                       for_merging_p ? &gtc_ob : &gtc_ob2);
-  gcc_assert (p->same_p == -2);
+  gcc_assert (p->same_p[mode] == -2);
 
   state = XOBNEW (sccstate_obstack, struct sccs);
   *pointer_map_insert (sccstate, p) = state;
@@ -3529,7 +3525,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
     {
     case VECTOR_TYPE:
     case COMPLEX_TYPE:
-      if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+      if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
                      state, sccstack, sccstate, sccstate_obstack))
        goto different_types;
       goto same_types;
@@ -3537,7 +3533,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
     case ARRAY_TYPE:
       /* Array types are the same if the element types are the same and
         the number of elements are the same.  */
-      if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+      if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
                      state, sccstack, sccstate, sccstate_obstack)
          || TYPE_STRING_FLAG (t1) != TYPE_STRING_FLAG (t2)
          || TYPE_NONALIASED_COMPONENT (t1) != TYPE_NONALIASED_COMPONENT (t2))
@@ -3587,8 +3583,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
     case METHOD_TYPE:
       /* Method types should belong to the same class.  */
       if (!gtc_visit (TYPE_METHOD_BASETYPE (t1), TYPE_METHOD_BASETYPE (t2),
-                     for_merging_p,
-                     state, sccstack, sccstate, sccstate_obstack))
+                     mode, state, sccstack, sccstate, sccstate_obstack))
        goto different_types;
 
       /* Fallthru  */
@@ -3596,10 +3591,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
     case FUNCTION_TYPE:
       /* Function types are the same if the return type and arguments types
         are the same.  */
-      if ((for_merging_p
+      if ((mode != GTC_DIAG
           || !gimple_compatible_complete_and_incomplete_subtype_p
                 (TREE_TYPE (t1), TREE_TYPE (t2)))
-         && !gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+         && !gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
                         state, sccstack, sccstate, sccstate_obstack))
        goto different_types;
 
@@ -3616,11 +3611,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
               parms1 && parms2;
               parms1 = TREE_CHAIN (parms1), parms2 = TREE_CHAIN (parms2))
            {
-             if ((for_merging_p
+             if ((mode == GTC_MERGE
                   || !gimple_compatible_complete_and_incomplete_subtype_p
                         (TREE_VALUE (parms1), TREE_VALUE (parms2)))
-                 && !gtc_visit (TREE_VALUE (parms1), TREE_VALUE (parms2),
-                                for_merging_p,
+                 && !gtc_visit (TREE_VALUE (parms1), TREE_VALUE (parms2), mode,
                                 state, sccstack, sccstate, sccstate_obstack))
                goto different_types;
            }
@@ -3633,10 +3627,10 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
 
     case OFFSET_TYPE:
       {
-       if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+       if (!gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
                        state, sccstack, sccstate, sccstate_obstack)
            || !gtc_visit (TYPE_OFFSET_BASETYPE (t1),
-                          TYPE_OFFSET_BASETYPE (t2), for_merging_p,
+                          TYPE_OFFSET_BASETYPE (t2), mode,
                           state, sccstack, sccstate, sccstate_obstack))
          goto different_types;
 
@@ -3653,20 +3647,24 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
 
        /* If one pointer points to an incomplete type variant of
           the other pointed-to type they are the same.  */
-       if (!for_merging_p
+       if (mode == GTC_DIAG
            && gimple_compatible_complete_and_incomplete_subtype_p
                 (TREE_TYPE (t1), TREE_TYPE (t2)))
          goto same_types;
 
        /* Otherwise, pointer and reference types are the same if the
           pointed-to types are the same.  */
-       if (gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), for_merging_p,
+       if (gtc_visit (TREE_TYPE (t1), TREE_TYPE (t2), mode,
                       state, sccstack, sccstate, sccstate_obstack))
          goto same_types;
 
        goto different_types;
       }
 
+    case NULLPTR_TYPE:
+      /* There is only one decltype(nullptr).  */
+      goto same_types;
+
     case INTEGER_TYPE:
     case BOOLEAN_TYPE:
       {
@@ -3756,7 +3754,7 @@ gimple_types_compatible_p_1 (tree t1, tree t2, bool for_merging_p,
            if (DECL_NAME (f1) != DECL_NAME (f2)
                || DECL_NONADDRESSABLE_P (f1) != DECL_NONADDRESSABLE_P (f2)
                || !gimple_compare_field_offset (f1, f2)
-               || !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), for_merging_p,
+               || !gtc_visit (TREE_TYPE (f1), TREE_TYPE (f2), mode,
                               state, sccstack, sccstate, sccstate_obstack))
              goto different_types;
          }
@@ -3795,7 +3793,7 @@ pop:
          x = VEC_pop (type_pair_t, *sccstack);
          cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
          cstate->on_sccstack = false;
-         x->same_p = cstate->u.same_p;
+         x->same_p[mode] = cstate->u.same_p;
        }
       while (x != p);
     }
@@ -3808,7 +3806,7 @@ pop:
    are considered different, otherwise they are considered compatible.  */
 
 bool
-gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
+gimple_types_compatible_p (tree t1, tree t2, enum gtc_mode mode)
 {
   VEC(type_pair_t, heap) *sccstack = NULL;
   struct pointer_map_t *sccstate;
@@ -3889,21 +3887,19 @@ gimple_types_compatible_p (tree t1, tree t2, bool for_merging_p)
 
   /* If we've visited this type pair before (in the case of aggregates
      with self-referential types), and we made a decision, return it.  */
-  p = lookup_type_pair (t1, t2,
-                       for_merging_p ? &gtc_visited : &gtc_visited2,
-                       for_merging_p ? &gtc_ob : &gtc_ob2);
-  if (p->same_p == 0 || p->same_p == 1)
+  p = lookup_type_pair (t1, t2, &gtc_visited, &gtc_ob);
+  if (p->same_p[mode] == 0 || p->same_p[mode] == 1)
     {
       /* We have already decided whether T1 and T2 are the
         same, return the cached result.  */
-      return p->same_p == 1;
+      return p->same_p[mode] == 1;
     }
 
   /* Now set up the SCC machinery for the comparison.  */
   gtc_next_dfs_num = 1;
   sccstate = pointer_map_create ();
   gcc_obstack_init (&sccstate_obstack);
-  res = gimple_types_compatible_p_1 (t1, t2, for_merging_p,
+  res = gimple_types_compatible_p_1 (t1, t2, mode, p,
                                     &sccstack, sccstate, &sccstate_obstack);
   VEC_free (type_pair_t, heap, sccstack);
   pointer_map_destroy (sccstate);
@@ -3929,12 +3925,15 @@ visit (tree t, struct sccs *state, hashval_t v,
        struct obstack *sccstate_obstack)
 {
   struct sccs *cstate = NULL;
+  struct tree_int_map m;
   void **slot;
 
   /* If there is a hash value recorded for this type then it can't
      possibly be part of our parent SCC.  Simply mix in its hash.  */
-  if ((slot = pointer_map_contains (type_hash_cache, t)))
-    return iterative_hash_hashval_t ((hashval_t) (size_t) *slot, v);
+  m.base.from = t;
+  if ((slot = htab_find_slot (type_hash_cache, &m, NO_INSERT))
+      && *slot)
+    return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, v);
 
   if ((slot = pointer_map_contains (sccstate, t)) != NULL)
     cstate = (struct sccs *)*slot;
@@ -4001,9 +4000,8 @@ iterative_hash_gimple_type (tree type, hashval_t val,
   struct sccs *state;
 
 #ifdef ENABLE_CHECKING
-  /* Not visited during this DFS walk nor during previous walks.  */
-  gcc_assert (!pointer_map_contains (type_hash_cache, type)
-             && !pointer_map_contains (sccstate, type));
+  /* Not visited during this DFS walk.  */
+  gcc_assert (!pointer_map_contains (sccstate, type));
 #endif
   state = XOBNEW (sccstate_obstack, struct sccs);
   *pointer_map_insert (sccstate, type) = state;
@@ -4150,12 +4148,15 @@ iterative_hash_gimple_type (tree type, hashval_t val,
       do
        {
          struct sccs *cstate;
+         struct tree_int_map *m = ggc_alloc_cleared_tree_int_map ();
          x = VEC_pop (tree, *sccstack);
-         gcc_assert (!pointer_map_contains (type_hash_cache, x));
          cstate = (struct sccs *)*pointer_map_contains (sccstate, x);
          cstate->on_sccstack = false;
-         slot = pointer_map_insert (type_hash_cache, x);
-         *slot = (void *) (size_t) cstate->u.hash;
+         m->base.from = x;
+         m->to = cstate->u.hash;
+         slot = htab_find_slot (type_hash_cache, m, INSERT);
+         gcc_assert (!*slot);
+         *slot = (void *) m;
        }
       while (x != type);
     }
@@ -4181,12 +4182,16 @@ gimple_type_hash (const void *p)
   struct obstack sccstate_obstack;
   hashval_t val;
   void **slot;
+  struct tree_int_map m;
 
   if (type_hash_cache == NULL)
-    type_hash_cache = pointer_map_create ();
+    type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
+                                      tree_int_map_eq, NULL);
 
-  if ((slot = pointer_map_contains (type_hash_cache, p)) != NULL)
-    return iterative_hash_hashval_t ((hashval_t) (size_t) *slot, 0);
+  m.base.from = CONST_CAST_TREE (t);
+  if ((slot = htab_find_slot (type_hash_cache, &m, NO_INSERT))
+      && *slot)
+    return iterative_hash_hashval_t (((struct tree_int_map *) *slot)->to, 0);
 
   /* Perform a DFS walk and pre-hash all reachable types.  */
   next_dfs_num = 1;
@@ -4210,7 +4215,7 @@ gimple_type_eq (const void *p1, const void *p2)
   const_tree t1 = (const_tree) p1;
   const_tree t2 = (const_tree) p2;
   return gimple_types_compatible_p (CONST_CAST_TREE (t1),
-                                   CONST_CAST_TREE (t2), true);
+                                   CONST_CAST_TREE (t2), GTC_MERGE);
 }
 
 
@@ -4227,8 +4232,9 @@ gimple_register_type (tree t)
   gcc_assert (TYPE_P (t));
 
   /* In TYPE_CANONICAL we cache the result of gimple_register_type.
-     It is initially set to NULL during LTO streaming.  */
-  if (TYPE_CANONICAL (t))
+     It is initially set to NULL during LTO streaming.
+     But do not mess with TYPE_CANONICAL when not in WPA or link phase.  */
+  if (in_lto_p && TYPE_CANONICAL (t))
     return TYPE_CANONICAL (t);
 
   /* Always register the main variant first.  This is important so we
@@ -4238,7 +4244,7 @@ gimple_register_type (tree t)
     gimple_register_type (TYPE_MAIN_VARIANT (t));
 
   if (gimple_types == NULL)
-    gimple_types = htab_create (16381, gimple_type_hash, gimple_type_eq, 0);
+    gimple_types = htab_create_ggc (16381, gimple_type_hash, gimple_type_eq, 0);
 
   slot = htab_find_slot (gimple_types, t, INSERT);
   if (*slot
@@ -4294,12 +4300,14 @@ gimple_register_type (tree t)
          TYPE_NEXT_REF_TO (t) = NULL_TREE;
        }
 
-      TYPE_CANONICAL (t) = new_type;
+      if (in_lto_p)
+       TYPE_CANONICAL (t) = new_type;
       t = new_type;
     }
   else
     {
-      TYPE_CANONICAL (t) = t;
+      if (in_lto_p)
+       TYPE_CANONICAL (t) = t;
       *slot = (void *) t;
     }
 
@@ -4322,8 +4330,18 @@ print_gimple_types_stats (void)
             htab_collisions (gimple_types));
   else
     fprintf (stderr, "GIMPLE type table is empty\n");
+  if (type_hash_cache)
+    fprintf (stderr, "GIMPLE type hash table: size %ld, %ld elements, "
+            "%ld searches, %ld collisions (ratio: %f)\n",
+            (long) htab_size (type_hash_cache),
+            (long) htab_elements (type_hash_cache),
+            (long) type_hash_cache->searches,
+            (long) type_hash_cache->collisions,
+            htab_collisions (type_hash_cache));
+  else
+    fprintf (stderr, "GIMPLE type hash table is empty\n");
   if (gtc_visited)
-    fprintf (stderr, "GIMPLE type merging comparison table: size %ld, %ld "
+    fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
             "elements, %ld searches, %ld collisions (ratio: %f)\n",
             (long) htab_size (gtc_visited),
             (long) htab_elements (gtc_visited),
@@ -4331,16 +4349,6 @@ print_gimple_types_stats (void)
             (long) gtc_visited->collisions,
             htab_collisions (gtc_visited));
   else
-    fprintf (stderr, "GIMPLE type merging comparison table is empty\n");
-  if (gtc_visited2)
-    fprintf (stderr, "GIMPLE type comparison table: size %ld, %ld "
-            "elements, %ld searches, %ld collisions (ratio: %f)\n",
-            (long) htab_size (gtc_visited2),
-            (long) htab_elements (gtc_visited2),
-            (long) gtc_visited2->searches,
-            (long) gtc_visited2->collisions,
-            htab_collisions (gtc_visited2));
-  else
     fprintf (stderr, "GIMPLE type comparison table is empty\n");
 }
 
@@ -4360,7 +4368,7 @@ free_gimple_type_tables (void)
     }
   if (type_hash_cache)
     {
-      pointer_map_destroy (type_hash_cache);
+      htab_delete (type_hash_cache);
       type_hash_cache = NULL;
     }
   if (gtc_visited)
@@ -4369,12 +4377,6 @@ free_gimple_type_tables (void)
       obstack_free (&gtc_ob, NULL);
       gtc_visited = NULL;
     }
-  if (gtc_visited2)
-    {
-      htab_delete (gtc_visited2);
-      obstack_free (&gtc_ob2, NULL);
-      gtc_visited2 = NULL;
-    }
 }
 
 
@@ -4607,63 +4609,6 @@ gimple_get_alias_set (tree t)
       if (t1 != t)
        return get_alias_set (t1);
     }
-  else if (POINTER_TYPE_P (t))
-    {
-      /* From the common C and C++ langhook implementation:
-
-        Unfortunately, there is no canonical form of a pointer type.
-        In particular, if we have `typedef int I', then `int *', and
-        `I *' are different types.  So, we have to pick a canonical
-        representative.  We do this below.
-
-        Technically, this approach is actually more conservative that
-        it needs to be.  In particular, `const int *' and `int *'
-        should be in different alias sets, according to the C and C++
-        standard, since their types are not the same, and so,
-        technically, an `int **' and `const int **' cannot point at
-        the same thing.
-
-        But, the standard is wrong.  In particular, this code is
-        legal C++:
-
-        int *ip;
-        int **ipp = &ip;
-        const int* const* cipp = ipp;
-        And, it doesn't make sense for that to be legal unless you
-        can dereference IPP and CIPP.  So, we ignore cv-qualifiers on
-        the pointed-to types.  This issue has been reported to the
-        C++ committee.  */
-
-      /* In addition to the above canonicalization issue with LTO
-         we should also canonicalize `T (*)[]' to `T *' avoiding
-        alias issues with pointer-to element types and pointer-to
-        array types.
-
-        Likewise we need to deal with the situation of incomplete
-        pointed-to types and make `*(struct X **)&a' and
-        `*(struct X {} **)&a' alias.  Otherwise we will have to
-        guarantee that all pointer-to incomplete type variants
-        will be replaced by pointer-to complete type variants if
-        they are available.
-
-        With LTO the convenient situation of using `void *' to
-        access and store any pointer type will also become
-        more apparent (and `void *' is just another pointer-to
-        incomplete type).  Assigning alias-set zero to `void *'
-        and all pointer-to incomplete types is a not appealing
-        solution.  Assigning an effective alias-set zero only
-        affecting pointers might be - by recording proper subset
-        relationships of all pointer alias-sets.
-
-        Pointer-to function types are another grey area which
-        needs caution.  Globbing them all into one alias-set
-        or the above effective zero set would work.  */
-
-      /* For now just assign the same alias-set to all pointers.
-         That's simple and avoids all the above problems.  */
-      if (t != ptr_type_node)
-       return get_alias_set (ptr_type_node);
-    }
 
   return -1;
 }
@@ -4807,7 +4752,6 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
          if (TREE_CODE (rhs) == ADDR_EXPR)
            ret |= visit_addr (stmt, TREE_OPERAND (rhs, 0), data);
          else if (TREE_CODE (rhs) == TARGET_MEM_REF
-                   && TMR_BASE (rhs) != NULL_TREE
                   && TREE_CODE (TMR_BASE (rhs)) == ADDR_EXPR)
            ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (rhs), 0), data);
          else if (TREE_CODE (rhs) == OBJ_TYPE_REF
@@ -4816,7 +4760,6 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
                                                   0), data);
           lhs = gimple_assign_lhs (stmt);
          if (TREE_CODE (lhs) == TARGET_MEM_REF
-              && TMR_BASE (lhs) != NULL_TREE
               && TREE_CODE (TMR_BASE (lhs)) == ADDR_EXPR)
             ret |= visit_addr (stmt, TREE_OPERAND (TMR_BASE (lhs), 0), data);
        }