This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[lto] Support variable-sized aggregates


This patch adds support for variable sized aggregates in the
streamer.  It stops pass_ipa_free_lang_data from removing
non-constant bounds from types and add support for comparing
variable-sized aggregates in gimple_compare_types.

This fixes 6 failures in execute.exp.


Diego.


	* tree.c (free_lang_data_in_type): Do not reset
	TYPE_SIZE, TYPE_SIZE_UNIT, TYPE_MIN_VALUE and
	TYPE_MAX_VALUE.
	* gimple.c (gimple_compare_types): Do not assume that
	TYPE_MIN_VALUE and TYPE_MAX_VALUE are constants.
	(iterative_hash_gimple_type): Do not assume that
	TYPE_SIZE and TYPE_SIZE_UNIT are constants.

lto/ChangeLog

	* lto.c (lto_fixup_type): Fixup TYPE_SIZE and
	TYPE_SIZE_UNIT.

testsuite/ChangeLog.lto

	* gcc.dg/lto/20090706-1_0.c: New test.
	* gcc.dg/lto/20090706-2_0.c: New test.

Index: tree.c
===================================================================
--- tree.c	(revision 149291)
+++ tree.c	(working copy)
@@ -4044,20 +4044,6 @@ free_lang_data_in_type (tree type)
   TREE_LANG_FLAG_5 (type) = 0;
   TREE_LANG_FLAG_6 (type) = 0;
 
-  if (TREE_CODE (type) == ARRAY_TYPE
-      || TREE_CODE (type) == RECORD_TYPE)
-    {
-      tree unit_size = TYPE_SIZE_UNIT (type);
-      tree size = TYPE_SIZE (type);
-
-      if ((unit_size && TREE_CODE (unit_size) != INTEGER_CST)
-	  || (size && TREE_CODE (size) != INTEGER_CST))
-	{
-	  TYPE_SIZE_UNIT (type) = NULL_TREE;
-	  TYPE_SIZE (type) = NULL_TREE;
-	}
-    }
-
   if (TREE_CODE (type) == FUNCTION_TYPE)
     {
       /* Remove the const and volatile qualifiers from arguments.  The
@@ -4126,23 +4112,6 @@ free_lang_data_in_type (tree type)
       TYPE_BINFO (type)  = NULL_TREE;
     }
 
-  if (TREE_CODE (type) == INTEGER_TYPE)
-    {
-      tree old_max = TYPE_MAX_VALUE (type);
-      tree old_min = TYPE_MIN_VALUE (type);
-
-      if ((old_max && TREE_CODE (old_max) != INTEGER_CST)
-	  || (old_min && TREE_CODE (old_min) != INTEGER_CST))
-	  set_min_and_max_values_for_integral_type (type,
-						    TYPE_PRECISION (type),
-				 		    TYPE_UNSIGNED (type));
-
-      if (old_max && TREE_CODE (old_max) == INTEGER_CST)
-	TYPE_MAX_VALUE (type) = old_max;
-      if (old_min && TREE_CODE (old_min) == INTEGER_CST)
-	TYPE_MIN_VALUE (type) = old_min;
-    }
-
   /* Overloads TYPE_BINFO for non-record, non-union types.  */
   if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE)
     TYPE_LANG_SLOT_1 (type) = NULL_TREE;
Index: testsuite/gcc.dg/lto/20090706-1_0.c
===================================================================
--- testsuite/gcc.dg/lto/20090706-1_0.c	(revision 0)
+++ testsuite/gcc.dg/lto/20090706-1_0.c	(revision 0)
@@ -0,0 +1,42 @@
+#include <stdarg.h>
+
+extern void abort (void);
+
+void foo (int size, ...)
+{
+  struct
+    {
+      struct
+	{
+	  char x[size];
+	} e;
+      unsigned r;
+    } d;
+  va_list ap;
+  char c;
+  int i;
+
+  va_start (ap, size);
+  d = va_arg (ap, typeof (d));
+  c = d.e.x[3];
+  if (c != '3')
+    abort ();
+  if (d.r != 2602)
+    abort ();
+  va_end (ap);
+}
+
+int main (void)
+{
+  int z = 5, i;
+  struct { struct { char a[z]; } y; unsigned r; } x;
+          
+  x.y.a[0] = '0';
+  x.y.a[1] = '1';
+  x.y.a[2] = '2';
+  x.y.a[3] = '3';
+  x.y.a[4] = '4';
+  x.r = 2602;
+  foo (z, x);
+  return 0;
+}
Index: testsuite/gcc.dg/lto/20090706-2_0.c
===================================================================
--- testsuite/gcc.dg/lto/20090706-2_0.c	(revision 0)
+++ testsuite/gcc.dg/lto/20090706-2_0.c	(revision 0)
@@ -0,0 +1,16 @@
+extern void abort (void);
+
+int foo (int size)
+{
+  int a[size];
+  a[size - 10] = 42;
+  return a[size - 10] + size;
+}
+
+main()
+{
+  int x = foo (20);
+  if (x != 62)
+    abort ();
+  return 0;
+}
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 149291)
+++ lto/lto.c	(working copy)
@@ -1204,8 +1204,8 @@ lto_fixup_type (tree t, void *data)
 {
   lto_fixup_common (t, data);
   LTO_FIXUP_SUBTREE (TYPE_CACHED_VALUES (t));
-  gcc_assert (no_fixup_p (TYPE_SIZE (t)));
-  gcc_assert (no_fixup_p (TYPE_SIZE_UNIT (t)));
+  LTO_FIXUP_SUBTREE (TYPE_SIZE (t));
+  LTO_FIXUP_SUBTREE (TYPE_SIZE_UNIT (t));
   LTO_FIXUP_SUBTREE (TYPE_ATTRIBUTES (t));
   LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_POINTER_TO (t));
   LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_REFERENCE_TO (t));
Index: gimple.c
===================================================================
--- gimple.c	(revision 149291)
+++ gimple.c	(working copy)
@@ -3278,16 +3278,28 @@ gimple_compare_types (tree t1, tree t2, 
 	 represented in GIMPLE and have each front end lower to that.  */
       if (TREE_CODE (t1) != ENUMERAL_TYPE)
 	{
+	  tree min1 = TYPE_MIN_VALUE (t1);
+	  tree max1 = TYPE_MAX_VALUE (t1);
+	  tree min2 = TYPE_MIN_VALUE (t2);
+	  tree max2 = TYPE_MAX_VALUE (t2);
+	  bool min_equal_p = false;
+	  bool max_equal_p = false;
+
 	  /* If either type has a minimum value, the other type must
 	     have the same.  */
-	  if ((TYPE_MIN_VALUE (t1) || TYPE_MIN_VALUE (t2))
-	      && !tree_int_cst_equal (TYPE_MIN_VALUE (t1), TYPE_MIN_VALUE (t2)))
-	    goto different_types;
+	  if (min1 == NULL_TREE && min2 == NULL_TREE)
+	    min_equal_p = true;
+	  else if (min1 && min2 && operand_equal_p (min1, min2, 0))
+	    min_equal_p = true;
 
 	  /* Likewise, if either type has a maximum value, the other
 	     type must have the same.  */
-	  if ((TYPE_MAX_VALUE (t1) || TYPE_MAX_VALUE (t2))
-	      && !tree_int_cst_equal (TYPE_MAX_VALUE (t1), TYPE_MAX_VALUE (t2)))
+	  if (max1 == NULL_TREE && max2 == NULL_TREE)
+	    max_equal_p = true;
+	  else if (max1 && max2 && operand_equal_p (max1, max2, 0))
+	    max_equal_p = true;
+
+	  if (!min_equal_p || !max_equal_p)
 	    goto different_types;
 	}
 
@@ -3331,49 +3343,34 @@ gimple_compare_types (tree t1, tree t2, 
 	      tree min2 = TYPE_MIN_VALUE (i2);
 	      tree max1 = TYPE_MAX_VALUE (i1);
 	      tree max2 = TYPE_MAX_VALUE (i2);
+	      bool min_equal_p = false;
+	      bool max_equal_p = false;
 
-	      /* If the array types both have unspecified bounds, then
-		 MAX{1,2} will be NULL_TREE.  */
-	      if (min1 && min2 && !max1 && !max2)
-		{
-		  if (integer_zerop (min1) && integer_zerop (min2))
-		    goto same_types;
-		  else
-		    goto different_types;
-		}
+	      /* For variable-sized arrays, use the same notion as in the C
+		 front end.  If either domain is variable, consider the types
+		 compatible.  */
+	      if (min1 == NULL_TREE && min2 == NULL_TREE)
+		min_equal_p = true;
+	      else if (min1 && TREE_CODE (min1) != INTEGER_CST)
+		min_equal_p = true;
+	      else if (min2 && TREE_CODE (min2) != INTEGER_CST)
+		min_equal_p = true;
+	      else if (min1 && min2 && operand_equal_p (min1, min2, 0))
+		min_equal_p = true;
+	      
+	      if (max1 == NULL_TREE && max2 == NULL_TREE)
+		max_equal_p = true;
+	      else if (max1 && TREE_CODE (max1) != INTEGER_CST)
+		max_equal_p = true;
+	      else if (max2 && TREE_CODE (max2) != INTEGER_CST)
+		max_equal_p = true;
+	      else if (max1 && max2 && operand_equal_p (max1, max2, 0))
+		max_equal_p = true;
 
-	      /* Otherwise, we need the bounds to be fully specified.  */
-	      if (!min1 || !min2 || !max1 || !max2)
-		goto different_types;
-	      else if (TREE_CODE (min1) != INTEGER_CST
-		       || TREE_CODE (min2) != INTEGER_CST
-		       || TREE_CODE (max1) != INTEGER_CST
-		       || TREE_CODE (max2) != INTEGER_CST)
-		goto different_types;
-	      else if (tree_int_cst_equal (min1, min2))
-		{
-		  if (tree_int_cst_equal (max1, max2))
-		    goto same_types;
-		  else
-		    goto different_types;
-		}
+	      if (min_equal_p && max_equal_p)
+		goto same_types;
 	      else
-		{
-		  tree nelts1 = array_type_nelts (t1);
-		  tree nelts2 = array_type_nelts (t2);
-
-		  if (!nelts1 || !nelts2)
-		    goto different_types;
-
-		  if (TREE_CODE (nelts1) != INTEGER_CST
-		      || TREE_CODE (nelts2) != INTEGER_CST)
-		    goto different_types;
-
-		  if (tree_int_cst_equal (nelts1, nelts2))
-		    goto same_types;
-		  else
-		    goto different_types;
-		}
+		goto different_types;
 	    }
 	}
 
@@ -3553,10 +3550,8 @@ iterative_hash_gimple_type (const_tree t
      checked.  */
   v = iterative_hash_hashval_t (TREE_CODE (type), val);
   v = iterative_hash_hashval_t (TYPE_QUALS (type), v);
-  if (TYPE_SIZE (type))
-    v = iterative_hash_host_wide_int (int_cst_value (TYPE_SIZE (type)), v);
-  if (TYPE_SIZE_UNIT (type))
-    v = iterative_hash_hashval_t (int_cst_value (TYPE_SIZE_UNIT (type)), v);
+  v = iterative_hash_expr (TYPE_SIZE (type), v);
+  v = iterative_hash_expr (TYPE_SIZE_UNIT (type), v);
   v = iterative_hash_hashval_t (TREE_ADDRESSABLE (type), v);
 
   /* Incorporate common features of numerical types.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]