Branch data Line data Source code
1 : : // Implementation of private inline member functions for RTL SSA -*- C++ -*-
2 : : // Copyright (C) 2020-2024 Free Software Foundation, Inc.
3 : : //
4 : : // This file is part of GCC.
5 : : //
6 : : // GCC is free software; you can redistribute it and/or modify it under
7 : : // the terms of the GNU General Public License as published by the Free
8 : : // Software Foundation; either version 3, or (at your option) any later
9 : : // version.
10 : : //
11 : : // GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : // WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : // for more details.
15 : : //
16 : : // You should have received a copy of the GNU General Public License
17 : : // along with GCC; see the file COPYING3. If not see
18 : : // <http://www.gnu.org/licenses/>.
19 : :
20 : : namespace rtl_ssa {
21 : :
22 : : // Construct a new access with the given resource () and kind () values.
23 : 520236055 : inline access_info::access_info (resource_info resource, access_kind kind)
24 : 520236055 : : m_regno (resource.regno),
25 : 520236055 : m_mode (resource.mode),
26 : 520236055 : m_kind (kind),
27 : 325833407 : m_is_artificial (false),
28 : 520236055 : m_is_set_with_nondebug_insn_uses (false),
29 : 520236055 : m_is_pre_post_modify (false),
30 : 520236055 : m_is_call_clobber (false),
31 : 520236055 : m_is_live_out_use (false),
32 : 520236055 : m_includes_address_uses (false),
33 : 520236055 : m_includes_read_writes (false),
34 : 520236055 : m_includes_subregs (false),
35 : 520236055 : m_includes_multiregs (false),
36 : 520236055 : m_only_occurs_in_notes (false),
37 : 520236055 : m_is_last_nondebug_insn_use (false),
38 : 194402648 : m_is_in_debug_insn_or_phi (false),
39 : 520236055 : m_has_been_superceded (false),
40 : 520236055 : m_is_temp (false)
41 : : {
42 : : }
43 : :
44 : : // Construct a use of RESOURCE in LOCATION. The resource's value is provided
45 : : // by DEF, or is completely undefined if DEF is null.
46 : 325833407 : inline use_info::use_info (insn_or_phi location, resource_info resource,
47 : 325833407 : set_info *definition)
48 : : : access_info (resource, access_kind::USE),
49 : 325833407 : m_insn_or_phi (location),
50 : 325833407 : m_last_use_or_prev_use (nullptr),
51 : 325833407 : m_last_nondebug_insn_use_or_next_use (nullptr),
52 : 325833407 : m_def (definition)
53 : : {
54 : 325833407 : if (m_insn_or_phi.is_second ())
55 : : {
56 : 44216373 : m_is_in_debug_insn_or_phi = true;
57 : 44216373 : m_is_artificial = true;
58 : : }
59 : : else
60 : : {
61 : 281617034 : insn_info *insn = m_insn_or_phi.known_first ();
62 : 281617034 : m_is_in_debug_insn_or_phi = insn->is_debug_insn ();
63 : 281617034 : m_is_artificial = insn->is_artificial ();
64 : : }
65 : 325833407 : }
66 : :
67 : : // Return the correct (uncached) value of m_is_last_nondebug_insn_use.
68 : : inline bool
69 : 875297273 : use_info::calculate_is_last_nondebug_insn_use () const
70 : : {
71 : 875297273 : use_info *next = next_use ();
72 : 875297273 : return is_in_nondebug_insn () && (!next || next->is_in_debug_insn_or_phi ());
73 : : }
74 : :
75 : : // Accumulate any properties about REF that are also stored in use_infos.
76 : : // IS_FIRST is true if REF is the first access to resource () that we have
77 : : // recorded in this way, false if we have already recorded previous
78 : : // references.
79 : : inline void
80 : 186943926 : use_info::record_reference (rtx_obj_reference ref, bool is_first)
81 : : {
82 : 186943926 : if (is_first)
83 : : {
84 : 171438086 : m_includes_address_uses = ref.in_address ();
85 : 171438086 : m_includes_read_writes = ref.is_write ();
86 : 171438086 : m_includes_subregs = ref.in_subreg ();
87 : 171438086 : m_includes_multiregs = ref.is_multireg ();
88 : 171438086 : m_only_occurs_in_notes = ref.in_note ();
89 : : }
90 : : else
91 : : {
92 : 15505840 : m_includes_address_uses |= ref.in_address ();
93 : 15505840 : m_includes_read_writes |= ref.is_write ();
94 : 15505840 : m_includes_subregs |= ref.in_subreg ();
95 : 15505840 : m_includes_multiregs |= ref.is_multireg ();
96 : 15505840 : m_only_occurs_in_notes &= ref.in_note ();
97 : : }
98 : 186943926 : }
99 : :
100 : : // Change the value of insn () to INSN.
101 : : inline void
102 : : use_info::set_insn (insn_info *insn)
103 : : {
104 : : m_insn_or_phi = insn;
105 : : m_is_artificial = insn->is_artificial ();
106 : : }
107 : :
108 : : // Copy the overloaded prev link from OTHER.
109 : : inline void
110 : 8843550 : use_info::copy_prev_from (use_info *other)
111 : : {
112 : 5600188 : m_last_use_or_prev_use = other->m_last_use_or_prev_use;
113 : 3243362 : }
114 : :
115 : : // Copy the overloaded next link from OTHER.
116 : : inline void
117 : 191732854 : use_info::copy_next_from (use_info *other)
118 : : {
119 : 191732854 : m_last_nondebug_insn_use_or_next_use
120 : 191732854 : = other->m_last_nondebug_insn_use_or_next_use;
121 : 186516725 : m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
122 : 5216129 : }
123 : :
124 : : // Record that this use is the first in the list and that the last use is LAST.
125 : : inline void
126 : 299368034 : use_info::set_last_use (use_info *last_use)
127 : : {
128 : 299368034 : m_last_use_or_prev_use.set_first (last_use);
129 : 132959423 : }
130 : :
131 : : // Record that this use is not the first in the list and that the previous
132 : : // use is PREV.
133 : : inline void
134 : 218068674 : use_info::set_prev_use (use_info *prev_use)
135 : : {
136 : 218068674 : m_last_use_or_prev_use.set_second (prev_use);
137 : 25951761 : }
138 : :
139 : : // Record that this use is the last use in the list. If USE is nonnull,
140 : : // record that USE is the last use in the list by a nondebug instruction,
141 : : // otherwise record that there are no uses by nondebug instructions
142 : : // in the list.
143 : : inline void
144 : 263195276 : use_info::set_last_nondebug_insn_use (use_info *use)
145 : : {
146 : 263195276 : m_last_nondebug_insn_use_or_next_use.set_first (use);
147 : 263195276 : m_is_last_nondebug_insn_use = (use == this);
148 : 263195276 : }
149 : :
150 : : // Record that this use is not the last in the list and that the next
151 : : // use is NEXT_USE.
152 : : inline void
153 : 192487031 : use_info::set_next_use (use_info *next_use)
154 : : {
155 : 192487031 : m_last_nondebug_insn_use_or_next_use.set_second (next_use);
156 : 192487031 : m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
157 : 192487031 : }
158 : :
159 : : // Clear any information relating to the position of the use in its
160 : : // definition's list.
161 : : inline void
162 : 9650091 : use_info::clear_use_links ()
163 : : {
164 : 9650091 : m_last_use_or_prev_use = nullptr;
165 : 9650091 : m_last_nondebug_insn_use_or_next_use = nullptr;
166 : 9650091 : m_is_last_nondebug_insn_use = false;
167 : : }
168 : :
169 : : // Return true if the use has any links to other uses. This is mostly
170 : : // for assert checking.
171 : : inline bool
172 : 499522361 : use_info::has_use_links ()
173 : : {
174 : 499522361 : return (m_last_use_or_prev_use
175 : 499522361 : || m_last_nondebug_insn_use_or_next_use
176 : 999044722 : || m_is_last_nondebug_insn_use);
177 : : }
178 : :
179 : : // Construct a definition of RESOURCE in INSN, giving it kind KIND.
180 : 194402648 : inline def_info::def_info (insn_info *insn, resource_info resource,
181 : 194402648 : access_kind kind)
182 : : : access_info (resource, kind),
183 : 194402648 : m_insn (insn),
184 : 194402648 : m_last_def_or_prev_def (nullptr),
185 : 194402648 : m_splay_root_or_next_def (nullptr)
186 : : {
187 : 194402648 : m_is_artificial = insn->is_artificial ();
188 : 194402648 : }
189 : :
190 : : // Record any properties about REF that are also stored in def_infos.
191 : : // IS_FIRST is true if REF is the first access to resource () that we have
192 : : // recorded in this way, false if we have already recorded previous
193 : : // references.
194 : : inline void
195 : 128937699 : def_info::record_reference (rtx_obj_reference ref, bool is_first)
196 : : {
197 : 128937699 : if (is_first)
198 : : {
199 : 128934940 : m_is_pre_post_modify = ref.is_pre_post_modify ();
200 : 128934940 : m_includes_read_writes = ref.is_read ();
201 : 128934940 : m_includes_subregs = ref.in_subreg ();
202 : 128934940 : m_includes_multiregs = ref.is_multireg ();
203 : : }
204 : : else
205 : : {
206 : 2759 : m_is_pre_post_modify |= ref.is_pre_post_modify ();
207 : 2759 : m_includes_read_writes |= ref.is_read ();
208 : 2759 : m_includes_subregs |= ref.in_subreg ();
209 : 2759 : m_includes_multiregs |= ref.is_multireg ();
210 : : }
211 : 128937699 : }
212 : :
213 : : // Return the last definition in the list. Only valid when is_first ()
214 : : // is true.
215 : : inline def_info *
216 : 148053013 : def_info::last_def () const
217 : : {
218 : 148053013 : return m_last_def_or_prev_def.known_first ();
219 : : }
220 : :
221 : : // Return the root of the splay tree of definitions of resource (),
222 : : // or null if no splay tree has been created for this resource.
223 : : // Only valid when is_last () is true.
224 : : inline def_node *
225 : 129514385 : def_info::splay_root () const
226 : : {
227 : 129514385 : return m_splay_root_or_next_def.known_first ();
228 : : }
229 : :
230 : : // Copy the overloaded prev link from OTHER.
231 : : inline void
232 : 1794425 : def_info::copy_prev_from (def_info *other)
233 : : {
234 : 1794425 : m_last_def_or_prev_def
235 : 162317 : = other->m_last_def_or_prev_def;
236 : 1632108 : }
237 : :
238 : : // Copy the overloaded next link from OTHER.
239 : : inline void
240 : 30855039 : def_info::copy_next_from (def_info *other)
241 : : {
242 : 27212939 : m_splay_root_or_next_def = other->m_splay_root_or_next_def;
243 : 3642100 : }
244 : :
245 : : // Record that this definition is the first in the list and that the last
246 : : // definition is LAST.
247 : : inline void
248 : 194769239 : def_info::set_last_def (def_info *last_def)
249 : : {
250 : 194769239 : m_last_def_or_prev_def.set_first (last_def);
251 : 126529823 : }
252 : :
253 : : // Record that this definition is not the first in the list and that the
254 : : // previous definition is PREV.
255 : : inline void
256 : 125067600 : def_info::set_prev_def (def_info *prev_def)
257 : : {
258 : 125067600 : m_last_def_or_prev_def.set_second (prev_def);
259 : 260677 : }
260 : :
261 : : // Record that this definition is the last in the list and that the root
262 : : // of the splay tree associated with resource () is ROOT.
263 : : inline void
264 : 1639678 : def_info::set_splay_root (def_node *root)
265 : : {
266 : 1639678 : m_splay_root_or_next_def = root;
267 : 34055 : }
268 : :
269 : : // Record that this definition is not the last in the list and that the
270 : : // next definition is NEXT.
271 : : inline void
272 : 125060415 : def_info::set_next_def (def_info *next_def)
273 : : {
274 : 124913334 : m_splay_root_or_next_def = next_def;
275 : 253492 : }
276 : :
277 : : // Clear the prev and next links
278 : : inline void
279 : 3660871 : def_info::clear_def_links ()
280 : : {
281 : 3530 : m_last_def_or_prev_def = nullptr;
282 : 3530 : m_splay_root_or_next_def = nullptr;
283 : : }
284 : :
285 : : // Return true if the definition has any links to other definitions.
286 : : // This is mostly for assert checking.
287 : : inline bool
288 : 220421595 : def_info::has_def_links ()
289 : : {
290 : 220421595 : return m_last_def_or_prev_def || m_splay_root_or_next_def;
291 : : }
292 : :
293 : : // Construct a clobber of register REGNO in insn INSN.
294 : 44555404 : inline clobber_info::clobber_info (insn_info *insn, unsigned int regno)
295 : : : def_info (insn, { E_BLKmode, regno }, access_kind::CLOBBER),
296 : 133666212 : m_children (),
297 : 44555404 : m_parent (nullptr),
298 : 44555404 : m_group (nullptr)
299 : : {
300 : 44555404 : }
301 : :
302 : : // Set the containing group to GROUP, if it isn't already. The main
303 : : // use of this function is to update the new root of GROUP's splay tree.
304 : : inline void
305 : 383496 : clobber_info::update_group (clobber_group *group)
306 : : {
307 : 383496 : if (UNLIKELY (m_group != group))
308 : 0 : m_group = group;
309 : : }
310 : :
311 : : // Cconstruct a set_info for a store to RESOURCE in INSN, giving it
312 : : // kind KIND.
313 : 149847244 : inline set_info::set_info (insn_info *insn, resource_info resource,
314 : 149847244 : access_kind kind)
315 : : : def_info (insn, resource, kind),
316 : 299694488 : m_first_use (nullptr)
317 : : {
318 : : }
319 : :
320 : : // Cconstruct a set_info for a store to RESOURCE in INSN.
321 : 122694648 : inline set_info::set_info (insn_info *insn, resource_info resource)
322 : 122694648 : : set_info (insn, resource, access_kind::SET)
323 : : {
324 : 122694648 : }
325 : :
326 : : // Record that USE is the first use of this definition.
327 : : inline void
328 : 142060373 : set_info::set_first_use (use_info *first_use)
329 : : {
330 : 142060373 : m_first_use = first_use;
331 : 137626411 : m_is_set_with_nondebug_insn_uses
332 : 161528232 : = (first_use && first_use->is_in_nondebug_insn ());
333 : 9664032 : }
334 : :
335 : : // Construct a phi for RESOURCE in INSN, giving it identifier UID.
336 : 27152596 : inline phi_info::phi_info (insn_info *insn, resource_info resource,
337 : 27152596 : unsigned int uid)
338 : : : set_info (insn, resource, access_kind::PHI),
339 : 27152596 : m_uid (uid),
340 : 27152596 : m_num_inputs (0),
341 : 27152596 : m_prev_phi (nullptr),
342 : 27152596 : m_next_phi (nullptr)
343 : : {
344 : 27152596 : }
345 : :
346 : : // Turn the phi into a degenerate phi, with INPUT representing the
347 : : // value of the resource on all incoming edges.
348 : : inline void
349 : 462868 : phi_info::make_degenerate (use_info *input)
350 : : {
351 : 462868 : m_num_inputs = 1;
352 : 462868 : m_single_input = input;
353 : 342207 : }
354 : :
355 : : // Set the inputs of the phi to INPUTS.
356 : : inline void
357 : 27031935 : phi_info::set_inputs (use_array inputs)
358 : : {
359 : 27031935 : m_num_inputs = inputs.size ();
360 : 27031935 : if (inputs.size () == 1)
361 : 17647649 : m_single_input = inputs[0];
362 : : else
363 : 9384286 : m_inputs = access_array (inputs).begin ();
364 : 27031935 : }
365 : :
366 : : // Construct a definition splay tree node for FIRST_DEF, which is either
367 : : // the first clobber_info in a group or a standalone set_info.
368 : 14645728 : inline def_node::def_node (clobber_or_set first_def)
369 : 14645728 : : m_clobber_or_set (first_def),
370 : 43937184 : m_children ()
371 : : {
372 : : }
373 : :
374 : : // Construct a new group of clobber_infos that initially contains just CLOBBER.
375 : 6026327 : inline clobber_group::clobber_group (clobber_info *clobber)
376 : : : def_node (clobber),
377 : 6026327 : m_last_clobber (clobber),
378 : 12052654 : m_clobber_tree (clobber)
379 : : {
380 : 6026327 : clobber->m_group = this;
381 : : }
382 : :
383 : : // Construct a node for the instruction with uid UID.
384 : 0 : inline insn_info::order_node::order_node (int uid)
385 : : : insn_note (kind),
386 : 0 : m_children (),
387 : 0 : m_parent (nullptr)
388 : : {
389 : 0 : m_data32 = uid;
390 : : }
391 : :
392 : : // Construct a note for instruction INSN, giving it abi_id () value ABI_ID.
393 : 8119797 : inline insn_call_clobbers_note::insn_call_clobbers_note (unsigned int abi_id,
394 : 8119797 : insn_info *insn)
395 : : : insn_note (kind),
396 : 24359391 : m_children (),
397 : 16239594 : m_insn (insn)
398 : : {
399 : 8119797 : m_data32 = abi_id;
400 : : }
401 : :
402 : : // Construct an instruction with the given bb () and rtl () values.
403 : : // If the instruction is real, COST_OR_UID is the value of cost (),
404 : : // otherwise it is the value of uid ().
405 : 242969112 : inline insn_info::insn_info (bb_info *bb, rtx_insn *rtl, int cost_or_uid)
406 : 242969112 : : m_prev_insn_or_last_debug_insn (nullptr),
407 : 242969112 : m_next_nondebug_or_debug_insn (nullptr),
408 : 242969112 : m_bb (bb),
409 : 242969112 : m_rtl (rtl),
410 : 242969112 : m_accesses (nullptr),
411 : 242969112 : m_num_uses (0),
412 : 242969112 : m_num_defs (0),
413 : 242969112 : m_is_debug_insn (rtl && DEBUG_INSN_P (rtl)),
414 : 242969112 : m_can_be_optimized (false),
415 : 242969112 : m_is_asm (false),
416 : 242969112 : m_has_pre_post_modify (false),
417 : 242969112 : m_has_volatile_refs (false),
418 : 242969112 : m_is_temp (false),
419 : 242969112 : m_spare (0),
420 : 242969112 : m_point (0),
421 : 242969112 : m_cost_or_uid (cost_or_uid),
422 : 242969112 : m_first_note (nullptr)
423 : : {
424 : 242969112 : }
425 : :
426 : : // Copy any insn properties from PROPERTIES that are also stored in an
427 : : // insn_info.
428 : : inline void
429 : 186061963 : insn_info::set_properties (const rtx_properties &properties)
430 : : {
431 : 186061963 : m_is_asm = properties.has_asm;
432 : 186061963 : m_has_pre_post_modify = properties.has_pre_post_modify;
433 : 186061963 : m_has_volatile_refs = properties.has_volatile_refs;
434 : : // Not strictly related to the properties we've been given, but it's
435 : : // a convenient location to do this.
436 : 186061963 : m_can_be_optimized = (NONDEBUG_INSN_P (m_rtl)
437 : 186061963 : & (GET_CODE (PATTERN (m_rtl)) != USE)
438 : 186061963 : & (GET_CODE (PATTERN (m_rtl)) != CLOBBER));
439 : 186061963 : }
440 : :
441 : : // Change the list of instruction accesses to ACCESSES, which contains
442 : : // NUM_DEFS definitions followed by NUM_USES uses.
443 : : inline void
444 : 226571735 : insn_info::set_accesses (access_info **accesses,
445 : : unsigned int num_defs, unsigned int num_uses)
446 : : {
447 : 226571735 : m_accesses = accesses;
448 : 226571735 : m_num_defs = num_defs;
449 : 226571735 : gcc_assert (num_defs == m_num_defs);
450 : 226571735 : m_num_uses = num_uses;
451 : : }
452 : :
453 : : // Change defs () and uses () to DEFS and USES respectively, given that
454 : : // the existing m_accesses array has enough room for them.
455 : : inline void
456 : 2939378 : insn_info::copy_accesses (access_array defs, access_array uses)
457 : : {
458 : 2939378 : gcc_assert (defs.size () + uses.size () <= m_num_defs + m_num_uses);
459 : 2939378 : memcpy (m_accesses, defs.begin (), defs.size_bytes ());
460 : 2939378 : memcpy (m_accesses + defs.size (), uses.begin (), uses.size_bytes ());
461 : 2939378 : m_num_defs = defs.size ();
462 : 2939378 : gcc_assert (m_num_defs == defs.size ());
463 : 2939378 : m_num_uses = uses.size ();
464 : 2939378 : }
465 : :
466 : : // If the instruction has an insn_info::order_node, return the node,
467 : : // otherwise return null.
468 : : inline insn_info::order_node *
469 : 0 : insn_info::get_order_node () const
470 : : {
471 : : // The order_node always comes first.
472 : 0 : if (insn_note *note = first_note ())
473 : 0 : return note->dyn_cast<insn_info::order_node *> ();
474 : : return nullptr;
475 : : }
476 : :
477 : : // Like get_order_node (), but the node is known to exist.
478 : : inline insn_info::order_node *
479 : 0 : insn_info::get_known_order_node () const
480 : : {
481 : : // The order_node always comes first.
482 : 0 : return first_note ()->as_a<insn_info::order_node *> ();
483 : : }
484 : :
485 : : // Copy the overloaded prev link from OTHER.
486 : : inline void
487 : 0 : insn_info::copy_prev_from (insn_info *other)
488 : : {
489 : 0 : m_prev_insn_or_last_debug_insn = other->m_prev_insn_or_last_debug_insn;
490 : : }
491 : :
492 : : // Copy the overloaded next link from OTHER.
493 : : inline void
494 : 241020436 : insn_info::copy_next_from (insn_info *other)
495 : : {
496 : 241020436 : m_next_nondebug_or_debug_insn = other->m_next_nondebug_or_debug_insn;
497 : : }
498 : :
499 : : // If this is a nondebug instruction, record that the previous nondebug
500 : : // instruction is PREV. (There might be intervening debug instructions.)
501 : : //
502 : : // If this is a debug instruction, record that the previous instruction
503 : : // is debug instruction PREV.
504 : : inline void
505 : 386637827 : insn_info::set_prev_sametype_insn (insn_info *prev)
506 : : {
507 : 386637827 : m_prev_insn_or_last_debug_insn.set_first (prev);
508 : 216631612 : }
509 : :
510 : : // Only valid for debug instructions. Record that this instruction starts
511 : : // a subsequence of debug instructions that ends with LAST.
512 : : inline void
513 : 71014221 : insn_info::set_last_debug_insn (insn_info *last)
514 : : {
515 : 71014221 : m_prev_insn_or_last_debug_insn.set_second (last);
516 : 71014221 : }
517 : :
518 : : // Record that the next instruction of any kind is NEXT.
519 : : inline void
520 : 241020436 : insn_info::set_next_any_insn (insn_info *next)
521 : : {
522 : 241020436 : if (next && next->is_debug_insn ())
523 : 71014221 : m_next_nondebug_or_debug_insn.set_second (next);
524 : : else
525 : 170006215 : m_next_nondebug_or_debug_insn.set_first (next);
526 : 241020436 : }
527 : :
528 : : // Clear the list links and point number for this instruction.
529 : : inline void
530 : 0 : insn_info::clear_insn_links ()
531 : : {
532 : 0 : m_prev_insn_or_last_debug_insn = nullptr;
533 : 0 : m_next_nondebug_or_debug_insn = nullptr;
534 : 0 : m_point = 0;
535 : : }
536 : :
537 : : // Return true if the instruction contains any list information.
538 : : // This is used by assert checking.
539 : : inline bool
540 : 483989548 : insn_info::has_insn_links ()
541 : : {
542 : 483989548 : return (m_prev_insn_or_last_debug_insn
543 : 483989548 : || m_next_nondebug_or_debug_insn
544 : 967979096 : || m_point);
545 : : }
546 : :
547 : : // Construct a representation of basic block CFG_BB.
548 : 22749425 : inline bb_info::bb_info (basic_block cfg_bb)
549 : 22749425 : : m_prev_bb (nullptr),
550 : 22749425 : m_next_bb (nullptr),
551 : 22749425 : m_cfg_bb (cfg_bb),
552 : 22749425 : m_ebb (nullptr),
553 : 22749425 : m_head_insn (nullptr),
554 : 22749425 : m_end_insn (nullptr)
555 : : {
556 : : }
557 : :
558 : : // Construct a tree of call clobbers for the given ABI.
559 : 4616052 : inline ebb_call_clobbers_info::
560 : 4616052 : ebb_call_clobbers_info (const predefined_function_abi *abi)
561 : 4616052 : : m_next (nullptr),
562 : 4616052 : m_abi (abi)
563 : : {
564 : : }
565 : :
566 : : // Construct an EBB whose first block is FIRST_BB and whose last block
567 : : // is LAST_BB.
568 : 14354407 : inline ebb_info::ebb_info (bb_info *first_bb, bb_info *last_bb)
569 : 14354407 : : m_first_phi (nullptr),
570 : 14354407 : m_phi_insn (nullptr),
571 : 14354407 : m_first_bb (first_bb),
572 : 14354407 : m_last_bb (last_bb),
573 : 14354407 : m_first_call_clobbers (nullptr)
574 : : {
575 : : }
576 : :
577 : : // Record register definition DEF in last_access, pushing a definition
578 : : // to def_stack where appropriate.
579 : : inline void
580 : 178059934 : function_info::build_info::record_reg_def (def_info *def)
581 : : {
582 : 178059934 : unsigned int regno = def->regno ();
583 : 178059934 : auto *prev_dominating_def = safe_as_a<def_info *> (last_access[regno + 1]);
584 : 178059934 : if (!prev_dominating_def)
585 : : // Indicate that DEF is the first dominating definition of REGNO.
586 : 73964524 : def_stack.safe_push (def);
587 : 104095410 : else if (prev_dominating_def->bb () != def->bb ())
588 : : // Record that PREV_DOMINATING_DEF was the dominating definition
589 : : // of REGNO on entry to the current block.
590 : 45261961 : def_stack.safe_push (prev_dominating_def);
591 : 178059934 : last_access[regno + 1] = def;
592 : 178059934 : }
593 : :
594 : : // Set the contents of last_access for memory to DEF.
595 : : inline void
596 : 14635455 : function_info::build_info::record_mem_def (def_info *def)
597 : : {
598 : 14635455 : last_access[0] = def;
599 : 331560 : }
600 : :
601 : : // Return the current value of live register REGNO, or null if the register's
602 : : // value is completedly undefined.
603 : : inline set_info *
604 : 301735421 : function_info::build_info::current_reg_value (unsigned int regno) const
605 : : {
606 : 301735421 : return safe_dyn_cast<set_info *> (last_access[regno + 1]);
607 : : }
608 : :
609 : : // Return the current value of memory.
610 : : inline set_info *
611 : 25646936 : function_info::build_info::current_mem_value () const
612 : : {
613 : 25646936 : return as_a<set_info *> (last_access[0]);
614 : : }
615 : :
616 : : // Allocate a T on the function's main obstack, passing ARGS
617 : : // to its constructor.
618 : : template<typename T, typename... Ts>
619 : : inline T *
620 : 829731893 : function_info::allocate (Ts... args)
621 : : {
622 : : static_assert (std::is_trivially_destructible<T>::value,
623 : : "destructor won't be called");
624 : : static_assert (alignof (T) <= obstack_alignment,
625 : : "too much alignment required");
626 : 829731893 : void *addr = obstack_alloc (&m_obstack, sizeof (T));
627 : 829731893 : return new (addr) T (std::forward<Ts> (args)...);
628 : : }
629 : :
630 : : // Allocate a T on the function's temporary obstack, passing ARGS
631 : : // to its constructor.
632 : : template<typename T, typename... Ts>
633 : : inline T *
634 : 4142184 : function_info::allocate_temp (Ts... args)
635 : : {
636 : : static_assert (std::is_trivially_destructible<T>::value,
637 : : "destructor won't be called");
638 : : static_assert (alignof (T) <= obstack_alignment,
639 : : "too much alignment required");
640 : 4142184 : void *addr = obstack_alloc (&m_temp_obstack, sizeof (T));
641 : 4142184 : return new (addr) T (std::forward<Ts> (args)...);
642 : : }
643 : :
644 : : // Add INSN to the end of the function's list of instructions.
645 : : inline void
646 : 242969112 : function_info::append_insn (insn_info *insn)
647 : : {
648 : 242969112 : gcc_checking_assert (!insn->has_insn_links ());
649 : 242969112 : if (insn_info *after = m_last_insn)
650 : 241020436 : add_insn_after (insn, after);
651 : : else
652 : : // The first instruction is for the entry block and is always a nondebug
653 : : // insn
654 : 1948676 : m_first_insn = m_last_insn = m_last_nondebug_insn = insn;
655 : 242969112 : }
656 : :
657 : : // Start building a new list of uses and definitions for an instruction.
658 : : inline void
659 : 226565005 : function_info::start_insn_accesses ()
660 : : {
661 : 451181334 : gcc_checking_assert (m_temp_defs.is_empty ()
662 : : && m_temp_uses.is_empty ());
663 : 226565005 : }
664 : :
665 : : // Return a mode that encapsulates two distinct references to a register,
666 : : // one with mode MODE1 and one with mode MODE2. Treat BLKmode as a
667 : : // "don't know" wildcard.
668 : : inline machine_mode
669 : 70776414 : combine_modes (machine_mode mode1, machine_mode mode2)
670 : : {
671 : 70776414 : if (mode1 == E_BLKmode)
672 : : return mode2;
673 : :
674 : 24464957 : if (mode2 == E_BLKmode)
675 : : return mode1;
676 : :
677 : 24464312 : if (!ordered_p (GET_MODE_SIZE (mode1), GET_MODE_SIZE (mode2)))
678 : : return BLKmode;
679 : :
680 : 24464312 : return wider_subreg_mode (mode1, mode2);
681 : : }
682 : :
683 : : // PRINTER (PP, ARGS...) prints ARGS... to a pretty_printer PP. Use it
684 : : // to print ARGS... to FILE.
685 : : template<typename Printer, typename... Args>
686 : : inline void
687 : 0 : dump_using (FILE *file, Printer printer, Args... args)
688 : : {
689 : 0 : pretty_printer pp;
690 : 0 : printer (&pp, args...);
691 : 0 : pp_newline (&pp);
692 : 0 : fprintf (file, "%s", pp_formatted_text (&pp));
693 : 0 : }
694 : :
695 : : }
|