From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 19173 invoked by alias); 6 Jul 2007 05:01:47 -0000 Received: (qmail 19012 invoked by uid 22791); 6 Jul 2007 05:01:41 -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; Fri, 06 Jul 2007 05:01:35 +0000 Received: from smtp1.dnsmadeeasy.com (localhost [127.0.0.1]) by smtp1.dnsmadeeasy.com (Postfix) with ESMTP id 1B3972FAF03; Fri, 6 Jul 2007 05:01:33 +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; Fri, 6 Jul 2007 05:01:32 +0000 (UTC) Received: from jennifer.localdomain ([192.168.7.229]) by avtrex.com with Microsoft SMTPSVC(6.0.3790.1830); Thu, 5 Jul 2007 22:01:31 -0700 Message-ID: <468DCC7E.5020500@avtrex.com> Date: Fri, 06 Jul 2007 06:19:00 -0000 From: David Daney User-Agent: Thunderbird 2.0.0.4 (X11/20070615) MIME-Version: 1.0 To: Mark Mitchell Cc: Paolo Bonzini , gcc-patches@gcc.gnu.org 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> In-Reply-To: <468DB46D.50709@codesourcery.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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/msg00549.txt.bz2 Mark Mitchell wrote: > David Daney wrote: > > >> Ok, I think I have come around to your way of thinking. I still have >> the new predicate __builtin_clear_cache_inline_p() for use in target >> CLEAR_INSN_CACHE definitions, but I leave __clear_cache unchanged. >> > > I don't understand the need for the inline_p function. It seems to me > there are two scenarios: > > 1. The back-end has an inline definition of __builtin___clear_cache. In > that case, it does: > > #define CLEAR_INSN_CACHE(BEG, END) __builtin___clear_cache(BEG, END); > > 2. The back-end does not have an inline definition of > __builtin_clear_cache. In that case, it does: > > #define CLEAR_INSN_CACHE(BEG, END) \ > /* Something not involving __builtin___clear_cache */ > > In both cases, the libgcc __clear_cache routine just does: > > CLEAR_INSN_CACHE (beg, end); > > And, in both cases, the user can write either __clear_cache (always an > out-of-line call), or __builtin_clear_cache (may be an out-of-line call, > or may be inline code). > > Is your concern that in case (1) the back-end has to do two things: > define the builtin and define CLEAR_INSN_CACHE? That's a little lame, > but it doesn't seem worse than having to define two builtins. > > Am I missing some intermediate case? > The MIPS family has some members that can clear the instruction cache with in-line instructions from user space. Other members of the family can only clear the instruction cache from kernel space and must make a system call (perhaps via __clear_cache() in libgcc). There are command line switches that select the ISA, and thus for which of these cases we are generating code. When Paolo Bonzini wrote: > try to see how __clear_cache could use the definition of the builtin. I realized that if one were not careful, infinite recursion might result. The idea behind __builtin_clear_cache_inline_p() is that it allows us to test in source code which of these two cases are in effect at compile time. At the time we write a CLEAR_INSN_CACHE macro, we don't know which ISA will be targeted when libgcc is built. When __builtin___clear_cache() expands to a library call to __clear_cache() in libgcc, we cannot have __clear_cache() be implemented by __builtin___clear_cache() or we would recurse infinitely. I envision that __builtin_clear_cache_inline_p() would be tested in like this: #define CLEAR_INSN_CACHE(BEG, END) \ { \ extern void _flush_cache (char *b, int l, int f); \ if (__builtin_clear_cache_inline_p()) \ __builtin___clear_cache ((BEG), (END)); \ else \ _flush_cache ((BEG), ((char *)(END) - (char *)(BEG)), 3); \ } The same thing could probably be achieved by setting and examining a set of preprocessor symbols, but I think having a single well defined predicate is a cleaner solution. That said, after corresponding with Richard Sandiford about the MIPS portion of the patch, I think that I will expand the calls to _flush_cache() directly in the back-end rather than call to __clear_cache() in libgcc which would then do the system call. So for MIPS __builtin_clear_cache_inline_p() would be unconditionally true. i386 and x86_64 don't need to clear their instruction caches, so for these targets __builtin_clear_cache_inline_p() would likewise be true unconditionally. IIRC there are only two targets that currently define CLEAR_INSN_CACHE, they are arm and m86k. I don't know if __builtin_clear_cache_inline_p() would be useful for them. I hope that explains what I was thinking. Not knowing the intimate details of the majority of GCC targets, I do not know if __builtin_clear_cache_inline_p() would ever used for anything. Hypothetically if arm were to add instructions that flushed the cache without making a system call, something like __builtin_clear_cache_inline_p() would be useful in writing the CLEAR_INSN_CACHE macro. 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). David Daney