1------------------------------------------------------------------------------ 2-- -- 3-- GNAT COMPILER COMPONENTS -- 4-- -- 5-- I N L I N E -- 6-- -- 7-- S p e c -- 8-- -- 9-- Copyright (C) 1992-2015, Free Software Foundation, Inc. -- 10-- -- 11-- GNAT is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 3, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- 17-- for more details. You should have received a copy of the GNU General -- 18-- Public License distributed with GNAT; see file COPYING3. If not, go to -- 19-- http://www.gnu.org/licenses for a complete copy of the license. -- 20-- -- 21-- GNAT was originally developed by the GNAT team at New York University. -- 22-- Extensive contributions were provided by Ada Core Technologies Inc. -- 23-- -- 24------------------------------------------------------------------------------ 25 26-- This module handles four kinds of inlining activity: 27 28-- a) Instantiation of generic bodies. This is done unconditionally, after 29-- analysis and expansion of the main unit. 30 31-- b) Compilation of unit bodies that contain the bodies of inlined sub- 32-- programs. This is done only if inlining is enabled (-gnatn). Full inlining 33-- requires that a) an b) be mutually recursive, because each step may 34-- generate another generic expansion and further inlined calls. For now each 35-- of them uses a workpile algorithm, but they are called independently from 36-- Frontend, and thus are not mutually recursive. 37 38-- c) Front-end inlining for Inline_Always subprograms. This is primarily an 39-- expansion activity that is performed for performance reasons, and when the 40-- target does not use the gcc backend. 41 42-- d) Front-end inlining for GNATprove, to perform source transformations 43-- to simplify formal verification. The machinery used is the same than for 44-- Inline_Always subprograms, but there are fewer restrictions on the source 45-- of subprograms. 46 47with Alloc; 48with Opt; use Opt; 49with Sem; use Sem; 50with Table; 51with Types; use Types; 52with Warnsw; use Warnsw; 53 54package Inline is 55 56 -------------------------------- 57 -- Generic Body Instantiation -- 58 -------------------------------- 59 60 -- The bodies of generic instantiations are built after semantic analysis 61 -- of the main unit is complete. Generic instantiations are saved in a 62 -- global data structure, and the bodies constructed by means of a separate 63 -- analysis and expansion step. 64 65 -- See full description in body of Sem_Ch12 for more details 66 67 type Pending_Body_Info is record 68 Inst_Node : Node_Id; 69 -- Node for instantiation that requires the body 70 71 Act_Decl : Node_Id; 72 -- Declaration for package or subprogram spec for instantiation 73 74 Expander_Status : Boolean; 75 -- If the body is instantiated only for semantic checking, expansion 76 -- must be inhibited. 77 78 Current_Sem_Unit : Unit_Number_Type; 79 -- The semantic unit within which the instantiation is found. Must 80 -- be restored when compiling the body, to insure that internal enti- 81 -- ties use the same counter and are unique over spec and body. 82 83 Scope_Suppress : Suppress_Record; 84 Local_Suppress_Stack_Top : Suppress_Stack_Entry_Ptr; 85 -- Save suppress information at the point of instantiation. Used to 86 -- properly inherit check status active at this point (see RM 11.5 87 -- (7.2/2), AI95-00224-01): 88 -- 89 -- "If a checking pragma applies to a generic instantiation, then the 90 -- checking pragma also applies to the instance. If a checking pragma 91 -- applies to a call to a subprogram that has a pragma Inline applied 92 -- to it, then the checking pragma also applies to the inlined 93 -- subprogram body". 94 -- 95 -- This means we have to capture this information from the current scope 96 -- at the point of instantiation. 97 98 Version : Ada_Version_Type; 99 -- The body must be compiled with the same language version as the 100 -- spec. The version may be set by a configuration pragma in a separate 101 -- file or in the current file, and may differ from body to body. 102 103 Version_Pragma : Node_Id; 104 -- This is linked with the Version value 105 106 Warnings : Warning_Record; 107 -- Capture values of warning flags 108 109 SPARK_Mode : SPARK_Mode_Type; 110 SPARK_Mode_Pragma : Node_Id; 111 -- SPARK_Mode for an instance is the one applicable at the point of 112 -- instantiation. SPARK_Mode_Pragma is the related active pragma. 113 end record; 114 115 package Pending_Instantiations is new Table.Table ( 116 Table_Component_Type => Pending_Body_Info, 117 Table_Index_Type => Int, 118 Table_Low_Bound => 0, 119 Table_Initial => Alloc.Pending_Instantiations_Initial, 120 Table_Increment => Alloc.Pending_Instantiations_Increment, 121 Table_Name => "Pending_Instantiations"); 122 123 -- The following table records subprograms and packages for which 124 -- generation of subprogram descriptors must be delayed. 125 126 package Pending_Descriptor is new Table.Table ( 127 Table_Component_Type => Entity_Id, 128 Table_Index_Type => Int, 129 Table_Low_Bound => 0, 130 Table_Initial => Alloc.Pending_Instantiations_Initial, 131 Table_Increment => Alloc.Pending_Instantiations_Increment, 132 Table_Name => "Pending_Descriptor"); 133 134 -- The following should be initialized in an init call in Frontend, we 135 -- have thoughts of making the frontend reusable in future ??? 136 137 ----------------- 138 -- Subprograms -- 139 ----------------- 140 141 procedure Initialize; 142 -- Initialize internal tables 143 144 procedure Lock; 145 -- Lock internal tables before calling backend 146 147 procedure Instantiate_Bodies; 148 -- This procedure is called after semantic analysis is complete, to 149 -- instantiate the bodies of generic instantiations that appear in the 150 -- compilation unit. 151 152 procedure Add_Inlined_Body (E : Entity_Id; N : Node_Id); 153 -- E is an inlined subprogram appearing in a call, either explicitly or in 154 -- a discriminant check for which gigi builds a call or an at-end handler. 155 -- Add E's enclosing unit to Inlined_Bodies so that E can be subsequently 156 -- retrieved and analyzed. N is the node giving rise to the call to E. 157 158 procedure Analyze_Inlined_Bodies; 159 -- At end of compilation, analyze the bodies of all units that contain 160 -- inlined subprograms that are actually called. 161 162 procedure Build_Body_To_Inline (N : Node_Id; Spec_Id : Entity_Id); 163 -- If a subprogram has pragma Inline and inlining is active, use generic 164 -- machinery to build an unexpanded body for the subprogram. This body is 165 -- subsequently used for inline expansions at call sites. If subprogram can 166 -- be inlined (depending on size and nature of local declarations) the 167 -- template body is created. Otherwise subprogram body is treated normally 168 -- and calls are not inlined in the frontend. If proper warnings are 169 -- enabled and the subprogram contains a construct that cannot be inlined, 170 -- the problematic construct is flagged accordingly. 171 172 procedure Cannot_Inline 173 (Msg : String; 174 N : Node_Id; 175 Subp : Entity_Id; 176 Is_Serious : Boolean := False); 177 -- This procedure is called if the node N, an instance of a call to 178 -- subprogram Subp, cannot be inlined. Msg is the message to be issued, 179 -- which ends with ? (it does not end with ?p?, this routine takes care of 180 -- the need to change ? to ?p?). The behavior of this routine depends on 181 -- the value of Back_End_Inlining: 182 -- 183 -- * If Back_End_Inlining is not set (ie. legacy frontend inlining model) 184 -- then if Subp has a pragma Always_Inlined, then an error message is 185 -- issued (by removing the last character of Msg). If Subp is not 186 -- Always_Inlined, then a warning is issued if the flag Ineffective_ 187 -- Inline_Warnings is set, adding ?p to the msg, and if not, the call 188 -- has no effect. 189 -- 190 -- * If Back_End_Inlining is set then: 191 -- - If Is_Serious is true, then an error is reported (by removing the 192 -- last character of Msg); 193 -- 194 -- - otherwise: 195 -- 196 -- * Compiling without optimizations if Subp has a pragma 197 -- Always_Inlined, then an error message is issued; if Subp is 198 -- not Always_Inlined, then a warning is issued if the flag 199 -- Ineffective_Inline_Warnings is set (adding p?), and if not, 200 -- the call has no effect. 201 -- 202 -- * Compiling with optimizations then a warning is issued if the 203 -- flag Ineffective_Inline_Warnings is set (adding p?); otherwise 204 -- no effect since inlining may be performed by the backend. 205 206 procedure Check_And_Split_Unconstrained_Function 207 (N : Node_Id; 208 Spec_Id : Entity_Id; 209 Body_Id : Entity_Id); 210 -- Spec_Id and Body_Id are the entities of the specification and body of 211 -- the subprogram body N. If N can be inlined by the frontend (supported 212 -- cases documented in Check_Body_To_Inline) then build the body-to-inline 213 -- associated with N and attach it to the declaration node of Spec_Id. 214 215 procedure Check_Package_Body_For_Inlining (N : Node_Id; P : Entity_Id); 216 -- If front-end inlining is enabled and a package declaration contains 217 -- inlined subprograms, load and compile the package body to collect the 218 -- bodies of these subprograms, so they are available to inline calls. 219 -- N is the compilation unit for the package. 220 221 procedure Expand_Inlined_Call 222 (N : Node_Id; 223 Subp : Entity_Id; 224 Orig_Subp : Entity_Id); 225 -- If called subprogram can be inlined by the front-end, retrieve the 226 -- analyzed body, replace formals with actuals and expand call in place. 227 -- Generate thunks for actuals that are expressions, and insert the 228 -- corresponding constant declarations before the call. If the original 229 -- call is to a derived operation, the return type is the one of the 230 -- derived operation, but the body is that of the original, so return 231 -- expressions in the body must be converted to the desired type (which 232 -- is simply not noted in the tree without inline expansion). 233 234 function Has_Excluded_Declaration 235 (Subp : Entity_Id; 236 Decls : List_Id) return Boolean; 237 -- Check a list of declarations, Decls, that make the inlining of Subp not 238 -- worthwhile 239 240 function Has_Excluded_Statement 241 (Subp : Entity_Id; 242 Stats : List_Id) return Boolean; 243 -- Check a list of statements, Stats, that make inlining of Subp not 244 -- worthwhile, including any tasking statement, nested at any level. 245 246 procedure List_Inlining_Info; 247 -- Generate listing of calls inlined by the frontend plus listing of 248 -- calls to inline subprograms passed to the backend. 249 250 procedure Remove_Dead_Instance (N : Node_Id); 251 -- If an instantiation appears in unreachable code, delete the pending 252 -- body instance. 253 254 function Can_Be_Inlined_In_GNATprove_Mode 255 (Spec_Id : Entity_Id; 256 Body_Id : Entity_Id) return Boolean; 257 -- Returns True if the subprogram identified by Spec_Id and Body_Id can 258 -- be inlined in GNATprove mode. One but not both of Spec_Id and Body_Id 259 -- can be Empty. Body_Id is Empty when doing a partial check on a call 260 -- to a subprogram whose body has not been seen yet, to know whether this 261 -- subprogram could possibly be inlined. GNATprove relies on this to adapt 262 -- its treatment of the subprogram. 263 264end Inline; 265