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]

rfc: early sra breaks stdarg optimization


On mainline we're now doing SRA before inlining.  This is all well
and good.  Unfortunately, it can break the scanning that tree-stdarg.c
does for structures.

This can be seen in failures of gcc.c-torture/execute/stdarg-4.c
(at -O1) and gcc.c-torture/execute/stdarg-1.c (at -O3) on Alpha.

The scanning in tree-stdarg.c relies on seeing a store to
ap.__offset in order to know that a read from the va_list has
occurred.  If we run sra first, this store initially turns into
a store to a scalar, and then later is eliminated by dce.

I fear that to fix this Properly would require a major rewrite
to tree-stdarg.c; not something I'm looking forward to right now.

A hack that appears to work is to simply deny scalarizing va_list
in the early passes.  We'll do it again after stdarg runs anyway,
and that will produce results similar to what we get on previous
branches.

A hack that does not work (and I hoped would) is to run the stdarg
optimization pass early as well, if va_list is an aggregate.  But
we have no aliasing information then so, boom.

Thoughts?  I'll wait for a while to commit this patch.


r~


	* tree-sra.c (early_sra): New.
	(decl_can_be_decomposed_p): Deny va_list if early_sra.
	(tree_sra_early, pass_sra_early): New.
	* tree-pass.h (pass_sra_early): Declare.
	* passes.c (init_optimization_passes): Use it.

--- passes.c	(revision 121896)
+++ passes.c	(local)
@@ -489,7 +489,7 @@ init_optimization_passes (void)
 	  NEXT_PASS (pass_rename_ssa_copies);
 	  NEXT_PASS (pass_ccp);
 	  NEXT_PASS (pass_forwprop);
-	  NEXT_PASS (pass_sra);
+	  NEXT_PASS (pass_sra_early);
 	  NEXT_PASS (pass_copy_prop);
 	  NEXT_PASS (pass_merge_phi);
 	  NEXT_PASS (pass_dce);
--- tree-pass.h	(revision 121896)
+++ tree-pass.h	(local)
@@ -241,6 +241,7 @@ extern struct tree_opt_pass pass_early_t
 extern struct tree_opt_pass pass_cleanup_cfg;
 extern struct tree_opt_pass pass_referenced_vars;
 extern struct tree_opt_pass pass_sra;
+extern struct tree_opt_pass pass_sra_early;
 extern struct tree_opt_pass pass_tail_recursion;
 extern struct tree_opt_pass pass_tail_calls;
 extern struct tree_opt_pass pass_tree_loop;
--- tree-sra.c	(revision 121896)
+++ tree-sra.c	(local)
@@ -75,6 +75,9 @@ Software Foundation, 51 Franklin Street,
 */
 
 
+/* True if this is the "early" pass, before inlining.  */
+static bool early_sra;
+
 /* The set of todo flags to return from tree_sra.  */
 static unsigned int todoflags;
 
@@ -342,6 +345,15 @@ decl_can_be_decomposed_p (tree var)
       return false;
     }
 
+  /* HACK: if we decompose a va_list_type_node before inlining, then we'll
+     confuse tree-stdarg.c, and we won't be able to figure out which and
+     how many arguments are accessed.  This really should be improved in
+     tree-stdarg.c, as the decomposition is truely a win.  */
+  if (early_sra
+      && TYPE_MAIN_VARIANT (TREE_TYPE (var))
+	 == TYPE_MAIN_VARIANT (va_list_type_node))
+    return false;
+
   return true;
 }
 
@@ -2365,12 +2377,44 @@ tree_sra (void)
   return todoflags;
 }
 
+static unsigned int
+tree_sra_early (void)
+{
+  unsigned int ret;
+
+  early_sra = true;
+  ret = tree_sra ();
+  early_sra = false;
+
+  return ret;
+}
+
 static bool
 gate_sra (void)
 {
   return flag_tree_sra != 0;
 }
 
+struct tree_opt_pass pass_sra_early =
+{
+  "esra",				/* name */
+  gate_sra,				/* gate */
+  tree_sra_early,			/* execute */
+  NULL,					/* sub */
+  NULL,					/* next */
+  0,					/* static_pass_number */
+  TV_TREE_SRA,				/* tv_id */
+  PROP_cfg | PROP_ssa,			/* properties_required */
+  0,					/* properties_provided */
+  0,				        /* properties_destroyed */
+  0,					/* todo_flags_start */
+  TODO_dump_func
+  | TODO_update_ssa
+  | TODO_ggc_collect
+  | TODO_verify_ssa,			/* todo_flags_finish */
+  0					/* letter */
+};
+
 struct tree_opt_pass pass_sra =
 {
   "sra",				/* name */


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