Wed Jul 4 22:20:00 GMT 2007

```> The problem is that in GIMPLE we only allow TREE_INVARIANT as a gimple
> value for ADDR_EXPRs.  We still require a TREE_CONSTANT as an array
> index.  So,  ARRAY[TREE_INVARIANT] is not valid GIMPLE.

OK, my understanding is that is_gimple_min_invariant as currently written is
correct as "non-recursive" predicate (for the updated grammar), i.e. during
gimplification.

> FRE should refuse to substitute a TREE_INVARIANT expression as an
> ARRAY_REF index.

The problem is that FRE (and other optimization passes) uses it as an absolute
predicate.  This mostly works because it essentially encompasses terminals of
the grammar, but fails for the non-terminal case.

How would you fix that?  By making it recursive, e.g.:

Index: tree-gimple.c
===================================================================
--- tree-gimple.c       (revision 126300)
+++ tree-gimple.c       (working copy)
@@ -166,8 +166,7 @@ is_gimple_addressable (tree t)
|| INDIRECT_REF_P (t));
}

-/* Return true if T is function invariant.  Or rather a restricted
-   form of function invariant.  */
+/* Return true if T is a GIMPLE minimal invariant.  */

bool
is_gimple_min_invariant (tree t)
@@ -175,7 +174,38 @@ is_gimple_min_invariant (tree t)
switch (TREE_CODE (t))
{
-      return TREE_INVARIANT (t);
+      if (!TREE_INVARIANT (t))
+       return false;
+
+      t = TREE_OPERAND (t, 0);
+
+      while (handled_component_p (t))
+       {
+         if (TREE_CODE (t) == COMPONENT_REF)
+           {
+             if (TREE_OPERAND (t, 2) && !is_gimple_val (TREE_OPERAND (t, 2)))
+               return false;
+           }
+         else if (TREE_CODE (t) == ARRAY_REF
+                  || TREE_CODE (t) == ARRAY_RANGE_REF)
+           {
+             if (!is_gimple_val (TREE_OPERAND (t, 1)))
+               return false;
+             if (TREE_OPERAND (t, 2) && !is_gimple_val (TREE_OPERAND (t, 2)))
+               return false;
+             if (TREE_OPERAND (t, 3) && !is_gimple_val (TREE_OPERAND (t, 3)))
+               return false;
+           }
+         else if (TREE_CODE (t) == BIT_FIELD_REF)
+           {
+             if (!is_gimple_val (TREE_OPERAND (t, 2)))
+               return false;
+           }
+
+         t = TREE_OPERAND (t, 0);
+       }
+
+      return is_gimple_min_lval (t);

case INTEGER_CST:
case REAL_CST:

or by uncoupling the 2 functions, i.e creating a recursive predicate for use
outside of gimplification?

--
Eric Botcazou

```