OSDN Git Service

PR c/43893
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-structalias.c
index 781eff3..207cb17 100644 (file)
@@ -1706,7 +1706,8 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
             the set.  Use ESCAPED as representative instead.  */
          else if (v->id == escaped_id)
            flag |= bitmap_set_bit (sol, escaped_id);
-         else if (add_graph_edge (graph, lhs, t))
+         else if (v->may_have_pointers
+                  && add_graph_edge (graph, lhs, t))
            flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
 
          /* If the variable is not exactly at the requested offset
@@ -1745,6 +1746,7 @@ do_ds_constraint (constraint_t c, bitmap delta)
   unsigned int j;
   bitmap_iterator bi;
   HOST_WIDE_INT loff = c->lhs.offset;
+  bool escaped_p = false;
 
   /* Our IL does not allow this.  */
   gcc_assert (c->rhs.offset == 0);
@@ -1791,22 +1793,6 @@ do_ds_constraint (constraint_t c, bitmap delta)
       unsigned int t;
       HOST_WIDE_INT fieldoffset = v->offset + loff;
 
-      /* If v is a global variable then this is an escape point.  */
-      if (v->is_global_var)
-       {
-         t = find (escaped_id);
-         if (add_graph_edge (graph, t, rhs)
-             && bitmap_ior_into (get_varinfo (t)->solution, sol)
-             && !TEST_BIT (changed, t))
-           {
-             SET_BIT (changed, t);
-             changed_count++;
-           }
-       }
-
-      if (v->is_special_var)
-       continue;
-
       if (v->is_full_var)
        fieldoffset = v->offset;
       else if (loff != 0)
@@ -1819,6 +1805,25 @@ do_ds_constraint (constraint_t c, bitmap delta)
        {
          if (v->may_have_pointers)
            {
+             /* If v is a global variable then this is an escape point.  */
+             if (v->is_global_var
+                 && !escaped_p)
+               {
+                 t = find (escaped_id);
+                 if (add_graph_edge (graph, t, rhs)
+                     && bitmap_ior_into (get_varinfo (t)->solution, sol)
+                     && !TEST_BIT (changed, t))
+                   {
+                     SET_BIT (changed, t);
+                     changed_count++;
+                   }
+                 /* Enough to let rhs escape once.  */
+                 escaped_p = true;
+               }
+
+             if (v->is_special_var)
+               break;
+
              t = find (v->id);
              if (add_graph_edge (graph, t, rhs)
                  && bitmap_ior_into (get_varinfo (t)->solution, sol)
@@ -2885,6 +2890,16 @@ process_constraint (constraint_t t)
   /* ADDRESSOF on the lhs is invalid.  */
   gcc_assert (lhs.type != ADDRESSOF);
 
+  /* We shouldn't add constraints from things that cannot have pointers.
+     It's not completely trivial to avoid in the callers, so do it here.  */
+  if (rhs.type != ADDRESSOF
+      && !get_varinfo (rhs.var)->may_have_pointers)
+    return;
+
+  /* Likewise adding to the solution of a non-pointer var isn't useful.  */
+  if (!get_varinfo (lhs.var)->may_have_pointers)
+    return;
+
   /* This can happen in our IR with things like n->a = *p */
   if (rhs.type == DEREF && lhs.type == DEREF && rhs.var != anything_id)
     {