From 9bf2f779045072c0db1e57f67fbc864caf212585 Mon Sep 17 00:00:00 2001 From: Kyrylo Tkachov Date: Thu, 4 May 2017 16:14:37 +0000 Subject: [PATCH] [AArch64] Accept more addressing modes for PRFM * config/aarch64/aarch64.md (prefetch); Adjust predicate and constraint on operand 0 to allow more general addressing modes. Adjust output template. * config/aarch64/aarch64.c (aarch64_address_valid_for_prefetch_p): New function. * config/aarch64/aarch64-protos.h (aarch64_address_valid_for_prefetch_p): Declare prototype. * config/aarch64/constraints.md (Dp): New address constraint. * config/aarch64/predicates.md (aarch64_prefetch_operand): New predicate. * gcc.target/aarch64/prfm_imm_offset_1.c: New test. From-SVN: r247603 --- gcc/ChangeLog | 13 ++++++++++ gcc/config/aarch64/aarch64-protos.h | 1 + gcc/config/aarch64/aarch64.c | 18 ++++++++++++++ gcc/config/aarch64/aarch64.md | 24 +++++++++++-------- gcc/config/aarch64/constraints.md | 5 ++++ gcc/config/aarch64/predicates.md | 3 +++ gcc/testsuite/ChangeLog | 4 ++++ .../gcc.target/aarch64/prfm_imm_offset_1.c | 18 ++++++++++++++ 8 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c9e34c017b9..34a56ab17c6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2016-05-04 Kyrylo Tkachov + + * config/aarch64/aarch64.md (prefetch); Adjust predicate and + constraint on operand 0 to allow more general addressing modes. + Adjust output template. + * config/aarch64/aarch64.c (aarch64_address_valid_for_prefetch_p): + New function. + * config/aarch64/aarch64-protos.h + (aarch64_address_valid_for_prefetch_p): Declare prototype. + * config/aarch64/constraints.md (Dp): New address constraint. + * config/aarch64/predicates.md (aarch64_prefetch_operand): New + predicate. + 2017-05-04 Jan Hubicka * ipa-cp.c (perform_estimation_of_a_value): Drop base_time parameter; diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h index 9543f8c9f29..2895a2a97b5 100644 --- a/gcc/config/aarch64/aarch64-protos.h +++ b/gcc/config/aarch64/aarch64-protos.h @@ -301,6 +301,7 @@ extern struct tune_params aarch64_tune_params; HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned); int aarch64_get_condition_code (rtx); +bool aarch64_address_valid_for_prefetch_p (rtx, bool); bool aarch64_bitmask_imm (HOST_WIDE_INT val, machine_mode); unsigned HOST_WIDE_INT aarch64_and_split_imm1 (HOST_WIDE_INT val_in); unsigned HOST_WIDE_INT aarch64_and_split_imm2 (HOST_WIDE_INT val_in); diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c index b760905ce3b..43fc928b460 100644 --- a/gcc/config/aarch64/aarch64.c +++ b/gcc/config/aarch64/aarch64.c @@ -4549,6 +4549,24 @@ aarch64_classify_address (struct aarch64_address_info *info, } } +/* Return true if the address X is valid for a PRFM instruction. + STRICT_P is true if we should do strict checking with + aarch64_classify_address. */ + +bool +aarch64_address_valid_for_prefetch_p (rtx x, bool strict_p) +{ + struct aarch64_address_info addr; + + /* PRFM accepts the same addresses as DImode... */ + bool res = aarch64_classify_address (&addr, x, DImode, MEM, strict_p); + if (!res) + return false; + + /* ... except writeback forms. */ + return addr.type != ADDRESS_REG_WB; +} + bool aarch64_symbolic_address_p (rtx x) { diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md index 51368e29f2d..d39b8507c75 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -519,27 +519,31 @@ ) (define_insn "prefetch" - [(prefetch (match_operand:DI 0 "register_operand" "r") + [(prefetch (match_operand:DI 0 "aarch64_prefetch_operand" "Dp") (match_operand:QI 1 "const_int_operand" "") (match_operand:QI 2 "const_int_operand" ""))] "" { - const char * pftype[2][4] = + const char * pftype[2][4] = { - {"prfm\\tPLDL1STRM, %a0", - "prfm\\tPLDL3KEEP, %a0", - "prfm\\tPLDL2KEEP, %a0", - "prfm\\tPLDL1KEEP, %a0"}, - {"prfm\\tPSTL1STRM, %a0", - "prfm\\tPSTL3KEEP, %a0", - "prfm\\tPSTL2KEEP, %a0", - "prfm\\tPSTL1KEEP, %a0"}, + {"prfm\\tPLDL1STRM, %0", + "prfm\\tPLDL3KEEP, %0", + "prfm\\tPLDL2KEEP, %0", + "prfm\\tPLDL1KEEP, %0"}, + {"prfm\\tPSTL1STRM, %0", + "prfm\\tPSTL3KEEP, %0", + "prfm\\tPSTL2KEEP, %0", + "prfm\\tPSTL1KEEP, %0"}, }; int locality = INTVAL (operands[2]); gcc_assert (IN_RANGE (locality, 0, 3)); + /* PRFM accepts the same addresses as a 64-bit LDR so wrap + the address into a DImode MEM so that aarch64_print_operand knows + how to print it. */ + operands[0] = gen_rtx_MEM (DImode, operands[0]); return pftype[INTVAL(operands[1])][locality]; } [(set_attr "type" "load1")] diff --git a/gcc/config/aarch64/constraints.md b/gcc/config/aarch64/constraints.md index 5a252c07afa..b8293376fde 100644 --- a/gcc/config/aarch64/constraints.md +++ b/gcc/config/aarch64/constraints.md @@ -214,3 +214,8 @@ A constraint that matches an immediate operand valid for AdvSIMD scalar." (and (match_code "const_int") (match_test "aarch64_simd_imm_scalar_p (op, GET_MODE (op))"))) + +(define_address_constraint "Dp" + "@internal + An address valid for a prefetch instruction." + (match_test "aarch64_address_valid_for_prefetch_p (op, true)")) diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md index e83d45b3945..8e3ea9b4696 100644 --- a/gcc/config/aarch64/predicates.md +++ b/gcc/config/aarch64/predicates.md @@ -165,6 +165,9 @@ (match_test "aarch64_legitimate_address_p (mode, XEXP (op, 0), PARALLEL, 0)"))) +(define_predicate "aarch64_prefetch_operand" + (match_test "aarch64_address_valid_for_prefetch_p (op, false)")) + (define_predicate "aarch64_valid_symref" (match_code "const, symbol_ref, label_ref") { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 00f1cf245b9..b8d1e2f3cb3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2016-05-04 Kyrylo Tkachov + + * gcc.target/aarch64/prfm_imm_offset_1.c: New test. + 2017-05-04 Jan Hubicka * gcc.dg/ipa/ipcp-2.c: Decrease ipcp threshold diff --git a/gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c b/gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c new file mode 100644 index 00000000000..26ab9139cbc --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/prfm_imm_offset_1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +/* Check that we can generate the immediate-offset addressing + mode for PRFM. */ + +#define ARRSIZE 65 +int *bad_addr[ARRSIZE]; + +void +prefetch_for_read (void) +{ + int i; + for (i = 0; i < ARRSIZE; i++) + __builtin_prefetch (bad_addr[i] + 2, 0, 0); +} + +/* { dg-final { scan-assembler-times "prfm.*\\\[x\[0-9\]+, 8\\\]" 1 } } */ -- 2.30.2