This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] replace keep_function_tree_in_gimple_form
- From: Richard Henderson <rth at twiddle dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 26 Oct 2003 17:41:52 -0800
- Subject: [tree-ssa] replace keep_function_tree_in_gimple_form
We were using keep_function_tree_in_gimple_form for two different things,
which is bad.
Jason invented it to note whether the front end had gimplified the function
before inlining. In this case, we avoid extra work by forcing our local
changes to be gimple, and avoid rescanning the whole function. On the
other hand, if the front end is producing GENERIC (which is preferred),
then we get better results gimplifying everything at once at the end.
It was also being used to determine whether we should emit loop notes
based on the trees being emitted, or whether we should synthesize them
from the cfg. When comming from gimple, we must do the later. Except
using keep_function_tree_in_gimple_form is wrong here because it should
be true of *any* front end that uses the tree-ssa optimizers. It's
unrelated to whether gimplification happens before or after inlining.
Which means that we should have been getting things wrong for Fortran,
one way or another.
I'm of the mind that we should in the near future work on streamlining
the tree->rtl converters, and remove support for anything that's not
gimple. This is a teeny tiny step down that path. We now always
synthesize loop notes from the cfg.
r~
* gimplify.c (keep_function_tree_in_gimple_form): Remove.
(gimplify_function_tree): Return void. Remove hack for
language not supporting gimple.
* tree.h: Update decls.
* langhooks-def.h (LANG_HOOKS_GIMPLE_BEFORE_INLINING): New.
* langhooks.h (struct lang_hooks): Add gimple_before_inlining.
* tree-inline.c (copy_body_r): Check that instead of
keep_function_tree_in_gimple_form.
(initialize_inlined_parameters): Likewise.
(expand_call_inline, expand_calls_inline): Likewise.
* explow.c (probe_stack_range): Never emit loop notes.
* expr.c (emit_block_move_via_loop): Likewise.
* toplev.c (rest_of_compilation): Always synthesize loop notes.
fortran/
* f96-lang.c (gfc_gimplify_expr): Remove.
(LANG_HOOKS_GIMPLIFY_EXPR): Remove.
(LANG_HOOKS_GIMPLE_BEFORE_INLINING): New.
Index: explow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/explow.c,v
retrieving revision 1.94.2.18
diff -u -p -r1.94.2.18 explow.c
--- explow.c 28 Sep 2003 06:06:21 -0000 1.94.2.18
+++ explow.c 27 Oct 2003 00:13:39 -0000
@@ -1490,23 +1490,16 @@ probe_stack_range (HOST_WIDE_INT first,
rtx test_lab = gen_label_rtx ();
rtx end_lab = gen_label_rtx ();
rtx temp;
- int create_notes
- = ! keep_function_tree_in_gimple_form (current_function_decl);
if (GET_CODE (test_addr) != REG
|| REGNO (test_addr) < FIRST_PSEUDO_REGISTER)
test_addr = force_reg (Pmode, test_addr);
- if (create_notes)
- emit_note (NOTE_INSN_LOOP_BEG);
emit_jump (test_lab);
emit_label (loop_lab);
emit_stack_probe (test_addr);
- if (create_notes)
- emit_note (NOTE_INSN_LOOP_CONT);
-
#ifdef STACK_GROWS_DOWNWARD
#define CMP_OPCODE GTU
temp = expand_binop (Pmode, sub_optab, test_addr, incr, test_addr,
@@ -1524,8 +1517,6 @@ probe_stack_range (HOST_WIDE_INT first,
emit_cmp_and_jump_insns (test_addr, last_addr, CMP_OPCODE,
NULL_RTX, Pmode, 1, loop_lab);
emit_jump (end_lab);
- if (create_notes)
- emit_note (NOTE_INSN_LOOP_END);
emit_label (end_lab);
emit_stack_probe (last_addr);
Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.467.2.57
diff -u -p -r1.467.2.57 expr.c
--- expr.c 26 Oct 2003 18:16:53 -0000 1.467.2.57
+++ expr.c 27 Oct 2003 00:13:47 -0000
@@ -1676,9 +1676,6 @@ emit_block_move_via_loop (rtx x, rtx y,
{
rtx cmp_label, top_label, iter, x_addr, y_addr, tmp;
enum machine_mode iter_mode;
- int create_notes
- = ! keep_function_tree_in_gimple_form (current_function_decl);
-
iter_mode = GET_MODE (size);
if (iter_mode == VOIDmode)
@@ -1694,9 +1691,6 @@ emit_block_move_via_loop (rtx x, rtx y,
y_addr = force_operand (XEXP (y, 0), NULL_RTX);
do_pending_stack_adjust ();
- if (create_notes)
- emit_note (NOTE_INSN_LOOP_BEG);
-
emit_jump (cmp_label);
emit_label (top_label);
@@ -1713,15 +1707,10 @@ emit_block_move_via_loop (rtx x, rtx y,
if (tmp != iter)
emit_move_insn (iter, tmp);
- if (create_notes)
- emit_note (NOTE_INSN_LOOP_CONT);
emit_label (cmp_label);
emit_cmp_and_jump_insns (iter, size, LT, NULL_RTX, iter_mode,
true, top_label);
-
- if (create_notes)
- emit_note (NOTE_INSN_LOOP_END);
}
/* Copy all or part of a value X into registers starting at REGNO.
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.102
diff -u -p -r1.1.2.102 gimplify.c
--- gimplify.c 24 Oct 2003 07:41:31 -0000 1.1.2.102
+++ gimplify.c 27 Oct 2003 00:13:50 -0000
@@ -3147,52 +3147,18 @@ gimplify_body (tree *body_p, tree fndecl
input_location = saved_location;
}
-/* Return nonzero if we should keep FNDECL in gimple form during inlining. */
+/* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
+ node for the function we want to gimplify. */
-int
-keep_function_tree_in_gimple_form (tree fndecl)
-{
- tree fnbody;
-
- /* If the front-end does not support gimplification, then this
- function was never in gimple form to begin with. */
- if (lang_hooks.gimplify_expr == lhd_gimplify_expr)
- return 0;
-
- /* If the function has no body, then we consider it not in gimple
- form. */
- fnbody = DECL_SAVED_TREE (fndecl);
- if (fnbody == NULL_TREE)
- return 0;
-
- return 1;
-}
-
-/* Entry point to the gimplification pass. FNDECL is the FUNCTION_DECL
- node for the function we want to gimplify. */
-
-bool
+void
gimplify_function_tree (tree fndecl)
{
- tree fnbody;
tree oldfn;
- /* FIXME. Hack. If this front end does not support gimplification,
- do nothing. */
- if (lang_hooks.gimplify_expr == lhd_gimplify_expr)
- return false;
-
- fnbody = DECL_SAVED_TREE (fndecl);
- if (fnbody == NULL_TREE)
- return false;
-
oldfn = current_function_decl;
current_function_decl = fndecl;
- gimplify_body (&fnbody, fndecl);
+ gimplify_body (&DECL_SAVED_TREE (fndecl), fndecl);
- DECL_SAVED_TREE (fndecl) = fnbody;
current_function_decl = oldfn;
-
- return true;
}
Index: langhooks-def.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks-def.h,v
retrieving revision 1.34.2.22
diff -u -p -r1.34.2.22 langhooks-def.h
--- langhooks-def.h 25 Oct 2003 19:42:52 -0000 1.34.2.22
+++ langhooks-def.h 27 Oct 2003 00:13:50 -0000
@@ -207,6 +207,7 @@ extern int lhd_gimplify_expr (tree *, tr
/* Hooks for tree gimplification. */
#define LANG_HOOKS_GIMPLIFY_EXPR lhd_gimplify_expr
+#define LANG_HOOKS_GIMPLE_BEFORE_INLINING true
/* Tree dump hooks. */
extern bool lhd_tree_dump_dump_tree (void *, tree);
@@ -319,7 +320,8 @@ extern int lhd_tree_dump_type_quals (tre
LANG_HOOKS_DECLS, \
LANG_HOOKS_FOR_TYPES_INITIALIZER, \
LANG_HOOKS_RTL_EXPAND_INITIALIZER, \
- LANG_HOOKS_GIMPLIFY_EXPR \
+ LANG_HOOKS_GIMPLIFY_EXPR, \
+ LANG_HOOKS_GIMPLE_BEFORE_INLINING \
}
#endif /* GCC_LANG_HOOKS_DEF_H */
Index: langhooks.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/langhooks.h,v
retrieving revision 1.42.2.23
diff -u -p -r1.42.2.23 langhooks.h
--- langhooks.h 25 Oct 2003 19:42:52 -0000 1.42.2.23
+++ langhooks.h 27 Oct 2003 00:13:50 -0000
@@ -425,6 +425,10 @@ struct lang_hooks
enum gimplify_status, though we can't see that type here. */
int (*gimplify_expr) (tree *, tree *, tree *);
+ /* True if the front end has gimplified the function before running the
+ inliner, false if the front end generates GENERIC directly. */
+ bool gimple_before_inlining;
+
/* Whenever you add entries here, make sure you adjust langhooks-def.h
and langhooks.c accordingly. */
};
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.654.2.70
diff -u -p -r1.654.2.70 toplev.c
--- toplev.c 26 Oct 2003 18:16:54 -0000 1.654.2.70
+++ toplev.c 27 Oct 2003 00:13:54 -0000
@@ -3323,8 +3323,7 @@ rest_of_compilation (tree decl)
cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
| (flag_thread_jumps ? CLEANUP_THREADING : 0));
- if (keep_function_tree_in_gimple_form (current_function_decl))
- create_loop_notes ();
+ create_loop_notes ();
if (optimize)
{
Index: tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.26.2.54
diff -u -p -r1.26.2.54 tree-inline.c
--- tree-inline.c 25 Oct 2003 19:42:52 -0000 1.26.2.54
+++ tree-inline.c 27 Oct 2003 00:13:56 -0000
@@ -458,7 +458,7 @@ copy_body_r (tree *tp, int *walk_subtree
if (assignment)
{
/* Do not create a statement containing a naked RESULT_DECL. */
- if (keep_function_tree_in_gimple_form (id->decl))
+ if (lang_hooks.gimple_before_inlining)
if (TREE_CODE (assignment) == RESULT_DECL)
gimplify_stmt (&assignment);
@@ -724,7 +724,7 @@ initialize_inlined_parameters (inline_da
TREE_CHAIN (var) = vars;
vars = var;
/* Make gimplifier happy about this variable. */
- var->decl.seen_in_bind_expr = keep_function_tree_in_gimple_form (fn);
+ var->decl.seen_in_bind_expr = lang_hooks.gimple_before_inlining;
/* Even if P was TREE_READONLY, the new VAR should not be.
In the original code, we would have constructed a
@@ -789,8 +789,7 @@ initialize_inlined_parameters (inline_da
value);
}
- if (gimplify_init_stmts_p
- && keep_function_tree_in_gimple_form (fn))
+ if (gimplify_init_stmts_p && lang_hooks.gimple_before_inlining)
gimplify_body (&init_stmts, fn);
add_var_to_bind_expr (bind_expr, vars);
@@ -1605,7 +1604,7 @@ expand_call_inline (tree *tp, int *walk_
/* If we are working with gimple form, then we need to keep the tree
in gimple form. If we are not in gimple form, we can just replace
*tp with the new BIND_EXPR. */
- if (keep_function_tree_in_gimple_form (id->decl))
+ if (lang_hooks.gimple_before_inlining)
{
tree save_decl;
@@ -1732,7 +1731,7 @@ expand_calls_inline (tree *tp, inline_da
recursively as we do not know anything about the structure
of the tree. */
- if (! keep_function_tree_in_gimple_form (id->decl))
+ if (!lang_hooks.gimple_before_inlining)
{
walk_tree (tp, expand_call_inline, id, id->tree_pruner);
return;
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.62
diff -u -p -r1.1.4.62 tree-optimize.c
--- tree-optimize.c 26 Oct 2003 18:16:55 -0000 1.1.4.62
+++ tree-optimize.c 27 Oct 2003 00:13:56 -0000
@@ -277,31 +277,29 @@ tree_rest_of_compilation (tree fndecl, b
nested_p = true;
}
- /* Gimplify the function. Don't try to optimize the function if
- gimplification failed. */
- if (keep_function_tree_in_gimple_form (fndecl)
- || gimplify_function_tree (fndecl))
- {
- /* Debugging dump after gimplification. */
- dump_function (TDI_gimple, fndecl);
+ /* If the function has not already been gimplified, do so now. */
+ if (!lang_hooks.gimple_before_inlining)
+ gimplify_function_tree (fndecl);
- /* Run a pass over the statements deleting any obviously useless
- statements before we build the CFG. */
- remove_useless_stmts_and_vars (&DECL_SAVED_TREE (fndecl), false);
- dump_function (TDI_useless, fndecl);
+ /* Debugging dump after gimplification. */
+ dump_function (TDI_gimple, fndecl);
- /* Run a pass to lower magic exception handling constructs into,
- well, less magic though not completely mundane constructs. */
- lower_eh_constructs (&DECL_SAVED_TREE (fndecl));
+ /* Run a pass over the statements deleting any obviously useless
+ statements before we build the CFG. */
+ remove_useless_stmts_and_vars (&DECL_SAVED_TREE (fndecl), false);
+ dump_function (TDI_useless, fndecl);
- /* Lower the structured statements. */
- lower_function_body (&DECL_SAVED_TREE (fndecl));
- dump_function (TDI_lower, fndecl);
+ /* Run a pass to lower magic exception handling constructs into,
+ well, less magic though not completely mundane constructs. */
+ lower_eh_constructs (&DECL_SAVED_TREE (fndecl));
- /* Invoke the SSA tree optimizer. */
- if (optimize >= 1 && !flag_disable_tree_ssa)
- optimize_function_tree (fndecl);
- }
+ /* Lower the structured statements. */
+ lower_function_body (&DECL_SAVED_TREE (fndecl));
+ dump_function (TDI_lower, fndecl);
+
+ /* Invoke the SSA tree optimizer. */
+ if (optimize >= 1 && !flag_disable_tree_ssa)
+ optimize_function_tree (fndecl);
/* If the function has a variably modified type, there may be
SAVE_EXPRs in the parameter types. Their context must be set to
Index: tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree.h,v
retrieving revision 1.342.2.116
diff -u -p -r1.342.2.116 tree.h
--- tree.h 26 Oct 2003 18:16:55 -0000 1.342.2.116
+++ tree.h 27 Oct 2003 00:13:59 -0000
@@ -3443,10 +3443,9 @@ extern int containing_blocks_have_cleanu
void optimize_function_tree (tree);
/* In gimplify.c. */
-extern bool gimplify_function_tree (tree);
+extern void gimplify_function_tree (tree);
extern const char *get_name (tree);
extern tree unshare_expr (tree);
-extern int keep_function_tree_in_gimple_form (tree);
/* If KIND=='I', return a suitable global initializer (constructor) name.
If KIND=='D', return a suitable global clean-up (destructor) name. */
Index: fortran/f95-lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/Attic/f95-lang.c,v
retrieving revision 1.1.2.13
diff -u -p -r1.1.2.13 f95-lang.c
--- fortran/f95-lang.c 23 Oct 2003 16:45:53 -0000 1.1.2.13
+++ fortran/f95-lang.c 27 Oct 2003 00:14:00 -0000
@@ -106,7 +106,6 @@ void set_block (tree);
static void gfc_be_parse_file (int);
static int gfc_expand_decl (tree t);
static void gfc_expand_stmt (tree t);
-static int gfc_gimplify_expr (tree *, tree *, tree *);
#undef LANG_HOOKS_NAME
#undef LANG_HOOKS_INIT
@@ -124,7 +123,7 @@ static int gfc_gimplify_expr (tree *, tr
#undef LANG_HOOKS_UNSIGNED_TYPE
#undef LANG_HOOKS_SIGNED_TYPE
#undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
-#undef LANG_HOOKS_GIMPLIFY_EXPR
+#undef LANG_HOOKS_GIMPLE_BEFORE_INLINING
#undef LANG_HOOKS_RTL_EXPAND_STMT
/* Define lang hooks. */
@@ -144,8 +143,7 @@ static int gfc_gimplify_expr (tree *, tr
#define LANG_HOOKS_UNSIGNED_TYPE gfc_unsigned_type
#define LANG_HOOKS_SIGNED_TYPE gfc_signed_type
#define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE gfc_signed_or_unsigned_type
-/* We need to provide this otherwise the gimplifier ignores us. */
-#define LANG_HOOKS_GIMPLIFY_EXPR gfc_gimplify_expr
+#define LANG_HOOKS_GIMPLE_BEFORE_INLINING false
#define LANG_HOOKS_RTL_EXPAND_STMT gfc_expand_stmt
const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
@@ -360,18 +358,6 @@ gfc_print_identifier (FILE * file ATTRIB
int indent ATTRIBUTE_UNUSED)
{
return;
-}
-
-
-/* This must exist otherwise the gimplifier ignores us. */
-
-static int
-gfc_gimplify_expr (tree * expr_p ATTRIBUTE_UNUSED,
- tree * pre_p ATTRIBUTE_UNUSED,
- tree *post_p ATTRIBUTE_UNUSED)
-{
- /* Just let the gimplifier handle everything. */
- return GS_UNHANDLED;
}