annotate gcc/ada/live.adb @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- L I V E --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
9 -- Copyright (C) 2000-2018, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
kono
parents:
diff changeset
17 -- for more details. You should have received a copy of the GNU General --
kono
parents:
diff changeset
18 -- Public License distributed with GNAT; see file COPYING3. If not, go to --
kono
parents:
diff changeset
19 -- http://www.gnu.org/licenses for a complete copy of the license. --
kono
parents:
diff changeset
20 -- --
kono
parents:
diff changeset
21 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
22 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
23 -- --
kono
parents:
diff changeset
24 ------------------------------------------------------------------------------
kono
parents:
diff changeset
25
kono
parents:
diff changeset
26 with Atree; use Atree;
kono
parents:
diff changeset
27 with Einfo; use Einfo;
kono
parents:
diff changeset
28 with Lib; use Lib;
kono
parents:
diff changeset
29 with Nlists; use Nlists;
kono
parents:
diff changeset
30 with Sem_Aux; use Sem_Aux;
kono
parents:
diff changeset
31 with Sem_Util; use Sem_Util;
kono
parents:
diff changeset
32 with Sinfo; use Sinfo;
kono
parents:
diff changeset
33 with Types; use Types;
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 package body Live is
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 -- Name_Set
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39 -- The Name_Set type is used to store the temporary mark bits used by the
kono
parents:
diff changeset
40 -- garbage collection of entities. Using a separate array prevents using up
kono
parents:
diff changeset
41 -- any valuable per-node space and possibly results in better locality and
kono
parents:
diff changeset
42 -- cache usage.
kono
parents:
diff changeset
43
kono
parents:
diff changeset
44 type Name_Set is array (Node_Id range <>) of Boolean;
kono
parents:
diff changeset
45 pragma Pack (Name_Set);
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 function Marked (Marks : Name_Set; Name : Node_Id) return Boolean;
kono
parents:
diff changeset
48 pragma Inline (Marked);
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 procedure Set_Marked
kono
parents:
diff changeset
51 (Marks : in out Name_Set;
kono
parents:
diff changeset
52 Name : Node_Id;
kono
parents:
diff changeset
53 Mark : Boolean := True);
kono
parents:
diff changeset
54 pragma Inline (Set_Marked);
kono
parents:
diff changeset
55
kono
parents:
diff changeset
56 -- Algorithm
kono
parents:
diff changeset
57
kono
parents:
diff changeset
58 -- The problem of finding live entities is solved in two steps:
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 procedure Mark (Root : Node_Id; Marks : out Name_Set);
kono
parents:
diff changeset
61 -- Mark all live entities in Root as Marked
kono
parents:
diff changeset
62
kono
parents:
diff changeset
63 procedure Sweep (Root : Node_Id; Marks : Name_Set);
kono
parents:
diff changeset
64 -- For all unmarked entities in Root set Is_Eliminated to true
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 -- The Mark phase is split into two phases:
kono
parents:
diff changeset
67
kono
parents:
diff changeset
68 procedure Init_Marked (Root : Node_Id; Marks : out Name_Set);
kono
parents:
diff changeset
69 -- For all subprograms, reset Is_Public flag if a pragma Eliminate applies
kono
parents:
diff changeset
70 -- to the entity, and set the Marked flag to Is_Public.
kono
parents:
diff changeset
71
kono
parents:
diff changeset
72 procedure Trace_Marked (Root : Node_Id; Marks : in out Name_Set);
kono
parents:
diff changeset
73 -- Traverse the tree skipping any unmarked subprogram bodies. All visited
kono
parents:
diff changeset
74 -- entities are marked, as well as entities denoted by a visited identifier
kono
parents:
diff changeset
75 -- or operator. When an entity is first marked it is traced as well.
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 -- Local functions
kono
parents:
diff changeset
78
kono
parents:
diff changeset
79 function Body_Of (E : Entity_Id) return Node_Id;
kono
parents:
diff changeset
80 -- Returns subprogram body corresponding to entity E
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 function Spec_Of (N : Node_Id) return Entity_Id;
kono
parents:
diff changeset
83 -- Given a subprogram body N, return defining identifier of its declaration
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 -- ??? the body of this package contains no comments at all, this
kono
parents:
diff changeset
86 -- should be fixed.
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 -------------
kono
parents:
diff changeset
89 -- Body_Of --
kono
parents:
diff changeset
90 -------------
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 function Body_Of (E : Entity_Id) return Node_Id is
kono
parents:
diff changeset
93 Decl : constant Node_Id := Unit_Declaration_Node (E);
kono
parents:
diff changeset
94 Kind : constant Node_Kind := Nkind (Decl);
kono
parents:
diff changeset
95 Result : Node_Id;
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 begin
kono
parents:
diff changeset
98 if Kind = N_Subprogram_Body then
kono
parents:
diff changeset
99 Result := Decl;
kono
parents:
diff changeset
100
kono
parents:
diff changeset
101 elsif Kind /= N_Subprogram_Declaration
kono
parents:
diff changeset
102 and Kind /= N_Subprogram_Body_Stub
kono
parents:
diff changeset
103 then
kono
parents:
diff changeset
104 Result := Empty;
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 else
kono
parents:
diff changeset
107 Result := Corresponding_Body (Decl);
kono
parents:
diff changeset
108
kono
parents:
diff changeset
109 if Result /= Empty then
kono
parents:
diff changeset
110 Result := Unit_Declaration_Node (Result);
kono
parents:
diff changeset
111 end if;
kono
parents:
diff changeset
112 end if;
kono
parents:
diff changeset
113
kono
parents:
diff changeset
114 return Result;
kono
parents:
diff changeset
115 end Body_Of;
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 ------------------------------
kono
parents:
diff changeset
118 -- Collect_Garbage_Entities --
kono
parents:
diff changeset
119 ------------------------------
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 procedure Collect_Garbage_Entities is
kono
parents:
diff changeset
122 Root : constant Node_Id := Cunit (Main_Unit);
kono
parents:
diff changeset
123 Marks : Name_Set (0 .. Last_Node_Id);
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 begin
kono
parents:
diff changeset
126 Mark (Root, Marks);
kono
parents:
diff changeset
127 Sweep (Root, Marks);
kono
parents:
diff changeset
128 end Collect_Garbage_Entities;
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 -----------------
kono
parents:
diff changeset
131 -- Init_Marked --
kono
parents:
diff changeset
132 -----------------
kono
parents:
diff changeset
133
kono
parents:
diff changeset
134 procedure Init_Marked (Root : Node_Id; Marks : out Name_Set) is
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 function Process (N : Node_Id) return Traverse_Result;
kono
parents:
diff changeset
137 procedure Traverse is new Traverse_Proc (Process);
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 -------------
kono
parents:
diff changeset
140 -- Process --
kono
parents:
diff changeset
141 -------------
kono
parents:
diff changeset
142
kono
parents:
diff changeset
143 function Process (N : Node_Id) return Traverse_Result is
kono
parents:
diff changeset
144 begin
kono
parents:
diff changeset
145 case Nkind (N) is
kono
parents:
diff changeset
146 when N_Entity'Range =>
kono
parents:
diff changeset
147 if Is_Eliminated (N) then
kono
parents:
diff changeset
148 Set_Is_Public (N, False);
kono
parents:
diff changeset
149 end if;
kono
parents:
diff changeset
150
kono
parents:
diff changeset
151 Set_Marked (Marks, N, Is_Public (N));
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 when N_Subprogram_Body =>
kono
parents:
diff changeset
154 Traverse (Spec_Of (N));
kono
parents:
diff changeset
155
kono
parents:
diff changeset
156 when N_Package_Body_Stub =>
kono
parents:
diff changeset
157 if Present (Library_Unit (N)) then
kono
parents:
diff changeset
158 Traverse (Proper_Body (Unit (Library_Unit (N))));
kono
parents:
diff changeset
159 end if;
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 when N_Package_Body =>
kono
parents:
diff changeset
162 declare
kono
parents:
diff changeset
163 Elmt : Node_Id := First (Declarations (N));
kono
parents:
diff changeset
164 begin
kono
parents:
diff changeset
165 while Present (Elmt) loop
kono
parents:
diff changeset
166 Traverse (Elmt);
kono
parents:
diff changeset
167 Next (Elmt);
kono
parents:
diff changeset
168 end loop;
kono
parents:
diff changeset
169 end;
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 when others =>
kono
parents:
diff changeset
172 null;
kono
parents:
diff changeset
173 end case;
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 return OK;
kono
parents:
diff changeset
176 end Process;
kono
parents:
diff changeset
177
kono
parents:
diff changeset
178 -- Start of processing for Init_Marked
kono
parents:
diff changeset
179
kono
parents:
diff changeset
180 begin
kono
parents:
diff changeset
181 Marks := (others => False);
kono
parents:
diff changeset
182 Traverse (Root);
kono
parents:
diff changeset
183 end Init_Marked;
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 ----------
kono
parents:
diff changeset
186 -- Mark --
kono
parents:
diff changeset
187 ----------
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 procedure Mark (Root : Node_Id; Marks : out Name_Set) is
kono
parents:
diff changeset
190 begin
kono
parents:
diff changeset
191 Init_Marked (Root, Marks);
kono
parents:
diff changeset
192 Trace_Marked (Root, Marks);
kono
parents:
diff changeset
193 end Mark;
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 ------------
kono
parents:
diff changeset
196 -- Marked --
kono
parents:
diff changeset
197 ------------
kono
parents:
diff changeset
198
kono
parents:
diff changeset
199 function Marked (Marks : Name_Set; Name : Node_Id) return Boolean is
kono
parents:
diff changeset
200 begin
kono
parents:
diff changeset
201 return Marks (Name);
kono
parents:
diff changeset
202 end Marked;
kono
parents:
diff changeset
203
kono
parents:
diff changeset
204 ----------------
kono
parents:
diff changeset
205 -- Set_Marked --
kono
parents:
diff changeset
206 ----------------
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 procedure Set_Marked
kono
parents:
diff changeset
209 (Marks : in out Name_Set;
kono
parents:
diff changeset
210 Name : Node_Id;
kono
parents:
diff changeset
211 Mark : Boolean := True)
kono
parents:
diff changeset
212 is
kono
parents:
diff changeset
213 begin
kono
parents:
diff changeset
214 Marks (Name) := Mark;
kono
parents:
diff changeset
215 end Set_Marked;
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 -------------
kono
parents:
diff changeset
218 -- Spec_Of --
kono
parents:
diff changeset
219 -------------
kono
parents:
diff changeset
220
kono
parents:
diff changeset
221 function Spec_Of (N : Node_Id) return Entity_Id is
kono
parents:
diff changeset
222 begin
kono
parents:
diff changeset
223 if Acts_As_Spec (N) then
kono
parents:
diff changeset
224 return Defining_Entity (N);
kono
parents:
diff changeset
225 else
kono
parents:
diff changeset
226 return Corresponding_Spec (N);
kono
parents:
diff changeset
227 end if;
kono
parents:
diff changeset
228 end Spec_Of;
kono
parents:
diff changeset
229
kono
parents:
diff changeset
230 -----------
kono
parents:
diff changeset
231 -- Sweep --
kono
parents:
diff changeset
232 -----------
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 procedure Sweep (Root : Node_Id; Marks : Name_Set) is
kono
parents:
diff changeset
235
kono
parents:
diff changeset
236 function Process (N : Node_Id) return Traverse_Result;
kono
parents:
diff changeset
237 procedure Traverse is new Traverse_Proc (Process);
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 -------------
kono
parents:
diff changeset
240 -- Process --
kono
parents:
diff changeset
241 -------------
kono
parents:
diff changeset
242
kono
parents:
diff changeset
243 function Process (N : Node_Id) return Traverse_Result is
kono
parents:
diff changeset
244 begin
kono
parents:
diff changeset
245 case Nkind (N) is
kono
parents:
diff changeset
246 when N_Entity'Range =>
kono
parents:
diff changeset
247 Set_Is_Eliminated (N, not Marked (Marks, N));
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 when N_Subprogram_Body =>
kono
parents:
diff changeset
250 Traverse (Spec_Of (N));
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 when N_Package_Body_Stub =>
kono
parents:
diff changeset
253 if Present (Library_Unit (N)) then
kono
parents:
diff changeset
254 Traverse (Proper_Body (Unit (Library_Unit (N))));
kono
parents:
diff changeset
255 end if;
kono
parents:
diff changeset
256
kono
parents:
diff changeset
257 when N_Package_Body =>
kono
parents:
diff changeset
258 declare
kono
parents:
diff changeset
259 Elmt : Node_Id := First (Declarations (N));
kono
parents:
diff changeset
260 begin
kono
parents:
diff changeset
261 while Present (Elmt) loop
kono
parents:
diff changeset
262 Traverse (Elmt);
kono
parents:
diff changeset
263 Next (Elmt);
kono
parents:
diff changeset
264 end loop;
kono
parents:
diff changeset
265 end;
kono
parents:
diff changeset
266
kono
parents:
diff changeset
267 when others =>
kono
parents:
diff changeset
268 null;
kono
parents:
diff changeset
269 end case;
kono
parents:
diff changeset
270
kono
parents:
diff changeset
271 return OK;
kono
parents:
diff changeset
272 end Process;
kono
parents:
diff changeset
273
kono
parents:
diff changeset
274 -- Start of processing for Sweep
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 begin
kono
parents:
diff changeset
277 Traverse (Root);
kono
parents:
diff changeset
278 end Sweep;
kono
parents:
diff changeset
279
kono
parents:
diff changeset
280 ------------------
kono
parents:
diff changeset
281 -- Trace_Marked --
kono
parents:
diff changeset
282 ------------------
kono
parents:
diff changeset
283
kono
parents:
diff changeset
284 procedure Trace_Marked (Root : Node_Id; Marks : in out Name_Set) is
kono
parents:
diff changeset
285
kono
parents:
diff changeset
286 function Process (N : Node_Id) return Traverse_Result;
kono
parents:
diff changeset
287 procedure Process (N : Node_Id);
kono
parents:
diff changeset
288 procedure Traverse is new Traverse_Proc (Process);
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 -------------
kono
parents:
diff changeset
291 -- Process --
kono
parents:
diff changeset
292 -------------
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 procedure Process (N : Node_Id) is
kono
parents:
diff changeset
295 Result : Traverse_Result;
kono
parents:
diff changeset
296 pragma Warnings (Off, Result);
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 begin
kono
parents:
diff changeset
299 Result := Process (N);
kono
parents:
diff changeset
300 end Process;
kono
parents:
diff changeset
301
kono
parents:
diff changeset
302 function Process (N : Node_Id) return Traverse_Result is
kono
parents:
diff changeset
303 Result : Traverse_Result := OK;
kono
parents:
diff changeset
304 B : Node_Id;
kono
parents:
diff changeset
305 E : Entity_Id;
kono
parents:
diff changeset
306
kono
parents:
diff changeset
307 begin
kono
parents:
diff changeset
308 case Nkind (N) is
kono
parents:
diff changeset
309 when N_Generic_Declaration'Range
kono
parents:
diff changeset
310 | N_Pragma
kono
parents:
diff changeset
311 | N_Subprogram_Body_Stub
kono
parents:
diff changeset
312 | N_Subprogram_Declaration
kono
parents:
diff changeset
313 =>
kono
parents:
diff changeset
314 Result := Skip;
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 when N_Subprogram_Body =>
kono
parents:
diff changeset
317 if not Marked (Marks, Spec_Of (N)) then
kono
parents:
diff changeset
318 Result := Skip;
kono
parents:
diff changeset
319 end if;
kono
parents:
diff changeset
320
kono
parents:
diff changeset
321 when N_Package_Body_Stub =>
kono
parents:
diff changeset
322 if Present (Library_Unit (N)) then
kono
parents:
diff changeset
323 Traverse (Proper_Body (Unit (Library_Unit (N))));
kono
parents:
diff changeset
324 end if;
kono
parents:
diff changeset
325
kono
parents:
diff changeset
326 when N_Expanded_Name
kono
parents:
diff changeset
327 | N_Identifier
kono
parents:
diff changeset
328 | N_Operator_Symbol
kono
parents:
diff changeset
329 =>
kono
parents:
diff changeset
330 E := Entity (N);
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 if E /= Empty and then not Marked (Marks, E) then
kono
parents:
diff changeset
333 Process (E);
kono
parents:
diff changeset
334
kono
parents:
diff changeset
335 if Is_Subprogram (E) then
kono
parents:
diff changeset
336 B := Body_Of (E);
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 if B /= Empty then
kono
parents:
diff changeset
339 Traverse (B);
kono
parents:
diff changeset
340 end if;
kono
parents:
diff changeset
341 end if;
kono
parents:
diff changeset
342 end if;
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 when N_Entity'Range =>
kono
parents:
diff changeset
345 if (Ekind (N) = E_Component) and then not Marked (Marks, N) then
kono
parents:
diff changeset
346 if Present (Discriminant_Checking_Func (N)) then
kono
parents:
diff changeset
347 Process (Discriminant_Checking_Func (N));
kono
parents:
diff changeset
348 end if;
kono
parents:
diff changeset
349 end if;
kono
parents:
diff changeset
350
kono
parents:
diff changeset
351 Set_Marked (Marks, N);
kono
parents:
diff changeset
352
kono
parents:
diff changeset
353 when others =>
kono
parents:
diff changeset
354 null;
kono
parents:
diff changeset
355 end case;
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 return Result;
kono
parents:
diff changeset
358 end Process;
kono
parents:
diff changeset
359
kono
parents:
diff changeset
360 -- Start of processing for Trace_Marked
kono
parents:
diff changeset
361
kono
parents:
diff changeset
362 begin
kono
parents:
diff changeset
363 Traverse (Root);
kono
parents:
diff changeset
364 end Trace_Marked;
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 end Live;