Branch data Line data Source code
1 : : // Access-related utilities 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 : : // Return a referene to the whole of register REGNO.
23 : : inline resource_info
24 : 12555205 : full_register (unsigned int regno)
25 : : {
26 : 12555205 : return { GET_MODE (regno_reg_rtx[regno]), regno };
27 : : }
28 : :
29 : : // Return true if sorted array ACCESSES includes an access to hard registers.
30 : : inline bool
31 : 0 : accesses_include_hard_registers (const access_array &accesses)
32 : : {
33 : 0 : return accesses.size () && HARD_REGISTER_NUM_P (accesses.front ()->regno ());
34 : : }
35 : :
36 : : // Return true if ACCESSES includes a reference to a non-fixed hard register.
37 : : inline bool
38 : : accesses_include_nonfixed_hard_registers (access_array accesses)
39 : : {
40 : : for (access_info *access : accesses)
41 : : {
42 : : if (!HARD_REGISTER_NUM_P (access->regno ()))
43 : : break;
44 : : if (!fixed_regs[access->regno ()])
45 : : return true;
46 : : }
47 : : return false;
48 : : }
49 : :
50 : : // Return true if sorted array ACCESSES includes an access to memory.
51 : : inline bool
52 : : accesses_include_memory (const access_array &accesses)
53 : : {
54 : : return accesses.size () && accesses.back ()->is_mem ();
55 : : }
56 : :
57 : : // If sorted array ACCESSES includes an access to memory, return the access,
58 : : // otherwise return null.
59 : : template<typename T>
60 : : inline auto
61 : 55966416 : memory_access (T accesses) -> decltype (accesses[0])
62 : : {
63 : 109678119 : if (accesses.size () && accesses.back ()->is_mem ())
64 : : return accesses.back ();
65 : : return nullptr;
66 : : }
67 : :
68 : : // If ACCESSES has a memory access, drop it. Otherwise, return ACCESSES
69 : : // unchanged.
70 : : template<typename T>
71 : : inline T
72 : : drop_memory_access (T accesses)
73 : : {
74 : : if (!memory_access (accesses))
75 : : return accesses;
76 : :
77 : : access_array arr (accesses);
78 : : return T (arr.begin (), accesses.size () - 1);
79 : : }
80 : :
81 : : // Filter ACCESSES to return an access_array of only those accesses that
82 : : // satisfy PREDICATE. Alocate the new array above WATERMARK.
83 : : template<typename T, typename FilterPredicate>
84 : : inline T
85 : 742075 : filter_accesses (obstack_watermark &watermark,
86 : : T accesses,
87 : : FilterPredicate predicate)
88 : : {
89 : 742075 : access_array_builder builder (watermark);
90 : 742075 : builder.reserve (accesses.size ());
91 : 2790249 : for (auto access : accesses)
92 : 2048174 : if (predicate (access))
93 : 896773 : builder.quick_push (access);
94 : 742075 : return T (builder.finish ());
95 : 742075 : }
96 : :
97 : : // Given an array of ACCESSES, remove any access with regno REGNO.
98 : : // Allocate the new access array above WM.
99 : : template<typename T>
100 : : inline T
101 : : remove_regno_access (obstack_watermark &watermark,
102 : : T accesses, unsigned int regno)
103 : : {
104 : : using Access = decltype (accesses[0]);
105 : : auto pred = [regno](Access a) { return a->regno () != regno; };
106 : : return filter_accesses (watermark, accesses, pred);
107 : : }
108 : :
109 : : // As above, but additionally check that we actually did remove an access.
110 : : template<typename T>
111 : : inline T
112 : : check_remove_regno_access (obstack_watermark &watermark,
113 : : T accesses, unsigned regno)
114 : : {
115 : : auto orig_size = accesses.size ();
116 : : auto result = remove_regno_access (watermark, accesses, regno);
117 : : gcc_assert (result.size () < orig_size);
118 : : return result;
119 : : }
120 : :
121 : : // If sorted array ACCESSES includes a reference to REGNO, return the
122 : : // access, otherwise return null.
123 : : template<typename T>
124 : : inline auto
125 : 8670854 : find_access (T accesses, unsigned int regno) -> decltype (accesses[0])
126 : : {
127 : 8670854 : unsigned int start = 0;
128 : 8670854 : unsigned int end = accesses.size ();
129 : 21783282 : while (start < end)
130 : : {
131 : 11461787 : unsigned int mid = (start + end) / 2;
132 : 22923574 : unsigned int found = accesses[mid]->regno ();
133 : 11461787 : if (found == regno)
134 : : return accesses[mid];
135 : 4441574 : if (found < regno)
136 : 2366549 : start = mid + 1;
137 : : else
138 : : end = mid;
139 : : }
140 : : return nullptr;
141 : : }
142 : :
143 : : // If sorted array ACCESSES includes a reference to REGNO, return the
144 : : // index of the access, otherwise return -1.
145 : : inline int
146 : 2036287 : find_access_index (access_array accesses, unsigned int regno)
147 : : {
148 : 2036287 : unsigned int start = 0;
149 : 2036287 : unsigned int end = accesses.size ();
150 : 4102315 : while (start < end)
151 : : {
152 : 2066028 : unsigned int mid = (start + end) / 2;
153 : 2066028 : unsigned int found = accesses[mid]->regno ();
154 : 2066028 : if (found == regno)
155 : 2036287 : return mid;
156 : 29741 : if (found < regno)
157 : 374 : start = mid + 1;
158 : : else
159 : : end = mid;
160 : : }
161 : : return -1;
162 : : }
163 : :
164 : : // If ACCESS is a set whose result is used by at least one instruction,
165 : : // return the access as a set_info, otherwise return null.
166 : : inline const set_info *
167 : 64041587 : set_with_nondebug_insn_uses (const access_info *access)
168 : : {
169 : 64041587 : if (access->is_set_with_nondebug_insn_uses ())
170 : : // No need for as_a; this test is just as definitive.
171 : 40565730 : return static_cast<const set_info *> (access);
172 : : return nullptr;
173 : : }
174 : :
175 : : // A non-const version of the above.
176 : : inline set_info *
177 : : set_with_nondebug_insn_uses (access_info *access)
178 : : {
179 : : if (access->is_set_with_nondebug_insn_uses ())
180 : : return static_cast<set_info *> (access);
181 : : return nullptr;
182 : : }
183 : :
184 : : // ACCESS is known to be associated with an instruction rather than
185 : : // a phi node. Return which instruction that is.
186 : : inline insn_info *
187 : 53358661 : access_insn (const access_info *access)
188 : : {
189 : : // In release builds this function reduces to a single pointer reference.
190 : 53358661 : if (auto *def = dyn_cast<const def_info *> (access))
191 : 17252347 : return def->insn ();
192 : 36106314 : return as_a<const use_info *> (access)->insn ();
193 : : }
194 : :
195 : : // If ACCESS records a use, return the value that it uses. If ACCESS records
196 : : // a set, return that set. If ACCESS records a clobber, return null.
197 : : inline const set_info *
198 : : access_value (const access_info *access)
199 : : {
200 : : if (!access)
201 : : return nullptr;
202 : :
203 : : if (auto *use = dyn_cast<const use_info *> (access))
204 : : return use->def ();
205 : :
206 : : return dyn_cast<const set_info *> (access);
207 : : }
208 : :
209 : : // A non-const version of the above.
210 : : inline set_info *
211 : : access_value (access_info *access)
212 : : {
213 : : auto *const_access = const_cast<const access_info *> (access);
214 : : return const_cast<set_info *> (access_value (const_access));
215 : : }
216 : :
217 : : // If ACCESS is a degenerate phi, return the set_info that defines its input,
218 : : // otherwise return ACCESS itself.
219 : : template<typename T>
220 : : inline const T *
221 : 154617555 : look_through_degenerate_phi (const T *access)
222 : : {
223 : 19086080 : if (auto *phi = dyn_cast<const phi_info *> (access))
224 : 19086080 : if (phi->is_degenerate ())
225 : 8533105 : return phi->input_value (0);
226 : : return access;
227 : : }
228 : :
229 : : // A non-const version of the above.
230 : : template<typename T>
231 : : inline T *
232 : 154617555 : look_through_degenerate_phi (T *access)
233 : : {
234 : 154617555 : auto *const_access = const_cast<const T *> (access);
235 : 154617555 : return const_cast<T *> (look_through_degenerate_phi (const_access));
236 : : }
237 : :
238 : : // If CLOBBER is in a group, return the first clobber in the group,
239 : : // otherwise return CLOBBER itself.
240 : : inline clobber_info *
241 : 8138579 : first_clobber_in_group (clobber_info *clobber)
242 : : {
243 : 8138579 : if (clobber->is_in_group ())
244 : 8082594 : return clobber->group ()->first_clobber ();
245 : : return clobber;
246 : : }
247 : :
248 : : // If CLOBBER is in a group, return the last clobber in the group,
249 : : // otherwise return CLOBBER itself.
250 : : inline clobber_info *
251 : 8781081 : last_clobber_in_group (clobber_info *clobber)
252 : : {
253 : 8781081 : if (clobber->is_in_group ())
254 : 8781080 : return clobber->group ()->last_clobber ();
255 : : return clobber;
256 : : }
257 : :
258 : : // If DEF is a clobber in a group, return the containing group,
259 : : // otherwise return DEF.
260 : : inline def_mux
261 : 3633565 : clobber_group_or_single_def (def_info *def)
262 : : {
263 : 3633565 : if (auto *clobber = dyn_cast<clobber_info *> (def))
264 : 2160296 : if (clobber->is_in_group ())
265 : 1990007 : return clobber->group ();
266 : 1643558 : return def;
267 : : }
268 : :
269 : : // Return the first definition associated with NODE. If NODE holds
270 : : // a single set, the result is that set. If NODE holds a clobber_group,
271 : : // the result is the first clobber in the group.
272 : : inline def_info *
273 : 26234084 : first_def (def_node *node)
274 : : {
275 : 46059151 : return node->first_def ();
276 : : }
277 : :
278 : : // Likewise for something that is either a node or a single definition.
279 : : inline def_info *
280 : 1738285 : first_def (def_mux mux)
281 : : {
282 : 2685952 : return mux.first_def ();
283 : : }
284 : :
285 : : // Return the last definition associated with NODE. If NODE holds
286 : : // a single set, the result is that set. If NODE holds a clobber_group,
287 : : // the result is the last clobber in the group.
288 : : inline def_info *
289 : 3877106 : last_def (def_node *node)
290 : : {
291 : 3877106 : if (auto *group = dyn_cast<clobber_group *> (node))
292 : 2040018 : return group->last_clobber ();
293 : 1837088 : return node->first_def ();
294 : : }
295 : :
296 : : // Likewise for something that is either a node or a single definition.
297 : : inline def_info *
298 : 1895280 : last_def (def_mux mux)
299 : : {
300 : 1895280 : return mux.last_def ();
301 : : }
302 : :
303 : : // If INSN's definitions contain a single set, return that set, otherwise
304 : : // return null.
305 : : inline set_info *
306 : : single_set_info (insn_info *insn)
307 : : {
308 : : set_info *set = nullptr;
309 : : for (auto def : insn->defs ())
310 : : if (auto this_set = dyn_cast<set_info *> (def))
311 : : {
312 : : if (set)
313 : : return nullptr;
314 : : set = this_set;
315 : : }
316 : : return set;
317 : : }
318 : :
319 : : int lookup_use (splay_tree<use_info *> &, insn_info *);
320 : : int lookup_def (def_splay_tree &, insn_info *);
321 : : int lookup_clobber (clobber_tree &, insn_info *);
322 : : int lookup_call_clobbers (insn_call_clobbers_tree &, insn_info *);
323 : :
324 : : // Search backwards from immediately before INSN for the first instruction
325 : : // recorded in TREE, ignoring any instruction I for which IGNORE (I) is true.
326 : : // Return null if no such instruction exists.
327 : : template<typename IgnorePredicate>
328 : : insn_info *
329 : 7638870 : prev_call_clobbers_ignoring (insn_call_clobbers_tree &tree, insn_info *insn,
330 : : IgnorePredicate ignore)
331 : : {
332 : 7638870 : if (!tree)
333 : : return nullptr;
334 : :
335 : 7638870 : int comparison = lookup_call_clobbers (tree, insn);
336 : 9625540 : while (comparison <= 0 || ignore (tree->insn ()))
337 : : {
338 : 6157005 : if (!tree.splay_prev_node ())
339 : : return nullptr;
340 : :
341 : : comparison = 1;
342 : : }
343 : : return tree->insn ();
344 : : }
345 : :
346 : : // Search forwards from immediately after INSN for the first instruction
347 : : // recorded in TREE, ignoring any instruction I for which IGNORE (I) is true.
348 : : // Return null if no such instruction exists.
349 : : template<typename IgnorePredicate>
350 : : insn_info *
351 : 20803069 : next_call_clobbers_ignoring (insn_call_clobbers_tree &tree, insn_info *insn,
352 : : IgnorePredicate ignore)
353 : : {
354 : 20803069 : if (!tree)
355 : : return nullptr;
356 : :
357 : 20803069 : int comparison = lookup_call_clobbers (tree, insn);
358 : 30071670 : while (comparison >= 0 || ignore (tree->insn ()))
359 : : {
360 : 17512244 : if (!tree.splay_next_node ())
361 : : return nullptr;
362 : :
363 : : comparison = -1;
364 : : }
365 : 36 : return tree->insn ();
366 : : }
367 : :
368 : : // Search forwards from immediately after INSN for the first instruction
369 : : // recorded in TREE. Return null if no such instruction exists.
370 : : inline insn_info *
371 : 574 : next_call_clobbers (insn_call_clobbers_tree &tree, insn_info *insn)
372 : : {
373 : 574 : auto ignore = [](const insn_info *) { return false; };
374 : 574 : return next_call_clobbers_ignoring (tree, insn, ignore);
375 : : }
376 : :
377 : : // If ACCESS is a set, return the first use of ACCESS by a nondebug insn I
378 : : // for which IGNORE (I) is false. Return null if ACCESS is not a set or if
379 : : // no such use exists.
380 : : template<typename IgnorePredicate>
381 : : inline use_info *
382 : 41459701 : first_nondebug_insn_use_ignoring (const access_info *access,
383 : : IgnorePredicate ignore)
384 : : {
385 : 21996989 : if (const set_info *set = set_with_nondebug_insn_uses (access))
386 : : {
387 : : // Written this way to emphasize to the compiler that first_use
388 : : // must be nonnull in this situation.
389 : 21996989 : use_info *use = set->first_use ();
390 : : do
391 : : {
392 : 21996989 : if (!ignore (use->insn ()))
393 : 21996989 : return use;
394 : 0 : use = use->next_nondebug_insn_use ();
395 : : }
396 : 0 : while (use);
397 : : }
398 : : return nullptr;
399 : : }
400 : :
401 : : // If ACCESS is a set, return the last use of ACCESS by a nondebug insn I for
402 : : // which IGNORE (I) is false. Return null if ACCESS is not a set or if no
403 : : // such use exists.
404 : : template<typename IgnorePredicate>
405 : : inline use_info *
406 : 22581886 : last_nondebug_insn_use_ignoring (const access_info *access,
407 : : IgnorePredicate ignore)
408 : : {
409 : 18568741 : if (const set_info *set = set_with_nondebug_insn_uses (access))
410 : : {
411 : : // Written this way to emphasize to the compiler that
412 : : // last_nondebug_insn_use must be nonnull in this situation.
413 : 18568741 : use_info *use = set->last_nondebug_insn_use ();
414 : : do
415 : : {
416 : 19899948 : if (!ignore (use->insn ()))
417 : 14109325 : return use;
418 : 5790623 : use = use->prev_use ();
419 : : }
420 : 5790623 : while (use);
421 : : }
422 : : return nullptr;
423 : : }
424 : :
425 : : // If DEF is null, return null.
426 : : //
427 : : // Otherwise, search backwards for an access to DEF->resource (), starting at
428 : : // the end of DEF's live range. Ignore clobbers if IGNORE_CLOBBERS_SETTING
429 : : // is YES, otherwise treat them like any other access. Also ignore any
430 : : // access A for which IGNORE (access_insn (A)) is true.
431 : : //
432 : : // Thus if DEF is a set that is used by nondebug insns, the first access
433 : : // that the function considers is the last such use of the set. Otherwise,
434 : : // the first access that the function considers is DEF itself.
435 : : //
436 : : // Return the access found, or null if there is no access that meets
437 : : // the criteria.
438 : : //
439 : : // Note that this function does not consider separately-recorded call clobbers,
440 : : // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
441 : : template<typename IgnorePredicate>
442 : : access_info *
443 : 42435513 : last_access_ignoring (def_info *def, ignore_clobbers ignore_clobbers_setting,
444 : : IgnorePredicate ignore)
445 : : {
446 : 42435513 : while (def)
447 : : {
448 : 30720465 : auto *clobber = dyn_cast<clobber_info *> (def);
449 : 30720465 : if (clobber && ignore_clobbers_setting == ignore_clobbers::YES)
450 : 8138579 : def = first_clobber_in_group (clobber);
451 : : else
452 : : {
453 : 22581886 : if (use_info *use = last_nondebug_insn_use_ignoring (def, ignore))
454 : 14109325 : return use;
455 : :
456 : 8472561 : insn_info *insn = def->insn ();
457 : 8472561 : if (!ignore (insn))
458 : 8472561 : return def;
459 : : }
460 : 50574092 : def = def->prev_def ();
461 : : }
462 : : return nullptr;
463 : : }
464 : :
465 : : // Search backwards for an access to DEF->resource (), starting
466 : : // immediately before the point at which DEF occurs. Ignore clobbers
467 : : // if IGNORE_CLOBBERS_SETTING is YES, otherwise treat them like any other
468 : : // access. Also ignore any access A for which IGNORE (access_insn (A))
469 : : // is true.
470 : : //
471 : : // Thus if DEF->insn () uses DEF->resource (), that use is the first access
472 : : // that the function considers, since an instruction's uses occur strictly
473 : : // before its definitions.
474 : : //
475 : : // Note that this function does not consider separately-recorded call clobbers,
476 : : // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
477 : : template<typename IgnorePredicate>
478 : : inline access_info *
479 : 41459701 : prev_access_ignoring (def_info *def, ignore_clobbers ignore_clobbers_setting,
480 : : IgnorePredicate ignore)
481 : : {
482 : 41459701 : return last_access_ignoring (def->prev_def (), ignore_clobbers_setting,
483 : 41459701 : ignore);
484 : : }
485 : :
486 : : // If DEF is null, return null.
487 : : //
488 : : // Otherwise, search forwards for a definition of DEF->resource (),
489 : : // starting at DEF itself. Ignore clobbers if IGNORE_CLOBBERS_SETTING
490 : : // is YES, otherwise treat them like any other access. Also ignore any
491 : : // definition D for which IGNORE (D->insn ()) is true.
492 : : //
493 : : // Return the definition found, or null if there is no access that meets
494 : : // the criteria.
495 : : //
496 : : // Note that this function does not consider separately-recorded call clobbers,
497 : : // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
498 : : template<typename IgnorePredicate>
499 : : def_info *
500 : 109940816 : first_def_ignoring (def_info *def, ignore_clobbers ignore_clobbers_setting,
501 : : IgnorePredicate ignore)
502 : : {
503 : 109940816 : while (def)
504 : : {
505 : 55936635 : auto *clobber = dyn_cast<clobber_info *> (def);
506 : 55936635 : if (clobber && ignore_clobbers_setting == ignore_clobbers::YES)
507 : 8781081 : def = last_clobber_in_group (clobber);
508 : 47155554 : else if (!ignore (def->insn ()))
509 : 39253546 : return def;
510 : :
511 : 126623905 : def = def->next_def ();
512 : : }
513 : : return nullptr;
514 : : }
515 : :
516 : : // Search forwards for the next access to DEF->resource (),
517 : : // starting immediately after DEF's instruction. Ignore clobbers if
518 : : // IGNORE_CLOBBERS_SETTING is YES, otherwise treat them like any other access.
519 : : // Also ignore any access A for which IGNORE (access_insn (A)) is true;
520 : : // in this context, ignoring a set includes ignoring all uses of the set.
521 : : //
522 : : // Thus if DEF is a set with uses by nondebug insns, the first access that the
523 : : // function considers is the first such use of the set.
524 : : //
525 : : // Return the access found, or null if there is no access that meets the
526 : : // criteria.
527 : : //
528 : : // Note that this function does not consider separately-recorded call clobbers,
529 : : // although such clobbers are only relevant if IGNORE_CLOBBERS_SETTING is NO.
530 : : template<typename IgnorePredicate>
531 : : access_info *
532 : 41459701 : next_access_ignoring (def_info *def, ignore_clobbers ignore_clobbers_setting,
533 : : IgnorePredicate ignore)
534 : : {
535 : 41459701 : if (use_info *use = first_nondebug_insn_use_ignoring (def, ignore))
536 : : return use;
537 : :
538 : 19462712 : return first_def_ignoring (def->next_def (), ignore_clobbers_setting,
539 : 19462712 : ignore);
540 : : }
541 : :
542 : : // Return true if ACCESS1 should before ACCESS2 in an access_array.
543 : : inline bool
544 : 346734728 : compare_access_infos (const access_info *access1, const access_info *access2)
545 : : {
546 : 346734728 : gcc_checking_assert (access1 == access2
547 : : || access1->regno () != access2->regno ());
548 : 346734728 : return access1->regno () < access2->regno ();
549 : : }
550 : :
551 : : // Sort [BEGIN, END) into ascending regno order. The sequence must have
552 : : // at most one access to a given a regno.
553 : : inline void
554 : 248518204 : sort_accesses (access_info **begin, access_info **end)
555 : : {
556 : 248518204 : auto count = end - begin;
557 : 248518204 : if (count <= 1)
558 : : return;
559 : :
560 : 90893327 : if (count == 2)
561 : : {
562 : 58785369 : gcc_checking_assert (begin[0]->regno () != begin[1]->regno ());
563 : 58785369 : if (begin[0]->regno () > begin[1]->regno ())
564 : 40437316 : std::swap (begin[0], begin[1]);
565 : 58785369 : return;
566 : : }
567 : :
568 : 32107958 : std::sort (begin, end, compare_access_infos);
569 : : }
570 : :
571 : : // Sort the accesses in CONTAINER, which contains pointers to access_infos.
572 : : template<typename T>
573 : : inline void
574 : 248518204 : sort_accesses (T &container)
575 : : {
576 : 745554612 : return sort_accesses (container.begin (), container.end ());
577 : : }
578 : :
579 : : // The underlying non-template implementation of merge_access_arrays.
580 : : access_array merge_access_arrays_base (obstack_watermark &, access_array,
581 : : access_array);
582 : : // Merge access arrays ACCESSES1 and ACCESSES2, including the allocation
583 : : // in the area governed by WATERMARK. Return an invalid access_array if
584 : : // ACCESSES1 and ACCESSES2 contain conflicting accesses to the same resource.
585 : : //
586 : : // T can be an access_array, a def_array or a use_array.
587 : : template<typename T>
588 : : inline T
589 : 30200567 : merge_access_arrays (obstack_watermark &watermark, T accesses1, T accesses2)
590 : : {
591 : 30200567 : return T (merge_access_arrays_base (watermark, accesses1, accesses2));
592 : : }
593 : :
594 : : // The underlying non-template implementation of insert_access.
595 : : access_array insert_access_base (obstack_watermark &, access_info *,
596 : : access_array);
597 : :
598 : : // Return a new access_array that contains the result of inserting ACCESS1
599 : : // into sorted access array ACCESSES2. Allocate the returned array in the
600 : : // area governed by WATERMARK. Return an invalid access_array if ACCESSES2
601 : : // contains a conflicting access to the same resource as ACCESS1.
602 : : //
603 : : // T can be an access_array, a def_array or a use_array.
604 : : template<typename T>
605 : : inline T
606 : 1650641 : insert_access (obstack_watermark &watermark,
607 : : typename T::value_type access1, T accesses2)
608 : : {
609 : 1650641 : return T (insert_access_base (watermark, access1, accesses2));
610 : : }
611 : :
612 : : // Return a copy of USES that drops any use of DEF.
613 : : use_array remove_uses_of_def (obstack_watermark &, use_array uses,
614 : : def_info *def);
615 : :
616 : : // The underlying non-template implementation of remove_note_accesses.
617 : : access_array remove_note_accesses_base (obstack_watermark &, access_array);
618 : :
619 : : // If ACCESSES contains accesses that only occur in notes, return a new
620 : : // array without such accesses, allocating it in the area governed by
621 : : // WATERMARK. Return ACCESSES itself otherwise.
622 : : //
623 : : // T can be an access_array, a def_array or a use_array.
624 : : template<typename T>
625 : : inline T
626 : 41913914 : remove_note_accesses (obstack_watermark &watermark, T accesses)
627 : : {
628 : 41913914 : return T (remove_note_accesses_base (watermark, accesses));
629 : : }
630 : :
631 : : // Return true if ACCESSES1 and ACCESSES2 have at least one resource in common.
632 : : bool accesses_reference_same_resource (access_array accesses1,
633 : : access_array accesses2);
634 : :
635 : : // Return true if INSN clobbers the value of any resources in ACCESSES.
636 : : bool insn_clobbers_resources (insn_info *insn, access_array accesses);
637 : :
638 : : }
|