diff gcc/tree-ssa-alias.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
line wrap: on
line diff
--- a/gcc/tree-ssa-alias.c	Fri Feb 12 23:41:23 2010 +0900
+++ b/gcc/tree-ssa-alias.c	Mon May 24 12:47:05 2010 +0900
@@ -1,5 +1,5 @@
 /* Alias analysis for trees.
-   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
 
@@ -24,9 +24,7 @@
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "rtl.h"
 #include "tm_p.h"
-#include "hard-reg-set.h"
 #include "basic-block.h"
 #include "timevar.h"
 #include "expr.h"
@@ -35,6 +33,7 @@
 #include "flags.h"
 #include "function.h"
 #include "diagnostic.h"
+#include "tree-pretty-print.h"
 #include "tree-dump.h"
 #include "gimple.h"
 #include "tree-flow.h"
@@ -189,7 +188,7 @@
 	ptr = TREE_OPERAND (base, 0);
       else if (base
 	       && SSA_VAR_P (base))
-	return operand_equal_p (base, decl, 0);
+	return base == decl;
       else if (base
 	       && CONSTANT_CLASS_P (base))
 	return false;
@@ -214,7 +213,7 @@
   if (DECL_RESTRICTED_P (decl)
       && TYPE_RESTRICT (TREE_TYPE (ptr))
       && pi->pt.vars_contains_restrict)
-    return bitmap_bit_p (pi->pt.vars, DECL_UID (decl));
+    return bitmap_bit_p (pi->pt.vars, DECL_PT_UID (decl));
 
   return pt_solution_includes (&pi->pt, decl);
 }
@@ -336,8 +335,6 @@
 
   fprintf (file, "\nESCAPED");
   dump_points_to_solution (file, &cfun->gimple_df->escaped);
-  fprintf (file, "\nCALLUSED");
-  dump_points_to_solution (file, &cfun->gimple_df->callused);
 
   fprintf (file, "\n\nFlow-insensitive points-to information\n\n");
 
@@ -403,6 +400,9 @@
   if (pt->escaped)
     fprintf (file, ", points-to escaped");
 
+  if (pt->ipa_escaped)
+    fprintf (file, ", points-to unit escaped");
+
   if (pt->null)
     fprintf (file, ", points-to NULL");
 
@@ -412,6 +412,8 @@
       dump_decl_set (file, pt->vars);
       if (pt->vars_contains_global)
 	fprintf (file, " (includes global vars)");
+      if (pt->vars_contains_restrict)
+	fprintf (file, " (includes restrict tags)");
     }
 }
 
@@ -537,13 +539,24 @@
   if (TYPE_CANONICAL (type1) == TYPE_CANONICAL (type2))
     return 1;
 
-  /* ???  Array types are not properly unified in all cases as we have
+  /* ??? Array types are not properly unified in all cases as we have
      spurious changes in the index types for example.  Removing this
      causes all sorts of problems with the Fortran frontend.  */
   if (TREE_CODE (type1) == ARRAY_TYPE
       && TREE_CODE (type2) == ARRAY_TYPE)
     return -1;
 
+  /* ??? In Ada, an lvalue of an unconstrained type can be used to access an
+     object of one of its constrained subtypes, e.g. when a function with an
+     unconstrained parameter passed by reference is called on an object and
+     inlined.  But, even in the case of a fixed size, type and subtypes are
+     not equivalent enough as to share the same TYPE_CANONICAL, since this
+     would mean that conversions between them are useless, whereas they are
+     not (e.g. type and subtypes can have different modes).  So, in the end,
+     they are only guaranteed to have the same alias set.  */
+  if (get_alias_set (type1) == get_alias_set (type2))
+    return -1;
+
   /* The types are known to be not equal.  */
   return 0;
 }
@@ -600,19 +613,9 @@
       offset1 -= offadj;
       return ranges_overlap_p (offset1, max_size1, offset2, max_size2);
     }
-
-  /* We haven't found any common base to apply offset-based disambiguation.
-     There are two cases:
-       1. The base access types have the same alias set.  This can happen
-	  in Ada when a function with an unconstrained parameter passed by
-	  reference is called on a constrained object and inlined: the types
-	  have the same alias set but aren't equivalent.  The references may
-	  alias in this case.
-       2. The base access types don't have the same alias set, i.e. one set
-	  is a subset of the other.  We have proved that B1 is not in the
-	  access path B2.path and that B2 is not in the access path B1.path
-	  so the references may not alias.  */
-  return get_alias_set (type1) == get_alias_set (type2);
+  /* If we have two type access paths B1.path1 and B2.path2 they may
+     only alias if either B1 is in B2.path2 or B2 is in B1.path1.  */
+  return false;
 }
 
 /* Return true if two memory references based on the variables BASE1
@@ -628,7 +631,7 @@
   gcc_assert (SSA_VAR_P (base1) && SSA_VAR_P (base2));
 
   /* If both references are based on different variables, they cannot alias.  */
-  if (!operand_equal_p (base1, base2, 0))
+  if (base1 != base2)
     return false;
 
   /* If both references are based on the same variable, they cannot alias if
@@ -819,6 +822,77 @@
     return decl_refs_may_alias_p (base1, offset1, max_size1,
 				  base2, offset2, max_size2);
 
+  ind1_p = INDIRECT_REF_P (base1);
+  ind2_p = INDIRECT_REF_P (base2);
+  /* Canonicalize the pointer-vs-decl case.  */
+  if (ind1_p && var2_p)
+    {
+      HOST_WIDE_INT tmp1;
+      tree tmp2;
+      ao_ref *tmp3;
+      tmp1 = offset1; offset1 = offset2; offset2 = tmp1;
+      tmp1 = max_size1; max_size1 = max_size2; max_size2 = tmp1;
+      tmp2 = base1; base1 = base2; base2 = tmp2;
+      tmp3 = ref1; ref1 = ref2; ref2 = tmp3;
+      var1_p = true;
+      ind1_p = false;
+      var2_p = false;
+      ind2_p = true;
+    }
+
+  /* If we are about to disambiguate pointer-vs-decl try harder to
+     see must-aliases and give leeway to some invalid cases.
+     This covers a pretty minimal set of cases only and does not
+     when called from the RTL oracle.  It handles cases like
+
+       int i = 1;
+       return *(float *)&i;
+
+     and also fixes gfortran.dg/lto/pr40725.  */
+  if (var1_p && ind2_p
+      && cfun
+      && gimple_in_ssa_p (cfun)
+      && TREE_CODE (TREE_OPERAND (base2, 0)) == SSA_NAME)
+    {
+      gimple def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (base2, 0));
+      while (is_gimple_assign (def_stmt)
+	     && (gimple_assign_rhs_code (def_stmt) == SSA_NAME
+		 || CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))))
+	{
+	  tree rhs = gimple_assign_rhs1 (def_stmt);
+	  HOST_WIDE_INT offset, size, max_size;
+
+	  /* Look through SSA name copies and pointer conversions.  */
+	  if (TREE_CODE (rhs) == SSA_NAME
+	      && POINTER_TYPE_P (TREE_TYPE (rhs)))
+	    {
+	      def_stmt = SSA_NAME_DEF_STMT (rhs);
+	      continue;
+	    }
+	  if (TREE_CODE (rhs) != ADDR_EXPR)
+	    break;
+
+	  /* If the pointer is defined as an address based on a decl
+	     use plain offset disambiguation and ignore TBAA.  */
+	  rhs = TREE_OPERAND (rhs, 0);
+	  rhs = get_ref_base_and_extent (rhs, &offset, &size, &max_size);
+	  if (SSA_VAR_P (rhs))
+	    {
+	      base2 = rhs;
+	      offset2 += offset;
+	      if (size != max_size
+		  || max_size == -1)
+		max_size2 = -1;
+	      return decl_refs_may_alias_p (base1, offset1, max_size1,
+					    base2, offset2, max_size2);
+	    }
+
+	  /* Do not continue looking through &p->x to limit time
+	     complexity.  */
+	  break;
+	}
+    }
+
   /* First defer to TBAA if possible.  */
   if (tbaa_p
       && flag_strict_aliasing
@@ -834,19 +908,12 @@
     return true;
 
   /* Dispatch to the pointer-vs-decl or pointer-vs-pointer disambiguators.  */
-  ind1_p = INDIRECT_REF_P (base1);
-  ind2_p = INDIRECT_REF_P (base2);
   set = tbaa_p ? -1 : 0;
   if (var1_p && ind2_p)
     return indirect_ref_may_alias_decl_p (ref2->ref, TREE_OPERAND (base2, 0),
 					  offset2, max_size2, set,
 					  ref1->ref, base1,
 					  offset1, max_size1, set);
-  else if (ind1_p && var2_p)
-    return indirect_ref_may_alias_decl_p (ref1->ref, TREE_OPERAND (base1, 0),
-					  offset1, max_size1, set,
-					  ref2->ref, base2,
-					  offset2, max_size2, set);
   else if (ind1_p && ind2_p)
     return indirect_refs_may_alias_p (ref1->ref, TREE_OPERAND (base1, 0),
 				      offset1, max_size1, set,
@@ -964,6 +1031,7 @@
 	/* The following builtins do not read from memory.  */
 	case BUILT_IN_FREE:
 	case BUILT_IN_MALLOC:
+	case BUILT_IN_CALLOC:
 	case BUILT_IN_MEMSET:
 	case BUILT_IN_FREXP:
 	case BUILT_IN_FREXPF:
@@ -992,8 +1060,7 @@
   /* Check if base is a global static variable that is not read
      by the function.  */
   if (TREE_CODE (base) == VAR_DECL
-      && TREE_STATIC (base)
-      && !TREE_PUBLIC (base))
+      && TREE_STATIC (base))
     {
       bitmap not_read;
 
@@ -1004,57 +1071,34 @@
 	goto process_args;
     }
 
-  /* If the base variable is call-used or call-clobbered then
-     it may be used.  */
-  if (flags & (ECF_PURE|ECF_CONST|ECF_LOOPING_CONST_OR_PURE|ECF_NOVOPS))
+  /* Check if the base variable is call-used.  */
+  if (DECL_P (base))
     {
-      if (DECL_P (base))
-	{
-	  if (is_call_used (base))
-	    return true;
-	}
-      else if (INDIRECT_REF_P (base)
-	       && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
-	{
-	  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
-	  if (!pi)
-	    return true;
+      if (pt_solution_includes (gimple_call_use_set (call), base))
+	return true;
+    }
+  else if (INDIRECT_REF_P (base)
+	   && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
+    {
+      struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
+      if (!pi)
+	return true;
 
-	  if (pt_solution_includes_global (&pi->pt)
-	      || pt_solutions_intersect (&cfun->gimple_df->callused, &pi->pt)
-	      || pt_solutions_intersect (&cfun->gimple_df->escaped, &pi->pt))
-	    return true;
-	}
-      else
+      if (pt_solutions_intersect (gimple_call_use_set (call), &pi->pt))
 	return true;
     }
   else
-    {
-      if (DECL_P (base))
-	{
-	  if (is_call_clobbered (base))
-	    return true;
-	}
-      else if (INDIRECT_REF_P (base)
-	       && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
-	{
-	  struct ptr_info_def *pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0));
-	  if (!pi)
-	    return true;
-
-	  if (pt_solution_includes_global (&pi->pt)
-	      || pt_solutions_intersect (&cfun->gimple_df->escaped, &pi->pt))
-	    return true;
-	}
-      else
-	return true;
-    }
+    return true;
 
   /* Inspect call arguments for passed-by-value aliases.  */
 process_args:
   for (i = 0; i < gimple_call_num_args (call); ++i)
     {
       tree op = gimple_call_arg (call, i);
+      int flags = gimple_call_arg_flags (call, i);
+
+      if (flags & EAF_UNUSED)
+	continue;
 
       if (TREE_CODE (op) == WITH_SIZE_EXPR)
 	op = TREE_OPERAND (op, 0);
@@ -1191,6 +1235,24 @@
 	/* Allocating memory does not have any side-effects apart from
 	   being the definition point for the pointer.  */
 	case BUILT_IN_MALLOC:
+	case BUILT_IN_CALLOC:
+	  /* Unix98 specifies that errno is set on allocation failure.
+	     Until we properly can track the errno location assume it
+	     is not a local decl but external or anonymous storage in
+	     a different translation unit.  Also assume it is of
+	     type int as required by the standard.  */
+	  if (flag_errno_math
+	      && TREE_TYPE (base) == integer_type_node)
+	    {
+	      struct ptr_info_def *pi;
+	      if (DECL_P (base)
+		  && !TREE_STATIC (base))
+		return true;
+	      else if (INDIRECT_REF_P (base)
+		       && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
+		       && (pi = SSA_NAME_PTR_INFO (TREE_OPERAND (base, 0))))
+		return pi->pt.anything || pi->pt.nonlocal;
+	    }
 	  return false;
 	/* Freeing memory kills the pointed-to memory.  More importantly
 	   the call has to serve as a barrier for moving loads and stores
@@ -1252,8 +1314,7 @@
      by the function.  */
   if (callee != NULL_TREE
       && TREE_CODE (base) == VAR_DECL
-      && TREE_STATIC (base)
-      && !TREE_PUBLIC (base))
+      && TREE_STATIC (base))
     {
       bitmap not_written;
 
@@ -1263,8 +1324,9 @@
 	return false;
     }
 
+  /* Check if the base variable is call-clobbered.  */
   if (DECL_P (base))
-    return is_call_clobbered (base);
+    return pt_solution_includes (gimple_call_clobber_set (call), base);
   else if (INDIRECT_REF_P (base)
 	   && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
     {
@@ -1272,14 +1334,16 @@
       if (!pi)
 	return true;
 
-      return (pt_solution_includes_global (&pi->pt)
-	      || pt_solutions_intersect (&cfun->gimple_df->escaped, &pi->pt));
+      return pt_solutions_intersect (gimple_call_clobber_set (call), &pi->pt);
     }
 
   return true;
 }
 
-static bool ATTRIBUTE_UNUSED
+/* If the call in statement CALL may clobber the memory reference REF
+   return true, otherwise return false.  */
+
+bool
 call_may_clobber_ref_p (gimple call, tree ref)
 {
   bool res;