"H.J. Lu via Gcc-patches" <[email protected]> writes:
> gen_reg_rtx tracks stack alignment needed for pseudo registers so that
> associated hard registers can be properly spilled onto stack. But there
> are cases where associated hard registers will never be spilled onto
> stack. gen_reg_rtx is changed to take an argument for register alignment
> so that stack realignment can be avoided when not needed.
How is it guaranteed that they will never be spilled though?
I don't think that that guarantee exists for any kind of pseudo,
except perhaps for the temporary pseudos that the RA creates to
replace (match_scratch …)es.
Thanks,
Richard
> * emit-rtl.c (gen_reg_rtx): Add an argument for register
> alignment and use it if it isn't zero.
> * explow.c (force_reg): Add an argument for register alignment
> and pass it to gen_reg_rtx.
> * explow.h (force_reg): Add an argument for register alignment
> and default it to 0.
> * expr.h (convert_to_mode): Likewise.
> (convert_modes): Likewise.
> * expr.c (convert_to_mode): Add an argument for register
> alignment and pass it to convert_modes.
> (convert_modes): Add an argument for register alignment and
> pass it to gen_reg_rtx.
> ---
> gcc/emit-rtl.c | 5 +++--
> gcc/explow.c | 6 +++---
> gcc/explow.h | 2 +-
> gcc/expr.c | 10 ++++++----
> gcc/expr.h | 6 ++++--
> gcc/rtl.h | 2 +-
> 6 files changed, 18 insertions(+), 13 deletions(-)
>
> diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
> index 07e908624a0..4accf851d23 100644
> --- a/gcc/emit-rtl.c
> +++ b/gcc/emit-rtl.c
> @@ -1160,10 +1160,11 @@ subreg_memory_offset (const_rtx x)
> This pseudo is assigned the next sequential register number. */
>
> rtx
> -gen_reg_rtx (machine_mode mode)
> +gen_reg_rtx (machine_mode mode, unsigned int align)
> {
> rtx val;
> - unsigned int align = GET_MODE_ALIGNMENT (mode);
> + if (align == 0)
> + align = GET_MODE_ALIGNMENT (mode);
>
> gcc_assert (can_create_pseudo_p ());
>
> diff --git a/gcc/explow.c b/gcc/explow.c
> index b6da277f689..c8673ce512d 100644
> --- a/gcc/explow.c
> +++ b/gcc/explow.c
> @@ -663,7 +663,7 @@ copy_to_mode_reg (machine_mode mode, rtx x)
> since we mark it as a "constant" register. */
>
> rtx
> -force_reg (machine_mode mode, rtx x)
> +force_reg (machine_mode mode, rtx x, unsigned int reg_align)
> {
> rtx temp, set;
> rtx_insn *insn;
> @@ -673,7 +673,7 @@ force_reg (machine_mode mode, rtx x)
>
> if (general_operand (x, mode))
> {
> - temp = gen_reg_rtx (mode);
> + temp = gen_reg_rtx (mode, reg_align);
> insn = emit_move_insn (temp, x);
> }
> else
> @@ -683,7 +683,7 @@ force_reg (machine_mode mode, rtx x)
> insn = get_last_insn ();
> else
> {
> - rtx temp2 = gen_reg_rtx (mode);
> + rtx temp2 = gen_reg_rtx (mode, reg_align);
> insn = emit_move_insn (temp2, temp);
> temp = temp2;
> }
> diff --git a/gcc/explow.h b/gcc/explow.h
> index 698f2a2a21c..621cdd7d356 100644
> --- a/gcc/explow.h
> +++ b/gcc/explow.h
> @@ -40,7 +40,7 @@ extern rtx copy_to_suggested_reg (rtx, rtx, machine_mode);
>
> /* Copy a value to a register if it isn't already a register.
> Args are mode (in case value is a constant) and the value. */
> -extern rtx force_reg (machine_mode, rtx);
> +extern rtx force_reg (machine_mode, rtx, unsigned int reg_align = 0);
>
> /* Return given rtx, copied into a new temp reg if it was in memory. */
> extern rtx force_not_mem (rtx);
> diff --git a/gcc/expr.c b/gcc/expr.c
> index b4c110f8c17..42db4ddbe0a 100644
> --- a/gcc/expr.c
> +++ b/gcc/expr.c
> @@ -658,9 +658,10 @@ convert_mode_scalar (rtx to, rtx from, int unsignedp)
> or by copying to a new temporary with conversion. */
>
> rtx
> -convert_to_mode (machine_mode mode, rtx x, int unsignedp)
> +convert_to_mode (machine_mode mode, rtx x, int unsignedp,
> + unsigned int reg_align)
> {
> - return convert_modes (mode, VOIDmode, x, unsignedp);
> + return convert_modes (mode, VOIDmode, x, unsignedp, reg_align);
> }
>
> /* Return an rtx for a value that would result
> @@ -674,7 +675,8 @@ convert_to_mode (machine_mode mode, rtx x, int unsignedp)
> You can give VOIDmode for OLDMODE, if you are sure X has a nonvoid mode.
> */
>
> rtx
> -convert_modes (machine_mode mode, machine_mode oldmode, rtx x, int unsignedp)
> +convert_modes (machine_mode mode, machine_mode oldmode, rtx x,
> + int unsignedp, unsigned int reg_align)
> {
> rtx temp;
> scalar_int_mode int_mode;
> @@ -734,7 +736,7 @@ convert_modes (machine_mode mode, machine_mode oldmode,
> rtx x, int unsignedp)
> return simplify_gen_subreg (mode, x, oldmode, 0);
> }
>
> - temp = gen_reg_rtx (mode);
> + temp = gen_reg_rtx (mode, reg_align);
> convert_move (temp, x, unsignedp);
> return temp;
> }
> diff --git a/gcc/expr.h b/gcc/expr.h
> index 9a2736f69fa..2b06da1a889 100644
> --- a/gcc/expr.h
> +++ b/gcc/expr.h
> @@ -66,10 +66,12 @@ extern void init_expr (void);
> extern void convert_move (rtx, rtx, int);
>
> /* Convert an rtx to specified machine mode and return the result. */
> -extern rtx convert_to_mode (machine_mode, rtx, int);
> +extern rtx convert_to_mode (machine_mode, rtx, int,
> + unsigned int reg_align = 0);
>
> /* Convert an rtx to MODE from OLDMODE and return the result. */
> -extern rtx convert_modes (machine_mode, machine_mode, rtx, int);
> +extern rtx convert_modes (machine_mode, machine_mode, rtx, int,
> + unsigned int reg_align = 0);
>
> /* Expand a call to memcpy or memmove or memcmp, and return the result. */
> extern rtx emit_block_op_via_libcall (enum built_in_function, rtx, rtx, rtx,
> diff --git a/gcc/rtl.h b/gcc/rtl.h
> index 398d745aff5..c72f7fd59b9 100644
> --- a/gcc/rtl.h
> +++ b/gcc/rtl.h
> @@ -3125,7 +3125,7 @@ subreg_promoted_mode (rtx x)
> /* In emit-rtl.c */
> extern rtvec gen_rtvec_v (int, rtx *);
> extern rtvec gen_rtvec_v (int, rtx_insn **);
> -extern rtx gen_reg_rtx (machine_mode);
> +extern rtx gen_reg_rtx (machine_mode, unsigned int align = 0);
> extern rtx gen_rtx_REG_offset (rtx, machine_mode, unsigned int, poly_int64);
> extern rtx gen_reg_rtx_offset (rtx, machine_mode, int);
> extern rtx gen_reg_rtx_and_attrs (rtx);