OSDN Git Service

* configure.ac (gcc_cv_nm): Don't use an in-tree nm if
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-structalias.c
index 2ddbe0f..7a00de4 100644 (file)
@@ -1040,7 +1040,7 @@ merge_graph_nodes (constraint_graph_t graph, unsigned int to,
                       graph->zero_weight_succs[from]);
     }
 
-  /* Merge all the non-zero weighted predecessor edges.  */
+  /* Merge all the nonzero weighted predecessor edges.  */
   for (i = 0; VEC_iterate (constraint_edge_t, predvec, i, c); i++)
     {
       unsigned int d = c->dest;
@@ -1064,7 +1064,7 @@ merge_graph_nodes (constraint_graph_t graph, unsigned int to,
       
     }
   
-  /* Merge all the non-zero weighted successor edges.  */
+  /* Merge all the nonzero weighted successor edges.  */
   for (i = 0; VEC_iterate (constraint_edge_t, succvec, i, c); i++)
     {
       unsigned int d = c->dest;
@@ -1535,8 +1535,6 @@ type_safe (unsigned int n, unsigned HOST_WIDE_INT *offset)
   return (get_varinfo (n)->offset + *offset) < get_varinfo (n)->fullsize;
 }
 
-#define DONT_PROPAGATE_WITH_ANYTHING 0
-
 /* Process a constraint C that represents *x = &y.  */
 
 static void
@@ -1593,7 +1591,6 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
   unsigned int j;
   bitmap_iterator bi;
 
-#if DONT_PROPAGATE_WITH_ANYTHING 
  if (bitmap_bit_p (delta, anything_id))
    {
      flag = !bitmap_bit_p (sol, anything_id);
@@ -1601,7 +1598,6 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
        bitmap_set_bit (sol, anything_id);
      goto done;
    }
-#endif
   /* For each variable j in delta (Sol(y)), add    
      an edge in the graph from j to x, and union Sol(j) into Sol(x).  */
   EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
@@ -1629,9 +1625,8 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
        fprintf (dump_file, "Untypesafe usage in do_sd_constraint\n");
       
     }
-#if DONT_PROPAGATE_WITH_ANYTHING
+
 done:
-#endif
   /* If the LHS solution changed, mark the var as changed.  */
   if (flag)
     {
@@ -1655,7 +1650,6 @@ do_ds_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
   unsigned int j;
   bitmap_iterator bi;
 
-#if DONT_PROPAGATE_WITH_ANYTHING 
  if (bitmap_bit_p (sol, anything_id))
    {
      EXECUTE_IF_SET_IN_BITMAP (delta, 0, j, bi)
@@ -1683,7 +1677,6 @@ do_ds_constraint (constraint_graph_t graph, constraint_t c, bitmap delta)
        }
      return;
    }
-#endif
 
   /* For each member j of delta (Sol(x)), add an edge from y to j and
      union Sol(y) into Sol(j) */
@@ -2491,6 +2484,7 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results)
              struct constraint_expr *c;
              unsigned int i;
              tree exp = TREE_OPERAND (t, 0);
+             tree pttype = TREE_TYPE (TREE_TYPE (t));
 
              get_constraint_for (exp, results);
              /* Make sure we capture constraints to all elements
@@ -2514,6 +2508,26 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results)
                      VEC_safe_push (ce_s, heap, *results, &tmp);
                    }
                }
+             else if (VEC_length (ce_s, *results) == 1
+                      && (AGGREGATE_TYPE_P (pttype)
+                          || TREE_CODE (pttype) == COMPLEX_TYPE))
+               {
+                 struct constraint_expr *origrhs;
+                 varinfo_t origvar;
+                 struct constraint_expr tmp;
+
+                 gcc_assert (VEC_length (ce_s, *results) == 1);
+                 origrhs = VEC_last (ce_s, *results);
+                 tmp = *origrhs;
+                 VEC_pop (ce_s, *results);
+                 origvar = get_varinfo (origrhs->var);
+                 for (; origvar; origvar = origvar->next)
+                   {
+                     tmp.var = origvar->id;
+                     VEC_safe_push (ce_s, heap, *results, &tmp);
+                   }
+               }
+             
              for (i = 0; VEC_iterate (ce_s, *results, i, c); i++)
                {
                  if (c->type == DEREF)
@@ -2538,7 +2552,8 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results)
                  {                 
                    heapvar = create_tmp_var_raw (ptr_type_node, "HEAP");
                    DECL_EXTERNAL (heapvar) = 1;
-                   add_referenced_tmp_var (heapvar);
+                   if (referenced_vars)
+                     add_referenced_tmp_var (heapvar);
                    heapvar_insert (t, heapvar);
                  }
 
@@ -3026,7 +3041,7 @@ update_alias_info (tree stmt, struct alias_info *ai)
       if (!TEST_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (op)))
        {
          SET_BIT (ai->ssa_names_visited, SSA_NAME_VERSION (op));
-         VARRAY_PUSH_TREE (ai->processed_ptrs, op);
+         VEC_safe_push (tree, heap, ai->processed_ptrs, op);
        }
 
       /* If STMT is a PHI node, then it will not have pointer
@@ -3167,7 +3182,8 @@ handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr)
   VEC (ce_s, heap) *temp = NULL;
   unsigned int rhsoffset = 0;
 
-  if (TREE_CODE (expr) != PLUS_EXPR)
+  if (TREE_CODE (expr) != PLUS_EXPR
+      && TREE_CODE (expr) != MINUS_EXPR)
     return false;
 
   op0 = TREE_OPERAND (expr, 0);
@@ -3175,7 +3191,8 @@ handle_ptr_arith (VEC (ce_s, heap) *lhsc, tree expr)
 
   get_constraint_for (op0, &temp);
   if (POINTER_TYPE_P (TREE_TYPE (op0))
-      && TREE_CODE (op1) == INTEGER_CST)
+      && TREE_CODE (op1) == INTEGER_CST
+      && TREE_CODE (expr) == PLUS_EXPR)
     {
       rhsoffset = TREE_INT_CST_LOW (op1) * BITS_PER_UNIT;
     }
@@ -3226,10 +3243,12 @@ find_func_aliases (tree origt)
   /* Now build constraints expressions.  */
   if (TREE_CODE (t) == PHI_NODE)
     {
+      gcc_assert (!AGGREGATE_TYPE_P (TREE_TYPE (PHI_RESULT (t))));
+
       /* Only care about pointers and structures containing
         pointers.  */
       if (POINTER_TYPE_P (TREE_TYPE (PHI_RESULT (t)))
-         || AGGREGATE_TYPE_P (TREE_TYPE (PHI_RESULT (t))))
+         || TREE_CODE (TREE_TYPE (PHI_RESULT (t))) == COMPLEX_TYPE)
        {
          int i;
          unsigned int j;
@@ -3246,26 +3265,6 @@ find_func_aliases (tree origt)
              rhstype = TREE_TYPE (strippedrhs);
              get_constraint_for (PHI_ARG_DEF (t, i), &rhsc);
 
-             if (TREE_CODE (strippedrhs) == ADDR_EXPR
-                && AGGREGATE_TYPE_P (TREE_TYPE (rhstype))
-                && VEC_length (ce_s, rhsc) == 1)
-               {
-                 struct constraint_expr *origrhs;
-                 varinfo_t origvar;
-                 struct constraint_expr tmp;
-
-                 gcc_assert (VEC_length (ce_s, rhsc) == 1);
-                 origrhs = VEC_last (ce_s, rhsc);
-                 tmp = *origrhs;
-                 VEC_pop (ce_s, rhsc);
-                 origvar = get_varinfo (origrhs->var);
-                 for (; origvar; origvar = origvar->next)
-                   {
-                     tmp.var = origvar->id;
-                     VEC_safe_push (ce_s, heap, rhsc, &tmp);
-                   }
-               }
-
              for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
                {
                  struct constraint_expr *c2;
@@ -3295,7 +3294,6 @@ find_func_aliases (tree origt)
       tree lhsop;
       tree rhsop;
       unsigned int varid;
-      bool found = false;
       tree arglist;
       varinfo_t fi;
       int i = 1;
@@ -3317,14 +3315,12 @@ find_func_aliases (tree origt)
         we should still be able to handle.  */
       if (decl)
        {
-         found = lookup_id_for_tree (decl, &varid);
-         gcc_assert (found);
+         varid = get_id_for_tree (decl);
        }
       else
        {
          decl = TREE_OPERAND (rhsop, 0);
-         found = lookup_id_for_tree (decl, &varid);
-         gcc_assert (found);
+         varid = get_id_for_tree (decl);
        }
 
       /* Assign all the passed arguments to the appropriate incoming
@@ -3390,8 +3386,10 @@ find_func_aliases (tree origt)
       tree rhsop = TREE_OPERAND (t, 1);
       int i;
 
-      if (AGGREGATE_TYPE_P (TREE_TYPE (lhsop)) 
-         && AGGREGATE_TYPE_P (TREE_TYPE (rhsop)))
+      if ((AGGREGATE_TYPE_P (TREE_TYPE (lhsop)) 
+          || TREE_CODE (TREE_TYPE (lhsop)) == COMPLEX_TYPE)
+         && (AGGREGATE_TYPE_P (TREE_TYPE (rhsop))
+             || TREE_CODE (TREE_TYPE (lhsop)) == COMPLEX_TYPE))
        {
          do_structure_copy (lhsop, rhsop);
        }
@@ -3401,6 +3399,7 @@ find_func_aliases (tree origt)
             containing pointers, dereferences, and call expressions.  */
          if (POINTER_TYPE_P (TREE_TYPE (lhsop))
              || AGGREGATE_TYPE_P (TREE_TYPE (lhsop))
+             || TREE_CODE (TREE_TYPE (lhsop)) == COMPLEX_TYPE
              || TREE_CODE (rhsop) == CALL_EXPR)
            {
              get_constraint_for (lhsop, &lhsc);
@@ -3417,35 +3416,8 @@ find_func_aliases (tree origt)
                  case tcc_unary:
                      {
                        unsigned int j;
-                       tree strippedrhs = rhsop;
-                       tree rhstype;
-
-                       /* XXX: Push this back into the ADDR_EXPR
-                          case, and remove anyoffset handling.  */
-                       STRIP_NOPS (strippedrhs);
-                       rhstype = TREE_TYPE (strippedrhs);
-                       
-                       get_constraint_for (rhsop, &rhsc);
-                       if (TREE_CODE (strippedrhs) == ADDR_EXPR
-                           && AGGREGATE_TYPE_P (TREE_TYPE (rhstype))
-                           && VEC_length (ce_s, rhsc) == 1)
-                         {
-                           struct constraint_expr *origrhs;
-                           varinfo_t origvar;
-                           struct constraint_expr tmp;
-
-                           gcc_assert (VEC_length (ce_s, rhsc) == 1);
-                           origrhs = VEC_last (ce_s, rhsc);
-                           tmp = *origrhs;
-                           VEC_pop (ce_s, rhsc);
-                           origvar = get_varinfo (origrhs->var);
-                           for (; origvar; origvar = origvar->next)
-                             {
-                               tmp.var = origvar->id;
-                               VEC_safe_push (ce_s, heap, rhsc, &tmp);
-                             }
-                         }
 
+                       get_constraint_for (rhsop, &rhsc);
                        for (j = 0; VEC_iterate (ce_s, lhsc, j, c); j++)
                          {
                            struct constraint_expr *c2;
@@ -3531,11 +3503,24 @@ first_vi_for_offset (varinfo_t start, unsigned HOST_WIDE_INT offset)
 }
 
 
+/* Insert the varinfo FIELD into the field list for BASE, at the front
+   of the list.  */
+
+static void
+insert_into_field_list (varinfo_t base, varinfo_t field)
+{
+  varinfo_t prev = base;
+  varinfo_t curr = base->next;
+  
+  field->next = curr;
+  prev->next = field;
+}
+
 /* Insert the varinfo FIELD into the field list for BASE, ordered by
    offset.  */
 
 static void
-insert_into_field_list (varinfo_t base, varinfo_t field)
+insert_into_field_list_sorted (varinfo_t base, varinfo_t field)
 {
   varinfo_t prev = base;
   varinfo_t curr = base->next;
@@ -3817,7 +3802,7 @@ create_function_info_for (tree decl, const char *name)
       argvi->size = 1;
       argvi->fullsize = vi->fullsize;
       argvi->has_union = false;
-      insert_into_field_list (vi, argvi);
+      insert_into_field_list_sorted (vi, argvi);
       stats.total_vars ++;
       if (arg)
        {
@@ -3825,7 +3810,7 @@ create_function_info_for (tree decl, const char *name)
          arg = TREE_CHAIN (arg);
        }
     }
-  
+
   /* Create a variable for the return var.  */
   if (DECL_RESULT (decl) != NULL
       || !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl))))
@@ -3838,7 +3823,6 @@ create_function_info_for (tree decl, const char *name)
 
       vi->fullsize ++;
 
-
       if (DECL_RESULT (decl))
        resultdecl = DECL_RESULT (decl);
       
@@ -3854,7 +3838,7 @@ create_function_info_for (tree decl, const char *name)
       resultvi->size = 1;
       resultvi->fullsize = vi->fullsize;
       resultvi->has_union = false;
-      insert_into_field_list (vi, resultvi);
+      insert_into_field_list_sorted (vi, resultvi);
       stats.total_vars ++;
       if (DECL_RESULT (decl))
        insert_id_for_tree (DECL_RESULT (decl), newindex);
@@ -3881,7 +3865,6 @@ check_for_overlaps (VEC (fieldoff_s,heap) *fieldstack)
     }
   return false;
 }
-
 /* Create a varinfo structure for NAME and DECL, and add it to VARMAP.
    This will also create any varinfo structures necessary for fields
    of DECL.  */
@@ -3945,7 +3928,8 @@ create_variable_info_for (tree decl, const char *name)
   if (use_field_sensitive 
       && !notokay 
       && !vi->is_unknown_size_var 
-      && var_can_have_subvars (decl))
+      && var_can_have_subvars (decl)
+      && VEC_length (fieldoff_s, fieldstack) <= MAX_FIELDS_FOR_FIELD_SENSITIVE)
     {
       unsigned int newindex = VEC_length (varinfo_t, varmap);
       fieldoff_s *fo = NULL;
@@ -3991,7 +3975,9 @@ create_variable_info_for (tree decl, const char *name)
       
       vi->size = TREE_INT_CST_LOW (fo->size);
       vi->offset = fo->offset;
-      for (i = 1; VEC_iterate (fieldoff_s, fieldstack, i, fo); i++)
+      for (i = VEC_length (fieldoff_s, fieldstack) - 1; 
+          i >= 1 && VEC_iterate (fieldoff_s, fieldstack, i, fo); 
+          i--)
        {
          varinfo_t newvi;
          const char *newname;
@@ -4055,7 +4041,7 @@ intra_create_variable_infos (void)
   tree t;
 
   /* For each incoming argument arg, ARG = &ANYTHING or a dummy variable if
-     flag_argument_noalias > 1. */
+     flag_argument_noalias > 2. */
   for (t = DECL_ARGUMENTS (current_function_decl); t; t = TREE_CHAIN (t))
     {
       struct constraint_expr lhs;
@@ -4065,11 +4051,11 @@ intra_create_variable_infos (void)
       lhs.type = SCALAR;
       lhs.var  = create_variable_info_for (t, alias_get_name (t));
 
-      /* With flag_argument_noalias greater than one means that the incomming
+      /* With flag_argument_noalias greater than two means that the incoming
          argument cannot alias anything except for itself so create a HEAP
          variable.  */
       if (POINTER_TYPE_P (TREE_TYPE (t))
-         && flag_argument_noalias > 1)
+         && flag_argument_noalias > 2)
        {
          varinfo_t vi;
          struct constraint_expr rhs;
@@ -4077,9 +4063,11 @@ intra_create_variable_infos (void)
          unsigned int id;
          if (heapvar == NULL_TREE)
            {
-             heapvar = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (t)), "PARM_NOALIAS");
+             heapvar = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (t)), 
+                                           "PARM_NOALIAS");
              DECL_EXTERNAL (heapvar) = 1;
-             add_referenced_tmp_var (heapvar);
+             if (referenced_vars)
+               add_referenced_tmp_var (heapvar);
              heapvar_insert (t, heapvar);
            }
          id = create_variable_info_for (heapvar,
@@ -4560,19 +4548,20 @@ static bool
 gate_ipa_pta (void)
 {
   return (flag_unit_at_a_time != 0
+          && flag_ipa_pta
          /* Don't bother doing anything if the program has errors.  */
          && !(errorcount || sorrycount));
 }
 
 /* Execute the driver for IPA PTA.  */
-static void
+static unsigned int
 ipa_pta_execute (void)
 {
   struct cgraph_node *node;
   in_ipa_mode = 1;
-
+  init_alias_heapvars ();
   init_alias_vars ();
-  
+   
   for (node = cgraph_nodes; node; node = node->next)
     {
       if (!node->analyzed || cgraph_is_master_clone (node))
@@ -4658,6 +4647,9 @@ ipa_pta_execute (void)
   if (dump_file)
     dump_sa_points_to_info (dump_file);
   in_ipa_mode = 0;
+  delete_alias_heapvars ();
+  delete_points_to_sets ();
+  return 0;
 }
   
 struct tree_opt_pass pass_ipa_pta =