This is the mail archive of the gcc@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]

Re: About the is_gimple_min_invariant predicate


> 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


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