]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
builtin-types.def (BT_FN_VOID_PTR_INT_INT): New.
authorJanis Johnson <janis@gcc.gnu.org>
Tue, 4 Dec 2001 00:50:35 +0000 (00:50 +0000)
committerJanis Johnson <janis@gcc.gnu.org>
Tue, 4 Dec 2001 00:50:35 +0000 (00:50 +0000)
* 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
gcc/builtins.c
gcc/builtins.def
gcc/doc/extend.texi

index 78f4748d6be43431b85de83c4b928401713d699a..b4c866fdddaf9fc115affe7d578d21fcc2a12b47 100644 (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)
index 65d19e27f792e5e14a317bdbff457c1bc670c0bc..6785ce546581fc43eb5ccde6a4724eb35df254e2 100644 (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",
index 204da8e09b7b6b77d20df9f5c4f44a7d5d5a9787..ebb323f235de18ef70d4942c18dd248ceea02904 100644 (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,
index d0fdae60c11aa7349c12d85fee379697f8f01622..781fa997addc1a2dfa5af8186af783edf549eb80 100644 (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