This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, aarch64] Add prefetch support


First of all, the recognized interval between pings is a week; please
don't ping more often than that.

On 04/07/14 11:57, Gopalasubramanian, Ganesh wrote:
> Hi,
> 
> Attached is a patch that implements
> *	Prefetch with immediate offset in the range 0 to 32760 (multiple of 8). Added a predicate for this.
> *	Prefetch with immediate offset - in the range -256 to 255 (Gets generated only when we have a negative offset. Generates prfum instruction). Added a predicate for this.
> *	Prefetch with register offset. (modified for printing the locality)
> 
> This patch has been already discussed on https://gcc.gnu.org/ml/gcc-patches/2014-02/msg01644.html
> 
> "make -k check" passes. Ok for trunk?
> 
> Changelog
> 
> 2014-07-04  Ganesh Gopalasubramanian <Ganesh.Gopalasubramanian@amd.com>
> 
>         * config/aarch64/aarch64.md (define_insn "*prefetch")
>         (define_insn "prefetch"): New

You shouldn't have multiple patterns with the same name; it makes
distinguishing them tricky; however, see below.  Full stop after "New".

>         * config/aarch64/predicates.md (aarch64_prefetch_pimm) 
>         (aarch64_prefetch_unscaled): New.
>         * config/arm/types.md (define_attr "type"): Add prefetch.
> 
> Regards
> Ganesh
> 
> 
> prefetch.diff
> 
> 
> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
> index 3eb783c..1a86e02 100644
> --- a/gcc/config/aarch64/aarch64.md
> +++ b/gcc/config/aarch64/aarch64.md
> @@ -311,6 +311,74 @@
>    [(set_attr "type" "no_insn")]
>  )
>  
> +(define_insn "*prefetch"
> +  [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
> +                      (match_operand:DI 1 "aarch64_prefetch_pimm" "")
> +             )
> +            (match_operand:QI 2 "const_int_operand" "n")
> +           (match_operand:QI 3 "const_int_operand" "n"))]
> +  ""
> +  "*
> +{
> +  int locality = INTVAL (operands[3]);
> +
> +  gcc_assert (IN_RANGE (locality, 0, 3));
> +
> +  if (locality == 0)
> +     /* non temporal locality */
> +     return (INTVAL(operands[2])) ? \"prfm\\tPSTL1STRM, [%0, %1]\" : \"prfm\\tPLDL1STRM, [%0, %1]\";
> +
> +  /* temporal locality */
> +  return (INTVAL(operands[2])) ? \"prfm\\tPSTL%3KEEP, [%0, %1]\" : \"prfm\\tPLDL%3KEEP, [%0, %1]\";
> +}"
> +  [(set_attr "type" "prefetch")]
> +)
> +
> +(define_insn "*prefetch"
> +  [(prefetch (plus:DI (match_operand:DI 0 "register_operand" "r")
> +                      (match_operand:DI 1 "aarch64_prefetch_unscaled" "")
> +             )
> +            (match_operand:QI 2 "const_int_operand" "n")
> +            (match_operand:QI 3 "const_int_operand" "n"))]
> +  ""
> +  "*
> +{
> +  int locality = INTVAL (operands[3]);
> +
> +  gcc_assert (IN_RANGE (locality, 0, 3));
> +
> +  if (locality == 0)
> +     /* non temporal locality */
> +     return (INTVAL(operands[2])) ? \"prfum\\tPSTL1STRM, [%0, %1]\" : \"prfm\\tPLDL1STRM, [%0, %1]\";
> +
> +  /* temporal locality */
> +  return (INTVAL(operands[2])) ? \"prfum\\tPSTL%3KEEP, [%0, %1]\" : \"prfm\\tPLDL%3KEEP, [%0, %1]\";
> +}"
> +  [(set_attr "type" "prefetch")]
> +)
> +
> +(define_insn "prefetch"
> +  [(prefetch (match_operand:DI 0 "address_operand" "r")
> +            (match_operand:QI 1 "const_int_operand" "n")
> +            (match_operand:QI 2 "const_int_operand" "n"))]
> +  ""
> +  "*
> +{
> +  int locality = INTVAL (operands[2]);
> +
> +  gcc_assert (IN_RANGE (locality, 0, 3));
> +
> +  if (locality == 0)
> +     /* non temporal locality */
> +     return (INTVAL(operands[1])) ? \"prfm\\tPSTL1STRM, [%0, #0]\" : \"prfm\\tPLDL1STRM, [%0, #0]\";
> +
> +  /* temporal locality */
> +  return (INTVAL(operands[1])) ? \"prfm\\tPSTL%2KEEP, [%0, #0]\" : \"prfm\\tPLDL%2KEEP, [%0, #0]\";
> +}"
> +  [(set_attr "type" "prefetch")]
> +)

I don't particularly like all this duplication.  Fortunately, the
assembler can help you and there are probably cleaner ways of handling
the various prefetch types.

I think you really need just one RTL pattern (not three), similar to
that in the arm backend.  So the pattern should look like

(define_insn "prefetch"
  [(prefetch (match_operand:DI 0 "address_operand" "p")
             (match_operand 1 "const_int_operand" "")
             (match_operand 2 "const_int_operand" ""))]

(you don't need constraints on the const ints, there's nothing reload
can do to make them work if they are ever anything else).

When it comes to emitting the pattern, always use "prfm" -- the prfum
form can be generated from the prfm mnemonic when the offset implies
this is necessary.

For the prefetch-subtype, then use a two-dimensional array of strings,
something like

   const char * const pftype[2][]
     = { {"PLDL1STRM", "PLDL1..."},
         ...
       };

and then form a pattern that you output with output_asm_insn, before
simply returning "" rather than a pattern in itself.  For the address,
use %a0 -- that should format it correctly.

I think you'll find that should make the logic in the body of the
pattern much clearer.

R.

> +
> +
>  (define_insn "trap"
>    [(trap_if (const_int 1) (const_int 8))]
>    ""
> diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
> index 2702a3c..c37a8a9 100644
> --- a/gcc/config/aarch64/predicates.md
> +++ b/gcc/config/aarch64/predicates.md
> @@ -66,6 +66,14 @@
>    (ior (match_operand 0 "register_operand")
>         (match_operand 0 "aarch64_plus_immediate")))
>  
> +(define_predicate "aarch64_prefetch_pimm"
> +  (and (match_code "const_int")
> +       (match_test "(INTVAL (op) < 0x7ff8 && (0 == INTVAL (op) % 8))")))
> +
> +(define_predicate "aarch64_prefetch_unscaled"
> +  (and (match_code "const_int")
> +       (match_test "(INTVAL (op) < 255 && INTVAL (op) > -256)")))
> +
>  (define_predicate "aarch64_pluslong_immediate"
>    (and (match_code "const_int")
>         (match_test "(INTVAL (op) < 0xffffff && INTVAL (op) > -0xffffff)")))
> diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md
> index efbf7a7..0b92c1a 100644
> --- a/gcc/config/arm/types.md
> +++ b/gcc/config/arm/types.md
> @@ -117,6 +117,7 @@
>  ; mvn_shift_reg      inverting move instruction, shifted operand by a register.
>  ; no_insn            an insn which does not represent an instruction in the
>  ;                    final output, thus having no impact on scheduling.
> +; prefetch           a prefetch instruction
>  ; rbit               reverse bits.
>  ; rev                reverse bytes.
>  ; sdiv               signed division.
> @@ -554,6 +555,7 @@
>    call,\
>    clz,\
>    no_insn,\
> +  prefetch,\
>    csel,\
>    crc,\
>    extend,\
> 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]