This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix PR35607, another revenge of invariant addresses (ivopts)
Hi,
> > Indeed. Copied the list now. And Diego who had much to say about
> > gimple grammar in the threads referenced above (read between the
> > two arrows ;).
>
> This problem keeps surfacing again and again. I have a small Ada testcase
> that triggers it locally (with local Gigi changes) and there is no loop.
IMHO there are two possible ways to solve these problems:
1) something like the patch below (up to details of
address_invariant_p, this is just a quick hack).
2) making TREE_INVARIANT behave equivalently to this patch after
gimplification (or introducing a new tree flag with this altered
semantics)
2) seems complicated and possibly causing further problems, so I would
propose to go with 1), unless there are compile-time performance
problems due to this change.
I tried to understand Diego's proposal
(http://gcc.gnu.org/ml/gcc/2007-07/msg00097.html), however it seems to
propose to keep relying on TREE_INVARIANT with its current semantics,
which seems wrong -- I think middle-end should not use TREE_INVARIANT at
all, as it is more or less redundant with SSA form,
Zdenek
Index: tree-gimple.c
===================================================================
*** tree-gimple.c (revision 133282)
--- tree-gimple.c (working copy)
*************** is_gimple_addressable (tree t)
*** 167,172 ****
--- 167,211 ----
|| INDIRECT_REF_P (t));
}
+ /* Returns true if T is an object with invariant address. */
+
+ static bool
+ address_invariant_p (const_tree t)
+ {
+ for (; handled_component_p (t); t = TREE_OPERAND (t, 0))
+ {
+ switch (TREE_CODE (t))
+ {
+ case ARRAY_REF:
+ if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+ return false;
+
+ if (TREE_OPERAND (t, 2)
+ && !is_gimple_min_invariant (TREE_OPERAND (t, 2)))
+ return false;
+
+ if (TREE_OPERAND (t, 3)
+ && !is_gimple_min_invariant (TREE_OPERAND (t, 3)))
+ return false;
+ break;
+
+ case COMPONENT_REF:
+ if (TREE_OPERAND (t, 2)
+ && !is_gimple_min_invariant (TREE_OPERAND (t, 2)))
+ return false;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (INDIRECT_REF_P (t))
+ return is_gimple_min_invariant (TREE_OPERAND (t, 0));
+
+ return CONSTANT_CLASS_P (t) || DECL_P (t);
+ }
+
/* Return true if T is a GIMPLE minimal invariant. It's a restricted
form of function invariant. */
*************** is_gimple_min_invariant (const_tree t)
*** 176,182 ****
switch (TREE_CODE (t))
{
case ADDR_EXPR:
! return TREE_INVARIANT (t);
case INTEGER_CST:
case REAL_CST:
--- 215,223 ----
switch (TREE_CODE (t))
{
case ADDR_EXPR:
! if (!TREE_INVARIANT (t))
! return false;
! return address_invariant_p (TREE_OPERAND (t, 0));
case INTEGER_CST:
case REAL_CST: