From patchwork Thu Nov 12 11:06:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 543307 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 43135140281 for ; Thu, 12 Nov 2015 22:06:55 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=V6xqoglR; 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=VvPgfyaCM/KaxQWnCLvL85jFbmFTJDL6WgRxAWPigMYlcDe2s4 m78toGbAjIgrq+wZ6hJ2Ef+0w7nMjnQwLpOaHQhnd0Krixr6YEcA+Vb3FZ7Hbix3 GsmMyh+xueq16ErSBzqXxD79r/aJEYSmry5lRc2cYGya4u1XQEpwYoeHA= 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=XBOW9BOu9Gr+Pd3JJhDTzHL3rZQ=; b=V6xqoglRCZ8SG4pU7Ehd Le36fXQrnXs/kO8mhp3PGgpW19ef8+LiSfjpIWdekA4oKyCJQ9B05cx2VBLo9ChF 3zhKp8ntw/uTgx2jmjzupmx4YfG42Ulx2uxT2nQnm4lsVb+F4gknFmeW9WlOnfQx XVrIeEQtlzIrLDefmrdGa4Q= Received: (qmail 13231 invoked by alias); 12 Nov 2015 11:06:47 -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 12679 invoked by uid 89); 12 Nov 2015 11:06:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.9 required=5.0 tests=BAYES_50, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 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 (AES256-SHA encrypted) ESMTPS; Thu, 12 Nov 2015 11:06:45 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id ECE1029823; Thu, 12 Nov 2015 06:06:43 -0500 (EST) 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 XilPIKukIc2T; Thu, 12 Nov 2015 06:06:43 -0500 (EST) Received: from tron.gnat.com (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) by rock.gnat.com (Postfix) with ESMTP id DAF252981D; Thu, 12 Nov 2015 06:06:43 -0500 (EST) Received: by tron.gnat.com (Postfix, from userid 4192) id D5EA429E; Thu, 12 Nov 2015 06:06:43 -0500 (EST) Date: Thu, 12 Nov 2015 06:06:43 -0500 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Eric Botcazou Subject: [Ada] More efficient code generated for object overlays Message-ID: <20151112110643.GA117606@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) This change refines the use of the "volatile hammer" to implement the advice given in RM 13.3(19) by disabling it for object overlays altogether. relying instead on the ref-all aliasing property of reference types to achieve the desired effect. This will generate better code for object overlays, for example the following function should now make no memory accesses at all on 64-bit platforms when compiled at -O2 or above: package Vec is type U64 is mod 2**64; function Prod (A, B : U64) return U64; end Vec; package body Vec is function Prod (A, B : U64) return U64 is type U16 is mod 2**16; type V16 is array (1..4) of U16; VA : V16; for VA'Address use A'Address; VB : V16; for VB'Address use B'Address; R : U64 := 0; begin for I in V16'Range loop R := R + U64(VA (I)) * U64(VB (I)); end loop; return R; end; end Vec; Tested on x86_64-pc-linux-gnu, committed on trunk 2015-11-12 Eric Botcazou * sem_ch13.adb (Analyze_Attribute_Definition_Clause): For a variable, if this is not an overlay, set on Treat_As_Volatile on it. * gcc-interface/decl.c (E_Variable): Do not force the type to volatile for address clauses. Tweak and adjust various RM references. Index: sem_ch13.adb =================================================================== --- sem_ch13.adb (revision 230229) +++ sem_ch13.adb (working copy) @@ -4724,10 +4724,24 @@ Find_Overlaid_Entity (N, O_Ent, Off); - -- If the object overlays a constant view, mark it so + if Present (O_Ent) then + -- If the object overlays a constant object, mark it so - if Present (O_Ent) and then Is_Constant_Object (O_Ent) then - Set_Overlays_Constant (U_Ent); + if Is_Constant_Object (O_Ent) then + Set_Overlays_Constant (U_Ent); + end if; + else + -- If this is not an overlay, mark a variable as being + -- volatile to prevent unwanted optimizations. It's a + -- conservative interpretation of RM 13.3(19) for the + -- cases where the compiler cannot detect potential + -- aliasing issues easily and it also covers the case + -- of an absolute address where the volatile aspect is + -- kind of implicit. + + if Ekind (U_Ent) = E_Variable then + Set_Treat_As_Volatile (U_Ent); + end if; end if; -- Overlaying controlled objects is erroneous. Index: gcc-interface/decl.c =================================================================== --- gcc-interface/decl.c (revision 230229) +++ gcc-interface/decl.c (working copy) @@ -1068,14 +1068,12 @@ } /* Make a volatile version of this object's type if we are to make - the object volatile. We also interpret 13.3(19) conservatively - and disallow any optimizations for such a non-constant object. */ + the object volatile. We also implement RM 13.3(19) for exported + and imported (non-constant) objects by making them volatile. */ if ((Treat_As_Volatile (gnat_entity) || (!const_flag && gnu_type != except_type_node - && (Is_Exported (gnat_entity) - || imported_p - || Present (Address_Clause (gnat_entity))))) + && (Is_Exported (gnat_entity) || imported_p))) && !TYPE_VOLATILE (gnu_type)) { const int quals @@ -1118,7 +1116,8 @@ gnu_expr = convert (gnu_type, gnu_expr); /* If this is a pointer that doesn't have an initializing expression, - initialize it to NULL, unless the object is imported. */ + initialize it to NULL, unless the object is declared imported as + per RM B.1(24). */ if (definition && (POINTER_TYPE_P (gnu_type) || TYPE_IS_FAT_POINTER_P (gnu_type)) && !gnu_expr @@ -1141,7 +1140,7 @@ save_gnu_tree (gnat_entity, NULL_TREE, false); /* Convert the type of the object to a reference type that can - alias everything as per 13.3(19). */ + alias everything as per RM 13.3(19). */ gnu_type = build_reference_type_for_mode (gnu_type, ptr_mode, true); gnu_address = convert (gnu_type, gnu_address); @@ -1206,11 +1205,10 @@ as an indirect object. Likewise for Stdcall objects that are imported. */ if ((!definition && Present (Address_Clause (gnat_entity))) - || (Is_Imported (gnat_entity) - && Has_Stdcall_Convention (gnat_entity))) + || (imported_p && Has_Stdcall_Convention (gnat_entity))) { /* Convert the type of the object to a reference type that can - alias everything as per 13.3(19). */ + alias everything as per RM 13.3(19). */ gnu_type = build_reference_type_for_mode (gnu_type, ptr_mode, true); used_by_ref = true; @@ -1402,10 +1400,9 @@ /* If this name is external or a name was specified, use it, but don't use the Interface_Name with an address clause (see cd30005). */ - if ((Present (Interface_Name (gnat_entity)) - && No (Address_Clause (gnat_entity))) - || (Is_Public (gnat_entity) - && (!Is_Imported (gnat_entity) || Is_Exported (gnat_entity)))) + if ((Is_Public (gnat_entity) && !Is_Imported (gnat_entity)) + || (Present (Interface_Name (gnat_entity)) + && No (Address_Clause (gnat_entity)))) gnu_ext_name = create_concat_name (gnat_entity, NULL); /* If this is an aggregate constant initialized to a constant, force it @@ -4618,7 +4615,7 @@ save_gnu_tree (gnat_entity, NULL_TREE, false); /* Convert the type of the object to a reference type that can - alias everything as per 13.3(19). */ + alias everything as per RM 13.3(19). */ gnu_type = build_reference_type_for_mode (gnu_type, ptr_mode, true); if (gnu_address)