[tree-ssa] Virtual operands of &a[1]?

Diego Novillo dnovillo@redhat.com
Wed Dec 3 15:29:00 GMT 2003


On Tue, 2003-12-02 at 14:43, Zdenek Dvorak wrote:
> Hello,
> 
> > > Is it correct to assume that
> > > anything inside ADDR_EXPR never creates VUSEs?
> > > 
> > No.  &VAR.FIELD[i] should create a use for 'i'.  You could in this case,
> > but you have to be careful in the general case.
> 
> OK. This seems to do what I want, now that Richard has fixed the
> non-gimple expressions created problem.  Bootstrapped and regtested on
> i686.
> 
> Zdenek
> 
> 	* tree-dfa.c (opf_no_vuses): New.
> 	(add_stmt_operand): Don't create virtual operands when opf_no_vuses
> 	is passed in flags.
> 	(get_expr_operands): Don't create VUSEs if the argument of & is
> 	invariant.
> 
No.  Two things:

      * If you want to stop looking for operands after you found a
        gimple invariant ADDR_EXPR, just return.
      * This will look for operands in things like '&ptr->field' which
        isn't a gimple invariant, but it should not generate operands
        either.

I think that the only expressions that can generate operands inside the
argument to an ADDR_EXPR are expressions that contain array references. 
For instance, &ptr->q.a[i]->b[j] ought to generate uses for 'i' and 'j'.

Right now, you won't be able to get such an expression from the
gimplifier.  The folders aren't that smart and the FE decomposes such
expressions.  But they are possible.

To deal with this, we should do a separate walk of the ADDR_EXPR operand
looking for ARRAY_REFs and adding their operands.  You cannot just block
vuse operands, because if 'i' and 'j' happened to be aliased, you would
fail to add them as operands.

The idea I have in mind is something like this.  It's still under
testing and I'm not completely sure it catches all the cases.  Jason?


Diego.


        * tree-dfa.c (struct get_expr_operands_data): New.
        (get_array_index_operands_r): New.
        (get_expr_operands): Call it when looking for operands in ADDR_EXPR
        nodes that are not invariant.

Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.194
diff -d -c -p -r1.1.4.194 tree-dfa.c
*** tree-dfa.c	2 Dec 2003 22:57:59 -0000	1.1.4.194
--- tree-dfa.c	3 Dec 2003 15:23:57 -0000
*************** struct walk_state
*** 103,108 ****
--- 103,115 ----
    int num_calls;
  };
  
+ /* Used to pass arguments into get_array_index_operands_r.  */
+ struct get_expr_operands_data
+ {
+   tree stmt;
+   voperands_t prev_vops;
+ };
+ 
  
  /* Flags to describe operand properties in get_stmt_operands and helpers.  */
  
*************** static void add_call_clobber_ops (tree, 
*** 136,141 ****
--- 143,149 ----
  static void add_call_read_ops (tree, voperands_t);
  static void add_stmt_operand (tree *, tree, int, voperands_t);
  static void add_immediate_use (tree, tree);
+ static tree get_array_index_operands_r (tree *, int *, void *);
  static tree find_vars_r (tree *, int *, void *);
  static void add_referenced_var (tree, struct walk_state *);
  static tree get_memory_tag_for (tree);
*************** get_expr_operands (tree stmt, tree *expr
*** 343,367 ****
       has interesting variable references.  */
    if (code == ADDR_EXPR)
      {
-       enum tree_code subcode = TREE_CODE (TREE_OPERAND (expr, 0));
- 
        /* Taking the address of a variable does not represent a
  	 reference to it, but the fact that STMT takes its address will be
  	 of interest to some passes (e.g. must-alias resolution).  */
        add_stmt_operand (expr_p, stmt, 0, NULL);
  
!       /* Only a few specific types of ADDR_EXPR expressions are
!        	 of interest.  */
!       if (subcode != COMPONENT_REF
! 	  && subcode != INDIRECT_REF
! 	  && subcode != ARRAY_REF)
! 	return;
  
!       /* Avoid recursion.  */
!       code = subcode;
!       class = TREE_CODE_CLASS (code);
!       expr_p = &TREE_OPERAND (expr, 0);
!       expr = *expr_p;
      }
  
    /* If we found a variable, add it to DEFS or USES depending on the
--- 351,373 ----
       has interesting variable references.  */
    if (code == ADDR_EXPR)
      {
        /* Taking the address of a variable does not represent a
  	 reference to it, but the fact that STMT takes its address will be
  	 of interest to some passes (e.g. must-alias resolution).  */
        add_stmt_operand (expr_p, stmt, 0, NULL);
  
!       /* If the address is not an invariant, look for references inside
! 	 array indices that may be referenced by the expression.  */
!       if (!is_gimple_min_invariant (expr))
! 	{
! 	  struct get_expr_operands_data wd;
! 	  wd.stmt = stmt;
! 	  wd.prev_vops = prev_vops;
! 	  walk_tree (&TREE_OPERAND (expr, 0), get_array_index_operands_r, &wd,
! 		     NULL);
! 	}
  
!       return;
      }
  
    /* If we found a variable, add it to DEFS or USES depending on the
*************** mark_new_vars_to_rename (tree stmt, sbit
*** 2767,2772 ****
--- 2773,2797 ----
      sbitmap_a_or_b (vars_to_rename, vars_to_rename, vars_in_vops_to_rename);
  
    sbitmap_free (vars_in_vops_to_rename);
+ }
+ 
+ 
+ /* Callback for walk_tree.  Used to find array index references inside
+    ADDR_EXPR nodes.  */
+ 
+ static tree
+ get_array_index_operands_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
+ 			    void *data)
+ {
+   tree t = *tp;
+   struct get_expr_operands_data *wd = data;
+ 
+   if (TREE_CODE (t) == ARRAY_REF)
+     if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+       add_stmt_operand (&TREE_OPERAND (t, 1), wd->stmt, opf_none,
+ 			wd->prev_vops);
+ 
+   return NULL_TREE;
  }
  
  #include "gt-tree-dfa.h"



More information about the Gcc-patches mailing list