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

[PATCH]: Fix -Os bootstrap/PR tree-optimization/20542


This fixes the -Os bootstrap failure (PR 20542) by making
tree-ssa-loop-im's is_call_clobbered_ref know about subvars.
I moved overlap_subvar into tree-flow-inline.h so i could use it (and it
is a very simple function, the comments are longer than the code :P).
I also noticed a place in tree-ssa-alias.c it could be used that i will
submit a followup patch for.

I'll simply note that, besides being a pain to find and update places
that don't use the virutal operands on the call to find out what is call
clobbered, this way of doing things will start to lose tons of
optimization opportunities as we move towards having call clobbering on
a per-call basis represented by the operands, and having
is_call_clobbered mean it's clobbered by some call in the entire
function. Already, with Kenny's static variable call clobbering changes
that are coming in soon, we elide the operands for various statics on
calls that don't really clobber them, but is_call_clobbered will still
be true (because for unknown calls, and in general, it *is* call
clobbered).

Soon (once these call clobbering changes start getting merged from
tree-profiling) you will be better off pre-scanning the loop and
recording what the *operands* say is killed in some hash table, and
using that, even if it is possibly a little slower than the current
method.

Bootstrapped and regtested on i686-pc-linux-gnu.
Bootstrapped on i386-netbsdelf by Richard Earnshaw

Okay for mainline?

--Dan

2005-03-18  Daniel Berlin  <dberlin@dberlin.org>

	PR tree-optimization/20542

	* tree-flow-inline.h (overlap_subvar): Move to here.
	* tree-dfa.c: From here.
	* tree-flow.h (overlap_subvar): Declare.
	* tree-ssa-alias.c (add_pointed_to_var): Use overlap_subvar here.
	* tree-ssa-loop-im.c (is_call_clobbered_ref): Return proper answer
	for variables with subvars.

Index: tree-flow-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow-inline.h,v
retrieving revision 2.33
diff -u -p -r2.33 tree-flow-inline.h
--- tree-flow-inline.h	15 Mar 2005 01:26:34 -0000	2.33
+++ tree-flow-inline.h	19 Mar 2005 00:11:50 -0000
@@ -933,5 +933,48 @@ var_can_have_subvars (tree v)
 }
 
   
+/* Return true if OFFSET and SIZE define a range that overlaps with some
+   portion of the range of SV, a subvar.  If there was an exact overlap,
+   *EXACT will be set to true upon return. */
+
+static inline bool
+overlap_subvar (HOST_WIDE_INT offset, HOST_WIDE_INT size,
+		subvar_t sv,  bool *exact)
+{
+  /* There are three possible cases of overlap.
+     1. We can have an exact overlap, like so:   
+     |offset, offset + size             |
+     |sv->offset, sv->offset + sv->size |
+     
+     2. We can have offset starting after sv->offset, like so:
+     
+           |offset, offset + size              |
+     |sv->offset, sv->offset + sv->size  |
+
+     3. We can have offset starting before sv->offset, like so:
+     
+     |offset, offset + size    |
+       |sv->offset, sv->offset + sv->size|
+  */
+
+  if (exact)
+    *exact = false;
+  if (offset == sv->offset && size == sv->size)
+    {
+      if (exact)
+	*exact = true;
+      return true;
+    }
+  else if (offset >= sv->offset && offset < (sv->offset + sv->size))
+    {
+      return true;
+    }
+  else if (offset < sv->offset && (offset + size > sv->offset))
+    {
+      return true;
+    }
+  return false;
+
+}
 
 #endif /* _TREE_FLOW_INLINE_H  */
Index: tree-flow.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-flow.h,v
retrieving revision 2.86
diff -u -p -r2.86 tree-flow.h
--- tree-flow.h	13 Mar 2005 00:45:52 -0000	2.86
+++ tree-flow.h	19 Mar 2005 00:11:51 -0000
@@ -596,6 +596,9 @@ static inline bool ref_contains_array_re
 extern tree okay_component_ref_for_subvars (tree, HOST_WIDE_INT *,
 					    HOST_WIDE_INT *);
 static inline bool var_can_have_subvars (tree);
+static inline bool overlap_subvar (HOST_WIDE_INT, HOST_WIDE_INT,
+				   subvar_t, bool *);
+
 /* Call-back function for walk_use_def_chains().  At each reaching
    definition, a function with this prototype is called.  */
 typedef bool (*walk_use_def_chains_fn) (tree, tree, void *);
Index: tree-ssa-alias.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-alias.c,v
retrieving revision 2.75
diff -u -p -r2.75 tree-ssa-alias.c
--- tree-ssa-alias.c	16 Mar 2005 16:25:45 -0000	2.75
+++ tree-ssa-alias.c	19 Mar 2005 00:11:51 -0000
@@ -1992,12 +1992,7 @@ add_pointed_to_var (struct alias_info *a
 
       for (sv = svars; sv; sv = sv->next)
 	{
-	  if (offset == sv->offset && size == sv->size)
-	    bitmap_set_bit (pi->pt_vars, var_ann (sv->var)->uid);
-	  else if (offset >= sv->offset && offset < (sv->offset + sv->size))
-	    bitmap_set_bit (pi->pt_vars, var_ann (sv->var)->uid);
-	  else if (offset < sv->offset 
-		   && (offset + size > sv->offset))
+	  if (overlap_subvar (offset, size, sv, NULL))
 	    bitmap_set_bit (pi->pt_vars, var_ann (sv->var)->uid);
 	}
     }
Index: tree-ssa-loop-im.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-loop-im.c,v
retrieving revision 2.31
diff -u -p -r2.31 tree-ssa-loop-im.c
--- tree-ssa-loop-im.c	11 Mar 2005 09:05:10 -0000	2.31
+++ tree-ssa-loop-im.c	19 Mar 2005 00:11:52 -0000
@@ -1146,13 +1146,40 @@ static bool
 is_call_clobbered_ref (tree ref)
 {
   tree base;
+  HOST_WIDE_INT offset, size;
+  subvar_t sv;
+  subvar_t svars;
+  tree sref = ref;
 
+  if (TREE_CODE (sref) == COMPONENT_REF
+      && (sref = okay_component_ref_for_subvars (sref, &offset, &size)))
+    {
+      svars = get_subvars_for_var (sref);
+      for (sv = svars; sv; sv = sv->next)
+	{
+	  if (overlap_subvar (offset, size, sv, NULL)
+	      && is_call_clobbered (sv->var))
+	    return true;
+	}
+    }
+	      
   base = get_base_address (ref);
   if (!base)
     return true;
 
   if (DECL_P (base))
-    return is_call_clobbered (base);
+    {
+      if (var_can_have_subvars (base)
+	  && (svars = get_subvars_for_var (base)))
+	{
+	  for (sv = svars; sv; sv = sv->next)
+	    if (is_call_clobbered (sv->var))
+	      return true;
+	  return false;
+	}
+      else
+	return is_call_clobbered (base);
+    }
 
   if (INDIRECT_REF_P (base))
     {
Index: tree-ssa-operands.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-ssa-operands.c,v
retrieving revision 2.68
diff -u -p -r2.68 tree-ssa-operands.c
--- tree-ssa-operands.c	15 Mar 2005 01:26:34 -0000	2.68
+++ tree-ssa-operands.c	19 Mar 2005 00:11:52 -0000
@@ -1024,49 +1024,6 @@ get_stmt_operands (tree stmt)
 }
 
 
-/* Return true if OFFSET and SIZE define a range that overlaps with some
-   portion of the range of SV, a subvar.  If there was an exact overlap,
-   *EXACT will be set to true upon return. */
-
-static bool
-overlap_subvar (HOST_WIDE_INT offset, HOST_WIDE_INT size,
-		subvar_t sv,  bool *exact)
-{
-  /* There are three possible cases of overlap.
-     1. We can have an exact overlap, like so:   
-     |offset, offset + size             |
-     |sv->offset, sv->offset + sv->size |
-     
-     2. We can have offset starting after sv->offset, like so:
-     
-           |offset, offset + size              |
-     |sv->offset, sv->offset + sv->size  |
-
-     3. We can have offset starting before sv->offset, like so:
-     
-     |offset, offset + size    |
-       |sv->offset, sv->offset + sv->size|
-  */
-
-  if (exact)
-    *exact = false;
-  if (offset == sv->offset && size == sv->size)
-    {
-      if (exact)
-	*exact = true;
-      return true;
-    }
-  else if (offset >= sv->offset && offset < (sv->offset + sv->size))
-    {
-      return true;
-    }
-  else if (offset < sv->offset && (offset + size > sv->offset))
-    {
-      return true;
-    }
-  return false;
-
-}
 /* Recursively scan the expression pointed by EXPR_P in statement referred to
    by INFO.  FLAGS is one of the OPF_* constants modifying how to interpret the
    operands found.  */

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