From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 927 invoked by alias); 8 Jul 2007 19:16:08 -0000 Received: (qmail 919 invoked by uid 22791); 8 Jul 2007 19:16:07 -0000 X-Spam-Check-By: sourceware.org Received: from smtp1.dnsmadeeasy.com (HELO smtp1.dnsmadeeasy.com) (205.234.170.134) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sun, 08 Jul 2007 19:16:04 +0000 Received: from smtp1.dnsmadeeasy.com (localhost [127.0.0.1]) by smtp1.dnsmadeeasy.com (Postfix) with ESMTP id 0C4862FD6E6; Sun, 8 Jul 2007 19:16:02 +0000 (UTC) X-Authenticated-Name: js.dnsmadeeasy X-Transit-System: In case of SPAM please contact abuse@dnsmadeeasy.com Received: from avtrex.com (unknown [67.116.42.147]) by smtp1.dnsmadeeasy.com (Postfix) with ESMTP; Sun, 8 Jul 2007 19:16:01 +0000 (UTC) Received: from jennifer.localdomain ([192.168.7.221]) by avtrex.com with Microsoft SMTPSVC(6.0.3790.1830); Sun, 8 Jul 2007 12:15:59 -0700 Message-ID: <469137A0.4010305@avtrex.com> Date: Sun, 08 Jul 2007 19:22:00 -0000 From: David Daney User-Agent: Thunderbird 2.0.0.4 (X11/20070615) MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Cc: Mark Mitchell , Paolo Bonzini , rsandifo@nildram.co.uk Subject: Re: [Patch] 1/3 Add new builtin __builtin_flush_icache(). References: <468734D3.3020908@avtrex.com> <46875F54.8070905@gnu.org> <4687F6C1.6050906@avtrex.com> <46888752.2040207@gnu.org> <468ADFB4.4060400@codesourcery.com> <468BCF25.40807@avtrex.com> <468BD6CA.8000703@codesourcery.com> <468C999B.1000102@avtrex.com> <468DB46D.50709@codesourcery.com> <468DCC7E.5020500@avtrex.com> <468E6EBA.5040409@codesourcery.com> In-Reply-To: <468E6EBA.5040409@codesourcery.com> Content-Type: multipart/mixed; boundary="------------030503090009080208090207" X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-07/txt/msg00702.txt.bz2 This is a multi-part message in MIME format. --------------030503090009080208090207 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 2777 Mark Mitchell wrote: > David Daney wrote: > > >> If it is deemed to be useless, I will remove >> __builtin_clear_cache_inline_p() from the patch as it is unneeded for my >> current target of interest (MIPS). >> > > Since you don't need it yet, I would suggest leaving it out for now. > The ARM and 68K ports are using OS syscalls to clear the cache, which is > ISA-independent, so they don't need the inline_p test either. > > I understand what you were trying to accomplish, and we may well end up > needing it, but let's not do it until we do. If we do need it, we may > want it as a predefined macro, not as a builtin, so that it can be used > in preprocessor tests. (I believe we've done that with other builtins.) > Here is a new version of the patch. Taking Mark's suggestion to remove __builtin_clear_cache_inline_p() simplifies things somewhat. My new implementation has three cases for __builtin___clear_cache(): 1) No "clear_cache" insn is supplied but the target does supply a definition for CLEAR_INSN_CACHE. In this case (arm, m68k IIRC) the new builtin will expand to a call to the existing __clear_cache in libgcc. 2) A "clear_cache" insn is supplied. For this case, the builtin expands to said insn. The mips portion of the patch currently has the only implemtation of "clear_cache". 3) Neither "clear_cache" or CLEAR_INSN_CACHE is defined. This case covers most GCC targets including but not limited to i386 and x86_64. In this case the builtin expands to nothing, so it is a nop. As additional targets add support for __builtin___clear_cache(), there are several options: * Do everything in libgcc via a definition of CLEAR_INSN_CACHE. If this is done, backwards compatibility will have to be maintained in all future versions of libgcc. * Do everything in a clear_cache insn. In this case there are no backwards compatibility issues in libgcc. This is what we chose to do in the MIPS portion of the patch. * Some sort of hybrid of the other two options. Care should be taken to avoid situations where calls to either the builtin or the library function would recursively call each other. Bootstrapped and regression tested on: x86_64-unknown-linux-gnu all default languages. i686-unknown-linux-gnu to mipsel-linux (--with-arch=mips32 and --with-arch-mips32r2) cross tested with no regressions. OK to commit? :ADDPATCH middle-end: 2007-07-08 David Daney * builtins.def (BUILT_IN_CLEAR_CACHE): New builtin. * builtins.c (expand_builtin___clear_cache): New function. (expand_builtin): Call expand_builtin___clear_cache for BUILT_IN_CLEAR_CACHE case. * doc/extend.texi (__builtin___clear_cache): Document new builtin. * testsuite/gcc.dg/builtins-64.c: New test. --------------030503090009080208090207 Content-Type: text/x-patch; name="flush-cache1.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="flush-cache1.diff" Content-length: 5272 Index: gcc/builtins.def =================================================================== --- gcc/builtins.def (revision 125997) +++ gcc/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. @@ -609,6 +609,7 @@ DEF_GCC_BUILTIN (BUILT_IN_APPLY_A DEF_GCC_BUILTIN (BUILT_IN_ARGS_INFO, "args_info", BT_FN_INT_INT, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_BSWAP32, "bswap32", BT_FN_UINT32_UINT32, ATTR_CONST_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_BSWAP64, "bswap64", BT_FN_UINT64_UINT64, ATTR_CONST_NOTHROW_LIST) +DEF_EXT_LIB_BUILTIN (BUILT_IN_CLEAR_CACHE, "__clear_cache", BT_FN_VOID_PTR_PTR, ATTR_NOTHROW_LIST) DEF_LIB_BUILTIN (BUILT_IN_CALLOC, "calloc", BT_FN_PTR_SIZE_SIZE, ATTR_MALLOC_NOTHROW_LIST) DEF_GCC_BUILTIN (BUILT_IN_CLASSIFY_TYPE, "classify_type", BT_FN_INT_VAR, ATTR_NULL) DEF_GCC_BUILTIN (BUILT_IN_CLZ, "clz", BT_FN_INT_UINT, ATTR_CONST_NOTHROW_LIST) Index: gcc/builtins.c =================================================================== --- gcc/builtins.c (revision 125997) +++ gcc/builtins.c (working copy) @@ -5513,6 +5513,58 @@ expand_builtin_profile_func (bool exitp) return const0_rtx; } +/* Expand a call to __builtin___clear_cache. */ + +static rtx +expand_builtin___clear_cache (tree exp ATTRIBUTE_UNUSED) +{ +#ifndef HAVE_clear_cache +#ifdef CLEAR_INSN_CACHE + /* There is no "clear_cache" insn, and __clear_cache() in libgcc + does something. Just do the default expansion to a call to __clear_cache(). */ + return NULL_RTX; +#else + /* There is no "clear_cache" insn, and __clear_cache() in libgcc + does nothing. There is no need to call it. Do nothing. */ + return const0_rtx; +#endif /* CLEAR_INSN_CACHE */ +#else + /* We have a "clear_cache" insn, and it will handle everything. */ + tree begin, end; + rtx begin_rtx, end_rtx; + enum insn_code icode; + + /* We must not expand to a library call. If we did, any + fallback library function in libgcc that might contain a call to + __builtin___clear_cache() would recurse infinitely. */ + if (!validate_arglist (exp, POINTER_TYPE, POINTER_TYPE, VOID_TYPE)) + { + error ("both arguments to %<__builtin___clear_cache%> must be pointers"); + return const0_rtx; + } + + if (HAVE_clear_cache) + { + icode = CODE_FOR_clear_cache; + + begin = CALL_EXPR_ARG (exp, 0); + begin_rtx = expand_expr (begin, NULL_RTX, Pmode, EXPAND_NORMAL); + begin_rtx = convert_memory_address (Pmode, begin_rtx); + if (!insn_data[icode].operand[0].predicate (begin_rtx, Pmode)) + begin_rtx = copy_to_mode_reg (Pmode, begin_rtx); + + end = CALL_EXPR_ARG (exp, 1); + end_rtx = expand_expr (end, NULL_RTX, Pmode, EXPAND_NORMAL); + end_rtx = convert_memory_address (Pmode, end_rtx); + if (!insn_data[icode].operand[1].predicate (end_rtx, Pmode)) + end_rtx = copy_to_mode_reg (Pmode, end_rtx); + + emit_insn (gen_clear_cache (begin_rtx, end_rtx)); + } + return const0_rtx; +#endif /* HAVE_clear_cache */ +} + /* Given a trampoline address, make sure it satisfies TRAMPOLINE_ALIGNMENT. */ static rtx @@ -6181,6 +6233,12 @@ expand_builtin (tree exp, rtx target, rt return const0_rtx; return expand_builtin_next_arg (); + case BUILT_IN_CLEAR_CACHE: + target = expand_builtin___clear_cache (exp); + if (target) + return target; + break; + case BUILT_IN_CLASSIFY_TYPE: return expand_builtin_classify_type (exp); Index: gcc/doc/extend.texi =================================================================== --- gcc/doc/extend.texi (revision 125997) +++ gcc/doc/extend.texi (working copy) @@ -6086,6 +6086,18 @@ if (__builtin_expect (ptr != NULL, 1)) when testing pointer or floating-point values. @end deftypefn +@deftypefn {Built-in Function} void __builtin___clear_cache (char *@var{begin}, char *@var{end}) +This functions is used to flush the processor's instruction cache for +the region of memory between @var{begin} and @var{end}. 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, +@code{__builtin___clear_cache} has no effect. Otherwise either +instructions are emitted in-line to clear the instruction cache or a +call to the @code{__clear_cache} function in libgcc is made. +@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: gcc/testsuite/gcc.dg/builtins-64.c =================================================================== --- gcc/testsuite/gcc.dg/builtins-64.c (revision 0) +++ gcc/testsuite/gcc.dg/builtins-64.c (revision 0) @@ -0,0 +1,8 @@ +/* { dg-do run } */ + +int main () +{ + char *mem = __builtin_alloca (40); + __builtin___clear_cache (mem, mem + 40); + return 0; +} --------------030503090009080208090207--