Line data Source code
1 : // Implementation of private inline member functions for RTL SSA -*- C++ -*-
2 : // Copyright (C) 2020-2026 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 1953940023 : inline access_info::access_info (resource_info resource, access_kind kind)
24 1953940023 : : m_regno (resource.regno),
25 1953940023 : m_mode (resource.mode),
26 1953940023 : m_kind (kind),
27 : m_is_artificial (false),
28 1953940023 : m_is_set_with_nondebug_insn_uses (false),
29 1953940023 : m_is_pre_post_modify (false),
30 1953940023 : m_is_call_clobber (false),
31 1953940023 : m_is_live_out_use (false),
32 1953940023 : m_includes_address_uses (false),
33 1953940023 : m_includes_read_writes (false),
34 1953940023 : m_includes_subregs (false),
35 1953940023 : m_includes_multiregs (false),
36 1953940023 : m_only_occurs_in_notes (false),
37 1953940023 : m_is_last_nondebug_insn_use (false),
38 725402284 : m_is_in_debug_insn_or_phi (false),
39 1953940023 : m_has_been_superceded (false),
40 1953940023 : 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 1228537739 : inline use_info::use_info (insn_or_phi location, resource_info resource,
47 1228537739 : set_info *definition)
48 : : access_info (resource, access_kind::USE),
49 1228537739 : m_insn_or_phi (location),
50 1228537739 : m_last_use_or_prev_use (nullptr),
51 1228537739 : m_last_nondebug_insn_use_or_next_use (nullptr),
52 1228537739 : m_def (definition)
53 : {
54 1228537739 : if (m_insn_or_phi.is_second ())
55 : {
56 193986805 : m_is_in_debug_insn_or_phi = true;
57 193986805 : m_is_artificial = true;
58 : }
59 : else
60 : {
61 1034550934 : insn_info *insn = m_insn_or_phi.known_first ();
62 1034550934 : m_is_in_debug_insn_or_phi = insn->is_debug_insn ();
63 1034550934 : m_is_artificial = insn->is_artificial ();
64 : }
65 1228537739 : }
66 :
67 : // Return the correct (uncached) value of m_is_last_nondebug_insn_use.
68 : inline bool
69 3171481424 : use_info::calculate_is_last_nondebug_insn_use () const
70 : {
71 3171481424 : use_info *next = next_use ();
72 3171481424 : 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 773805152 : use_info::record_reference (rtx_obj_reference ref, bool is_first)
81 : {
82 773805152 : if (is_first)
83 : {
84 696634080 : m_includes_address_uses = ref.in_address ();
85 696634080 : m_includes_read_writes = ref.is_write ();
86 696634080 : m_includes_subregs = ref.in_subreg ();
87 696634080 : m_includes_multiregs = ref.is_multireg ();
88 696634080 : m_only_occurs_in_notes = ref.in_note ();
89 : }
90 : else
91 : {
92 77171072 : m_includes_address_uses |= ref.in_address ();
93 77171072 : m_includes_read_writes |= ref.is_write ();
94 77171072 : m_includes_subregs |= ref.in_subreg ();
95 77171072 : m_includes_multiregs |= ref.is_multireg ();
96 77171072 : m_only_occurs_in_notes &= ref.in_note ();
97 : }
98 773805152 : }
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 40676174 : use_info::copy_prev_from (use_info *other)
111 : {
112 24485752 : m_last_use_or_prev_use = other->m_last_use_or_prev_use;
113 16190422 : }
114 :
115 : // Copy the overloaded next link from OTHER.
116 : inline void
117 685999201 : use_info::copy_next_from (use_info *other)
118 : {
119 685999201 : m_last_nondebug_insn_use_or_next_use
120 685999201 : = other->m_last_nondebug_insn_use_or_next_use;
121 663593801 : m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
122 22405400 : }
123 :
124 : // Record that this use is the first in the list and that the last use is LAST.
125 : inline void
126 1130817863 : use_info::set_last_use (use_info *last_use)
127 : {
128 1130817863 : m_last_use_or_prev_use.set_first (last_use);
129 448035247 : }
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 784780346 : use_info::set_prev_use (use_info *prev_use)
135 : {
136 784780346 : m_last_use_or_prev_use.set_second (prev_use);
137 96700793 : }
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 948829948 : use_info::set_last_nondebug_insn_use (use_info *use)
145 : {
146 948829948 : m_last_nondebug_insn_use_or_next_use.set_first (use);
147 948829948 : m_is_last_nondebug_insn_use = (use == this);
148 948829948 : }
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 690782759 : use_info::set_next_use (use_info *next_use)
154 : {
155 690782759 : m_last_nondebug_insn_use_or_next_use.set_second (next_use);
156 690782759 : m_is_last_nondebug_insn_use = calculate_is_last_nondebug_insn_use ();
157 690782759 : }
158 :
159 : // Clear any information relating to the position of the use in its
160 : // definition's list.
161 : inline void
162 48751701 : use_info::clear_use_links ()
163 : {
164 48751701 : m_last_use_or_prev_use = nullptr;
165 48751701 : m_last_nondebug_insn_use_or_next_use = nullptr;
166 48751701 : 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 1827037686 : use_info::has_use_links ()
173 : {
174 1827037686 : return (m_last_use_or_prev_use
175 1827037686 : || m_last_nondebug_insn_use_or_next_use
176 3654075372 : || m_is_last_nondebug_insn_use);
177 : }
178 :
179 : // Construct a definition of RESOURCE in INSN, giving it kind KIND.
180 725402284 : inline def_info::def_info (insn_info *insn, resource_info resource,
181 725402284 : access_kind kind)
182 : : access_info (resource, kind),
183 725402284 : m_insn (insn),
184 725402284 : m_last_def_or_prev_def (nullptr),
185 725402284 : m_splay_root_or_next_def (nullptr)
186 : {
187 725402284 : m_is_artificial = insn->is_artificial ();
188 725402284 : }
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 486486560 : def_info::record_reference (rtx_obj_reference ref, bool is_first)
196 : {
197 486486560 : if (is_first)
198 : {
199 471294204 : m_is_pre_post_modify = ref.is_pre_post_modify ();
200 471294204 : m_includes_read_writes = ref.is_read ();
201 471294204 : m_includes_subregs = ref.in_subreg ();
202 471294204 : m_includes_multiregs = ref.is_multireg ();
203 : }
204 : else
205 : {
206 15192356 : m_is_pre_post_modify |= ref.is_pre_post_modify ();
207 15192356 : m_includes_read_writes |= ref.is_read ();
208 15192356 : m_includes_subregs |= ref.in_subreg ();
209 15192356 : m_includes_multiregs |= ref.is_multireg ();
210 : }
211 486486560 : }
212 :
213 : // Return the last definition in the list. Only valid when is_first ()
214 : // is true.
215 : inline def_info *
216 629998227 : def_info::last_def () const
217 : {
218 629998227 : 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 566170554 : def_info::splay_root () const
226 : {
227 566170554 : return m_splay_root_or_next_def.known_first ();
228 : }
229 :
230 : // Copy the overloaded prev link from OTHER.
231 : inline void
232 7474480 : def_info::copy_prev_from (def_info *other)
233 : {
234 7474480 : m_last_def_or_prev_def
235 382438 : = other->m_last_def_or_prev_def;
236 7092042 : }
237 :
238 : // Copy the overloaded next link from OTHER.
239 : inline void
240 141954124 : def_info::copy_next_from (def_info *other)
241 : {
242 127800998 : m_splay_root_or_next_def = other->m_splay_root_or_next_def;
243 14153126 : }
244 :
245 : // Record that this definition is the first in the list and that the last
246 : // definition is LAST.
247 : inline void
248 730424480 : def_info::set_last_def (def_info *last_def)
249 : {
250 730424480 : m_last_def_or_prev_def.set_first (last_def);
251 557264644 : }
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 551563762 : def_info::set_prev_def (def_info *prev_def)
257 : {
258 551563762 : m_last_def_or_prev_def.set_second (prev_def);
259 651673 : }
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 2700358 : def_info::set_splay_root (def_node *root)
265 : {
266 2700358 : m_splay_root_or_next_def = root;
267 98850 : }
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 551382488 : def_info::set_next_def (def_info *next_def)
273 : {
274 551066401 : m_splay_root_or_next_def = next_def;
275 470399 : }
276 :
277 : // Clear the prev and next links
278 : inline void
279 15969935 : def_info::clear_def_links ()
280 : {
281 1670695 : m_last_def_or_prev_def = nullptr;
282 1670695 : 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 852255361 : def_info::has_def_links ()
289 : {
290 852255361 : 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 146957138 : inline clobber_info::clobber_info (insn_info *insn, unsigned int regno)
295 : : def_info (insn, { E_BLKmode, regno }, access_kind::CLOBBER),
296 146957138 : m_children (),
297 146957138 : m_parent (nullptr),
298 146957138 : m_group (nullptr)
299 : {
300 146957138 : }
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 1135852 : clobber_info::update_group (clobber_group *group)
306 : {
307 1135852 : 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 578445146 : inline set_info::set_info (insn_info *insn, resource_info resource,
314 578445146 : access_kind kind)
315 : : def_info (insn, resource, kind),
316 1156890292 : m_first_use (nullptr)
317 : {
318 : }
319 :
320 : // Cconstruct a set_info for a store to RESOURCE in INSN.
321 451012238 : inline set_info::set_info (insn_info *insn, resource_info resource)
322 451012238 : : set_info (insn, resource, access_kind::SET)
323 : {
324 451012238 : }
325 :
326 : // Record that USE is the first use of this definition.
327 : inline void
328 579492423 : set_info::set_first_use (use_info *first_use)
329 : {
330 579492423 : m_first_use = first_use;
331 553146122 : m_is_set_with_nondebug_insn_uses
332 667479190 : = (first_use && first_use->is_in_nondebug_insn ());
333 48128847 : }
334 :
335 : // Construct a phi for RESOURCE in INSN, giving it identifier UID.
336 127432908 : inline phi_info::phi_info (insn_info *insn, resource_info resource,
337 127432908 : unsigned int uid)
338 : : set_info (insn, resource, access_kind::PHI),
339 127432908 : m_uid (uid),
340 127432908 : m_num_inputs (0),
341 127432908 : m_prev_phi (nullptr),
342 127432908 : m_next_phi (nullptr)
343 : {
344 127432908 : }
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 2141134 : phi_info::make_degenerate (use_info *input)
350 : {
351 2141134 : m_num_inputs = 1;
352 2141134 : m_single_input = input;
353 1961666 : }
354 :
355 : // Set the inputs of the phi to INPUTS.
356 : inline void
357 127253440 : phi_info::set_inputs (use_array inputs)
358 : {
359 127253440 : m_num_inputs = inputs.size ();
360 127253440 : if (inputs.size () == 1)
361 88224952 : m_single_input = inputs[0];
362 : else
363 39028488 : m_inputs = access_array (inputs).begin ();
364 127253440 : }
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 37074845 : inline def_node::def_node (clobber_or_set first_def)
369 37074845 : : m_clobber_or_set (first_def),
370 37074845 : m_children ()
371 : {
372 : }
373 :
374 : // Construct a new group of clobber_infos that initially contains just CLOBBER.
375 20535397 : inline clobber_group::clobber_group (clobber_info *clobber)
376 20535397 : : def_node (clobber),
377 20535397 : m_last_clobber (clobber),
378 20535397 : m_clobber_tree (clobber)
379 : {
380 20535397 : clobber->m_group = this;
381 : }
382 :
383 : // Construct a new group of clobber_infos that spans [FIRST_CLOBBER,
384 : // LAST_CLOBBER]. Set the root of the splay tree to CLOBBER_TREE.
385 0 : inline clobber_group::clobber_group (clobber_info *first_clobber,
386 : clobber_info *last_clobber,
387 0 : clobber_info *clobber_tree)
388 0 : : def_node (first_clobber),
389 0 : m_last_clobber (last_clobber),
390 0 : m_clobber_tree (clobber_tree)
391 : {
392 0 : first_clobber->m_group = this;
393 0 : last_clobber->m_group = this;
394 0 : clobber_tree->m_group = this;
395 : }
396 :
397 : // Construct a node for the instruction with uid UID.
398 1783 : inline insn_info::order_node::order_node (int uid)
399 : : insn_note (kind),
400 1783 : m_children (),
401 1783 : m_parent (nullptr)
402 : {
403 1783 : m_data32 = uid;
404 : }
405 :
406 : // Construct a note for instruction INSN, giving it abi_id () value ABI_ID.
407 30289691 : inline insn_call_clobbers_note::insn_call_clobbers_note (unsigned int abi_id,
408 30289691 : insn_info *insn)
409 : : insn_note (kind),
410 30289691 : m_children (),
411 30289691 : m_insn (insn)
412 : {
413 30289691 : m_data32 = abi_id;
414 : }
415 :
416 : // Construct an instruction with the given bb () and rtl () values.
417 : // If the instruction is real, COST_OR_UID is the value of cost (),
418 : // otherwise it is the value of uid ().
419 1003541413 : inline insn_info::insn_info (bb_info *bb, rtx_insn *rtl, int cost_or_uid)
420 1003516843 : : m_prev_sametype_or_last_debug_insn (nullptr),
421 1003541413 : m_next_nondebug_or_debug_insn (nullptr),
422 1003541413 : m_bb (bb),
423 1003541413 : m_rtl (rtl),
424 1003541413 : m_accesses (nullptr),
425 1003541413 : m_num_uses (0),
426 1003541413 : m_num_defs (0),
427 1003516843 : m_is_debug_insn (rtl && DEBUG_INSN_P (rtl)),
428 1003541413 : m_can_be_optimized (false),
429 1003541413 : m_is_asm (false),
430 1003541413 : m_has_pre_post_modify (false),
431 1003541413 : m_has_volatile_refs (false),
432 1003541413 : m_is_temp (false),
433 1003541413 : m_spare (0),
434 1003541413 : m_point (0),
435 1003541413 : m_cost_or_uid (cost_or_uid),
436 1003541413 : m_first_note (nullptr)
437 : {
438 1003516843 : }
439 :
440 : // Copy any insn properties from PROPERTIES that are also stored in an
441 : // insn_info.
442 : inline void
443 790771031 : insn_info::set_properties (const rtx_properties &properties)
444 : {
445 790771031 : m_is_asm = properties.has_asm;
446 790771031 : m_has_pre_post_modify = properties.has_pre_post_modify;
447 790771031 : m_has_volatile_refs = properties.has_volatile_refs;
448 : // Not strictly related to the properties we've been given, but it's
449 : // a convenient location to do this.
450 790771031 : m_can_be_optimized = (NONDEBUG_INSN_P (m_rtl)
451 790771031 : & (GET_CODE (PATTERN (m_rtl)) != USE)
452 790771031 : & (GET_CODE (PATTERN (m_rtl)) != CLOBBER));
453 790771031 : }
454 :
455 : // Change the list of instruction accesses to ACCESSES, which contains
456 : // NUM_DEFS definitions followed by NUM_USES uses.
457 : inline void
458 944179977 : insn_info::set_accesses (access_info **accesses,
459 : unsigned int num_defs, unsigned int num_uses)
460 : {
461 944179977 : m_accesses = accesses;
462 944179977 : m_num_defs = num_defs;
463 944179977 : gcc_assert (num_defs == m_num_defs);
464 944179977 : m_num_uses = num_uses;
465 : }
466 :
467 : // Change defs () and uses () to DEFS and USES respectively, given that
468 : // the existing m_accesses array has enough room for them.
469 : inline void
470 18345695 : insn_info::copy_accesses (access_array defs, access_array uses)
471 : {
472 18345695 : gcc_assert (defs.size () + uses.size () <= m_num_defs + m_num_uses);
473 18345695 : memcpy (m_accesses, defs.begin (), defs.size_bytes ());
474 18345695 : memcpy (m_accesses + defs.size (), uses.begin (), uses.size_bytes ());
475 18345695 : m_num_defs = defs.size ();
476 18345695 : gcc_assert (m_num_defs == defs.size ());
477 18345695 : m_num_uses = uses.size ();
478 18345695 : }
479 :
480 : // If the instruction has an insn_info::order_node, return the node,
481 : // otherwise return null.
482 : inline insn_info::order_node *
483 2238616 : insn_info::get_order_node () const
484 : {
485 : // The order_node always comes first.
486 2238616 : if (insn_note *note = first_note ())
487 2215281 : return note->dyn_cast<insn_info::order_node *> ();
488 : return nullptr;
489 : }
490 :
491 : // Like get_order_node (), but the node is known to exist.
492 : inline insn_info::order_node *
493 1708 : insn_info::get_known_order_node () const
494 : {
495 : // The order_node always comes first.
496 854 : return first_note ()->as_a<insn_info::order_node *> ();
497 : }
498 :
499 : // Copy the overloaded prev link from OTHER.
500 : inline void
501 46116 : insn_info::copy_prev_from (insn_info *other)
502 : {
503 46116 : m_prev_sametype_or_last_debug_insn
504 46116 : = other->m_prev_sametype_or_last_debug_insn;
505 : }
506 :
507 : // Copy the overloaded next link from OTHER.
508 : inline void
509 996569800 : insn_info::copy_next_from (insn_info *other)
510 : {
511 996569800 : m_next_nondebug_or_debug_insn = other->m_next_nondebug_or_debug_insn;
512 : }
513 :
514 : // If this is a nondebug instruction, record that the previous nondebug
515 : // instruction is PREV. (There might be intervening debug instructions.)
516 : //
517 : // If this is a debug instruction, record that the previous instruction
518 : // is debug instruction PREV.
519 : inline void
520 1535801934 : insn_info::set_prev_sametype_insn (insn_info *prev)
521 : {
522 1535801934 : m_prev_sametype_or_last_debug_insn.set_first (prev);
523 896934188 : }
524 :
525 : // Only valid for debug instructions. Record that this instruction starts
526 : // a subsequence of debug instructions that ends with LAST.
527 : inline void
528 359920854 : insn_info::set_last_debug_insn (insn_info *last)
529 : {
530 359920854 : m_prev_sametype_or_last_debug_insn.set_second (last);
531 359920854 : }
532 :
533 : // Record that the next instruction of any kind is NEXT.
534 : inline void
535 998781996 : insn_info::set_next_any_insn (insn_info *next)
536 : {
537 998781996 : if (next && next->is_debug_insn ())
538 360363588 : m_next_nondebug_or_debug_insn.set_second (next);
539 : else
540 638418408 : m_next_nondebug_or_debug_insn.set_first (next);
541 998781996 : }
542 :
543 : // Clear the list links and point number for this instruction.
544 : inline void
545 2236766 : insn_info::clear_insn_links ()
546 : {
547 2236766 : m_prev_sametype_or_last_debug_insn = nullptr;
548 2236766 : m_next_nondebug_or_debug_insn = nullptr;
549 2236766 : m_point = 0;
550 : }
551 :
552 : // Return true if the instruction contains any list information.
553 : // This is used by assert checking.
554 : inline bool
555 2000086643 : insn_info::has_insn_links ()
556 : {
557 996569800 : return (m_prev_sametype_or_last_debug_insn
558 2000086643 : || m_next_nondebug_or_debug_insn
559 4000173286 : || m_point);
560 : }
561 :
562 : // Construct a representation of basic block CFG_BB.
563 88466817 : inline bb_info::bb_info (basic_block cfg_bb)
564 88466817 : : m_prev_bb (nullptr),
565 88466817 : m_next_bb (nullptr),
566 88466817 : m_cfg_bb (cfg_bb),
567 88466817 : m_ebb (nullptr),
568 88466817 : m_head_insn (nullptr),
569 88466817 : m_end_insn (nullptr)
570 : {
571 : }
572 :
573 : // Construct a tree of call clobbers for the given ABI.
574 17776827 : inline ebb_call_clobbers_info::
575 17776827 : ebb_call_clobbers_info (const predefined_function_abi *abi)
576 17776827 : : m_next (nullptr),
577 17776827 : m_abi (abi)
578 : {
579 : }
580 :
581 : // Construct an EBB whose first block is FIRST_BB and whose last block
582 : // is LAST_BB.
583 54445376 : inline ebb_info::ebb_info (bb_info *first_bb, bb_info *last_bb)
584 54445376 : : m_first_phi (nullptr),
585 54445376 : m_phi_insn (nullptr),
586 54445376 : m_first_bb (first_bb),
587 54445376 : m_last_bb (last_bb),
588 54445376 : m_first_call_clobbers (nullptr)
589 : {
590 : }
591 :
592 : // Record register definition DEF in last_access, pushing a definition
593 : // to def_stack where appropriate.
594 : inline void
595 667526481 : function_info::build_info::record_reg_def (def_info *def)
596 : {
597 667526481 : unsigned int regno = def->regno ();
598 667526481 : auto *prev_dominating_def = safe_as_a<def_info *> (last_access[regno + 1]);
599 667526481 : if (!prev_dominating_def)
600 : // Indicate that DEF is the first dominating definition of REGNO.
601 190818705 : def_stack.safe_push (def);
602 476707776 : else if (prev_dominating_def->bb () != def->bb ())
603 : // Record that PREV_DOMINATING_DEF was the dominating definition
604 : // of REGNO on entry to the current block.
605 222028082 : def_stack.safe_push (prev_dominating_def);
606 667526481 : last_access[regno + 1] = def;
607 667526481 : }
608 :
609 : // Set the contents of last_access for memory to DEF.
610 : inline void
611 55592203 : function_info::build_info::record_mem_def (def_info *def)
612 : {
613 55592203 : last_access[0] = def;
614 1332045 : }
615 :
616 : // Return the current value of live register REGNO, or null if the register's
617 : // value is completedly undefined.
618 : inline set_info *
619 1107156583 : function_info::build_info::current_reg_value (unsigned int regno) const
620 : {
621 1107156583 : return safe_dyn_cast<set_info *> (last_access[regno + 1]);
622 : }
623 :
624 : // Return the current value of memory.
625 : inline set_info *
626 98630673 : function_info::build_info::current_mem_value () const
627 : {
628 98630673 : return as_a<set_info *> (last_access[0]);
629 : }
630 :
631 : // Allocate a T on the function's main obstack, passing ARGS
632 : // to its constructor.
633 : template<typename T, typename... Ts>
634 : inline T *
635 3202737880 : function_info::allocate (Ts... args)
636 : {
637 : static_assert (std::is_trivially_destructible<T>::value,
638 : "destructor won't be called");
639 : static_assert (alignof (T) <= obstack_alignment,
640 : "too much alignment required");
641 3202737880 : void *addr = obstack_alloc (&m_obstack, sizeof (T));
642 3202737880 : return new (addr) T (std::forward<Ts> (args)...);
643 : }
644 :
645 : // Allocate a T on the function's temporary obstack, passing ARGS
646 : // to its constructor.
647 : template<typename T, typename... Ts>
648 : inline T *
649 10348597 : function_info::allocate_temp (Ts... args)
650 : {
651 : static_assert (std::is_trivially_destructible<T>::value,
652 : "destructor won't be called");
653 : static_assert (alignof (T) <= obstack_alignment,
654 : "too much alignment required");
655 10348597 : void *addr = obstack_alloc (&m_temp_obstack, sizeof (T));
656 10348597 : return new (addr) T (std::forward<Ts> (args)...);
657 : }
658 :
659 : // Add INSN to the end of the function's list of instructions.
660 : inline void
661 1003516843 : function_info::append_insn (insn_info *insn)
662 : {
663 1003516843 : gcc_checking_assert (!insn->has_insn_links ());
664 1003516843 : if (insn_info *after = m_last_insn)
665 996520660 : add_insn_after (insn, after);
666 : else
667 : // The first instruction is for the entry block and is always a nondebug
668 : // insn
669 6996183 : m_first_insn = m_last_insn = m_last_nondebug_insn = insn;
670 1003516843 : }
671 :
672 : // Start building a new list of uses and definitions for an instruction.
673 : inline void
674 941704848 : function_info::start_insn_accesses ()
675 : {
676 1876413513 : gcc_checking_assert (m_temp_defs.is_empty ()
677 : && m_temp_uses.is_empty ());
678 941704848 : }
679 :
680 : // Return a mode that encapsulates two distinct references to a register,
681 : // one with mode MODE1 and one with mode MODE2. Treat BLKmode as a
682 : // "don't know" wildcard.
683 : inline machine_mode
684 317519983 : combine_modes (machine_mode mode1, machine_mode mode2)
685 : {
686 317519983 : if (mode1 == E_BLKmode)
687 : return mode2;
688 :
689 134878200 : if (mode2 == E_BLKmode)
690 : return mode1;
691 :
692 134877688 : if (!ordered_p (GET_MODE_SIZE (mode1), GET_MODE_SIZE (mode2)))
693 : return BLKmode;
694 :
695 134877688 : return wider_subreg_mode (mode1, mode2);
696 : }
697 :
698 : // PRINTER (PP, ARGS...) prints ARGS... to a pretty_printer PP. Use it
699 : // to print ARGS... to FILE.
700 : template<typename Printer, typename... Args>
701 : inline void
702 0 : dump_using (FILE *file, Printer printer, Args... args)
703 : {
704 0 : pretty_printer pp;
705 0 : printer (&pp, args...);
706 0 : pp_newline (&pp);
707 0 : fprintf (file, "%s", pp_formatted_text (&pp));
708 0 : }
709 :
710 : }
|