#include "reload.h"
#include "output.h"
#include "toplev.h"
+#include "tree-pass.h"
+#include "timevar.h"
/* This pass of the compiler performs global register allocation.
It assigns hard register numbers to all the pseudo registers
/* Number of calls crossed by each allocno. */
int calls_crossed;
+ /* Number of calls that might throw crossed by each allocno. */
+ int throwing_calls_crossed;
+
/* Number of refs to each allocno. */
int n_refs;
allocno[num].reg = i;
allocno[num].size = PSEUDO_REGNO_SIZE (i);
allocno[num].calls_crossed += REG_N_CALLS_CROSSED (i);
+ allocno[num].throwing_calls_crossed
+ += REG_N_THROWING_CALLS_CROSSED (i);
allocno[num].n_refs += REG_N_REFS (i);
allocno[num].freq += REG_FREQ (i);
if (allocno[num].live_length < REG_LIVE_LENGTH (i))
{
/* Did not find a register. If it would be profitable to
allocate a call-clobbered register and save and restore it
- around calls, do that. */
+ around calls, do that. Don't do this if it crosses any calls
+ that might throw. */
if (! accept_call_clobbered
&& allocno[num].calls_crossed != 0
+ && allocno[num].throwing_calls_crossed == 0
&& CALLER_SAVE_PROFITABLE (allocno[num].n_refs,
allocno[num].calls_crossed))
{
}
free_bb_info ();
}
+/* Run old register allocator. Return TRUE if we must exit
+ rest_of_compilation upon return. */
+static void
+rest_of_handle_global_alloc (void)
+{
+ bool failure;
+
+ /* If optimizing, allocate remaining pseudo-regs. Do the reload
+ pass fixing up any insns that are invalid. */
+
+ if (optimize)
+ failure = global_alloc (dump_file);
+ else
+ {
+ build_insn_chain (get_insns ());
+ failure = reload (get_insns (), 0);
+ }
+
+ if (dump_enabled_p (pass_global_alloc.static_pass_number))
+ {
+ timevar_push (TV_DUMP);
+ dump_global_regs (dump_file);
+ timevar_pop (TV_DUMP);
+ }
+
+ gcc_assert (reload_completed || failure);
+ reload_completed = !failure;
+}
+
+struct tree_opt_pass pass_global_alloc =
+{
+ "greg", /* name */
+ NULL, /* gate */
+ rest_of_handle_global_alloc, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_GLOBAL_ALLOC, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func |
+ TODO_ggc_collect, /* todo_flags_finish */
+ 'g' /* letter */
+};
+