From patchwork Mon Aug 19 08:38:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pierre-Marie de Rodat X-Patchwork-Id: 1149105 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-507218-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="M8OLXRfP"; dkim-atps=neutral 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 46BnRP3r45z9s3Z for ; Mon, 19 Aug 2019 18:39:45 +1000 (AEST) 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=Dgs3aDo/1CqbHpupflRIDf74grFwlZ/Hk+sb9vH8Kz5RX55JoJ FPo7NqfMn6E+E5b1AfFVBoYYREB0cyfU9m2803ZLtn2pnfb7CHibjz3Tfi30fAQI YmeWdStBokeE7fsPv5NZmB8hjgeCHXFALg9bAVw9Yr8Lz7N6rKDwRhNDQ= 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=5cUcyyhdpRW62og4WntK/I7YDsg=; b=M8OLXRfPA+06hpWkGiYW 1LvkOASu0ByPFgXCpFYMLH0PkW62+bofo6iMA+Breu0QIYyR0XCn4jAkwFr5b9Wd dWCcNSHZxr9XjSGbqLXiAbzwUl2ERdmoe747vuTRdQO5dPcGq/4sYxEpGUQWAEmO Nz+NELN9EzAhMsoKyEEVKSc= Received: (qmail 115059 invoked by alias); 19 Aug 2019 08:39:03 -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 114968 invoked by uid 89); 19 Aug 2019 08:39:03 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=former, demand, specifications, sk:corresp 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; Mon, 19 Aug 2019 08:39:00 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id 5DBE01161CE; Mon, 19 Aug 2019 04:38:59 -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 1IBDlHvtvnEW; Mon, 19 Aug 2019 04:38:59 -0400 (EDT) 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 4848011619A; Mon, 19 Aug 2019 04:38:59 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4862) id 472E66AB; Mon, 19 Aug 2019 04:38:59 -0400 (EDT) Date: Mon, 19 Aug 2019 04:38:59 -0400 From: Pierre-Marie de Rodat To: gcc-patches@gcc.gnu.org Cc: Eric Botcazou Subject: [Ada] Further cleanup in inlining machinery Message-ID: <20190819083858.GA33339@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes This gets rid of a small issue in the inlining machinery: under very peculiar circumstances, it would add a pending instantiation for the body of a generic package at the point of call to an inlined subprogram of the instance. That's theoritically problematic because the saved context is that of the call and not that of the instance in this case, although the strict conditions ensure that this doesn't make a real difference in practice. Now that the machinery can perform the pending instantiations on demand, we can optimistically add more of them when the instantiations are analyzed and thus remove the problematic handling at the point of call. No functional changes. Tested on x86_64-pc-linux-gnu, committed on trunk 2019-08-19 Eric Botcazou gcc/ada/ * inline.adb (Add_Inlined_Body): Do not add pending instantiations. * sem_ch12.adb (Needs_Body_Instantiated): New predicate. (Analyze_Package_Instantiation): Use it to decide whether to add a pending instantiation for the body of the package. --- gcc/ada/inline.adb +++ gcc/ada/inline.adb @@ -510,7 +510,6 @@ package body Inline is Inst : Entity_Id; Inst_Decl : Node_Id; - Inst_Node : Node_Id; Level : Inline_Level_Type; -- Start of processing for Add_Inlined_Body @@ -609,48 +608,24 @@ package body Inline is and then Is_Generic_Instance (Inst) and then not Is_Called (Inst) then - -- Do not add a pending instantiation if the body exits - -- already, or if the instance is a compilation unit, or - -- the instance node is missing. - Inst_Decl := Unit_Declaration_Node (Inst); + + -- Do not inline the instance if the body already exists, + -- or if the instance is a compilation unit, or else if + -- the instance node is simply missing. + if Present (Corresponding_Body (Inst_Decl)) or else Nkind (Parent (Inst_Decl)) = N_Compilation_Unit or else No (Next (Inst_Decl)) then Set_Is_Called (Inst); - else - -- If the inlined call itself appears within an instance, - -- ensure that the enclosing instance body is available. - -- This is necessary because Sem_Ch12.Might_Inline_Subp - -- does not recurse into nested instantiations. - - if not Is_Inlined (Inst) and then In_Instance then - Set_Is_Inlined (Inst); - - -- The instantiation node usually follows the package - -- declaration for the instance. If the generic unit - -- has aspect specifications, they are transformed - -- into pragmas in the instance, and the instance node - -- appears after them. - - Inst_Node := Next (Inst_Decl); - - while Nkind (Inst_Node) /= N_Package_Instantiation loop - Inst_Node := Next (Inst_Node); - end loop; - - Add_Pending_Instantiation (Inst_Node, Inst_Decl); - end if; - Add_Inlined_Instance (Inst); end if; end if; end if; - -- If the unit containing E is an instance, then the instance body - -- will be analyzed in any case, see Sem_Ch12.Might_Inline_Subp. + -- If the unit containing E is an instance, nothing more to do if Is_Generic_Instance (Pack) then null; --- gcc/ada/sem_ch12.adb +++ gcc/ada/sem_ch12.adb @@ -240,6 +240,10 @@ package body Sem_Ch12 is -- circularity is detected, and used to abandon compilation after the -- messages have been posted. + Circularity_Detected : Boolean := False; + -- It should really be reset upon encountering a new main unit, but in + -- practice we do not use multiple main units so this is not critical. + ----------------------------------------- -- Implementation of Generic Contracts -- ----------------------------------------- @@ -352,10 +356,6 @@ package body Sem_Ch12 is -- Instantiate_Subprogram_Contract - Circularity_Detected : Boolean := False; - -- This should really be reset on encountering a new main unit, but in - -- practice we are not using multiple main units so it is not critical. - -------------------------------------------------- -- Formal packages and partial parameterization -- -------------------------------------------------- @@ -380,23 +380,23 @@ package body Sem_Ch12 is -- the generic package, and a set of declarations that map the actuals -- into local renamings, just as we do for bona fide instantiations. For -- defaulted parameters and formals with a box, we copy directly the - -- declarations of the formal into this local package. The result is a - -- a package whose visible declarations may include generic formals. This + -- declarations of the formals into this local package. The result is a + -- package whose visible declarations may include generic formals. This -- package is only used for type checking and visibility analysis, and - -- never reaches the back-end, so it can freely violate the placement + -- never reaches the back end, so it can freely violate the placement -- rules for generic formal declarations. -- The list of declarations (renamings and copies of formals) is built -- by Analyze_Associations, just as for regular instantiations. -- At the point of instantiation, conformance checking must be applied only - -- to those parameters that were specified in the formal. We perform this + -- to those parameters that were specified in the formals. We perform this -- checking by creating another internal instantiation, this one including -- only the renamings and the formals (the rest of the package spec is not -- relevant to conformance checking). We can then traverse two lists: the -- list of actuals in the instance that corresponds to the formal package, -- and the list of actuals produced for this bogus instantiation. We apply - -- the conformance rules to those actuals that are not defaulted (i.e. + -- the conformance rules to those actuals that are not defaulted, i.e. -- which still appear as generic formals. -- When we compile an instance body we must make the right parameters @@ -3849,12 +3849,17 @@ package body Sem_Ch12 is -- Only relevant when back-end inlining is not enabled. function Might_Inline_Subp (Gen_Unit : Entity_Id) return Boolean; - -- If inlining is active and the generic contains inlined subprograms, - -- we either instantiate the body when front-end inlining is enabled, - -- or we add a pending instantiation when back-end inlining is enabled. - -- In the former case, this may cause superfluous instantiations, but - -- in either case we need to perform the instantiation of the body in - -- the context of the instance and not in that of the point of inlining. + -- Return True if inlining is active and Gen_Unit contains inlined + -- subprograms. In this case, we may either instantiate the body when + -- front-end inlining is enabled, or add a pending instantiation when + -- back-end inlining is enabled. In the former case, this may cause + -- superfluous instantiations, but in either case we need to perform + -- the instantiation of the body in the context of the instance and + -- not in that of the point of inlining. + + function Needs_Body_Instantiated (Gen_Unit : Entity_Id) return Boolean; + -- Return True if Gen_Unit needs to have its body instantiated in the + -- context of N. This in particular excludes generic contexts. ----------------------- -- Might_Inline_Subp -- @@ -3892,6 +3897,52 @@ package body Sem_Ch12 is return False; end Might_Inline_Subp; + ------------------------------- + -- Needs_Body_Instantiated -- + ------------------------------- + + function Needs_Body_Instantiated (Gen_Unit : Entity_Id) return Boolean is + begin + -- No need to instantiate bodies in generic units + + if Is_Generic_Unit (Cunit_Entity (Main_Unit)) then + return False; + end if; + + -- If the instantiation is in the main unit, then the body is needed + + if Is_In_Main_Unit (N) then + return True; + end if; + + -- If not, then again no need to instantiate bodies in generic units + + if Is_Generic_Unit (Cunit_Entity (Get_Code_Unit (N))) then + return False; + end if; + + -- Here we have a special handling for back-end inlining: if the + -- instantiation is not a compilation unit, then we want to have + -- its body instantiated. The reason is that Might_Inline_Subp + -- does not catch all the cases (since it does not recurse into + -- nested packages) so this avoids the need to patch things up + -- at a later stage. Moreover the instantiations that are not + -- compilation units are only performed on demand when back-end + -- inlining is enabled, so this causes very little extra work. + + if Nkind (Parent (N)) /= N_Compilation_Unit + and then Inline_Processing_Required + and then Back_End_Inlining + then + return True; + end if; + + -- We want to have the bodies instantiated in non-main units if + -- they might contribute inlined subprograms. + + return Might_Inline_Subp (Gen_Unit); + end Needs_Body_Instantiated; + -- Local declarations Gen_Id : constant Node_Id := Name (N); @@ -4256,9 +4307,7 @@ package body Sem_Ch12 is end if; -- Save the instantiation node for a subsequent instantiation of the - -- body if there is one and the main unit is not generic, and either - -- we are generating code for this main unit, or the instantiation - -- contains inlined subprograms and is not done in a generic unit. + -- body if there is one and it needs to be instantiated here. -- We instantiate the body only if we are generating code, or if we -- are generating cross-reference information, or if we are building @@ -4354,12 +4403,7 @@ package body Sem_Ch12 is (Unit_Requires_Body (Gen_Unit) or else Enclosing_Body_Present or else Present (Corresponding_Body (Gen_Decl))) - and then not Is_Generic_Unit (Cunit_Entity (Main_Unit)) - and then (Is_In_Main_Unit (N) - or else (Might_Inline_Subp (Gen_Unit) - and then - not Is_Generic_Unit - (Cunit_Entity (Get_Code_Unit (N))))) + and then Needs_Body_Instantiated (Gen_Unit) and then not Is_Actual_Pack and then not Inline_Now and then (Operating_Mode = Generate_Code