aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJanis Johnson <janis@gcc.gnu.org>2001-12-04 00:50:35 +0000
committerJanis Johnson <janis@gcc.gnu.org>2001-12-04 00:50:35 +0000
commita9ccbb60d4bfa7b7637a9157e10e58f4c60102a5 (patch)
tree40c85f3d7a5f7892b65417f4aa96b825f4936046
parent21b8482ae8289fccb3ddaaa74532995aa3f27c56 (diff)
downloadgcc-a9ccbb60d4bfa7b7637a9157e10e58f4c60102a5.zip
gcc-a9ccbb60d4bfa7b7637a9157e10e58f4c60102a5.tar.gz
gcc-a9ccbb60d4bfa7b7637a9157e10e58f4c60102a5.tar.bz2
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
-rw-r--r--gcc/builtin-types.def1
-rw-r--r--gcc/builtins.c68
-rw-r--r--gcc/builtins.def3
-rw-r--r--gcc/doc/extend.texi39
4 files changed, 111 insertions, 0 deletions
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