This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
My pretty-ipa merge 2: Fix get_ref_base_and_extent() handling of unions and variable sized arrays
- From: Martin Jambor <mjambor at suse dot cz>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Jan Hubicka <hubicka at ucw dot cz>, Richard Guenther <rguenther at suse dot de>
- Date: Sun, 29 Mar 2009 22:36:00 +0200
- Subject: 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