mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-11 03:56:53 +08:00
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:
parent
21b8482ae8
commit
a9ccbb60d4
@ -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)
|
||||
|
@ -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",
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user