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]

My pretty-ipa merge 2: Fix get_ref_base_and_extent() handling of unions and variable sized arrays


Hi,

the original email with this patch is at
http://gcc.gnu.org/ml/gcc-patches/2008-12/msg00765.html

It has been approved for 4.5 by Diego here:
http://gcc.gnu.org/ml/gcc-patches/2008-12/msg01147.html

I ackonowledge  that Diego has  requested a testcase, however,  I have
not been able to  come up with one without any of  the two new SRAs of
mine.  I  will therefore  instead add  a testcase for  this bug  to my
intraprocedural SRA which requires this bug is fixed.

I have added a FIXME as Richi requested at:
http://gcc.gnu.org/ml/gcc-patches/2008-12/msg01224.html

OTOH, I have not tried to do anything more sophisticated with the
problem.

I have  bootstrapped and  tested this patch  on trunk  on x86_64-linux
yesterday  without  any  problems.    Because  I  consider  the  patch
approved, I will commit it tomorrow unless anyone objects.

Thanks,

Martin



2009-03-29  Martin Jambor  <mjambor@suse.cz>

	* tree-dfa.c (get_ref_base_and_extent): Return -1 maxsize if
	seen_variable_array_ref while also traversing a union.

Index: mine/gcc/tree-dfa.c
===================================================================
--- mine.orig/gcc/tree-dfa.c	2009-03-29 19:48:21.000000000 +0200
+++ mine/gcc/tree-dfa.c	2009-03-29 19:48:56.000000000 +0200
@@ -801,6 +801,7 @@ get_ref_base_and_extent (tree exp, HOST_
   tree size_tree = NULL_TREE;
   HOST_WIDE_INT bit_offset = 0;
   bool seen_variable_array_ref = false;
+  bool seen_union = false;
 
   gcc_assert (!SSA_VAR_P (exp));
 
@@ -844,6 +845,9 @@ get_ref_base_and_extent (tree exp, HOST_
 	    tree field = TREE_OPERAND (exp, 1);
 	    tree this_offset = component_ref_field_offset (exp);
 
+	    if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == UNION_TYPE)
+	      seen_union = true;
+
 	    if (this_offset && TREE_CODE (this_offset) == INTEGER_CST)
 	      {
 		HOST_WIDE_INT hthis_offset = tree_low_cst (this_offset, 0);
@@ -934,12 +938,22 @@ get_ref_base_and_extent (tree exp, HOST_
      where we do not know maxsize for variable index accesses to
      the array.  The simplest way to conservatively deal with this
      is to punt in the case that offset + maxsize reaches the
-     base type boundary.  */
+     base type boundary.
+
+     Unfortunately this is difficult to determine reliably when unions are
+     involved and so we are conservative in such cases.
+
+     FIXME: This approach may be too conservative, we probably want to at least
+     check that the union is the last field/element at its level or even
+     propagate the calculated offsets back up the access chain and check
+     there.  */
+
   if (seen_variable_array_ref
-      && maxsize != -1
-      && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
-      && bit_offset + maxsize
-	   == (signed)TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))
+      && (seen_union
+	  || (maxsize != -1
+	      && host_integerp (TYPE_SIZE (TREE_TYPE (exp)), 1)
+	      && bit_offset + maxsize
+	      == (signed) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (exp))))))
     maxsize = -1;
 
   /* ???  Due to negative offsets in ARRAY_REF we can end up with


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