OSDN Git Service

2009-07-16 H.J. Lu <hongjiu.lu@intel.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-structalias.c
index ad5482a..a9eef0b 100644 (file)
@@ -337,10 +337,11 @@ new_var_info (tree t, const char *name)
   ret->decl = t;
   /* Vars without decl are artificial and do not have sub-variables.  */
   ret->is_artificial_var = (t == NULL_TREE);
-  ret->is_full_var = (t == NULL_TREE);
-  ret->is_heap_var = false;
   ret->is_special_var = false;
   ret->is_unknown_size_var = false;
+  ret->is_full_var = (t == NULL_TREE);
+  ret->is_heap_var = false;
+  ret->is_restrict_var = false;
   ret->may_have_pointers = true;
   ret->is_global_var = (t == NULL_TREE);
   if (t && DECL_P (t))
@@ -3387,6 +3388,7 @@ make_constraint_from_heapvar (varinfo_t lhs, const char *name)
   vi->is_artificial_var = true;
   vi->is_heap_var = true;
   vi->is_unknown_size_var = true;
+  vi->offset = 0;
   vi->fullsize = ~0;
   vi->size = ~0;
   vi->is_full_var = true;
@@ -3473,7 +3475,10 @@ handle_lhs_call (tree lhs, int flags, VEC(ce_s, heap) *rhsc)
     {
       varinfo_t vi;
       vi = make_constraint_from_heapvar (get_vi_for_tree (lhs), "HEAP");
-      make_copy_constraint (vi, nonlocal_id);
+      /* We delay marking allocated storage global until we know if
+         it escapes.  */
+      DECL_EXTERNAL (vi->decl) = 0;
+      vi->is_global_var = 0;
     }
   else if (VEC_length (ce_s, rhsc) > 0)
     {
@@ -3910,6 +3915,13 @@ find_func_aliases (gimple origt)
     {
       make_escape_constraint (gimple_assign_rhs1 (t));
     }
+  /* Handle escapes through return.  */
+  else if (gimple_code (t) == GIMPLE_RETURN
+          && gimple_return_retval (t) != NULL_TREE
+          && could_have_pointers (gimple_return_retval (t)))
+    {
+      make_escape_constraint (gimple_return_retval (t));
+    }
   /* Handle asms conservatively by adding escape constraints to everything.  */
   else if (gimple_code (t) == GIMPLE_ASM)
     {
@@ -4776,8 +4788,10 @@ find_what_var_points_to (varinfo_t vi, struct pt_solution *pt)
          else if (vi->is_heap_var)
            /* We represent heapvars in the points-to set properly.  */
            ;
+         else if (vi->id == readonly_id)
+           /* Nobody cares.  */
+           ;
          else if (vi->id == anything_id
-                  || vi->id == readonly_id
                   || vi->id == integer_id)
            pt->anything = 1;
        }
@@ -4873,6 +4887,28 @@ pt_solution_reset (struct pt_solution *pt)
   pt->anything = true;
 }
 
+/* Set the points-to solution *PT to point only to the variables
+   in VARS.  */
+
+void
+pt_solution_set (struct pt_solution *pt, bitmap vars)
+{
+  bitmap_iterator bi;
+  unsigned i;
+
+  memset (pt, 0, sizeof (struct pt_solution));
+  pt->vars = vars;
+  EXECUTE_IF_SET_IN_BITMAP (vars, 0, i, bi)
+    {
+      tree var = referenced_var_lookup (i);
+      if (is_global_var (var))
+       {
+         pt->vars_contains_global = true;
+         break;
+       }
+    }
+}
+
 /* Return true if the points-to solution *PT is empty.  */
 
 static bool
@@ -5350,6 +5386,7 @@ compute_points_to_sets (void)
   struct scc_info *si;
   basic_block bb;
   unsigned i;
+  varinfo_t vi;
 
   timevar_push (TV_TREE_PTA);
 
@@ -5447,6 +5484,14 @@ compute_points_to_sets (void)
      points-to solution queries.  */
   cfun->gimple_df->escaped.escaped = 0;
 
+  /* Mark escaped HEAP variables as global.  */
+  for (i = 0; VEC_iterate (varinfo_t, varmap, i, vi); ++i)
+    if (vi->is_heap_var
+       && !vi->is_restrict_var
+       && !vi->is_global_var)
+      DECL_EXTERNAL (vi->decl) = vi->is_global_var
+       = pt_solution_includes (&cfun->gimple_df->escaped, vi->decl);
+
   /* Compute the points-to sets for pointer SSA_NAMEs.  */
   for (i = 0; i < num_ssa_names; ++i)
     {