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
This commit is contained in:
Janis Johnson 2001-12-04 00:50:35 +00:00
parent 21b8482ae8
commit a9ccbb60d4
4 changed files with 111 additions and 0 deletions

View File

@ -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)

View File

@ -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",

View File

@ -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,

View File

@ -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