From patchwork Tue Apr 25 10:47:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 754721 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wC0L72hdTz9s8G for ; Tue, 25 Apr 2017 20:48:15 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="HUTrTP7O"; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=qdWKv/1Rme06jivGjauCwDp9xuDNHWq3JeMj3QOAoYLBCRgYaj sOXjp9BLjo9C+mAMB677r4B/kl7QUADL6zwckXr2ULNPnmoHEmhwwVx4CIPu56wg b/w7GBApXCFAdXHTfYRzzcsVv2ujv9CROPpFqITvVt8T2lNi3+OnRxK0A= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=Hd9Lz6PRIMzFT5DVHhY0yhUhMVY=; b=HUTrTP7OyYRqOWMPnpdQ frV86Cpd8M2UnEKw9s9BGkEsmhDtxTZVXg4QjHz19q9kcfhU3e2oncP8IXvKv5GB 8E0mtUfaA2wDNBqkXNWZ38mNFcL9VeuqCyhArwrkHgOXzOU/XuvgYQX4dccJO4Hw oQxrtKpSzGZ3rjK+vvvnIjk= Received: (qmail 13175 invoked by alias); 25 Apr 2017 10:47:34 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 13095 invoked by uid 89); 25 Apr 2017 10:47:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-10.2 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=prefixes X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 25 Apr 2017 10:47:30 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 6AF2835E1; Tue, 25 Apr 2017 06:47:31 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 4vSQLlU5Vhiq; Tue, 25 Apr 2017 06:47:31 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [205.232.38.10]) by rock.gnat.com (Postfix) with ESMTP id 5ADEB33B0; Tue, 25 Apr 2017 06:47:31 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4192) id 599483F0; Tue, 25 Apr 2017 06:47:31 -0400 (EDT) Date: Tue, 25 Apr 2017 06:47:31 -0400 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Eric Botcazou Subject: [Ada] Micro-optimize again Is_Internal_File_Name & Is_Predefined_File_Name Message-ID: <20170425104731.GA53842@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) This micro-optimizes again the implementation of a couple of hot functions after recent changes. No functional changes. Tested on x86_64-pc-linux-gnu, committed on trunk 2017-04-25 Eric Botcazou * fname.adb (Has_Internal_Extension): Add pragma Inline. Use direct 4-character slice comparisons. (Has_Prefix): Add pragma Inline. (Has_Suffix): Delete. (Is_Internal_File_Name): Test Is_Predefined_File_Name first. (Is_Predefined_File_Name): Use direct slice comparisons as much as possible and limit all comparisons to at most 8 characters. Index: fname.adb =================================================================== --- fname.adb (revision 247177) +++ fname.adb (working copy) @@ -58,27 +58,30 @@ Table_Name => "Fname_Dummy_Table"); function Has_Internal_Extension (Fname : String) return Boolean; + pragma Inline (Has_Internal_Extension); -- True if the extension is appropriate for an internal/predefined -- unit. That means ".ads" or ".adb" for source files, and ".ali" for -- ALI files. function Has_Prefix (X, Prefix : String) return Boolean; + pragma Inline (Has_Prefix); -- True if Prefix is at the beginning of X. For example, -- Has_Prefix("a-filename.ads", Prefix => "a-") is True. - function Has_Suffix (X, Suffix : String) return Boolean; - -- True if Suffix is at the end of X - ---------------------------- -- Has_Internal_Extension -- ---------------------------- function Has_Internal_Extension (Fname : String) return Boolean is begin - return - Has_Suffix (Fname, Suffix => ".ads") - or else Has_Suffix (Fname, Suffix => ".adb") - or else Has_Suffix (Fname, Suffix => ".ali"); + if Fname'Length >= 4 then + declare + S : String renames Fname (Fname'Last - 3 .. Fname'Last); + begin + return S = ".ads" or else S = ".adb" or else S = ".ali"; + end; + end if; + return False; end Has_Internal_Extension; ---------------- @@ -89,32 +92,14 @@ begin if X'Length >= Prefix'Length then declare - Slice : String renames - X (X'First .. X'First + Prefix'Length - 1); + S : String renames X (X'First .. X'First + Prefix'Length - 1); begin - return Slice = Prefix; + return S = Prefix; end; end if; return False; end Has_Prefix; - ---------------- - -- Has_Suffix -- - ---------------- - - function Has_Suffix (X, Suffix : String) return Boolean is - begin - if X'Length >= Suffix'Length then - declare - Slice : String renames - X (X'Last - Suffix'Length + 1 .. X'Last); - begin - return Slice = Suffix; - end; - end if; - return False; - end Has_Suffix; - --------------------------- -- Is_Internal_File_Name -- --------------------------- @@ -124,6 +109,10 @@ Renamings_Included : Boolean := True) return Boolean is begin + if Is_Predefined_File_Name (Fname, Renamings_Included) then + return True; + end if; + -- Check for internal extensions first, so we don't think (e.g.) -- "gnat.adc" is internal. @@ -131,10 +120,7 @@ return False; end if; - return - Is_Predefined_File_Name (Fname, Renamings_Included) - or else Has_Prefix (Fname, Prefix => "g-") - or else Has_Prefix (Fname, Prefix => "gnat."); + return Has_Prefix (Fname, "g-") or else Has_Prefix (Fname, "gnat."); end Is_Internal_File_Name; function Is_Internal_File_Name @@ -156,16 +142,38 @@ (Fname : String; Renamings_Included : Boolean := True) return Boolean is + subtype Str8 is String (1 .. 8); + + Renaming_Names : constant array (1 .. 8) of Str8 := + ("calendar", -- Calendar + "machcode", -- Machine_Code + "unchconv", -- Unchecked_Conversion + "unchdeal", -- Unchecked_Deallocation + "directio", -- Direct_IO + "ioexcept", -- IO_Exceptions + "sequenio", -- Sequential_IO + "text_io."); -- Text_IO + + -- Note: the implementation is optimized to perform uniform comparisons + -- on string slices whose length is known at compile time and at most 8 + -- characters; the remaining calls to Has_Prefix must be inlined so as + -- to expose the compile-time known length. + begin if not Has_Internal_Extension (Fname) then return False; end if; - if Has_Prefix (Fname, "a-") - or else Has_Prefix (Fname, "i-") - or else Has_Prefix (Fname, "s-") - then - return True; + -- Definitely predefined if prefix is a- i- or s- + + if Fname'Length >= 2 then + declare + S : String renames Fname (Fname'First .. Fname'First + 1); + begin + if S = "a-" or else S = "i-" or else S = "s-" then + return True; + end if; + end; end if; -- Definitely false if longer than 12 characters (8.3) @@ -176,53 +184,30 @@ -- We include the "." in the prefixes below, so we don't match (e.g.) -- adamant.ads. So the first line matches "ada.ads", "ada.adb", and - -- "ada.ali". + -- "ada.ali". But that's not necessary if they have 8 characters. - if Has_Prefix (Fname, Prefix => "ada.") -- Ada - or else Has_Prefix (Fname, Prefix => "interfac.") -- Interfaces - or else Has_Prefix (Fname, Prefix => "system.") -- System + if Has_Prefix (Fname, "ada.") -- Ada + or else Has_Prefix (Fname, "interfac") -- Interfaces + or else Has_Prefix (Fname, "system.") -- System then return True; end if; - if not Renamings_Included then - return False; + -- If instructed and the name has 8+ characters, check for renamings + + if Renamings_Included and then Fname'Length >= 8 then + declare + S : String renames Fname (Fname'First .. Fname'First + 7); + begin + for J in Renaming_Names'Range loop + if S = Renaming_Names (J) then + return True; + end if; + end loop; + end; end if; - -- The following are the predefined renamings - - return - -- Calendar - - Has_Prefix (Fname, Prefix => "calendar.") - - -- Machine_Code - - or else Has_Prefix (Fname, Prefix => "machcode.") - - -- Unchecked_Conversion - - or else Has_Prefix (Fname, Prefix => "unchconv.") - - -- Unchecked_Deallocation - - or else Has_Prefix (Fname, Prefix => "unchdeal.") - - -- Direct_IO - - or else Has_Prefix (Fname, Prefix => "directio.") - - -- IO_Exceptions - - or else Has_Prefix (Fname, Prefix => "ioexcept.") - - -- Sequential_IO - - or else Has_Prefix (Fname, Prefix => "sequenio.") - - -- Text_IO - - or else Has_Prefix (Fname, Prefix => "text_io."); + return False; end Is_Predefined_File_Name; function Is_Predefined_File_Name