> 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))
     {
     case ADDR_EXPR:
-      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

Reply via email to