[patch] for PR24793

Zdenek Dvorak rakdver@atrey.karlin.mff.cuni.cz
Thu Nov 17 12:25:00 GMT 2005


Hello,

currently, ivopts fail to preserve the set of subvars that alias the
rewritten memory references.  This does not cause problems too often,
since structure aliasing usually ignores arrays and pointers, which is
what ivopts deal with.  But this is not the case if the array is inside
a structure that by itself is inside a structure (a.b.c[i]), as then
subvars for a.b are used.  Also, this deficiency turns out to be much
more problematic once subvars handling is extended to arrays with
constant indices, see the patches by Richard Guenther
(http://gcc.gnu.org/ml/gcc-patches/2005-08/msg01608.html).

This patch fixes the problem by storing the original reference
in the created TARGET_MEM_REF, so that we are able to recover the
set of subvars of the statement.  This is quite fragile (once someone
comes with another bright idea how to make the process of determining
the virtual operands of a statement more complicated, this will
necessarily break again), but as long as virtual operands are
recomputed by update_stmt, not much else can be done.

Bootstrapped & regtested on i686.

Zdenek

	PR tree-optimization/24793
	* tree-ssa-loop-ivopts.c (get_ref_tag): Remember the
	original reference if there are subvars.
	* tree-ssa-operands.c (get_tmr_operands): Handle subvars.

Index: tree-ssa-loop-ivopts.c
===================================================================
--- tree-ssa-loop-ivopts.c	(revision 107077)
+++ tree-ssa-loop-ivopts.c	(working copy)
@@ -5490,11 +5490,19 @@
    and extracts this single useful piece of information.  */
 
 static tree
-get_ref_tag (tree ref)
+get_ref_tag (tree ref, tree orig)
 {
   tree var = get_base_address (ref);
-  tree tag;
+  tree tag, sv;
+  unsigned HOST_WIDE_INT offset, size;
 
+  for (sv = orig; handled_component_p (sv); sv = TREE_OPERAND (sv, 0))
+    if (okay_component_ref_for_subvars (sv, &offset, &size))
+      break;
+
+  if (handled_component_p (sv))
+    return unshare_expr (sv);
+
   if (!var)
     return NULL_TREE;
 
@@ -5540,8 +5548,8 @@
     copy_mem_ref_info (new_ref, old_ref);
   else
     {
-      TMR_TAG (new_ref) = get_ref_tag (old_ref);
       TMR_ORIGINAL (new_ref) = unshare_and_remove_ssa_names (old_ref);
+      TMR_TAG (new_ref) = get_ref_tag (old_ref, TMR_ORIGINAL (new_ref));
     }
 }
 
Index: tree-ssa-operands.c
===================================================================
--- tree-ssa-operands.c	(revision 107077)
+++ tree-ssa-operands.c	(working copy)
@@ -1523,7 +1523,10 @@
 static void
 get_tmr_operands (tree stmt, tree expr, int flags)
 {
-  tree tag = TMR_TAG (expr);
+  tree tag = TMR_TAG (expr), ref;
+  unsigned HOST_WIDE_INT offset, size;
+  subvar_t svars, sv;
+  stmt_ann_t s_ann = stmt_ann (stmt);
 
   /* First record the real operands.  */
   get_expr_operands (stmt, &TMR_BASE (expr), opf_none);
@@ -1538,11 +1541,33 @@
       add_to_addressable_set (TMR_SYMBOL (expr), &ann->addresses_taken);
     }
 
-  if (tag)
-    get_expr_operands (stmt, &tag, flags);
-  else
-    /* Something weird, so ensure that we will be careful.  */
-    stmt_ann (stmt)->has_volatile_ops = true;
+  if (!tag)
+    {
+      /* Something weird, so ensure that we will be careful.  */
+      stmt_ann (stmt)->has_volatile_ops = true;
+      return;
+    }
+
+  if (DECL_P (tag))
+    {
+      get_expr_operands (stmt, &tag, flags);
+      return;
+    }
+
+  ref = okay_component_ref_for_subvars (tag, &offset, &size);
+  gcc_assert (ref != NULL_TREE);
+  svars = get_subvars_for_var (ref);
+  for (sv = svars; sv; sv = sv->next)
+    {
+      bool exact;		
+      if (overlap_subvar (offset, size, sv, &exact))
+	{
+	  int subvar_flags = flags;
+	  if (!exact)
+	    subvar_flags &= ~opf_kill_def;
+	  add_stmt_operand (&sv->var, s_ann, subvar_flags);
+	}
+    }
 }
 
 /* A subroutine of get_expr_operands to handle CALL_EXPR.  */



More information about the Gcc-patches mailing list