+
+#ifdef STACK_REGS
+static void
+find_stack_regs (void)
+{
+ bitmap stack_regs = BITMAP_ALLOC (NULL);
+ int i;
+ HARD_REG_SET stack_hard_regs, used;
+ basic_block bb;
+
+ /* Any register that MAY be allocated to a register stack (like the
+ 387) is treated poorly. Each such register is marked as being
+ live everywhere. This keeps the register allocator and the
+ subsequent passes from doing anything useful with these values.
+
+ FIXME: This seems like an incredibly poor idea. */
+
+ CLEAR_HARD_REG_SET (stack_hard_regs);
+ for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
+ SET_HARD_REG_BIT (stack_hard_regs, i);
+
+ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
+ {
+ COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
+ IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
+ AND_HARD_REG_SET (used, stack_hard_regs);
+ if (!hard_reg_set_empty_p (used))
+ bitmap_set_bit (stack_regs, i);
+ }
+
+ if (dump_file)
+ bitmap_print (dump_file, stack_regs, "stack regs:", "\n");
+
+ FOR_EACH_BB (bb)
+ {
+ bitmap_ior_into (DF_LIVE_IN (bb), stack_regs);
+ bitmap_and_into (DF_LIVE_IN (bb), DF_LR_IN (bb));
+ bitmap_ior_into (DF_LIVE_OUT (bb), stack_regs);
+ bitmap_and_into (DF_LIVE_OUT (bb), DF_LR_OUT (bb));
+ }
+ BITMAP_FREE (stack_regs);
+}
+#endif
+
+/* Run old register allocator. Return TRUE if we must exit
+ rest_of_compilation upon return. */
+static unsigned int
+rest_of_handle_local_alloc (void)
+{
+ int rebuild_notes;
+ int max_regno = max_reg_num ();
+
+ df_note_add_problem ();
+
+ if (optimize == 1)
+ {
+ df_live_add_problem ();
+ df_live_set_all_dirty ();
+ }
+#ifdef ENABLE_CHECKING
+ df->changeable_flags |= DF_VERIFY_SCHEDULED;
+#endif
+ df_analyze ();
+#ifdef STACK_REGS
+ if (optimize)
+ find_stack_regs ();
+#endif
+ regstat_init_n_sets_and_refs ();
+ regstat_compute_ri ();
+
+ /* If we are not optimizing, then this is the only place before
+ register allocation where dataflow is done. And that is needed
+ to generate these warnings. */
+ if (warn_clobbered)
+ generate_setjmp_warnings ();
+
+ /* Determine if the current function is a leaf before running reload
+ since this can impact optimizations done by the prologue and
+ epilogue thus changing register elimination offsets. */
+ current_function_is_leaf = leaf_function_p ();
+
+ /* And the reg_equiv_memory_loc array. */
+ VEC_safe_grow (rtx, gc, reg_equiv_memory_loc_vec, max_regno);
+ memset (VEC_address (rtx, reg_equiv_memory_loc_vec), 0,
+ sizeof (rtx) * max_regno);
+ reg_equiv_memory_loc = VEC_address (rtx, reg_equiv_memory_loc_vec);
+
+ allocate_initial_values (reg_equiv_memory_loc);
+
+ regclass (get_insns (), max_regno);
+ rebuild_notes = local_alloc ();
+
+ /* Local allocation may have turned an indirect jump into a direct
+ jump. If so, we must rebuild the JUMP_LABEL fields of jumping
+ instructions. */
+ if (rebuild_notes)
+ {
+ timevar_push (TV_JUMP);
+
+ rebuild_jump_labels (get_insns ());
+ purge_all_dead_edges ();
+ timevar_pop (TV_JUMP);
+ }
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ timevar_push (TV_DUMP);
+ dump_flow_info (dump_file, dump_flags);
+ dump_local_alloc (dump_file);
+ timevar_pop (TV_DUMP);
+ }
+ return 0;
+}
+
+struct rtl_opt_pass pass_local_alloc =
+{
+ {
+ RTL_PASS,
+ "lreg", /* name */
+ NULL, /* gate */
+ rest_of_handle_local_alloc, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_LOCAL_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 */
+ }
+};
+