This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
rfc: early sra breaks stdarg optimization
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jakub Jelinek <jakub at redhat dot com>
- Date: Tue, 13 Feb 2007 11:45:12 -0800
- Subject: 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 */