This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] 1/3 Add new builtin __builtin_flush_icache().


This series of patches adds a new built-in __builtin_flush_icache.
The first part is the target independent support.  The second adds
support to the MIPS back-end.  And finally the third changes the MIPS
libffi support to use the new builtin instead of making a library
call.

The prototype for the new built-in is:

void __builtin_flush_icache(void *location, size_t len);

As one might expect, it flushes the region of memory pointed to by
location with length len from the instruction cache.  The
new builtin and the flush_icache insn would be the preferred mechanism
to flushing the i-cache.

Looking at the various targets, it seems possible that in addition my
mips support, alpha, arc, arm, ia64, m32r, m68k, pa, rs6000, score,
sparc, and xtensa could do something useful for __builtin_flush_icache.

Bootstrapped and tested on x86_64-unknown-linux-gnu all default
languages with no regressions.

Also tested on:
x86_64 cross to mipsel-linux --with-arch=mips32
i686   cross to mipsel-linux --with-arch=mips32r2

with no regressions.

OK to commit?
2007-06-30  David Daney  <ddaney@avtrex.com>

   * builtins.def (BUILT_IN_FLUSH_ICACHE): New builtin.
   * builtins.c (expand_builtin_flush_icache): New function.
   (expand_builtin): Call expand_builtin_flush_icache for
   BUILT_IN_FLUSH_ICACHE.
   (fold_builtin_flush_icache): New function.
   (fold_builtin_2): Call fold_builtin_flush_icache for
   BUILT_IN_FLUSH_ICACHE.
   * testsuite/gcc.dg/builtins-64.c: New test.
   * testsuite/gcc.dg/builtins-65.c: New test.
   * doc/extend.texi (__builtin_flush_icache): Document new builtin.


Index: builtins.def
===================================================================
--- builtins.def	(revision 125997)
+++ builtins.def	(working copy)
@@ -1,6 +1,6 @@
 /* This file contains the definitions and documentation for the
    builtins used in the GNU compiler.
-   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -640,6 +640,7 @@ DEF_EXT_LIB_BUILTIN    (BUILT_IN_FFS, "f
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_FFSIMAX, "ffsimax", BT_FN_INT_INTMAX, ATTR_CONST_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_FFSL, "ffsl", BT_FN_INT_LONG, ATTR_CONST_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_NOTHROW_LIST)
+DEF_GCC_BUILTIN        (BUILT_IN_FLUSH_ICACHE, "flush_icache", BT_FN_VOID_PTR_SIZE, ATTR_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN        (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST)
 DEF_GCC_BUILTIN        (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL)
 DEF_LIB_BUILTIN        (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LIST) 
Index: builtins.c
===================================================================
--- builtins.c	(revision 125997)
+++ builtins.c	(working copy)
@@ -5513,6 +5513,39 @@ expand_builtin_profile_func (bool exitp)
   return const0_rtx;
 }
 
+/* Expand a call to _builtin_flush_icache.  If the target does not
+   support the operation, it is a nop. */
+static rtx
+expand_builtin_flush_icache (tree exp)
+{
+  tree location, len;
+  rtx location_rtx, len_rtx;
+
+  if (!validate_arglist (exp, POINTER_TYPE, INTEGER_TYPE, VOID_TYPE))
+    return NULL_RTX;
+
+  location = CALL_EXPR_ARG (exp, 0);
+  len = CALL_EXPR_ARG (exp, 1);
+
+  /* Evaluate LOCATION in case it has side-effects. */
+  location_rtx = expand_expr (location, NULL_RTX, Pmode, EXPAND_NORMAL);
+  location_rtx = convert_memory_address (Pmode, location_rtx);
+
+  /* If the LEN parameter is zero, return. */
+  if (integer_zerop (len))
+    return const0_rtx;
+
+  len_rtx = expand_normal (len);
+
+#ifdef HAVE_flush_icache
+  if (HAVE_flush_icache)
+    {
+      emit_insn (gen_flush_icache (location_rtx, len_rtx));
+    }
+#endif
+  return const0_rtx;
+}
+
 /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT.  */
 
 static rtx
@@ -6590,6 +6623,9 @@ expand_builtin (tree exp, rtx target, rt
     case BUILT_IN_PROFILE_FUNC_EXIT:
       return expand_builtin_profile_func (true);
 
+    case BUILT_IN_FLUSH_ICACHE:
+      return expand_builtin_flush_icache (exp);
+
     case BUILT_IN_INIT_TRAMPOLINE:
       return expand_builtin_init_trampoline (exp);
     case BUILT_IN_ADJUST_TRAMPOLINE:
@@ -9558,6 +9594,22 @@ fold_builtin_unordered_cmp (tree fndecl,
 		      fold_build2 (code, type, arg0, arg1));
 }
 
+/* Fold function call to builtin flush_icache.  Return
+   NULL_TREE if no simplification can be made.  */
+
+static tree
+fold_builtin_flush_icache (tree location, tree len)
+{
+  if (! validate_arg (location, POINTER_TYPE)
+      || ! validate_arg (len, INTEGER_TYPE))
+    return NULL_TREE;
+
+  /* If len parameter is zero, do nothing. */
+  if (integer_zerop (len))
+    return omit_one_operand (void_type_node, location, len);
+  return NULL_TREE;
+}
+
 /* Fold a call to built-in function FNDECL with 0 arguments.
    IGNORE is true if the result of the function call is ignored.  This
    function returns NULL_TREE if no simplification was possible.  */
@@ -10068,6 +10120,8 @@ fold_builtin_2 (tree fndecl, tree arg0, 
     case BUILT_IN_VFPRINTF:
       return fold_builtin_fprintf (fndecl, arg0, arg1, NULL_TREE,
 				   ignore, fcode);
+    case BUILT_IN_FLUSH_ICACHE:
+      return fold_builtin_flush_icache (arg0, arg1);
 
     default:
       break;
Index: testsuite/gcc.dg/builtins-64.c
===================================================================
--- testsuite/gcc.dg/builtins-64.c	(revision 0)
+++ testsuite/gcc.dg/builtins-64.c	(revision 0)
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+void f()
+{
+  char *memory = __builtin_alloca(40);
+  __builtin_flush_icache(memory, 40);
+}
+
+/* { dg-final { scan-tree-dump "__builtin_flush_icache" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
Index: testsuite/gcc.dg/builtins-65.c
===================================================================
--- testsuite/gcc.dg/builtins-65.c	(revision 0)
+++ testsuite/gcc.dg/builtins-65.c	(revision 0)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+void f()
+{
+  char *memory = __builtin_alloca(40);
+  /* __builtin_flush_icache should be folded away for size == 0. */
+  __builtin_flush_icache(memory, 0);
+}
+
+/* { dg-final { scan-tree-dump-not "__builtin_flush_icache" "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
Index: doc/extend.texi
===================================================================
--- doc/extend.texi	(revision 125997)
+++ doc/extend.texi	(working copy)
@@ -6086,6 +6086,19 @@ if (__builtin_expect (ptr != NULL, 1))
 when testing pointer or floating-point values.
 @end deftypefn
 
+@deftypefn {Built-in Function} void __builtin_flush_icache (const void *@var{addr}, size_t @var{len})
+This functions is used to flush the processor's instruction cache for
+the region of memory of length @var{len} at location @var{addr}.  Some
+targets require that the instruction cache be flushed, after modifying
+memory containing code, in order to obtain deterministic behavior.
+
+If the target does not require instruction cache flushes or otherwise
+does not have support for @code{__builtin_flush_icache}, the address
+expression is evaluated if it includes side effects but no other code
+is generated.  Currently MIPS is the only target with support for
+@code{__builtin_flush_icache}.
+@end deftypefn
+
 @deftypefn {Built-in Function} void __builtin_prefetch (const void *@var{addr}, ...)
 This function is used to minimize cache-miss latency by moving data into
 a cache before it is accessed.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]