1 // RTL SSA utilities relating to instruction movement -*- C++ -*-
2 // Copyright (C) 2020-2022 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 // Restrict movement range RANGE so that the instruction is placed later
23 // than INSN. (The movement range is the range of instructions after which
24 // an instruction can be placed.)
25 inline insn_range_info
26 move_later_than (insn_range_info range
, insn_info
*insn
)
28 return { later_insn (range
.first
, insn
), range
.last
};
31 // Restrict movement range RANGE so that the instruction is placed no earlier
32 // than INSN. (The movement range is the range of instructions after which
33 // an instruction can be placed.)
34 inline insn_range_info
35 move_no_earlier_than (insn_range_info range
, insn_info
*insn
)
37 insn_info
*first
= later_insn (range
.first
, insn
->prev_nondebug_insn ());
38 return { first
, range
.last
};
41 // Restrict movement range RANGE so that the instruction is placed no later
42 // than INSN. (The movement range is the range of instructions after which
43 // an instruction can be placed.)
44 inline insn_range_info
45 move_no_later_than (insn_range_info range
, insn_info
*insn
)
47 return { range
.first
, earlier_insn (range
.last
, insn
) };
50 // Restrict movement range RANGE so that the instruction is placed earlier
51 // than INSN. (The movement range is the range of instructions after which
52 // an instruction can be placed.)
53 inline insn_range_info
54 move_earlier_than (insn_range_info range
, insn_info
*insn
)
56 insn_info
*last
= earlier_insn (range
.last
, insn
->prev_nondebug_insn ());
57 return { range
.first
, last
};
60 // Return true if it is possible to insert a new instruction after INSN.
62 can_insert_after (insn_info
*insn
)
64 return insn
->is_bb_head () || (insn
->is_real () && !insn
->is_jump ());
67 // Try to restrict move range MOVE_RANGE so that it is possible to
68 // insert INSN after both of the end points. Return true on success,
69 // otherwise leave MOVE_RANGE in an invalid state.
71 canonicalize_move_range (insn_range_info
&move_range
, insn_info
*insn
)
73 while (move_range
.first
!= insn
&& !can_insert_after (move_range
.first
))
74 move_range
.first
= move_range
.first
->next_nondebug_insn ();
75 while (move_range
.last
!= insn
&& !can_insert_after (move_range
.last
))
76 move_range
.last
= move_range
.last
->prev_nondebug_insn ();
77 return bool (move_range
);
80 // Try to restrict movement range MOVE_RANGE of INSN so that it can set
81 // or clobber REGNO. Assume that if:
83 // - an instruction I2 contains another access A to REGNO; and
84 // - IGNORE (I2) is true
88 // - A will be removed; or
89 // - something will ensure that the new definition of REGNO does not
90 // interfere with A, without this having to be enforced by I1's move range.
92 // Return true on success, otherwise leave MOVE_RANGE in an invalid state.
94 // This function only works correctly for instructions that remain within
95 // the same extended basic block.
96 template<typename IgnorePredicate
>
98 restrict_movement_for_dead_range (insn_range_info
&move_range
,
99 unsigned int regno
, insn_info
*insn
,
100 IgnorePredicate ignore
)
102 // Find a definition at or neighboring INSN.
103 resource_info resource
= full_register (regno
);
104 def_lookup dl
= crtl
->ssa
->find_def (resource
, insn
);
106 def_info
*prev
= dl
.last_def_of_prev_group ();
107 ebb_info
*ebb
= insn
->ebb ();
108 if (!prev
|| prev
->ebb () != ebb
)
110 // REGNO is not defined or used in EBB before INSN, but it
111 // might be live on entry. To keep complexity under control,
112 // handle only these cases:
114 // - If the register is not live on entry to EBB, the register is
115 // free from the start of EBB to the first definition in EBB.
117 // - Otherwise, if the register is live on entry to BB, refuse
118 // to allocate the register. We could in principle try to move
119 // the instruction to later blocks in the EBB, but it's rarely
120 // worth the effort, and could lead to linear complexity.
122 // - Otherwise, don't allow INSN to move earlier than its current
123 // block. Again, we could in principle look backwards to find where
124 // REGNO dies, but it's rarely worth the effort.
125 bb_info
*bb
= insn
->bb ();
127 if (!bitmap_bit_p (DF_LR_IN (ebb
->first_bb ()->cfg_bb ()), regno
))
128 limit
= ebb
->phi_insn ();
129 else if (bitmap_bit_p (DF_LR_IN (bb
->cfg_bb ()), regno
))
132 limit
= bb
->head_insn ();
133 move_range
= move_later_than (move_range
, limit
);
137 // Stop the instruction moving beyond the previous relevant access
139 access_info
*prev_access
140 = last_access_ignoring (prev
, ignore_clobbers::YES
, ignore
);
142 move_range
= move_later_than (move_range
, access_insn (prev_access
));
145 // Stop the instruction moving beyond the next relevant definition of REGNO.
146 def_info
*next
= dl
.matching_set_or_first_def_of_next_group ();
147 next
= first_def_ignoring (next
, ignore_clobbers::YES
, ignore
);
149 move_range
= move_earlier_than (move_range
, next
->insn ());
151 return canonicalize_move_range (move_range
, insn
);
154 // Try to restrict movement range MOVE_RANGE so that it is possible for the
155 // instruction being moved ("instruction I1") to perform all the definitions
156 // in DEFS while still preserving dependencies between those definitions
157 // and surrounding instructions. Assume that if:
159 // - DEFS contains a definition D of resource R;
160 // - an instruction I2 contains another access A to R; and
161 // - IGNORE (I2) is true
165 // - A will be removed; or
166 // - something will ensure that D and A maintain their current order,
167 // without this having to be enforced by I1's move range.
169 // Return true on success, otherwise leave MOVE_RANGE in an invalid state.
171 // This function only works correctly for instructions that remain within
172 // the same extended basic block.
173 template<typename IgnorePredicate
>
175 restrict_movement_for_defs_ignoring (insn_range_info
&move_range
,
176 def_array defs
, IgnorePredicate ignore
)
178 for (def_info
*def
: defs
)
180 // If the definition is a clobber, we can move it with respect
181 // to other clobbers.
183 // ??? We could also do this if a definition and all its uses
184 // are being moved at once.
185 bool is_clobber
= is_a
<clobber_info
*> (def
);
187 // Search back for the first unfiltered use or definition of the
190 access
= prev_access_ignoring (def
, ignore_clobbers (is_clobber
),
193 move_range
= move_later_than (move_range
, access_insn (access
));
195 // Search forward for the first unfiltered use of DEF,
196 // or the first unfiltered definition that follows DEF.
198 // We don't need to consider uses of following definitions, since
199 // if IGNORE (D->insn ()) is true for some definition D, the caller
200 // is guarantees that either
202 // - D will be removed, and thus its uses will be removed; or
203 // - D will occur after DEF, and thus D's uses will also occur
206 // This is purely a simplification: we could also process D's uses,
207 // but we don't need to.
208 access
= next_access_ignoring (def
, ignore_clobbers (is_clobber
),
211 move_range
= move_earlier_than (move_range
, access_insn (access
));
213 // If DEF sets a hard register, take any call clobbers
215 unsigned int regno
= def
->regno ();
216 if (!HARD_REGISTER_NUM_P (regno
) || is_clobber
)
219 ebb_info
*ebb
= def
->ebb ();
220 for (ebb_call_clobbers_info
*call_group
: ebb
->call_clobbers ())
222 if (!call_group
->clobbers (def
->resource ()))
225 // Exit now if we've already failed, and if the splay accesses
226 // below would be wasted work.
231 insn
= prev_call_clobbers_ignoring (*call_group
, def
->insn (),
234 move_range
= move_later_than (move_range
, insn
);
236 insn
= next_call_clobbers_ignoring (*call_group
, def
->insn (),
239 move_range
= move_earlier_than (move_range
, insn
);
243 // Make sure that we don't move stores between basic blocks, since we
244 // don't have enough information to tell whether it's safe.
245 if (def_info
*def
= memory_access (defs
))
247 move_range
= move_later_than (move_range
, def
->bb ()->head_insn ());
248 move_range
= move_earlier_than (move_range
, def
->bb ()->end_insn ());
251 return bool (move_range
);
254 // Like restrict_movement_for_defs_ignoring, but for the uses in USES.
255 template<typename IgnorePredicate
>
257 restrict_movement_for_uses_ignoring (insn_range_info
&move_range
,
258 use_array uses
, IgnorePredicate ignore
)
260 for (const use_info
*use
: uses
)
262 // Ignore uses of undefined values.
263 set_info
*set
= use
->def ();
267 // Ignore uses by debug instructions. Debug instructions are
268 // never supposed to move, and uses by debug instructions are
269 // never supposed to be transferred elsewhere, so we know that
270 // the caller must be changing the uses on the debug instruction
271 // and checking whether all new uses are available at the debug
272 // instruction's original location.
273 if (use
->is_in_debug_insn ())
276 // If the used value is defined by an instruction I2 for which
277 // IGNORE (I2) is true, the caller guarantees that I2 will occur
278 // before change.insn (). Otherwise, make sure that the use occurs
279 // after the definition.
280 insn_info
*insn
= set
->insn ();
282 move_range
= move_later_than (move_range
, insn
);
284 // Search forward for the first unfiltered definition that follows SET.
286 // We don't need to consider the uses of these definitions, since
287 // if IGNORE (D->insn ()) is true for some definition D, the caller
288 // is guarantees that either
290 // - D will be removed, and thus its uses will be removed; or
291 // - D will occur after USE, and thus D's uses will also occur
294 // This is purely a simplification: we could also process D's uses,
295 // but we don't need to.
297 def
= first_def_ignoring (set
->next_def (), ignore_clobbers::NO
,
300 move_range
= move_earlier_than (move_range
, def
->insn ());
302 // If USE uses a hard register, take any call clobbers into account too.
303 // SET will necessarily occur after any previous call clobber, so we
304 // only need to check for later clobbers.
305 unsigned int regno
= use
->regno ();
306 if (!HARD_REGISTER_NUM_P (regno
))
309 ebb_info
*ebb
= use
->ebb ();
310 for (ebb_call_clobbers_info
*call_group
: ebb
->call_clobbers ())
312 if (!call_group
->clobbers (use
->resource ()))
318 insn_info
*insn
= next_call_clobbers_ignoring (*call_group
,
319 use
->insn (), ignore
);
321 move_range
= move_earlier_than (move_range
, insn
);
325 // Make sure that we don't move loads into an earlier basic block.
327 // ??? It would be good to relax this for loads that can be safely
329 if (use_info
*use
= memory_access (uses
))
330 move_range
= move_later_than (move_range
, use
->bb ()->head_insn ());
332 return bool (move_range
);