This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [dataflow][PATCH] Fix a regression on ia64 - subregs_of_mode cleanup
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: Seongbae Park <seongbae dot park at gmail dot com>
- Cc: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 13 Mar 2007 20:40:22 -0400
- Subject: Re: [dataflow][PATCH] Fix a regression on ia64 - subregs_of_mode cleanup
- References: <ab3a61990703131704k4131f3ecod05d9ea64b538c23@mail.gmail.com>
Seongbae Park wrote:
> Hi,
>
ok to commit.
> This patch fixes a regression on ia64 which was due to
> subregs_of_mode not being up-to-date when used.
> Since I couldn't find any use of subregs_of_mode
> other than local and global allocs,
> I've moved subregs_of_mode_init just before local-alloc
> created a new subregs_of_mode_finish after global-alloc,
> and added extra assertions to make sure
> it is only used when valid,
> to prevent other passes from accidentally using it.
> Bootstrapped and regtested on ia64.
>
> 2007-03-13 Seongbae Park <seongbae.park@gmail.com>
>
> * tree-pass.h (pass_subregs_of_mode_finish): New pass declaration.
> * regclass.c (record_subregs_of_mode): Made static, and
> moved before init_subregs_of_mode to compile.
> (cannot_change_mode_set_regs, invalid_mode_change_p):
> Added assertion.
> (finish_subregs_of_mode): New function.
> (pass_subregs_of_mode_finish): New pass.
> * rtl.h (record_subregs_of_mode): Removed.
> * combine.c (gen_lowpart_for_combine): Removed
> calls to record_subregs_of_mode.
> * passes.c (init_optimization_passes): Moved
> pass_subregs_of_mode_init
> just before local_alloc. New pass pass_subregs_of_mode_finish
> after global_alloc.
>
> ------------------------------------------------------------------------
>
> Index: tree-pass.h
> ===================================================================
> --- tree-pass.h (revision 122890)
> +++ tree-pass.h (working copy)
> @@ -370,6 +370,7 @@ extern struct tree_opt_pass pass_cse2;
> extern struct tree_opt_pass pass_df_initialize;
> extern struct tree_opt_pass pass_regclass_init;
> extern struct tree_opt_pass pass_subregs_of_mode_init;
> +extern struct tree_opt_pass pass_subregs_of_mode_finish;
> extern struct tree_opt_pass pass_inc_dec;
> extern struct tree_opt_pass pass_no_new_pseudos;
> extern struct tree_opt_pass pass_stack_ptr_mod;
> Index: regclass.c
> ===================================================================
> --- regclass.c (revision 122890)
> +++ regclass.c (working copy)
> @@ -2677,6 +2677,38 @@ som_eq (const void *x, const void *y)
> }
>
>
> +static void
> +record_subregs_of_mode (rtx subreg)
> +{
> + struct subregs_of_mode_node dummy, *node;
> + enum machine_mode mode;
> + unsigned int regno;
> + void **slot;
> +
> + if (!REG_P (SUBREG_REG (subreg)))
> + return;
> +
> + regno = REGNO (SUBREG_REG (subreg));
> + mode = GET_MODE (subreg);
> +
> + if (regno < FIRST_PSEUDO_REGISTER)
> + return;
> +
> + dummy.block = regno & -8;
> + slot = htab_find_slot_with_hash (subregs_of_mode, &dummy,
> + dummy.block, INSERT);
> + node = *slot;
> + if (node == NULL)
> + {
> + node = XCNEW (struct subregs_of_mode_node);
> + node->block = regno & -8;
> + *slot = node;
> + }
> +
> + node->modes[mode] |= 1 << (regno & 7);
> +}
> +
> +
> /* Call record_subregs_of_mode for all the subregs in X. */
>
> static void
> @@ -2722,36 +2754,6 @@ init_subregs_of_mode (void)
> return 0;
> }
>
> -void
> -record_subregs_of_mode (rtx subreg)
> -{
> - struct subregs_of_mode_node dummy, *node;
> - enum machine_mode mode;
> - unsigned int regno;
> - void **slot;
> -
> - if (!REG_P (SUBREG_REG (subreg)))
> - return;
> -
> - regno = REGNO (SUBREG_REG (subreg));
> - mode = GET_MODE (subreg);
> -
> - if (regno < FIRST_PSEUDO_REGISTER)
> - return;
> -
> - dummy.block = regno & -8;
> - slot = htab_find_slot_with_hash (subregs_of_mode, &dummy,
> - dummy.block, INSERT);
> - node = *slot;
> - if (node == NULL)
> - {
> - node = XCNEW (struct subregs_of_mode_node);
> - node->block = regno & -8;
> - *slot = node;
> - }
> -
> - node->modes[mode] |= 1 << (regno & 7);
> -}
>
> /* Set bits in *USED which correspond to registers which can't change
> their mode from FROM to any mode in which REGNO was encountered. */
> @@ -2765,6 +2767,7 @@ cannot_change_mode_set_regs (HARD_REG_SE
> unsigned char mask;
> unsigned int i;
>
> + gcc_assert (subregs_of_mode);
> dummy.block = regno & -8;
> node = htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
> if (node == NULL)
> @@ -2790,6 +2793,7 @@ invalid_mode_change_p (unsigned int regn
> enum machine_mode to;
> unsigned char mask;
>
> + gcc_assert (subregs_of_mode);
> dummy.block = regno & -8;
> node = htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
> if (node == NULL)
> @@ -2803,12 +2807,25 @@ invalid_mode_change_p (unsigned int regn
>
> return false;
> }
> +
> +static unsigned int
> +finish_subregs_of_mode (void)
> +{
> + htab_delete (subregs_of_mode);
> + subregs_of_mode = 0;
> + return 0;
> +}
> #else
> static unsigned int
> init_subregs_of_mode (void)
> {
> return 0;
> }
> +static unsigned int
> +finish_subregs_of_mode (void)
> +{
> + return 0;
> +}
>
> #endif /* CANNOT_CHANGE_MODE_CLASS */
>
> @@ -2839,6 +2856,23 @@ struct tree_opt_pass pass_subregs_of_mod
> 0 /* letter */
> };
>
> +struct tree_opt_pass pass_subregs_of_mode_finish =
> +{
> + "subregs_of_mode_finish", /* name */
> + gate_subregs_of_mode_init, /* gate */
> + finish_subregs_of_mode, /* execute */
> + NULL, /* sub */
> + NULL, /* next */
> + 0, /* static_pass_number */
> + 0, /* tv_id */
> + 0, /* properties_required */
> + 0, /* properties_provided */
> + 0, /* properties_destroyed */
> + 0, /* todo_flags_start */
> + 0, /* todo_flags_finish */
> + 0 /* letter */
> +};
> +
>
>
> #include "gt-regclass.h"
> Index: rtl.h
> ===================================================================
> --- rtl.h (revision 122890)
> +++ rtl.h (working copy)
> @@ -2156,7 +2156,6 @@ extern void regclass (rtx, int);
> extern void reg_scan (rtx, unsigned int);
> extern void reg_scan_update (rtx, rtx, unsigned int);
> extern void fix_register (const char *, int, int);
> -extern void record_subregs_of_mode (rtx);
> #ifdef HARD_CONST
> extern void cannot_change_mode_set_regs (HARD_REG_SET *,
> enum machine_mode, unsigned int);
> Index: combine.c
> ===================================================================
>