1 // Access-related utilities for RTL SSA -*- C++ -*-
2 // Copyright (C) 2020-2021 Free Software Foundation, Inc.
4 // This file is part of GCC.
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
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
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/>.
22 // Return a referene to the whole of register REGNO.
24 full_register (unsigned int regno
)
26 return { GET_MODE (regno_reg_rtx
[regno
]), regno
};
29 // Return true if sorted array ACCESSES includes an access to hard registers.
31 accesses_include_hard_registers (const access_array
&accesses
)
33 return accesses
.size () && HARD_REGISTER_NUM_P (accesses
.front ()->regno ());
36 // Return true if sorted array ACCESSES includes an access to memory.
38 accesses_include_memory (const access_array
&accesses
)
40 return accesses
.size () && accesses
.back ()->is_mem ();
43 // If sorted array ACCESSES includes an access to memory, return the access,
44 // otherwise return null.
47 memory_access (T accesses
) -> decltype (accesses
[0])
49 if (accesses
.size () && accesses
.back ()->is_mem ())
50 return accesses
.back ();
54 // If sorted array ACCESSES includes a reference to REGNO, return the
55 // access, otherwise return null.
58 find_access (T accesses
, unsigned int regno
) -> decltype (accesses
[0])
60 unsigned int start
= 0;
61 unsigned int end
= accesses
.size ();
64 unsigned int mid
= (start
+ end
) / 2;
65 unsigned int found
= accesses
[mid
]->regno ();
76 // If sorted array ACCESSES includes a reference to REGNO, return the
77 // index of the access, otherwise return -1.
79 find_access_index (access_array accesses
, unsigned int regno
)
81 unsigned int start
= 0;
82 unsigned int end
= accesses
.size ();
85 unsigned int mid
= (start
+ end
) / 2;
86 unsigned int found
= accesses
[mid
]->regno ();
97 // If ACCESS is a set whose result is used by at least one instruction,
98 // return the access as a set_info, otherwise return null.
99 inline const set_info
*
100 set_with_nondebug_insn_uses (const access_info
*access
)
102 if (access
->is_set_with_nondebug_insn_uses ())
103 // No need for as_a; this test is just as definitive.
104 return static_cast<const set_info
*> (access
);
108 // A non-const version of the above.
110 set_with_nondebug_insn_uses (access_info
*access
)
112 if (access
->is_set_with_nondebug_insn_uses ())
113 return static_cast<set_info
*> (access
);
117 // Return true if SET is the only set of SET->resource () and if it
118 // dominates all uses (excluding uses of SET->resource () at points
119 // where SET->resource () is always undefined).
121 is_single_dominating_def (const set_info
*set
)
123 return set
->is_first_def () && set
->is_last_def ();
126 // SET is known to be available on entry to BB. Return true if it is
127 // also available on exit from BB. (The value might or might not be live.)
129 remains_available_on_exit (const set_info
*set
, bb_info
*bb
)
131 return (set
->is_last_def ()
132 || *set
->next_def ()->insn () > *bb
->end_insn ());
135 // ACCESS is known to be associated with an instruction rather than
136 // a phi node. Return which instruction that is.
138 access_insn (const access_info
*access
)
140 // In release builds this function reduces to a single pointer reference.
141 if (auto *def
= dyn_cast
<const def_info
*> (access
))
143 return as_a
<const use_info
*> (access
)->insn ();
146 // If ACCESS records a use, return the value that it uses. If ACCESS records
147 // a set, return that set. If ACCESS records a clobber, return null.
148 inline const set_info
*
149 access_value (const access_info
*access
)
154 if (auto *use
= dyn_cast
<const use_info
*> (access
))
157 return dyn_cast
<const set_info
*> (access
);
160 // A non-const version of the above.
162 access_value (access_info
*access
)
164 auto *const_access
= const_cast<const access_info
*> (access
);
165 return const_cast<set_info
*> (access_value (const_access
));
168 // If ACCESS is a degenerate phi, return the set_info that defines its input,
169 // otherwise return ACCESS itself.
172 look_through_degenerate_phi (const T
*access
)
174 if (auto *phi
= dyn_cast
<const phi_info
*> (access
))
175 if (phi
->is_degenerate ())
176 return phi
->input_value (0);
180 // A non-const version of the above.
183 look_through_degenerate_phi (T
*access
)
185 auto *const_access
= const_cast<const T
*> (access
);
186 return const_cast<T
*> (look_through_degenerate_phi (const_access
));
189 // If CLOBBER is in a group, return the first clobber in the group,
190 // otherwise return CLOBBER itself.
191 inline clobber_info
*
192 first_clobber_in_group (clobber_info
*clobber
)
194 if (clobber
->is_in_group ())
195 return clobber
->group ()->first_clobber ();
199 // If CLOBBER is in a group, return the last clobber in the group,
200 // otherwise return CLOBBER itself.
201 inline clobber_info
*
202 last_clobber_in_group (clobber_info
*clobber
)
204 if (clobber
->is_in_group ())
205 return clobber
->group ()->last_clobber ();
209 // If DEF is a clobber in a group, return the containing group,
210 // otherwise return DEF.
212 clobber_group_or_single_def (def_info
*def
)
214 if (auto *clobber
= dyn_cast
<clobber_info
*> (def
))
215 if (clobber
->is_in_group ())
216 return clobber
->group ();
220 // Return the first definition associated with NODE. If NODE holds
221 // a single set, the result is that set. If NODE holds a clobber_group,
222 // the result is the first clobber in the group.
224 first_def (def_node
*node
)
226 return node
->first_def ();
229 // Likewise for something that is either a node or a single definition.
231 first_def (def_mux mux
)
233 return mux
.first_def ();
236 // Return the last definition associated with NODE. If NODE holds
237 // a single set, the result is that set. If NODE holds a clobber_group,
238 // the result is the last clobber in the group.
240 last_def (def_node
*node
)
242 if (auto *group
= dyn_cast
<clobber_group
*> (node
))
243 return group
->last_clobber ();
244 return node
->first_def ();
247 // Likewise for something that is either a node or a single definition.
249 last_def (def_mux mux
)
251 return mux
.last_def ();
254 int lookup_use (splay_tree
<use_info
*> &, insn_info
*);
255 int lookup_def (def_splay_tree
&, insn_info
*);
256 int lookup_clobber (clobber_tree
&, insn_info
*);
257 int lookup_call_clobbers (insn_call_clobbers_tree
&, insn_info
*);
259 // Search backwards from immediately before INSN for the first instruction
260 // recorded in TREE, ignoring any instruction I for which IGNORE (I) is true.
261 // Return null if no such instruction exists.
262 template<typename IgnorePredicate
>
264 prev_call_clobbers_ignoring (insn_call_clobbers_tree
&tree
, insn_info
*insn
,
265 IgnorePredicate ignore
)
270 int comparison
= lookup_call_clobbers (tree
, insn
);
271 while (comparison
<= 0 || ignore (tree
->insn ()))
273 if (!tree
.splay_prev_node ())
278 return tree
->insn ();
281 // Search forwards from immediately after INSN for the first instruction
282 // recorded in TREE, ignoring any instruction I for which IGNORE (I) is true.
283 // Return null if no such instruction exists.
284 template<typename IgnorePredicate
>
286 next_call_clobbers_ignoring (insn_call_clobbers_tree
&tree
, insn_info
*insn
,
287 IgnorePredicate ignore
)
292 int comparison
= lookup_call_clobbers (tree
, insn
);
293 while (comparison
>= 0 || ignore (tree
->insn ()))
295 if (!tree
.splay_next_node ())
300 return tree
->insn ();
303 // If ACCESS is a set, return the first use of ACCESS by a nondebug insn I
304 // for which IGNORE (I) is false. Return null if ACCESS is not a set or if
305 // no such use exists.
306 template<typename IgnorePredicate
>
308 first_nondebug_insn_use_ignoring (const access_info
*access
,
309 IgnorePredicate ignore
)
311 if (const set_info
*set
= set_with_nondebug_insn_uses (access
))
313 // Written this way to emphasize to the compiler that first_use
314 // must be nonnull in this situation.
315 use_info
*use
= set
->first_use ();
318 if (!ignore (use
->insn ()))
320 use
= use
->next_nondebug_insn_use ();
327 // If ACCESS is a set, return the last use of ACCESS by a nondebug insn I for
328 // which IGNORE (I) is false. Return null if ACCESS is not a set or if no
330 template<typename IgnorePredicate
>
332 last_nondebug_insn_use_ignoring (const access_info
*access
,
333 IgnorePredicate ignore
)
335 if (const set_info
*set
= set_with_nondebug_insn_uses (access
))
337 // Written this way to emphasize to the compiler that
338 // last_nondebug_insn_use must be nonnull in this situation.
339 use_info
*use
= set
->last_nondebug_insn_use ();
342 if (!ignore (use
->insn ()))
344 use
= use
->prev_use ();
351 // If DEF is null, return null.
353 // Otherwise, search backwards for an access to DEF->resource (), starting at
354 // the end of DEF's live range. Ignore clobbers if IGNORE_CLOBBERS_SETTING
355 // is YES, otherwise treat them like any other access. Also ignore any
356 // access A for which IGNORE (access_insn (A)) is true.
358 // Thus if DEF is a set that is used by nondebug insns, the first access
359 // that the function considers is the last such use of the set. Otherwise,
360 // the first access that the function considers is DEF itself.
362 // Return the access found, or null if there is no access that meets
365 // Note that this function does not consider separately-recorded call clobbers,
366 // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
367 template<typename IgnorePredicate
>
369 last_access_ignoring (def_info
*def
, ignore_clobbers ignore_clobbers_setting
,
370 IgnorePredicate ignore
)
374 auto *clobber
= dyn_cast
<clobber_info
*> (def
);
375 if (clobber
&& ignore_clobbers_setting
== ignore_clobbers::YES
)
376 def
= first_clobber_in_group (clobber
);
379 if (use_info
*use
= last_nondebug_insn_use_ignoring (def
, ignore
))
382 insn_info
*insn
= def
->insn ();
386 def
= def
->prev_def ();
391 // Search backwards for an access to DEF->resource (), starting
392 // immediately before the point at which DEF occurs. Ignore clobbers
393 // if IGNORE_CLOBBERS_SETTING is YES, otherwise treat them like any other
394 // access. Also ignore any access A for which IGNORE (access_insn (A))
397 // Thus if DEF->insn () uses DEF->resource (), that use is the first access
398 // that the function considers, since an instruction's uses occur strictly
399 // before its definitions.
401 // Note that this function does not consider separately-recorded call clobbers,
402 // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
403 template<typename IgnorePredicate
>
405 prev_access_ignoring (def_info
*def
, ignore_clobbers ignore_clobbers_setting
,
406 IgnorePredicate ignore
)
408 return last_access_ignoring (def
->prev_def (), ignore_clobbers_setting
,
412 // If DEF is null, return null.
414 // Otherwise, search forwards for a definition of DEF->resource (),
415 // starting at DEF itself. Ignore clobbers if IGNORE_CLOBBERS_SETTING
416 // is YES, otherwise treat them like any other access. Also ignore any
417 // definition D for which IGNORE (D->insn ()) is true.
419 // Return the definition found, or null if there is no access that meets
422 // Note that this function does not consider separately-recorded call clobbers,
423 // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
424 template<typename IgnorePredicate
>
426 first_def_ignoring (def_info
*def
, ignore_clobbers ignore_clobbers_setting
,
427 IgnorePredicate ignore
)
431 auto *clobber
= dyn_cast
<clobber_info
*> (def
);
432 if (clobber
&& ignore_clobbers_setting
== ignore_clobbers::YES
)
433 def
= last_clobber_in_group (clobber
);
434 else if (!ignore (def
->insn ()))
437 def
= def
->next_def ();
442 // Search forwards for the next access to DEF->resource (),
443 // starting immediately after DEF's instruction. Ignore clobbers if
444 // IGNORE_CLOBBERS_SETTING is YES, otherwise treat them like any other access.
445 // Also ignore any access A for which IGNORE (access_insn (A)) is true;
446 // in this context, ignoring a set includes ignoring all uses of the set.
448 // Thus if DEF is a set with uses by nondebug insns, the first access that the
449 // function considers is the first such use of the set.
451 // Return the access found, or null if there is no access that meets the
454 // Note that this function does not consider separately-recorded call clobbers,
455 // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
456 template<typename IgnorePredicate
>
458 next_access_ignoring (def_info
*def
, ignore_clobbers ignore_clobbers_setting
,
459 IgnorePredicate ignore
)
461 if (use_info
*use
= first_nondebug_insn_use_ignoring (def
, ignore
))
464 return first_def_ignoring (def
->next_def (), ignore_clobbers_setting
,
468 // Return true if ACCESS1 should before ACCESS2 in an access_array.
470 compare_access_infos (const access_info
*access1
, const access_info
*access2
)
472 gcc_checking_assert (access1
== access2
473 || access1
->regno () != access2
->regno ());
474 return access1
->regno () < access2
->regno ();
477 // Sort [BEGIN, END) into ascending regno order. The sequence must have
478 // at most one access to a given a regno.
480 sort_accesses (access_info
**begin
, access_info
**end
)
482 auto count
= end
- begin
;
488 gcc_checking_assert (begin
[0]->regno () != begin
[1]->regno ());
489 if (begin
[0]->regno () > begin
[1]->regno ())
490 std::swap (begin
[0], begin
[1]);
494 std::sort (begin
, end
, compare_access_infos
);
497 // Sort the accesses in CONTAINER, which contains pointers to access_infos.
500 sort_accesses (T
&container
)
502 return sort_accesses (container
.begin (), container
.end ());
505 // The underlying non-template implementation of merge_access_arrays.
506 access_array
merge_access_arrays_base (obstack_watermark
&, access_array
,
508 // Merge access arrays ACCESSES1 and ACCESSES2, including the allocation
509 // in the area governed by WATERMARK. Return an invalid access_array if
510 // ACCESSES1 and ACCESSES2 contain conflicting accesses to the same resource.
512 // T can be an access_array, a def_array or a use_array.
515 merge_access_arrays (obstack_watermark
&watermark
, T accesses1
, T accesses2
)
517 return T (merge_access_arrays_base (watermark
, accesses1
, accesses2
));
520 // The underlying non-template implementation of insert_access.
521 access_array
insert_access_base (obstack_watermark
&, access_info
*,
524 // Return a new access_array that contains the result of inserting ACCESS1
525 // into sorted access array ACCESSES2. Allocate the returned array in the
526 // area governed by WATERMARK. Return an invalid access_array if ACCESSES2
527 // contains a conflicting access to the same resource as ACCESS1.
529 // T can be an access_array, a def_array or a use_array.
532 insert_access (obstack_watermark
&watermark
,
533 typename
T::value_type access1
, T accesses2
)
535 return T (insert_access_base (watermark
, access1
, accesses2
));
538 // The underlying non-template implementation of remove_note_accesses.
539 access_array
remove_note_accesses_base (obstack_watermark
&, access_array
);
541 // If ACCESSES contains accesses that only occur in notes, return a new
542 // array without such accesses, allocating it in the area governed by
543 // WATERMARK. Return ACCESSES itself otherwise.
545 // T can be an access_array, a def_array or a use_array.
548 remove_note_accesses (obstack_watermark
&watermark
, T accesses
)
550 return T (remove_note_accesses_base (watermark
, accesses
));