Re: [098/nnn] poly_int: load_register_parameters

2017-11-27 Thread Jeff Law
On 10/23/2017 11:40 AM, Richard Sandiford wrote:
> This patch makes load_register_parameters cope with polynomial sizes.
> The requirement here is that any register parameters with non-constant
> sizes must either have a specific mode (e.g. a variable-length vector
> mode) or must be represented with a PARALLEL.  This is in practice
> already a requirement for parameters passed in vector registers,
> since the default behaviour of splitting parameters into words doesn't
> make sense for them.
> 
> 
> 2017-10-23  Richard Sandiford  
>   Alan Hayward  
>   David Sherwood  
> 
> gcc/
>   * calls.c (load_register_parameters): Cope with polynomial
>   mode sizes.  Require a constant size for BLKmode parameters
>   that aren't described by a PARALLEL.  If BLOCK_REG_PADDING
>   forces a parameter to be padded at the lsb end in order to
>   fill a complete number of words, require the parameter size
>   to be ordered wrt UNITS_PER_WORD.
OK.
jeff


[098/nnn] poly_int: load_register_parameters

2017-10-23 Thread Richard Sandiford
This patch makes load_register_parameters cope with polynomial sizes.
The requirement here is that any register parameters with non-constant
sizes must either have a specific mode (e.g. a variable-length vector
mode) or must be represented with a PARALLEL.  This is in practice
already a requirement for parameters passed in vector registers,
since the default behaviour of splitting parameters into words doesn't
make sense for them.


2017-10-23  Richard Sandiford  
Alan Hayward  
David Sherwood  

gcc/
* calls.c (load_register_parameters): Cope with polynomial
mode sizes.  Require a constant size for BLKmode parameters
that aren't described by a PARALLEL.  If BLOCK_REG_PADDING
forces a parameter to be padded at the lsb end in order to
fill a complete number of words, require the parameter size
to be ordered wrt UNITS_PER_WORD.

Index: gcc/calls.c
===
--- gcc/calls.c 2017-10-23 17:25:38.230865460 +0100
+++ gcc/calls.c 2017-10-23 17:25:45.501604113 +0100
@@ -2520,7 +2520,8 @@ load_register_parameters (struct arg_dat
{
  int partial = args[i].partial;
  int nregs;
- int size = 0;
+ poly_int64 size = 0;
+ HOST_WIDE_INT const_size = 0;
  rtx_insn *before_arg = get_last_insn ();
  /* Set non-negative if we must move a word at a time, even if
 just one word (e.g, partial == 4 && mode == DFmode).  Set
@@ -2536,8 +2537,12 @@ load_register_parameters (struct arg_dat
}
  else if (TYPE_MODE (TREE_TYPE (args[i].tree_value)) == BLKmode)
{
- size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
- nregs = (size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ /* Variable-sized parameters should be described by a
+PARALLEL instead.  */
+ const_size = int_size_in_bytes (TREE_TYPE (args[i].tree_value));
+ gcc_assert (const_size >= 0);
+ nregs = (const_size + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD;
+ size = const_size;
}
  else
size = GET_MODE_SIZE (args[i].mode);
@@ -2559,21 +2564,27 @@ load_register_parameters (struct arg_dat
  /* Handle case where we have a value that needs shifting
 up to the msb.  eg. a QImode value and we're padding
 upward on a BYTES_BIG_ENDIAN machine.  */
- if (size < UNITS_PER_WORD
- && (args[i].locate.where_pad
- == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD)))
+ if (args[i].locate.where_pad
+ == (BYTES_BIG_ENDIAN ? PAD_UPWARD : PAD_DOWNWARD))
{
- rtx x;
- int shift = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
-
- /* Assigning REG here rather than a temp makes CALL_FUSAGE
-report the whole reg as used.  Strictly speaking, the
-call only uses SIZE bytes at the msb end, but it doesn't
-seem worth generating rtl to say that.  */
- reg = gen_rtx_REG (word_mode, REGNO (reg));
- x = expand_shift (LSHIFT_EXPR, word_mode, reg, shift, reg, 1);
- if (x != reg)
-   emit_move_insn (reg, x);
+ gcc_checking_assert (ordered_p (size, UNITS_PER_WORD));
+ if (may_lt (size, UNITS_PER_WORD))
+   {
+ rtx x;
+ poly_int64 shift
+   = (UNITS_PER_WORD - size) * BITS_PER_UNIT;
+
+ /* Assigning REG here rather than a temp makes
+CALL_FUSAGE report the whole reg as used.
+Strictly speaking, the call only uses SIZE
+bytes at the msb end, but it doesn't seem worth
+generating rtl to say that.  */
+ reg = gen_rtx_REG (word_mode, REGNO (reg));
+ x = expand_shift (LSHIFT_EXPR, word_mode,
+   reg, shift, reg, 1);
+ if (x != reg)
+   emit_move_insn (reg, x);
+   }
}
 #endif
}
@@ -2588,17 +2599,20 @@ load_register_parameters (struct arg_dat
 
  else if (partial == 0 || args[i].pass_on_stack)
{
+ /* SIZE and CONST_SIZE are 0 for partial arguments and
+the size of a BLKmode type otherwise.  */
+ gcc_checking_assert (must_eq (size, const_size));
  rtx mem = validize_mem (copy_rtx (args[i].value));
 
  /* Check for overlap with already clobbered argument area,
 providing that this has non-zero size.  */