diff mbox

[AArch64] Add addr_type attribute

Message ID CO2PR07MB26941223A801155CA8A7D964832C0@CO2PR07MB2694.namprd07.prod.outlook.com
State New
Headers show

Commit Message

Hurugalawadi, Naveen March 6, 2017, 5:08 a.m. UTC
Hi,

Please find attached the patch that adds "addr_type" attribute 
for AArch64.

The patch doesn't change spec but improve other benchmarks.

Bootstrapped and Regression tested on aarch64-thunder-linux.
Please review the patch and let us know if its okay for Stage-1?

Thanks,
Naveen

2017-03-06  Julian Brown  <julian@codesourcery.com>
	    Naveen H.S  <Naveen.Hurugalawadi@cavium.com>

	* config/aarch64/aarch64-protos.h (AARCH64_ADDR_REG_IMM)
	(AARCH64_ADDR_REG_WB, AARCH64_ADDR_REG_REG, AARCH64_ADDR_REG_SHIFT)
	(AARCH64_ADDR_REG_EXT, AARCH64_ADDR_REG_SHIFT_EXT, AARCH64_ADDR_LO_SUM)
	(AARCH64_ADDR_SYMBOLIC): New.
	(aarch64_mem_type_p): Add prototype.
	* config/aarch64/aarch64.c (aarch64_mem_type_p): New function.
	* config/aarch64/aarch64.md (addr_type): New attribute.
	(prefetch, *mov<mode>_aarch64, *movsi_aarch64, *movdi_aarch64)
	(*movti_aarch64, *movtf_aarch64, *movsf_aarch64, *movdf_aarch64)
	(load_pairsi, load_pairdi, store_pairsi, store_pairdi, load_pairsf)
	(load_pairdf, store_pairsf)
	(store_pairdf, loadwb_pair<GPI:mode>_<P:mode>)
	(storewb_pair<GPI:mode>_<P:mode>, extendsidi2_aarch64)
	(*load_pair_extendsidi2_aarch64, *zero_extendsidi2_aarch64)
	(*load_pair_zero_extendsidi2_aarch64)
	(*extend<SHORT:mode><GPI:mode>2_aarch64)
	(*zero_extend<SHORT:mode><GPI:mode>2_aarch64)
	(ldr_got_small_<mode>, ldr_got_small_sidi, ldr_got_tiny)
	(tlsie_small_<mode>, tlsie_small_sidi): Add addr_type attribute.

Comments

Hurugalawadi, Naveen April 25, 2017, 6:37 a.m. UTC | #1
Hi,  

Please consider this as a personal reminder to review the patch
at following link and let me know your comments on the same.  

https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00222.html

Thanks,
Naveen
Hurugalawadi, Naveen May 11, 2017, 4:46 a.m. UTC | #2
Hi,  

Please consider this as a personal reminder to review the patch
at following link and let me know your comments on the same.  

https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00222.html

Thanks,
Naveen
Hurugalawadi, Naveen May 11, 2017, 4:47 a.m. UTC | #3
Hi,  

Please consider this as a personal reminder to review the patch
at following link and let me know your comments on the same.  

https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00222.html

Thanks,
Naveen
Hurugalawadi, Naveen May 11, 2017, 4:48 a.m. UTC | #4
Hi,  

Please consider this as a personal reminder to review the patch
at following link and let me know your comments on the same.  

https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00222.html

Thanks,
Naveen
Hurugalawadi, Naveen May 11, 2017, 4:49 a.m. UTC | #5
Hi,  

Please consider this as a personal reminder to review the patch
at following link and let me know your comments on the same.  

https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00222.html

Thanks,
Naveen
Hurugalawadi, Naveen May 26, 2017, 6:19 a.m. UTC | #6
Hi,  

Please consider this as a personal reminder to review the patch
at following link and let me know your comments on the same.  

https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00222.html

Thanks,
Naveen
James Greenhalgh June 14, 2017, 2:39 p.m. UTC | #7
On Mon, Mar 06, 2017 at 05:08:57AM +0000, Hurugalawadi, Naveen wrote:
> Hi,
> 
> Please find attached the patch that adds "addr_type" attribute 
> for AArch64.
> 
> The patch doesn't change spec but improve other benchmarks.

What am I missing - you add a new function which is never called? This patch
does nothing!

Should this have been in series with a scheduling model change?

As it is, this is not OK - it just adds dead code.

When this was first proposed as an approach, Andrew replied:

> Since this is only about post and pre increment being split into two
> micro-ops.  I suspect something like what rs600 back-end does is
> better:
> ;; Does this instruction use update addressing?
> ;; This is used for load and store insns.  See the comments for "indexed".
> (define_attr "update" "no,yes"
>   (if_then_else (ior (match_operand 0 "update_address_mem")
>                      (match_operand 1 "update_address_mem"))
>                 (const_string "yes")
>                 (const_string "no")))
> 
> Where update_address_mem is defined as:
> ;; Return 1 if the operand is a MEM with an update-form address. This may
> ;; also include update-indexed form.
> (define_special_predicate "update_address_mem"
>   (match_test "(MEM_P (op)
>                 && (GET_CODE (XEXP (op, 0)) == PRE_INC
>                     || GET_CODE (XEXP (op, 0)) == PRE_DEC
>                     || GET_CODE (XEXP (op, 0)) == PRE_MODIFY))"))
> 
> 
> Note you need to include the POST ones for AARCH64 but it should be
> similar enough.
> And then you just check the attr update.

Which still sounds like the better approach!

Thanks,
James

> 
> Bootstrapped and Regression tested on aarch64-thunder-linux.
> Please review the patch and let us know if its okay for Stage-1?
> 
> Thanks,
> Naveen
> 
> 2017-03-06  Julian Brown  <julian@codesourcery.com>
> 	    Naveen H.S  <Naveen.Hurugalawadi@cavium.com>
> 
> 	* config/aarch64/aarch64-protos.h (AARCH64_ADDR_REG_IMM)
> 	(AARCH64_ADDR_REG_WB, AARCH64_ADDR_REG_REG, AARCH64_ADDR_REG_SHIFT)
> 	(AARCH64_ADDR_REG_EXT, AARCH64_ADDR_REG_SHIFT_EXT, AARCH64_ADDR_LO_SUM)
> 	(AARCH64_ADDR_SYMBOLIC): New.
> 	(aarch64_mem_type_p): Add prototype.
> 	* config/aarch64/aarch64.c (aarch64_mem_type_p): New function.
> 	* config/aarch64/aarch64.md (addr_type): New attribute.
> 	(prefetch, *mov<mode>_aarch64, *movsi_aarch64, *movdi_aarch64)
> 	(*movti_aarch64, *movtf_aarch64, *movsf_aarch64, *movdf_aarch64)
> 	(load_pairsi, load_pairdi, store_pairsi, store_pairdi, load_pairsf)
> 	(load_pairdf, store_pairsf)
> 	(store_pairdf, loadwb_pair<GPI:mode>_<P:mode>)
> 	(storewb_pair<GPI:mode>_<P:mode>, extendsidi2_aarch64)
> 	(*load_pair_extendsidi2_aarch64, *zero_extendsidi2_aarch64)
> 	(*load_pair_zero_extendsidi2_aarch64)
> 	(*extend<SHORT:mode><GPI:mode>2_aarch64)
> 	(*zero_extend<SHORT:mode><GPI:mode>2_aarch64)
> 	(ldr_got_small_<mode>, ldr_got_small_sidi, ldr_got_tiny)
> 	(tlsie_small_<mode>, tlsie_small_sidi): Add addr_type attribute.

> diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
> index 9543f8c..e045df8 100644
> --- a/gcc/config/aarch64/aarch64-protos.h
> +++ b/gcc/config/aarch64/aarch64-protos.h
> @@ -299,6 +299,19 @@ enum aarch64_parse_opt_result
>  
>  extern struct tune_params aarch64_tune_params;
>  
> +/* Mask bits to use for for aarch64_mem_type_p.  Unshifted/shifted index
> +   register variants are separated for scheduling purposes because the
> +   distinction matters on some cores.  */
> +
> +#define AARCH64_ADDR_REG_IMM		0x01
> +#define AARCH64_ADDR_REG_WB		0x02
> +#define AARCH64_ADDR_REG_REG		0x04
> +#define AARCH64_ADDR_REG_SHIFT		0x08
> +#define AARCH64_ADDR_REG_EXT		0x10
> +#define AARCH64_ADDR_REG_SHIFT_EXT	0x20
> +#define AARCH64_ADDR_LO_SUM		0x40
> +#define AARCH64_ADDR_SYMBOLIC		0x80
> +
>  HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
>  int aarch64_get_condition_code (rtx);
>  bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode);
> @@ -347,6 +360,7 @@ bool aarch64_simd_shift_imm_p (rtx, machine_mode, bool);
>  bool aarch64_simd_valid_immediate (rtx, machine_mode, bool,
>  				   struct simd_immediate_info *);
>  bool aarch64_split_dimode_const_store (rtx, rtx);
> +bool aarch64_mem_type_p (rtx_insn *, unsigned HOST_WIDE_INT);
>  bool aarch64_symbolic_address_p (rtx);
>  bool aarch64_uimm12_shift (HOST_WIDE_INT);
>  bool aarch64_use_return_insn_p (void);
> diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
> index 714bb79..fa25d43 100644
> --- a/gcc/config/aarch64/aarch64.c
> +++ b/gcc/config/aarch64/aarch64.c
> @@ -4551,6 +4551,88 @@ aarch64_classify_address (struct aarch64_address_info *info,
>      }
>  }
>  
> +/* Return TRUE if INSN uses an address that satisfies any of the (non-strict)
> +   addressing modes specified by MASK.  This is intended for use in scheduling
> +   models that are sensitive to the form of address used by some particular
> +   instruction.  */
> +
> +bool
> +aarch64_mem_type_p (rtx_insn *insn, unsigned HOST_WIDE_INT mask)
> +{
> +  aarch64_address_info info;
> +  bool valid;
> +  attr_addr_type addr_type;
> +  rtx mem, addr;
> +  machine_mode mode;
> +
> +  addr_type = get_attr_addr_type (insn);
> +
> +  switch (addr_type)
> +    {
> +    case ADDR_TYPE_WB:
> +      info.type = ADDRESS_REG_WB;
> +      break;
> +
> +    case ADDR_TYPE_LO_SUM:
> +      info.type = ADDRESS_LO_SUM;
> +      break;
> +
> +    case ADDR_TYPE_OP0:
> +    case ADDR_TYPE_OP1:
> +      extract_insn_cached (insn);
> +
> +      mem = recog_data.operand[(addr_type == ADDR_TYPE_OP0) ? 0 : 1];
> +
> +      gcc_assert (MEM_P (mem));
> +      
> +      addr = XEXP (mem, 0);
> +      mode = GET_MODE (mem);
> +
> +    classify:
> +      valid = aarch64_classify_address (&info, addr, mode, MEM, false);
> +      if (!valid)
> +	return false;
> +
> +      break;
> +
> +    case ADDR_TYPE_OP0ADDR:
> +    case ADDR_TYPE_OP1ADDR:
> +      extract_insn_cached (insn);
> +
> +      addr = recog_data.operand[(addr_type == ADDR_TYPE_OP0ADDR) ? 0 : 1];
> +      mode = DImode;
> +      goto classify;
> +
> +    case ADDR_TYPE_NONE:
> +      return false;
> +    }
> +
> +  switch (info.type)
> +    {
> +    case ADDRESS_REG_IMM:
> +      return (mask & AARCH64_ADDR_REG_IMM) != 0;
> +    case ADDRESS_REG_WB:
> +      return (mask & AARCH64_ADDR_REG_WB) != 0;
> +    case ADDRESS_REG_REG:
> +      if (info.shift == 0)
> +	return (mask & AARCH64_ADDR_REG_REG) != 0;
> +      else
> +        return (mask & AARCH64_ADDR_REG_SHIFT) != 0;
> +    case ADDRESS_REG_UXTW:
> +    case ADDRESS_REG_SXTW:
> +      if (info.shift == 0)
> +	return (mask & AARCH64_ADDR_REG_EXT) != 0;
> +      else
> +	return (mask & AARCH64_ADDR_REG_SHIFT_EXT) != 0;
> +    case ADDRESS_LO_SUM:
> +      return (mask & AARCH64_ADDR_LO_SUM) != 0;
> +    case ADDRESS_SYMBOLIC:
> +      return (mask & AARCH64_ADDR_SYMBOLIC) != 0;
> +    default:
> +      return false;
> +    }
> +}
> +
>  bool
>  aarch64_symbolic_address_p (rtx x)
>  {
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index 5adc5ed..f3dc65c 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -201,6 +201,9 @@
>  	     (const_string "no")
>  	] (const_string "yes")))
>  
> +(define_attr "addr_type" "none,op0,op1,op0addr,op1addr,lo_sum,wb"
> +  (const_string "none"))
> +
>  ;; Attribute that specifies whether we are dealing with a branch to a
>  ;; label that is far away, i.e. further away than the maximum/minimum
>  ;; representable in a signed 21-bits number.
> @@ -542,7 +545,8 @@
>  
>      return pftype[INTVAL(operands[1])][locality];
>    }
> -  [(set_attr "type" "load1")]
> +  [(set_attr "type" "load1")
> +   (set_attr "addr_type" "op0addr")]
>  )
>  
>  (define_insn "trap"
> @@ -998,7 +1002,8 @@
>  }
>    [(set_attr "type" "mov_reg,mov_imm,neon_move,load1,load1,store1,store1,\
>                       neon_to_gp<q>,neon_from_gp<q>,neon_dup")
> -   (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
> +   (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
> +   (set_attr "addr_type" "*,*,*,op1,op1,op0,op0,*,*,*")]
>  )
>  
>  (define_expand "mov<mode>"
> @@ -1054,7 +1059,8 @@
>      }"
>    [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
>                       adr,adr,f_mcr,f_mrc,fmov")
> -   (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
> +   (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")
> +   (set_attr "addr_type" "*,*,*,*,*,op1,op1,op0,op0,*,*,*,*,*")]
>  )
>  
>  (define_insn_and_split "*movdi_aarch64"
> @@ -1088,7 +1094,8 @@
>    [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
>                       adr,adr,f_mcr,f_mrc,fmov,neon_move")
>     (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
> -   (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
> +   (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")
> +   (set_attr "addr_type" "*,*,*,*,*,op1,op1,op0,op0,*,*,*,*,*,*")]
>  )
>  
>  (define_insn "insv_imm<mode>"
> @@ -1133,7 +1140,8 @@
>  		             load2,store2,store2,f_loadd,f_stored")
>     (set_attr "length" "8,8,8,4,4,4,4,4,4")
>     (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
> -   (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
> +   (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
> +   (set_attr "addr_type" "*,*,*,*,op1,op0,op0,op1,op0")]
>  )
>  
>  ;; Split a TImode register-register or register-immediate move into
> @@ -1205,7 +1213,8 @@
>     mov\\t%w0, %w1"
>    [(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconsts,\
>                       f_loads,f_stores,load1,store1,mov_reg")
> -   (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")]
> +   (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")
> +   (set_attr "addr_type" "*,*,*,*,*,op1,op0,op1,op0,*")]
>  )
>  
>  (define_insn "*movdf_aarch64"
> @@ -1226,7 +1235,8 @@
>     mov\\t%x0, %x1"
>    [(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconstd,\
>                       f_loadd,f_stored,load1,store1,mov_reg")
> -   (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")]
> +   (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")
> +   (set_attr "addr_type" "*,*,*,*,*,op1,op0,op1,op0,*")]
>  )
>  
>  (define_insn "*movtf_aarch64"
> @@ -1251,7 +1261,8 @@
>    [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,neon_move_q,f_mcr,\
>                       f_loadd,f_stored,load2,store2,store2")
>     (set_attr "length" "4,8,8,8,4,4,4,4,4,4,4")
> -   (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")]
> +   (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")
> +   (set_attr "addr_type" "*,*,*,*,*,*,op1,op0,op1,op0,op0")]
>  )
>  
>  (define_split
> @@ -1298,7 +1309,8 @@
>     ldp\\t%w0, %w2, %1
>     ldp\\t%s0, %s2, %1"
>    [(set_attr "type" "load2,neon_load1_2reg")
> -   (set_attr "fp" "*,yes")]
> +   (set_attr "fp" "*,yes")
> +   (set_attr "addr_type" "op1")]
>  )
>  
>  (define_insn "load_pairdi"
> @@ -1314,7 +1326,8 @@
>     ldp\\t%x0, %x2, %1
>     ldp\\t%d0, %d2, %1"
>    [(set_attr "type" "load2,neon_load1_2reg")
> -   (set_attr "fp" "*,yes")]
> +   (set_attr "fp" "*,yes")
> +   (set_attr "addr_type" "op1")]
>  )
>  
>  
> @@ -1333,7 +1346,8 @@
>     stp\\t%w1, %w3, %0
>     stp\\t%s1, %s3, %0"
>    [(set_attr "type" "store2,neon_store1_2reg")
> -   (set_attr "fp" "*,yes")]
> +   (set_attr "fp" "*,yes")
> +   (set_attr "addr_type" "op0")]
>  )
>  
>  (define_insn "store_pairdi"
> @@ -1349,7 +1363,8 @@
>     stp\\t%x1, %x3, %0
>     stp\\t%d1, %d3, %0"
>    [(set_attr "type" "store2,neon_store1_2reg")
> -   (set_attr "fp" "*,yes")]
> +   (set_attr "fp" "*,yes")
> +   (set_attr "addr_type" "op0")]
>  )
>  
>  ;; Operands 1 and 3 are tied together by the final condition; so we allow
> @@ -1367,7 +1382,8 @@
>     ldp\\t%s0, %s2, %1
>     ldp\\t%w0, %w2, %1"
>    [(set_attr "type" "neon_load1_2reg,load2")
> -   (set_attr "fp" "yes,*")]
> +   (set_attr "fp" "yes,*")
> +   (set_attr "addr_type" "op1")]
>  )
>  
>  (define_insn "load_pairdf"
> @@ -1383,7 +1399,8 @@
>     ldp\\t%d0, %d2, %1
>     ldp\\t%x0, %x2, %1"
>    [(set_attr "type" "neon_load1_2reg,load2")
> -   (set_attr "fp" "yes,*")]
> +   (set_attr "fp" "yes,*")
> +   (set_attr "addr_type" "op1")]
>  )
>  
>  ;; Operands 0 and 2 are tied together by the final condition; so we allow
> @@ -1401,7 +1418,8 @@
>     stp\\t%s1, %s3, %0
>     stp\\t%w1, %w3, %0"
>    [(set_attr "type" "neon_store1_2reg,store2")
> -   (set_attr "fp" "yes,*")]
> +   (set_attr "fp" "yes,*")
> +   (set_attr "addr_type" "op0")]
>  )
>  
>  (define_insn "store_pairdf"
> @@ -1417,7 +1435,8 @@
>     stp\\t%d1, %d3, %0
>     stp\\t%x1, %x3, %0"
>    [(set_attr "type" "neon_store1_2reg,store2")
> -   (set_attr "fp" "yes,*")]
> +   (set_attr "fp" "yes,*")
> +   (set_attr "addr_type" "op0")]
>  )
>  
>  ;; Load pair with post-index writeback.  This is primarily used in function
> @@ -1434,7 +1453,8 @@
>                     (match_operand:P 5 "const_int_operand" "n"))))])]
>    "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
>    "ldp\\t%<w>2, %<w>3, [%1], %4"
> -  [(set_attr "type" "load2")]
> +  [(set_attr "type" "load2")
> +   (set_attr "addr_type" "wb")]
>  )
>  
>  (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
> @@ -1467,7 +1487,8 @@
>            (match_operand:GPI 3 "register_operand" "r"))])]
>    "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
>    "stp\\t%<w>2, %<w>3, [%0, %4]!"
> -  [(set_attr "type" "store2")]
> +  [(set_attr "type" "store2")
> +   (set_attr "addr_type" "wb")]
>  )
>  
>  (define_insn "storewb_pair<GPF:mode>_<P:mode>"
> @@ -1503,7 +1524,8 @@
>    "@
>     sxtw\t%0, %w1
>     ldrsw\t%0, %1"
> -  [(set_attr "type" "extend,load1")]
> +  [(set_attr "type" "extend,load1")
> +   (set_attr "addr_type" "*,op1")]
>  )
>  
>  (define_insn "*load_pair_extendsidi2_aarch64"
> @@ -1516,7 +1538,8 @@
>  			       XEXP (operands[1], 0),
>  			       GET_MODE_SIZE (SImode)))"
>    "ldpsw\\t%0, %2, %1"
> -  [(set_attr "type" "load2")]
> +  [(set_attr "type" "load2")
> +   (set_attr "addr_type" "op1")]
>  )
>  
>  (define_insn "*zero_extendsidi2_aarch64"
> @@ -1526,7 +1549,8 @@
>    "@
>     uxtw\t%0, %w1
>     ldr\t%w0, %1"
> -  [(set_attr "type" "extend,load1")]
> +  [(set_attr "type" "extend,load1")
> +   (set_attr "addr_type" "*,op1")]
>  )
>  
>  (define_insn "*load_pair_zero_extendsidi2_aarch64"
> @@ -1539,7 +1563,8 @@
>  			       XEXP (operands[1], 0),
>  			       GET_MODE_SIZE (SImode)))"
>    "ldp\\t%w0, %w2, %1"
> -  [(set_attr "type" "load2")]
> +  [(set_attr "type" "load2")
> +   (set_attr "addr_type" "op1")]
>  )
>  
>  (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
> @@ -1555,7 +1580,8 @@
>    "@
>     sxt<SHORT:size>\t%<GPI:w>0, %w1
>     ldrs<SHORT:size>\t%<GPI:w>0, %1"
> -  [(set_attr "type" "extend,load1")]
> +  [(set_attr "type" "extend,load1")
> +   (set_attr "addr_type" "*,op1")]
>  )
>  
>  (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
> @@ -1566,7 +1592,8 @@
>     and\t%<GPI:w>0, %<GPI:w>1, <SHORT:short_mask>
>     ldr<SHORT:size>\t%w0, %1
>     ldr\t%<SHORT:size>0, %1"
> -  [(set_attr "type" "logic_imm,load1,load1")]
> +  [(set_attr "type" "logic_imm,load1,load1")
> +   (set_attr "addr_type" "*,op1,op1")]
>  )
>  
>  (define_expand "<optab>qihi2"
> @@ -5180,7 +5207,8 @@
>  		    UNSPEC_GOTSMALLPIC))]
>    ""
>    "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
> -  [(set_attr "type" "load1")]
> +  [(set_attr "type" "load1")
> +   (set_attr "addr_type" "lo_sum")]
>  )
>  
>  (define_insn "ldr_got_small_sidi"
> @@ -5192,7 +5220,8 @@
>  		    UNSPEC_GOTSMALLPIC)))]
>    "TARGET_ILP32"
>    "ldr\\t%w0, [%1, #:got_lo12:%a2]"
> -  [(set_attr "type" "load1")]
> +  [(set_attr "type" "load1")
> +   (set_attr "addr_type" "lo_sum")]
>  )
>  
>  (define_insn "ldr_got_small_28k_<mode>"
> @@ -5224,7 +5253,8 @@
>  		   UNSPEC_GOTTINYPIC))]
>    ""
>    "ldr\\t%0, %L1"
> -  [(set_attr "type" "load1")]
> +  [(set_attr "type" "load1")
> +   (set_attr "addr_type" "op1addr")]
>  )
>  
>  (define_insn "aarch64_load_tp_hard"
> @@ -5266,7 +5296,8 @@
>    ""
>    "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
>    [(set_attr "type" "load1")
> -   (set_attr "length" "8")]
> +   (set_attr "length" "8")
> +   (set_attr "addr_type" "op1addr")]
>  )
>  
>  (define_insn "tlsie_small_sidi"
> @@ -5277,7 +5308,8 @@
>    ""
>    "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
>    [(set_attr "type" "load1")
> -   (set_attr "length" "8")]
> +   (set_attr "length" "8")
> +   (set_attr "addr_type" "op1addr")]
>  )
>  
>  (define_insn "tlsie_tiny_<mode>"
diff mbox

Patch

diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 9543f8c..e045df8 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -299,6 +299,19 @@  enum aarch64_parse_opt_result
 
 extern struct tune_params aarch64_tune_params;
 
+/* Mask bits to use for for aarch64_mem_type_p.  Unshifted/shifted index
+   register variants are separated for scheduling purposes because the
+   distinction matters on some cores.  */
+
+#define AARCH64_ADDR_REG_IMM		0x01
+#define AARCH64_ADDR_REG_WB		0x02
+#define AARCH64_ADDR_REG_REG		0x04
+#define AARCH64_ADDR_REG_SHIFT		0x08
+#define AARCH64_ADDR_REG_EXT		0x10
+#define AARCH64_ADDR_REG_SHIFT_EXT	0x20
+#define AARCH64_ADDR_LO_SUM		0x40
+#define AARCH64_ADDR_SYMBOLIC		0x80
+
 HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
 int aarch64_get_condition_code (rtx);
 bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode);
@@ -347,6 +360,7 @@  bool aarch64_simd_shift_imm_p (rtx, machine_mode, bool);
 bool aarch64_simd_valid_immediate (rtx, machine_mode, bool,
 				   struct simd_immediate_info *);
 bool aarch64_split_dimode_const_store (rtx, rtx);
+bool aarch64_mem_type_p (rtx_insn *, unsigned HOST_WIDE_INT);
 bool aarch64_symbolic_address_p (rtx);
 bool aarch64_uimm12_shift (HOST_WIDE_INT);
 bool aarch64_use_return_insn_p (void);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 714bb79..fa25d43 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -4551,6 +4551,88 @@  aarch64_classify_address (struct aarch64_address_info *info,
     }
 }
 
+/* Return TRUE if INSN uses an address that satisfies any of the (non-strict)
+   addressing modes specified by MASK.  This is intended for use in scheduling
+   models that are sensitive to the form of address used by some particular
+   instruction.  */
+
+bool
+aarch64_mem_type_p (rtx_insn *insn, unsigned HOST_WIDE_INT mask)
+{
+  aarch64_address_info info;
+  bool valid;
+  attr_addr_type addr_type;
+  rtx mem, addr;
+  machine_mode mode;
+
+  addr_type = get_attr_addr_type (insn);
+
+  switch (addr_type)
+    {
+    case ADDR_TYPE_WB:
+      info.type = ADDRESS_REG_WB;
+      break;
+
+    case ADDR_TYPE_LO_SUM:
+      info.type = ADDRESS_LO_SUM;
+      break;
+
+    case ADDR_TYPE_OP0:
+    case ADDR_TYPE_OP1:
+      extract_insn_cached (insn);
+
+      mem = recog_data.operand[(addr_type == ADDR_TYPE_OP0) ? 0 : 1];
+
+      gcc_assert (MEM_P (mem));
+      
+      addr = XEXP (mem, 0);
+      mode = GET_MODE (mem);
+
+    classify:
+      valid = aarch64_classify_address (&info, addr, mode, MEM, false);
+      if (!valid)
+	return false;
+
+      break;
+
+    case ADDR_TYPE_OP0ADDR:
+    case ADDR_TYPE_OP1ADDR:
+      extract_insn_cached (insn);
+
+      addr = recog_data.operand[(addr_type == ADDR_TYPE_OP0ADDR) ? 0 : 1];
+      mode = DImode;
+      goto classify;
+
+    case ADDR_TYPE_NONE:
+      return false;
+    }
+
+  switch (info.type)
+    {
+    case ADDRESS_REG_IMM:
+      return (mask & AARCH64_ADDR_REG_IMM) != 0;
+    case ADDRESS_REG_WB:
+      return (mask & AARCH64_ADDR_REG_WB) != 0;
+    case ADDRESS_REG_REG:
+      if (info.shift == 0)
+	return (mask & AARCH64_ADDR_REG_REG) != 0;
+      else
+        return (mask & AARCH64_ADDR_REG_SHIFT) != 0;
+    case ADDRESS_REG_UXTW:
+    case ADDRESS_REG_SXTW:
+      if (info.shift == 0)
+	return (mask & AARCH64_ADDR_REG_EXT) != 0;
+      else
+	return (mask & AARCH64_ADDR_REG_SHIFT_EXT) != 0;
+    case ADDRESS_LO_SUM:
+      return (mask & AARCH64_ADDR_LO_SUM) != 0;
+    case ADDRESS_SYMBOLIC:
+      return (mask & AARCH64_ADDR_SYMBOLIC) != 0;
+    default:
+      return false;
+    }
+}
+
 bool
 aarch64_symbolic_address_p (rtx x)
 {
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 5adc5ed..f3dc65c 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -201,6 +201,9 @@ 
 	     (const_string "no")
 	] (const_string "yes")))
 
+(define_attr "addr_type" "none,op0,op1,op0addr,op1addr,lo_sum,wb"
+  (const_string "none"))
+
 ;; Attribute that specifies whether we are dealing with a branch to a
 ;; label that is far away, i.e. further away than the maximum/minimum
 ;; representable in a signed 21-bits number.
@@ -542,7 +545,8 @@ 
 
     return pftype[INTVAL(operands[1])][locality];
   }
-  [(set_attr "type" "load1")]
+  [(set_attr "type" "load1")
+   (set_attr "addr_type" "op0addr")]
 )
 
 (define_insn "trap"
@@ -998,7 +1002,8 @@ 
 }
   [(set_attr "type" "mov_reg,mov_imm,neon_move,load1,load1,store1,store1,\
                      neon_to_gp<q>,neon_from_gp<q>,neon_dup")
-   (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")]
+   (set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
+   (set_attr "addr_type" "*,*,*,op1,op1,op0,op0,*,*,*")]
 )
 
 (define_expand "mov<mode>"
@@ -1054,7 +1059,8 @@ 
     }"
   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
                      adr,adr,f_mcr,f_mrc,fmov")
-   (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
+   (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")
+   (set_attr "addr_type" "*,*,*,*,*,op1,op1,op0,op0,*,*,*,*,*")]
 )
 
 (define_insn_and_split "*movdi_aarch64"
@@ -1088,7 +1094,8 @@ 
   [(set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,\
                      adr,adr,f_mcr,f_mrc,fmov,neon_move")
    (set_attr "fp" "*,*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
-   (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
+   (set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,yes")
+   (set_attr "addr_type" "*,*,*,*,*,op1,op1,op0,op0,*,*,*,*,*,*")]
 )
 
 (define_insn "insv_imm<mode>"
@@ -1133,7 +1140,8 @@ 
 		             load2,store2,store2,f_loadd,f_stored")
    (set_attr "length" "8,8,8,4,4,4,4,4,4")
    (set_attr "simd" "*,*,*,yes,*,*,*,*,*")
-   (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")]
+   (set_attr "fp" "*,*,*,*,*,*,*,yes,yes")
+   (set_attr "addr_type" "*,*,*,*,op1,op0,op0,op1,op0")]
 )
 
 ;; Split a TImode register-register or register-immediate move into
@@ -1205,7 +1213,8 @@ 
    mov\\t%w0, %w1"
   [(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconsts,\
                      f_loads,f_stores,load1,store1,mov_reg")
-   (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")]
+   (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")
+   (set_attr "addr_type" "*,*,*,*,*,op1,op0,op1,op0,*")]
 )
 
 (define_insn "*movdf_aarch64"
@@ -1226,7 +1235,8 @@ 
    mov\\t%x0, %x1"
   [(set_attr "type" "neon_move,f_mcr,f_mrc,fmov,fconstd,\
                      f_loadd,f_stored,load1,store1,mov_reg")
-   (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")]
+   (set_attr "simd" "yes,*,*,*,*,*,*,*,*,*")
+   (set_attr "addr_type" "*,*,*,*,*,op1,op0,op1,op0,*")]
 )
 
 (define_insn "*movtf_aarch64"
@@ -1251,7 +1261,8 @@ 
   [(set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,neon_move_q,f_mcr,\
                      f_loadd,f_stored,load2,store2,store2")
    (set_attr "length" "4,8,8,8,4,4,4,4,4,4,4")
-   (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")]
+   (set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*,*")
+   (set_attr "addr_type" "*,*,*,*,*,*,op1,op0,op1,op0,op0")]
 )
 
 (define_split
@@ -1298,7 +1309,8 @@ 
    ldp\\t%w0, %w2, %1
    ldp\\t%s0, %s2, %1"
   [(set_attr "type" "load2,neon_load1_2reg")
-   (set_attr "fp" "*,yes")]
+   (set_attr "fp" "*,yes")
+   (set_attr "addr_type" "op1")]
 )
 
 (define_insn "load_pairdi"
@@ -1314,7 +1326,8 @@ 
    ldp\\t%x0, %x2, %1
    ldp\\t%d0, %d2, %1"
   [(set_attr "type" "load2,neon_load1_2reg")
-   (set_attr "fp" "*,yes")]
+   (set_attr "fp" "*,yes")
+   (set_attr "addr_type" "op1")]
 )
 
 
@@ -1333,7 +1346,8 @@ 
    stp\\t%w1, %w3, %0
    stp\\t%s1, %s3, %0"
   [(set_attr "type" "store2,neon_store1_2reg")
-   (set_attr "fp" "*,yes")]
+   (set_attr "fp" "*,yes")
+   (set_attr "addr_type" "op0")]
 )
 
 (define_insn "store_pairdi"
@@ -1349,7 +1363,8 @@ 
    stp\\t%x1, %x3, %0
    stp\\t%d1, %d3, %0"
   [(set_attr "type" "store2,neon_store1_2reg")
-   (set_attr "fp" "*,yes")]
+   (set_attr "fp" "*,yes")
+   (set_attr "addr_type" "op0")]
 )
 
 ;; Operands 1 and 3 are tied together by the final condition; so we allow
@@ -1367,7 +1382,8 @@ 
    ldp\\t%s0, %s2, %1
    ldp\\t%w0, %w2, %1"
   [(set_attr "type" "neon_load1_2reg,load2")
-   (set_attr "fp" "yes,*")]
+   (set_attr "fp" "yes,*")
+   (set_attr "addr_type" "op1")]
 )
 
 (define_insn "load_pairdf"
@@ -1383,7 +1399,8 @@ 
    ldp\\t%d0, %d2, %1
    ldp\\t%x0, %x2, %1"
   [(set_attr "type" "neon_load1_2reg,load2")
-   (set_attr "fp" "yes,*")]
+   (set_attr "fp" "yes,*")
+   (set_attr "addr_type" "op1")]
 )
 
 ;; Operands 0 and 2 are tied together by the final condition; so we allow
@@ -1401,7 +1418,8 @@ 
    stp\\t%s1, %s3, %0
    stp\\t%w1, %w3, %0"
   [(set_attr "type" "neon_store1_2reg,store2")
-   (set_attr "fp" "yes,*")]
+   (set_attr "fp" "yes,*")
+   (set_attr "addr_type" "op0")]
 )
 
 (define_insn "store_pairdf"
@@ -1417,7 +1435,8 @@ 
    stp\\t%d1, %d3, %0
    stp\\t%x1, %x3, %0"
   [(set_attr "type" "neon_store1_2reg,store2")
-   (set_attr "fp" "yes,*")]
+   (set_attr "fp" "yes,*")
+   (set_attr "addr_type" "op0")]
 )
 
 ;; Load pair with post-index writeback.  This is primarily used in function
@@ -1434,7 +1453,8 @@ 
                    (match_operand:P 5 "const_int_operand" "n"))))])]
   "INTVAL (operands[5]) == GET_MODE_SIZE (<GPI:MODE>mode)"
   "ldp\\t%<w>2, %<w>3, [%1], %4"
-  [(set_attr "type" "load2")]
+  [(set_attr "type" "load2")
+   (set_attr "addr_type" "wb")]
 )
 
 (define_insn "loadwb_pair<GPF:mode>_<P:mode>"
@@ -1467,7 +1487,8 @@ 
           (match_operand:GPI 3 "register_operand" "r"))])]
   "INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
   "stp\\t%<w>2, %<w>3, [%0, %4]!"
-  [(set_attr "type" "store2")]
+  [(set_attr "type" "store2")
+   (set_attr "addr_type" "wb")]
 )
 
 (define_insn "storewb_pair<GPF:mode>_<P:mode>"
@@ -1503,7 +1524,8 @@ 
   "@
    sxtw\t%0, %w1
    ldrsw\t%0, %1"
-  [(set_attr "type" "extend,load1")]
+  [(set_attr "type" "extend,load1")
+   (set_attr "addr_type" "*,op1")]
 )
 
 (define_insn "*load_pair_extendsidi2_aarch64"
@@ -1516,7 +1538,8 @@ 
 			       XEXP (operands[1], 0),
 			       GET_MODE_SIZE (SImode)))"
   "ldpsw\\t%0, %2, %1"
-  [(set_attr "type" "load2")]
+  [(set_attr "type" "load2")
+   (set_attr "addr_type" "op1")]
 )
 
 (define_insn "*zero_extendsidi2_aarch64"
@@ -1526,7 +1549,8 @@ 
   "@
    uxtw\t%0, %w1
    ldr\t%w0, %1"
-  [(set_attr "type" "extend,load1")]
+  [(set_attr "type" "extend,load1")
+   (set_attr "addr_type" "*,op1")]
 )
 
 (define_insn "*load_pair_zero_extendsidi2_aarch64"
@@ -1539,7 +1563,8 @@ 
 			       XEXP (operands[1], 0),
 			       GET_MODE_SIZE (SImode)))"
   "ldp\\t%w0, %w2, %1"
-  [(set_attr "type" "load2")]
+  [(set_attr "type" "load2")
+   (set_attr "addr_type" "op1")]
 )
 
 (define_expand "<ANY_EXTEND:optab><SHORT:mode><GPI:mode>2"
@@ -1555,7 +1580,8 @@ 
   "@
    sxt<SHORT:size>\t%<GPI:w>0, %w1
    ldrs<SHORT:size>\t%<GPI:w>0, %1"
-  [(set_attr "type" "extend,load1")]
+  [(set_attr "type" "extend,load1")
+   (set_attr "addr_type" "*,op1")]
 )
 
 (define_insn "*zero_extend<SHORT:mode><GPI:mode>2_aarch64"
@@ -1566,7 +1592,8 @@ 
    and\t%<GPI:w>0, %<GPI:w>1, <SHORT:short_mask>
    ldr<SHORT:size>\t%w0, %1
    ldr\t%<SHORT:size>0, %1"
-  [(set_attr "type" "logic_imm,load1,load1")]
+  [(set_attr "type" "logic_imm,load1,load1")
+   (set_attr "addr_type" "*,op1,op1")]
 )
 
 (define_expand "<optab>qihi2"
@@ -5180,7 +5207,8 @@ 
 		    UNSPEC_GOTSMALLPIC))]
   ""
   "ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
-  [(set_attr "type" "load1")]
+  [(set_attr "type" "load1")
+   (set_attr "addr_type" "lo_sum")]
 )
 
 (define_insn "ldr_got_small_sidi"
@@ -5192,7 +5220,8 @@ 
 		    UNSPEC_GOTSMALLPIC)))]
   "TARGET_ILP32"
   "ldr\\t%w0, [%1, #:got_lo12:%a2]"
-  [(set_attr "type" "load1")]
+  [(set_attr "type" "load1")
+   (set_attr "addr_type" "lo_sum")]
 )
 
 (define_insn "ldr_got_small_28k_<mode>"
@@ -5224,7 +5253,8 @@ 
 		   UNSPEC_GOTTINYPIC))]
   ""
   "ldr\\t%0, %L1"
-  [(set_attr "type" "load1")]
+  [(set_attr "type" "load1")
+   (set_attr "addr_type" "op1addr")]
 )
 
 (define_insn "aarch64_load_tp_hard"
@@ -5266,7 +5296,8 @@ 
   ""
   "adrp\\t%0, %A1\;ldr\\t%<w>0, [%0, #%L1]"
   [(set_attr "type" "load1")
-   (set_attr "length" "8")]
+   (set_attr "length" "8")
+   (set_attr "addr_type" "op1addr")]
 )
 
 (define_insn "tlsie_small_sidi"
@@ -5277,7 +5308,8 @@ 
   ""
   "adrp\\t%0, %A1\;ldr\\t%w0, [%0, #%L1]"
   [(set_attr "type" "load1")
-   (set_attr "length" "8")]
+   (set_attr "length" "8")
+   (set_attr "addr_type" "op1addr")]
 )
 
 (define_insn "tlsie_tiny_<mode>"