aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPaolo Bonzini <bonzini@gcc.gnu.org>2004-06-16 07:25:53 +0000
committerPaolo Bonzini <bonzini@gcc.gnu.org>2004-06-16 07:25:53 +0000
commit2f8e398bf476a5b0682e6fdc0f8b64df1cf0347b (patch)
tree9a0555f8f1b2223026f9437cfe0dae25fa815cd4 /gcc
parentfd660b1bee7af09cd69d1125cf35e6aa5826234c (diff)
downloadgcc-2f8e398bf476a5b0682e6fdc0f8b64df1cf0347b.zip
gcc-2f8e398bf476a5b0682e6fdc0f8b64df1cf0347b.tar.gz
gcc-2f8e398bf476a5b0682e6fdc0f8b64df1cf0347b.tar.bz2
coverage.c: Remove argument to rest_of_compilation.
gcc/ChangeLog: 2004-06-16 Paolo Bonzini <bonzini@gnu.org> * coverage.c: Remove argument to rest_of_compilation. * expr.c (execute_expand, set_save_expr_context, pass_expand): New. * passes.c (rest_of_compilation): Remove argument. (pass_rest_of_compilation): New. (rest_of_handle_final, rest_of_handle_delay_slots, rest_of_handle_stack_regs, rest_of_handle_variable_tracking rest_of_handle_machine_reorg, rest_of_handle_regrename rest_of_handle_sched, rest_of_handle_sched2, rest_of_handle_gcse2 rest_of_handle_regmove, rest_of_handle_tracer rest_of_handle_if_conversion, rest_of_handle_if_after_combine rest_of_handle_web, rest_of_handle_branch_prob rest_of_handle_value_profile_transformations, rest_of_handle_cfg rest_of_handle_addressof, rest_of_handle_jump_bypass rest_of_handle_life, rest_of_handle_cse, rest_of_handle_cse2): Check that the two arguments are actually superfluous. * toplev.h (rest_of_compilation): Adjust prototype. * tree-optimize.c (register_dump_files): Add properties argument. Track validity of passes. Only initialize dump files for tree-based passes. Store the full set of provided passes in the pass. (init_tree_optimization_passes): Register pass_expand and pass_rest_of_compilation. (execute_one_pass): Do not track the presence of required properties here. Set in_gimple_form. Do not update current_properties. (current_properties): Remove. (set_save_expr_context): Remove. (tree_rest_of_compilation): Do not set in_gimple_form. Do not expand to RTL here, and do not call rest_of_compilation. Push GGC context even before gimplification. * tree-pass.h (PROP_rtl, PROP_trees): New flags. (pass_expand, pass_rest_of_compilation): Declare. gcc/java/ChangeLog: 2004-06-16 Paolo Bonzini <bonzini@gnu.org> * java/class.c (emit_register_classes): Remove argument to rest_of_compilation. * java/resource.c (write_resource_constructor): Likewise. From-SVN: r83225
Diffstat (limited to 'gcc')
-rw-r--r--gcc/coverage.c2
-rw-r--r--gcc/expr.c91
-rw-r--r--gcc/java/class.c2
-rw-r--r--gcc/java/resource.c2
-rw-r--r--gcc/passes.c114
-rw-r--r--gcc/tree-optimize.c115
-rw-r--r--gcc/tree-pass.h6
7 files changed, 234 insertions, 98 deletions
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 8e95283..3eab7a5 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -955,7 +955,7 @@ create_coverage (void)
DECL_INITIAL (ctor) = make_node (BLOCK);
TREE_USED (DECL_INITIAL (ctor)) = 1;
- rest_of_compilation (ctor);
+ rest_of_compilation ();
if (! quiet_flag)
fflush (asm_out_file);
diff --git a/gcc/expr.c b/gcc/expr.c
index bb64d46..a3f89a1 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -48,7 +48,10 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "intl.h"
#include "tm_p.h"
#include "tree-iterator.h"
+#include "tree-pass.h"
+#include "tree-flow.h"
#include "target.h"
+#include "timevar.h"
/* Decide whether a function's arguments should be processed
from first to last or from last to first.
@@ -165,6 +168,7 @@ static void emit_single_push_insn (enum machine_mode, rtx, tree);
#endif
static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx);
static rtx const_vector_from_tree (tree);
+static void execute_expand (void);
/* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try
@@ -10204,5 +10208,92 @@ const_vector_from_tree (tree exp)
return gen_rtx_raw_CONST_VECTOR (mode, v);
}
+
+/* Called to move the SAVE_EXPRs for parameter declarations in a
+ nested function into the nested function. DATA is really the
+ nested FUNCTION_DECL. */
+
+static tree
+set_save_expr_context (tree *tp,
+ int *walk_subtrees,
+ void *data)
+{
+ if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp))
+ SAVE_EXPR_CONTEXT (*tp) = (tree) data;
+ /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause
+ circularity. */
+ else if (DECL_P (*tp))
+ *walk_subtrees = 0;
+
+ return NULL;
+}
+
+
+static void
+execute_expand (void)
+{
+ /* If the function has a variably modified type, there may be
+ SAVE_EXPRs in the parameter types. Their context must be set to
+ refer to this function; they cannot be expanded in the containing
+ function. */
+ if (decl_function_context (current_function_decl) == current_function_decl
+ && variably_modified_type_p (TREE_TYPE (current_function_decl)))
+ walk_tree (&TREE_TYPE (current_function_decl), set_save_expr_context,
+ current_function_decl, NULL);
+
+ /* Expand the variables recorded during gimple lowering. This must
+ occur before the call to expand_function_start to ensure that
+ all used variables are expanded before we expand anything on the
+ PENDING_SIZES list. */
+ expand_used_vars ();
+
+ /* Set up parameters and prepare for return, for the function. */
+ expand_function_start (current_function_decl, 0);
+
+ /* If this function is `main', emit a call to `__main'
+ to run global initializers, etc. */
+ if (DECL_NAME (current_function_decl)
+ && MAIN_NAME_P (DECL_NAME (current_function_decl))
+ && DECL_FILE_SCOPE_P (current_function_decl))
+ expand_main_function ();
+
+ /* Generate the RTL for this function. */
+ expand_expr_stmt_value (DECL_SAVED_TREE (current_function_decl), 0, 0);
+
+ /* We hard-wired immediate_size_expand to zero above.
+ expand_function_end will decrement this variable. So, we set the
+ variable to one here, so that after the decrement it will remain
+ zero. */
+ immediate_size_expand = 1;
+
+ /* Make sure the locus is set to the end of the function, so that
+ epilogue line numbers and warnings are set properly. */
+ if (cfun->function_end_locus.file)
+ input_location = cfun->function_end_locus;
+
+ /* The following insns belong to the top scope. */
+ record_block_change (DECL_INITIAL (current_function_decl));
+
+ /* Generate rtl for function exit. */
+ expand_function_end ();
+}
+
+struct tree_opt_pass pass_expand =
+{
+ "expand", /* name */
+ NULL, /* gate */
+ execute_expand, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_EXPAND, /* tv_id */
+ /* ??? If TER is enabled, we actually receive GENERIC. */
+ PROP_gimple_leh, /* properties_required */
+ PROP_rtl, /* properties_provided */
+ PROP_cfg | PROP_gimple_leh, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0 /* todo_flags_finish */
+};
+
#include "gt-expr.h"
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 57107dd..cfb3366 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -2316,7 +2316,7 @@ emit_register_classes (void)
input_location = DECL_SOURCE_LOCATION (init_decl);
expand_function_end ();
poplevel (1, 0, 1);
- rest_of_compilation (init_decl);
+ rest_of_compilation ();
current_function_decl = NULL_TREE;
if (targetm.have_ctors_dtors)
diff --git a/gcc/java/resource.c b/gcc/java/resource.c
index 5ebbf5e..0f8440d 100644
--- a/gcc/java/resource.c
+++ b/gcc/java/resource.c
@@ -153,7 +153,7 @@ write_resource_constructor (void)
poplevel (1, 0, 1);
/* rest_of_compilation forces generation even if -finline-functions. */
- rest_of_compilation (init_decl);
+ rest_of_compilation ();
current_function_decl = NULL_TREE;
if (targetm.have_ctors_dtors)
diff --git a/gcc/passes.c b/gcc/passes.c
index fb976a8..344cfb6 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -80,6 +80,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "coverage.h"
#include "value-prof.h"
#include "alloc-pool.h"
+#include "tree-pass.h"
#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
#include "dwarf2out.h"
@@ -430,6 +431,9 @@ rest_of_type_compilation (tree type, int toplev)
static void
rest_of_handle_final (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_FINAL);
{
rtx x;
@@ -483,6 +487,9 @@ rest_of_handle_final (tree decl, rtx insns)
static void
rest_of_handle_delay_slots (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_DBR_SCHED);
open_dump_file (DFI_dbr, decl);
@@ -501,6 +508,9 @@ rest_of_handle_delay_slots (tree decl, rtx insns)
static void
rest_of_handle_stack_regs (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
#if defined (HAVE_ATTR_length)
/* If flow2 creates new instructions which need splitting
and scheduling after reload is not done, they might not be
@@ -543,6 +553,9 @@ rest_of_handle_stack_regs (tree decl, rtx insns)
static void
rest_of_handle_variable_tracking (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_VAR_TRACKING);
open_dump_file (DFI_vartrack, decl);
@@ -556,6 +569,9 @@ rest_of_handle_variable_tracking (tree decl, rtx insns)
static void
rest_of_handle_machine_reorg (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_MACH_DEP);
open_dump_file (DFI_mach, decl);
@@ -575,6 +591,9 @@ rest_of_handle_new_regalloc (tree decl, rtx insns)
{
int failure;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
delete_trivially_dead_insns (insns, max_reg_num ());
reg_alloc ();
@@ -622,6 +641,9 @@ rest_of_handle_old_regalloc (tree decl, rtx insns)
int failure;
int rebuild_notes;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
/* Allocate the reg_renumber array. */
allocate_reg_info (max_regno, FALSE, TRUE);
@@ -695,6 +717,9 @@ rest_of_handle_old_regalloc (tree decl, rtx insns)
static void
rest_of_handle_regrename (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_RENAME_REGISTERS);
open_dump_file (DFI_rnreg, decl);
@@ -714,6 +739,9 @@ rest_of_handle_reorder_blocks (tree decl, rtx insns)
bool changed;
open_dump_file (DFI_bbro, decl);
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
/* Last attempt to optimize CFG, as scheduling, peepholing and insn
splitting possibly introduced more crossjumping opportunities. */
changed = cleanup_cfg (CLEANUP_EXPENSIVE
@@ -744,6 +772,9 @@ rest_of_handle_reorder_blocks (tree decl, rtx insns)
static void
rest_of_handle_sched (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_SMS);
if (optimize > 0 && flag_modulo_sched)
{
@@ -791,6 +822,9 @@ rest_of_handle_sched (tree decl, rtx insns)
static void
rest_of_handle_sched2 (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_SCHED2);
open_dump_file (DFI_sched2, decl);
@@ -820,6 +854,9 @@ rest_of_handle_sched2 (tree decl, rtx insns)
static void
rest_of_handle_gcse2 (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
open_dump_file (DFI_gcse2, decl);
gcse_after_reload_main (insns, dump_file);
@@ -839,6 +876,9 @@ rest_of_handle_gcse2 (tree decl, rtx insns)
static void
rest_of_handle_regmove (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_REGMOVE);
open_dump_file (DFI_regmove, decl);
@@ -855,6 +895,9 @@ rest_of_handle_regmove (tree decl, rtx insns)
static void
rest_of_handle_tracer (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
open_dump_file (DFI_tracer, decl);
if (dump_file)
dump_flow_info (dump_file);
@@ -868,6 +911,9 @@ rest_of_handle_tracer (tree decl, rtx insns)
static void
rest_of_handle_if_conversion (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
open_dump_file (DFI_ce1, decl);
if (flag_if_conversion)
{
@@ -891,6 +937,9 @@ rest_of_handle_if_conversion (tree decl, rtx insns)
static void
rest_of_handle_if_after_combine (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_IFCVT);
open_dump_file (DFI_ce2, decl);
@@ -905,6 +954,9 @@ rest_of_handle_if_after_combine (tree decl, rtx insns)
static void
rest_of_handle_web (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
open_dump_file (DFI_web, decl);
timevar_push (TV_WEB);
web_main ();
@@ -921,6 +973,8 @@ static void
rest_of_handle_branch_prob (tree decl, rtx insns)
{
struct loops loops;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
timevar_push (TV_BRANCH_PROB);
open_dump_file (DFI_bp, decl);
@@ -949,6 +1003,9 @@ rest_of_handle_branch_prob (tree decl, rtx insns)
static void
rest_of_handle_value_profile_transformations (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
open_dump_file (DFI_vpt, decl);
timevar_push (TV_VPT);
@@ -964,6 +1021,9 @@ rest_of_handle_value_profile_transformations (tree decl, rtx insns)
static void
rest_of_handle_cfg (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
open_dump_file (DFI_cfg, decl);
if (dump_file)
dump_flow_info (dump_file);
@@ -993,6 +1053,9 @@ rest_of_handle_cfg (tree decl, rtx insns)
static void
rest_of_handle_addressof (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
open_dump_file (DFI_addressof, decl);
purge_addressof (insns);
@@ -1007,6 +1070,9 @@ rest_of_handle_addressof (tree decl, rtx insns)
static void
rest_of_handle_jump_bypass (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_BYPASS);
open_dump_file (DFI_bypass, decl);
@@ -1036,6 +1102,9 @@ rest_of_handle_combine (tree decl, rtx insns)
{
int rebuild_jump_labels_after_combine = 0;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_COMBINE);
open_dump_file (DFI_combine, decl);
@@ -1064,6 +1133,9 @@ rest_of_handle_combine (tree decl, rtx insns)
static void
rest_of_handle_life (tree decl, rtx insns)
{
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
open_dump_file (DFI_life, decl);
regclass_init ();
@@ -1110,6 +1182,8 @@ static void
rest_of_handle_cse (tree decl, rtx insns)
{
int tem;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
open_dump_file (DFI_cse, decl);
if (dump_file)
@@ -1142,6 +1216,8 @@ static void
rest_of_handle_cse2 (tree decl, rtx insns)
{
int tem;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
timevar_push (TV_CSE2);
open_dump_file (DFI_cse2, decl);
@@ -1178,6 +1254,8 @@ rest_of_handle_gcse (tree decl, rtx insns)
{
int save_csb, save_cfj;
int tem2 = 0, tem;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
timevar_push (TV_GCSE);
open_dump_file (DFI_gcse, decl);
@@ -1241,6 +1319,9 @@ rest_of_handle_loop_optimize (tree decl, rtx insns)
{
int do_unroll, do_prefetch;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
timevar_push (TV_LOOP);
delete_dead_jumptables ();
cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
@@ -1294,6 +1375,9 @@ rest_of_handle_loop2 (tree decl, rtx insns)
struct loops *loops;
basic_block bb;
+ if (decl != current_function_decl || insns != get_insns ())
+ abort ();
+
if (!flag_unswitch_loops
&& !flag_peel_loops
&& !flag_unroll_loops
@@ -1353,11 +1437,15 @@ rest_of_handle_loop2 (tree decl, rtx insns)
After we return, the tree storage is freed. */
void
-rest_of_compilation (tree decl)
+rest_of_compilation (void)
{
+ tree decl = current_function_decl;
rtx insns;
- timevar_push (TV_REST_OF_COMPILATION);
+
+ /* There's no need to defer outputting this function any more; we
+ know we want to output it. */
+ DECL_DEFER_OUTPUT (current_function_decl) = 0;
/* There's no need to defer outputting this function any more; we
know we want to output it. */
@@ -1935,10 +2023,6 @@ rest_of_compilation (tree decl)
/* We're done with this function. Free up memory if we can. */
free_after_parsing (cfun);
-
- ggc_collect ();
-
- timevar_pop (TV_REST_OF_COMPILATION);
}
void
@@ -2019,3 +2103,21 @@ enable_rtl_dump_file (int letter)
return matched;
}
+
+struct tree_opt_pass pass_rest_of_compilation =
+{
+ "rest of compilation", /* name */
+ NULL, /* gate */
+ rest_of_compilation, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_REST_OF_COMPILATION, /* tv_id */
+ PROP_rtl, /* properties_required */
+ 0, /* properties_provided */
+ PROP_rtl, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_ggc_collect /* todo_flags_finish */
+};
+
+
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index 0061847..ad82644 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -210,17 +210,31 @@ register_one_dump_file (struct tree_opt_pass *pass)
pass->static_pass_number = dump_register (dot_name, flag_name);
}
-static void
-register_dump_files (struct tree_opt_pass *pass)
+static int
+register_dump_files (struct tree_opt_pass *pass, int properties)
{
do
{
- register_one_dump_file (pass);
+ /* Verify that all required properties are present. */
+ if (pass->properties_required & ~properties)
+ abort ();
+
+ if (pass->properties_destroyed & pass->properties_provided)
+ abort ();
+
+ pass->properties_required = properties;
+ pass->properties_provided = properties =
+ (properties | pass->properties_provided) & ~pass->properties_destroyed;
+
+ if (properties & PROP_trees)
+ register_one_dump_file (pass);
if (pass->sub)
- register_dump_files (pass->sub);
+ properties = register_dump_files (pass->sub, properties);
pass = pass->next;
}
while (pass);
+
+ return properties;
}
/* Duplicate a pass that's to be run more than once. */
@@ -272,6 +286,8 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_all_optimizations);
NEXT_PASS (pass_mudflap_2);
NEXT_PASS (pass_rebuild_bind);
+ NEXT_PASS (pass_expand);
+ NEXT_PASS (pass_rest_of_compilation);
*p = NULL;
p = &pass_all_optimizations.sub;
@@ -326,12 +342,11 @@ init_tree_optimization_passes (void)
#undef DUP_PASS
/* Register the passes with the tree dump code. */
- register_dump_files (all_passes);
+ register_dump_files (all_passes, 0);
}
static void execute_pass_list (struct tree_opt_pass *);
-static unsigned int current_properties;
static unsigned int last_verified;
static void
@@ -370,9 +385,9 @@ execute_one_pass (struct tree_opt_pass *pass)
if (pass->gate && !pass->gate ())
return false;
- /* Verify that all required properties are present. */
- if (pass->properties_required & ~current_properties)
- abort ();
+ /* Note that the folders should only create gimple expressions.
+ This is a hack until the new folder is ready. */
+ in_gimple_form = (pass->properties_provided & PROP_trees) != 0;
/* Run pre-pass verification. */
todo = pass->todo_flags_start & ~last_verified;
@@ -411,10 +426,6 @@ execute_one_pass (struct tree_opt_pass *pass)
if (todo)
execute_todo (todo);
- /* Update properties. */
- current_properties &= ~pass->properties_destroyed;
- current_properties |= pass->properties_provided;
-
/* Close down timevar and dump file. */
if (pass->tv_id)
timevar_pop (pass->tv_id);
@@ -440,25 +451,6 @@ execute_pass_list (struct tree_opt_pass *pass)
}
-/* Called to move the SAVE_EXPRs for parameter declarations in a
- nested function into the nested function. DATA is really the
- nested FUNCTION_DECL. */
-
-static tree
-set_save_expr_context (tree *tp,
- int *walk_subtrees,
- void *data)
-{
- if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp))
- SAVE_EXPR_CONTEXT (*tp) = (tree) data;
- /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause
- circularity. */
- else if (DECL_P (*tp))
- *walk_subtrees = 0;
-
- return NULL;
-}
-
/* For functions-as-trees languages, this performs all optimization and
compilation for FNDECL. */
@@ -522,68 +514,13 @@ tree_rest_of_compilation (tree fndecl, bool nested_p)
}
}
- /* Note that the folders should only create gimple expressions.
- This is a hack until the new folder is ready. */
- in_gimple_form = true;
-
- /* Perform all tree transforms and optimizations. */
- execute_pass_list (all_passes);
-
- /* Note that the folders can create non-gimple expressions again. */
- in_gimple_form = false;
-
- /* If the function has a variably modified type, there may be
- SAVE_EXPRs in the parameter types. Their context must be set to
- refer to this function; they cannot be expanded in the containing
- function. */
- if (decl_function_context (fndecl) == current_function_decl
- && variably_modified_type_p (TREE_TYPE (fndecl)))
- walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl,
- NULL);
-
- /* Expand the variables recorded during gimple lowering. This must
- occur before the call to expand_function_start to ensure that
- all used variables are expanded before we expand anything on the
- PENDING_SIZES list. */
- expand_used_vars ();
-
- /* Set up parameters and prepare for return, for the function. */
- expand_function_start (fndecl, 0);
-
- /* If this function is `main', emit a call to `__main'
- to run global initializers, etc. */
- if (DECL_NAME (fndecl)
- && MAIN_NAME_P (DECL_NAME (fndecl))
- && DECL_FILE_SCOPE_P (fndecl))
- expand_main_function ();
-
- /* Generate the RTL for this function. */
- expand_expr_stmt_value (DECL_SAVED_TREE (fndecl), 0, 0);
-
- /* We hard-wired immediate_size_expand to zero above.
- expand_function_end will decrement this variable. So, we set the
- variable to one here, so that after the decrement it will remain
- zero. */
- immediate_size_expand = 1;
-
- /* Make sure the locus is set to the end of the function, so that
- epilogue line numbers and warnings are set properly. */
- if (cfun->function_end_locus.file)
- input_location = cfun->function_end_locus;
-
- /* The following insns belong to the top scope. */
- record_block_change (DECL_INITIAL (current_function_decl));
-
- /* Generate rtl for function exit. */
- expand_function_end ();
-
/* If this is a nested function, protect the local variables in the stack
above us from being collected while we're compiling this function. */
if (nested_p)
ggc_push_context ();
- /* Run the optimizers and output the assembler code for this function. */
- rest_of_compilation (fndecl);
+ /* Perform all tree transforms and optimizations. */
+ execute_pass_list (all_passes);
/* Restore original body if still needed. */
if (cfun->saved_tree)
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index cdaf8ef..3a8c31e 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -75,6 +75,10 @@ struct tree_opt_pass
#define PROP_pta (1 << 5)
#define PROP_ssa (1 << 6)
#define PROP_no_crit_edges (1 << 7)
+#define PROP_rtl (1 << 8)
+
+#define PROP_trees \
+ (PROP_gimple_any | PROP_gimple_lcf | PROP_gimple_leh)
/* To-do flags. */
#define TODO_dump_func (1 << 0) /* pass doesn't dump itself */
@@ -125,6 +129,8 @@ extern struct tree_opt_pass pass_dse;
extern struct tree_opt_pass pass_nrv;
extern struct tree_opt_pass pass_remove_useless_vars;
extern struct tree_opt_pass pass_rename_ssa_copies;
+extern struct tree_opt_pass pass_expand;
+extern struct tree_opt_pass pass_rest_of_compilation;
#endif /* GCC_TREE_PASS_H */