OSDN Git Service

PR rtl-optimization/28940
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-structalias.c
index dbece90..0212499 100644 (file)
@@ -461,8 +461,10 @@ struct constraint_graph
      variable substitution.  */
   int *eq_rep;
 
-  /* Pointer equivalence node for a node.  if pe[a] != a, then node a
-     can be united with node pe[a] after initial constraint building.  */
+  /* Pointer equivalence label for a node.  All nodes with the same
+     pointer equivalence label can be unified together at some point
+     (either during constraint optimization or after the constraint
+     graph is built).  */
   unsigned int *pe;
 
   /* Pointer equivalence representative for a label.  This is used to
@@ -969,13 +971,12 @@ init_graph (unsigned int size)
   graph->indirect_cycles = XNEWVEC (int, graph->size);
   graph->rep = XNEWVEC (unsigned int, graph->size);
   graph->complex = XCNEWVEC (VEC(constraint_t, heap) *, size);
-  graph->pe = XNEWVEC (unsigned int, graph->size);
+  graph->pe = XCNEWVEC (unsigned int, graph->size);
   graph->pe_rep = XNEWVEC (int, graph->size);
 
   for (j = 0; j < graph->size; j++)
     {
       graph->rep[j] = j;
-      graph->pe[j] = j;
       graph->pe_rep[j] = -1;
       graph->indirect_cycles[j] = -1;
     }
@@ -1276,28 +1277,29 @@ unify_nodes (constraint_graph_t graph, unsigned int to, unsigned int from,
          changed_count--;
        }
     }
-
-  /* If the solution changes because of the merging, we need to mark
-     the variable as changed.  */
-  if (bitmap_ior_into (get_varinfo (to)->solution,
-                      get_varinfo (from)->solution))
+  if (get_varinfo (from)->solution)
     {
-      if (update_changed && !TEST_BIT (changed, to))
+      /* If the solution changes because of the merging, we need to mark
+        the variable as changed.  */
+      if (bitmap_ior_into (get_varinfo (to)->solution,
+                          get_varinfo (from)->solution))
        {
-         SET_BIT (changed, to);
-         changed_count++;
+         if (update_changed && !TEST_BIT (changed, to))
+           {
+             SET_BIT (changed, to);
+             changed_count++;
+           }
+       }
+      
+      BITMAP_FREE (get_varinfo (from)->solution);
+      BITMAP_FREE (get_varinfo (from)->oldsolution);
+      
+      if (stats.iterations > 0)
+       {
+         BITMAP_FREE (get_varinfo (to)->oldsolution);
+         get_varinfo (to)->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
        }
     }
-
-  BITMAP_FREE (get_varinfo (from)->solution);
-  BITMAP_FREE (get_varinfo (from)->oldsolution);
-
-  if (stats.iterations > 0)
-    {
-      BITMAP_FREE (get_varinfo (to)->oldsolution);
-      get_varinfo (to)->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
-    }
-
   if (valid_graph_edge (graph, to, to))
     {
       if (graph->succs[to])
@@ -1942,13 +1944,13 @@ perform_var_substitution (constraint_graph_t graph)
 
   /* Condense the nodes, which means to find SCC's, count incoming
      predecessors, and unite nodes in SCC's.  */
-  for (i = 0; i < LAST_REF_NODE; i++)
+  for (i = 0; i < FIRST_REF_NODE; i++)
     if (!TEST_BIT (si->visited, si->node_mapping[i]))
       condense_visit (graph, si, si->node_mapping[i]);
 
   sbitmap_zero (si->visited);
   /* Actually the label the nodes for pointer equivalences  */
-  for (i = 0; i < LAST_REF_NODE; i++)
+  for (i = 0; i < FIRST_REF_NODE; i++)
     if (!TEST_BIT (si->visited, si->node_mapping[i]))
       label_visit (graph, si, si->node_mapping[i]);
 
@@ -2014,8 +2016,7 @@ perform_var_substitution (constraint_graph_t graph)
     {
       unsigned int node = si->node_mapping[i];
 
-      if (graph->pointer_label[node] == 0
-         && TEST_BIT (graph->direct_nodes, node))
+      if (graph->pointer_label[node] == 0)
        {
          if (dump_file && (dump_flags & TDF_DETAILS))
            fprintf (dump_file,
@@ -2100,13 +2101,20 @@ unite_pointer_equivalences (constraint_graph_t graph)
 
   /* Go through the pointer equivalences and unite them to their
      representative, if they aren't already.  */
-  for (i = 0; i < graph->size; i++)
+  for (i = 0; i < FIRST_REF_NODE; i++)
     {
       unsigned int label = graph->pe[i];
-      int label_rep = graph->pe_rep[label];
-
-      if (label != i && unite (label_rep, i))
-       unify_nodes (graph, label_rep, i, false);
+      if (label)
+       {
+         int label_rep = graph->pe_rep[label];
+         
+         if (label_rep == -1)
+           continue;
+         
+         label_rep = find (label_rep);
+         if (label_rep >= 0 && unite (label_rep, find (i)))
+           unify_nodes (graph, label_rep, i, false);
+       }
     }
 }
 
@@ -2177,40 +2185,30 @@ rewrite_constraints (constraint_graph_t graph,
         the constraint.  */
       if (lhslabel == 0)
        {
-         if (!TEST_BIT (graph->direct_nodes, lhsnode))
-           lhslabel = graph->pointer_label[lhsnode] = pointer_equiv_class++;
-         else
+         if (dump_file && (dump_flags & TDF_DETAILS))
            {
-             if (dump_file && (dump_flags & TDF_DETAILS))
-               {
-
-                 fprintf (dump_file, "%s is a non-pointer variable,"
-                          "ignoring constraint:",
-                          get_varinfo (lhs.var)->name);
-                 dump_constraint (dump_file, c);
-               }
-             VEC_replace (constraint_t, constraints, i, NULL);
-             continue;
+             
+             fprintf (dump_file, "%s is a non-pointer variable,"
+                      "ignoring constraint:",
+                      get_varinfo (lhs.var)->name);
+             dump_constraint (dump_file, c);
            }
+         VEC_replace (constraint_t, constraints, i, NULL);
+         continue;
        }
 
       if (rhslabel == 0)
        {
-         if (!TEST_BIT (graph->direct_nodes, rhsnode))
-           rhslabel = graph->pointer_label[rhsnode] = pointer_equiv_class++;
-         else
+         if (dump_file && (dump_flags & TDF_DETAILS))
            {
-             if (dump_file && (dump_flags & TDF_DETAILS))
-               {
-
-                 fprintf (dump_file, "%s is a non-pointer variable,"
-                          "ignoring constraint:",
-                          get_varinfo (rhs.var)->name);
-                 dump_constraint (dump_file, c);
-               }
-             VEC_replace (constraint_t, constraints, i, NULL);
-             continue;
+             
+             fprintf (dump_file, "%s is a non-pointer variable,"
+                      "ignoring constraint:",
+                      get_varinfo (rhs.var)->name);
+             dump_constraint (dump_file, c);
            }
+         VEC_replace (constraint_t, constraints, i, NULL);
+         continue;
        }
 
       lhsvar = find_equivalent_node (graph, lhsvar, lhslabel);
@@ -3655,6 +3653,27 @@ handle_rhs_call  (tree rhs)
     }
 }
 
+/* For non-IPA mode, generate constraints necessary for a call
+   that returns a pointer and assigns it to LHS.  This simply makes
+   the LHS point to anything.  */
+
+static void
+handle_lhs_call (tree lhs)
+{
+  VEC(ce_s, heap) *lhsc = NULL;
+  struct constraint_expr rhsc;
+  unsigned int j;
+  struct constraint_expr *lhsp;
+
+  rhsc.var = anything_id;
+  rhsc.offset = 0;
+  rhsc.type = ADDRESSOF;
+  get_constraint_for (lhs, &lhsc);
+  for (j = 0; VEC_iterate (ce_s, lhsc, j, lhsp); j++)
+    process_constraint_1 (new_constraint (*lhsp, rhsc), true);
+  VEC_free (ce_s, heap, lhsc);
+}
+
 /* Walk statement T setting up aliasing constraints according to the
    references found in T.  This function is the main part of the
    constraint builder.  AI points to auxiliary alias information used
@@ -3726,7 +3745,11 @@ find_func_aliases (tree origt)
       if (!in_ipa_mode)
        {
          if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
-           handle_rhs_call (GIMPLE_STMT_OPERAND (t, 1));
+           {
+             handle_rhs_call (GIMPLE_STMT_OPERAND (t, 1));
+             if (POINTER_TYPE_P (TREE_TYPE (GIMPLE_STMT_OPERAND (t, 1))))
+               handle_lhs_call (GIMPLE_STMT_OPERAND (t, 0));
+           }
          else
            handle_rhs_call (t);
        }
@@ -4089,7 +4112,9 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
          else if (!(pushed = push_fields_onto_fieldstack
                     (TREE_TYPE (type), fieldstack,
                      offset + i * TREE_INT_CST_LOW (elsz), has_union,
-                     TREE_TYPE (type))))
+                     (TYPE_NONALIASED_COMPONENT (type)
+                      ? addressable_type
+                      : TREE_TYPE (type)))))
            /* Empty structures may have actual size, like in C++. So
               see if we didn't push any subfields and the size is
               nonzero, push the field onto the stack */
@@ -4104,7 +4129,10 @@ push_fields_onto_fieldstack (tree type, VEC(fieldoff_s,heap) **fieldstack,
              pair->size = elsz;
              pair->decl = NULL_TREE;
              pair->offset = offset + i * TREE_INT_CST_LOW (elsz);
-             pair->alias_set = -1;
+             if (TYPE_NONALIASED_COMPONENT (type))
+               pair->alias_set = get_alias_set (addressable_type);
+             else
+               pair->alias_set = -1;
              count++;
            }
          else
@@ -4470,8 +4498,10 @@ create_variable_info_for (tree decl, const char *name)
 
          stats.total_vars++;
        }
-      VEC_free (fieldoff_s, heap, fieldstack);
     }
+
+  VEC_free (fieldoff_s, heap, fieldstack);
+
   return index;
 }
 
@@ -4672,7 +4702,6 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
 {
   unsigned int i;
   bitmap_iterator bi;
-  subvar_t sv;
   alias_set_type ptr_alias_set = get_alias_set (TREE_TYPE (ptr));
 
   EXECUTE_IF_SET_IN_BITMAP (from, 0, i, bi)
@@ -4687,10 +4716,14 @@ set_uids_in_ptset (tree ptr, bitmap into, bitmap from, bool is_derefed,
 
       if (vi->has_union && get_subvars_for_var (vi->decl) != NULL)
        {
+         unsigned int i;
+         tree subvar;
+         subvar_t sv = get_subvars_for_var (vi->decl);
+
          /* Variables containing unions may need to be converted to
             their SFT's, because SFT's can have unions and we cannot.  */
-         for (sv = get_subvars_for_var (vi->decl); sv; sv = sv->next)
-           bitmap_set_bit (into, DECL_UID (sv->var));
+         for (i = 0; VEC_iterate (tree, sv, i, subvar); ++i)
+           bitmap_set_bit (into, DECL_UID (subvar));
        }
       else if (TREE_CODE (vi->decl) == VAR_DECL
               || TREE_CODE (vi->decl) == PARM_DECL