On Fri, Apr 30, 2021 at 2:06 AM Richard Sandiford <richard.sandif...@arm.com> wrote: > > "H.J. Lu via Gcc-patches" <gcc-patches@gcc.gnu.org> 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. >
The caller of creating pseudo registers with specific alignment must guarantee that they will never be spilled. I am only using it in /* Make operand1 a register if it isn't already. */ if (can_create_pseudo_p () && !register_operand (op0, mode) && !register_operand (op1, mode)) { /* NB: Don't increase stack alignment requirement when forcing operand1 into a pseudo register to copy data from one memory location to another since it doesn't require a spill. */ emit_move_insn (op0, force_reg (GET_MODE (op0), op1, (UNITS_PER_WORD * BITS_PER_UNIT))); return; } for vector moves. RA shouldn't spill it. > 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); -- H.J.