From a9ccbb60d4bfa7b7637a9157e10e58f4c60102a5 Mon Sep 17 00:00:00 2001 From: Janis Johnson Date: Tue, 4 Dec 2001 00:50:35 +0000 Subject: [PATCH] builtin-types.def (BT_FN_VOID_PTR_INT_INT): New. * builtin-types.def (BT_FN_VOID_PTR_INT_INT): New. * builtins.def (BUILT_IN_PREFETCH): New. * builtins.c (expand_builtin_expect): New. (expand_builtin): Call it. * doc/extend.texi: Document __builtin_expect. From-SVN: r47582 --- gcc/builtin-types.def | 1 + gcc/builtins.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ gcc/builtins.def | 3 +++ gcc/doc/extend.texi | 39 +++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+) diff --git a/gcc/builtin-types.def b/gcc/builtin-types.def index 78f4748..b4c866f 100644 --- a/gcc/builtin-types.def +++ b/gcc/builtin-types.def @@ -156,6 +156,7 @@ DEF_FUNCTION_TYPE_3 (BT_FN_TRAD_PTR_PTR_INT_SIZE, BT_TRAD_PTR, BT_PTR, BT_INT, BT_SIZE) DEF_FUNCTION_TYPE_3 (BT_FN_INT_TRAD_CONST_PTR_TRAD_CONST_PTR_LEN, BT_INT, BT_TRAD_CONST_PTR, BT_TRAD_CONST_PTR, BT_LEN) +DEF_FUNCTION_TYPE_3 (BT_FN_VOID_PTR_INT_INT, BT_VOID, BT_PTR, BT_INT, BT_INT) DEF_FUNCTION_TYPE_4 (BT_FN_SIZE_CONST_PTR_SIZE_SIZE_PTR, BT_SIZE, BT_CONST_PTR, BT_SIZE, BT_SIZE, BT_PTR) diff --git a/gcc/builtins.c b/gcc/builtins.c index 65d19e2..6785ce5 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -87,6 +87,7 @@ static int apply_result_size PARAMS ((void)); static rtx result_vector PARAMS ((int, rtx)); #endif static rtx expand_builtin_setjmp PARAMS ((tree, rtx)); +static void expand_builtin_prefetch PARAMS ((tree)); static rtx expand_builtin_apply_args PARAMS ((void)); static rtx expand_builtin_apply_args_1 PARAMS ((void)); static rtx expand_builtin_apply PARAMS ((rtx, rtx, rtx)); @@ -715,6 +716,69 @@ expand_builtin_longjmp (buf_addr, value) } } +/* Expand a call to __builtin_prefetch. For a target that does not support + data prefetch, evaluate the memory address argument in case it has side + effects. */ + +static void +expand_builtin_prefetch (arglist) + tree arglist; +{ + tree arg0, arg1, arg2; + rtx op0, op1, op2; + + arg0 = TREE_VALUE (arglist); + arg1 = TREE_VALUE (TREE_CHAIN (arglist)); + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist))); + + /* Argument 0 is an address. */ + op0 = expand_expr (arg0, NULL_RTX, Pmode, EXPAND_NORMAL); + + /* Argument 1 (read/write flag) must be a compile-time constant int. */ + if (TREE_CODE (arg1) != INTEGER_CST) + { + error ("second arg to `__builtin_prefetch' must be a constant"); + arg1 = integer_zero_node; + } + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0); + /* Argument 1 must be either zero or one. */ + if (INTVAL (op1) != 0 && INTVAL (op1) != 1) + { + warning ("invalid second arg to __builtin_prefetch; using zero"); + op1 = const0_rtx; + } + + /* Argument 2 (locality) must be a compile-time constant int. */ + if (TREE_CODE (arg2) != INTEGER_CST) + { + error ("third arg to `__builtin_prefetch' must be a constant"); + arg2 = integer_zero_node; + } + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0); + /* Argument 2 must be 0, 1, 2, or 3. */ + if (INTVAL (op2) < 0 || INTVAL (op2) > 3) + { + warning ("invalid third arg to __builtin_prefetch; using zero"); + op2 = const0_rtx; + } + +#ifdef HAVE_prefetch + if (HAVE_prefetch) + { + if (! (*insn_data[(int)CODE_FOR_prefetch].operand[0].predicate) + (op0, Pmode)) + op0 = force_reg (Pmode, op0); + emit_insn (gen_prefetch (op0, op1, op2)); + } + else +#endif + op0 = protect_from_queue (op0, 0); + /* Don't do anything with direct references to volatile memory, but + generate code to handle other side effects. */ + if (GET_CODE (op0) != MEM && side_effects_p (op0)) + emit_insn (op0); +} + /* Get a MEM rtx for expression EXP which is the address of an operand to be used to be used in a string instruction (cmpstrsi, movstrsi, ..). */ @@ -3809,6 +3873,10 @@ expand_builtin (exp, target, subtarget, mode, ignore) return expand_builtin_va_copy (arglist); case BUILT_IN_EXPECT: return expand_builtin_expect (arglist, target); + case BUILT_IN_PREFETCH: + expand_builtin_prefetch (arglist); + return const0_rtx; + default: /* just do library call, if unknown builtin */ error ("built-in function `%s' not currently supported", diff --git a/gcc/builtins.def b/gcc/builtins.def index 204da8e..ebb323f 100644 --- a/gcc/builtins.def +++ b/gcc/builtins.def @@ -336,6 +336,9 @@ DEF_GCC_BUILTIN(BUILT_IN_LONGJMP, DEF_GCC_BUILTIN(BUILT_IN_TRAP, "__builtin_trap", BT_FN_VOID) +DEF_GCC_BUILTIN(BUILT_IN_PREFETCH, + "__builtin_prefetch", + BT_FN_VOID_PTR_INT_INT) /* Stdio builtins. */ DEF_FALLBACK_BUILTIN(BUILT_IN_PUTCHAR, diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index d0fdae6..781fa99 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -4474,6 +4474,45 @@ if (__builtin_expect (ptr != NULL, 1)) when testing pointer or floating-point values. @end deftypefn +@deftypefn {Built-in Function} void __builtin_prefetch (void *@var{addr}, int @var{rw}, int @var{locality}) +This function is used to minimize cache-miss latency by moving data into +a cache before it is accessed. +You can insert calls to @code{__builtin_prefetch} into code for which +you know addresses of data in memory that is likely to be accessed soon. +If the target supports them, data prefetch instructions will be generated. +If the prefetch is done early enough before the access then the data will +be in the cache by the time it is accessed. + +The value of @var{addr} is the address of the memory to prefetch. +The value of @var{rw} is a compile-time constant one or zero; one +means that the prefetch is preparing for a write to the memory address. +The value @var{locality} must be a compile-time constant integer between +zero and three. A value of zero means that the data has no temporal +locality, so it need not be left in the cache after the access. A value +of three means that the data has a high degree of temporal locality and +should be left in all levels of cache possible. Values of one and two +mean, respectively, a low or moderate degree of temporal locality. + +@smallexample +for (i = 0; i < n; i++) + @{ + a[i] = a[i] + b[i]; + __builtin_prefetch (&a[i+j], 1, 1); + __builtin_prefetch (&b[i+j], 0, 1); + /* ... */ + @} +@end smallexample + +Data prefetch does not generate faults if @var{addr} is invalid, but +the address expression itself must be valid. For example, a prefetch +of @code{p->next} will not fault if @code{p->next} is not a valid +address, but evaluation will fault if @code{p} is not a valid address. + +If the target does not support data prefetch, the address expression +is evaluated if it includes side effects but no other code is generated +and GCC does not issue a warning. +@end deftypefn + @node Pragmas @section Pragmas Accepted by GCC @cindex pragmas -- 2.7.4