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.
* 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); -- 2.31.1