]>
Commit | Line | Data |
---|---|---|
8c660648 | 1 | /* Move registers around to reduce number of move instructions needed. |
7c475d11 JM |
2 | Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
3 | 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | |
6fb5fa3c | 4 | Free Software Foundation, Inc. |
8c660648 | 5 | |
1322177d | 6 | This file is part of GCC. |
8c660648 | 7 | |
1322177d LB |
8 | GCC is free software; you can redistribute it and/or modify it under |
9 | the terms of the GNU General Public License as published by the Free | |
9dcd6f09 | 10 | Software Foundation; either version 3, or (at your option) any later |
1322177d | 11 | version. |
8c660648 | 12 | |
1322177d LB |
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
8c660648 JL |
17 | |
18 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
8c660648 JL |
21 | |
22 | ||
2af2dbdc VM |
23 | /* This module makes some simple RTL code transformations which |
24 | improve the subsequent register allocation. */ | |
8c660648 JL |
25 | |
26 | #include "config.h" | |
670ee920 | 27 | #include "system.h" |
4977bab6 ZW |
28 | #include "coretypes.h" |
29 | #include "tm.h" | |
676dd4d4 | 30 | #include "rtl.h" |
6baf1cc8 | 31 | #include "tm_p.h" |
8c660648 JL |
32 | #include "insn-config.h" |
33 | #include "recog.h" | |
42db504c | 34 | #include "target.h" |
8c660648 | 35 | #include "regs.h" |
184bb750 R |
36 | #include "hard-reg-set.h" |
37 | #include "flags.h" | |
49ad7cfa | 38 | #include "function.h" |
184bb750 | 39 | #include "expr.h" |
ddc8bed2 | 40 | #include "basic-block.h" |
1a5428f7 | 41 | #include "except.h" |
718f9c0f | 42 | #include "diagnostic-core.h" |
8461e984 | 43 | #include "reload.h" |
ef330312 | 44 | #include "tree-pass.h" |
6fb5fa3c | 45 | #include "df.h" |
1833192f | 46 | #include "ira.h" |
595c2290 | 47 | |
0c20a65f AJ |
48 | static int optimize_reg_copy_1 (rtx, rtx, rtx); |
49 | static void optimize_reg_copy_2 (rtx, rtx, rtx); | |
50 | static void optimize_reg_copy_3 (rtx, rtx, rtx); | |
a78f3e71 | 51 | static void copy_src_to_dest (rtx, rtx, rtx); |
8c660648 | 52 | |
24b97832 ILT |
53 | enum match_use |
54 | { | |
55 | READ, | |
56 | WRITE, | |
57 | READWRITE | |
58 | }; | |
59 | ||
184bb750 R |
60 | struct match { |
61 | int with[MAX_RECOG_OPERANDS]; | |
24b97832 | 62 | enum match_use use[MAX_RECOG_OPERANDS]; |
184bb750 R |
63 | int commutative[MAX_RECOG_OPERANDS]; |
64 | int early_clobber[MAX_RECOG_OPERANDS]; | |
65 | }; | |
66 | ||
0c20a65f | 67 | static int find_matches (rtx, struct match *); |
10d22567 | 68 | static int fixup_match_2 (rtx, rtx, rtx, rtx); |
8c660648 | 69 | |
40f03658 | 70 | /* Return nonzero if registers with CLASS1 and CLASS2 can be merged without |
3bb806ed R |
71 | causing too much register allocation problems. */ |
72 | static int | |
07b8f0a8 | 73 | regclass_compatible_p (reg_class_t class0, reg_class_t class1) |
3bb806ed R |
74 | { |
75 | return (class0 == class1 | |
76 | || (reg_class_subset_p (class0, class1) | |
07b8f0a8 | 77 | && ! targetm.class_likely_spilled_p (class0)) |
3bb806ed | 78 | || (reg_class_subset_p (class1, class0) |
07b8f0a8 | 79 | && ! targetm.class_likely_spilled_p (class1))); |
3bb806ed R |
80 | } |
81 | ||
dc2cb191 | 82 | \f |
2af2dbdc VM |
83 | #ifdef AUTO_INC_DEC |
84 | ||
85 | /* Find the place in the rtx X where REG is used as a memory address. | |
86 | Return the MEM rtx that so uses it. | |
87 | If PLUSCONST is nonzero, search instead for a memory address equivalent to | |
88 | (plus REG (const_int PLUSCONST)). | |
89 | ||
90 | If such an address does not appear, return 0. | |
91 | If REG appears more than once, or is used other than in such an address, | |
92 | return (rtx) 1. */ | |
93 | ||
94 | static rtx | |
95 | find_use_as_address (rtx x, rtx reg, HOST_WIDE_INT plusconst) | |
184bb750 | 96 | { |
2af2dbdc VM |
97 | enum rtx_code code = GET_CODE (x); |
98 | const char * const fmt = GET_RTX_FORMAT (code); | |
99 | int i; | |
100 | rtx value = 0; | |
101 | rtx tem; | |
184bb750 | 102 | |
2af2dbdc VM |
103 | if (code == MEM && XEXP (x, 0) == reg && plusconst == 0) |
104 | return x; | |
184bb750 | 105 | |
2af2dbdc VM |
106 | if (code == MEM && GET_CODE (XEXP (x, 0)) == PLUS |
107 | && XEXP (XEXP (x, 0), 0) == reg | |
481683e1 | 108 | && CONST_INT_P (XEXP (XEXP (x, 0), 1)) |
2af2dbdc VM |
109 | && INTVAL (XEXP (XEXP (x, 0), 1)) == plusconst) |
110 | return x; | |
184bb750 | 111 | |
2af2dbdc VM |
112 | if (code == SIGN_EXTRACT || code == ZERO_EXTRACT) |
113 | { | |
114 | /* If REG occurs inside a MEM used in a bit-field reference, | |
115 | that is unacceptable. */ | |
116 | if (find_use_as_address (XEXP (x, 0), reg, 0) != 0) | |
117 | return (rtx) (size_t) 1; | |
118 | } | |
184bb750 | 119 | |
2af2dbdc VM |
120 | if (x == reg) |
121 | return (rtx) (size_t) 1; | |
184bb750 | 122 | |
2af2dbdc VM |
123 | for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) |
124 | { | |
125 | if (fmt[i] == 'e') | |
126 | { | |
127 | tem = find_use_as_address (XEXP (x, i), reg, plusconst); | |
128 | if (value == 0) | |
129 | value = tem; | |
130 | else if (tem != 0) | |
131 | return (rtx) (size_t) 1; | |
132 | } | |
133 | else if (fmt[i] == 'E') | |
134 | { | |
135 | int j; | |
136 | for (j = XVECLEN (x, i) - 1; j >= 0; j--) | |
137 | { | |
138 | tem = find_use_as_address (XVECEXP (x, i, j), reg, plusconst); | |
139 | if (value == 0) | |
140 | value = tem; | |
141 | else if (tem != 0) | |
142 | return (rtx) (size_t) 1; | |
143 | } | |
144 | } | |
145 | } | |
184bb750 | 146 | |
2af2dbdc | 147 | return value; |
184bb750 | 148 | } |
2af2dbdc VM |
149 | |
150 | ||
151 | /* INC_INSN is an instruction that adds INCREMENT to REG. | |
152 | Try to fold INC_INSN as a post/pre in/decrement into INSN. | |
153 | Iff INC_INSN_SET is nonzero, inc_insn has a destination different from src. | |
154 | Return nonzero for success. */ | |
155 | static int | |
156 | try_auto_increment (rtx insn, rtx inc_insn, rtx inc_insn_set, rtx reg, | |
157 | HOST_WIDE_INT increment, int pre) | |
158 | { | |
159 | enum rtx_code inc_code; | |
160 | ||
161 | rtx pset = single_set (insn); | |
162 | if (pset) | |
163 | { | |
164 | /* Can't use the size of SET_SRC, we might have something like | |
165 | (sign_extend:SI (mem:QI ... */ | |
166 | rtx use = find_use_as_address (pset, reg, 0); | |
167 | if (use != 0 && use != (rtx) (size_t) 1) | |
168 | { | |
169 | int size = GET_MODE_SIZE (GET_MODE (use)); | |
170 | if (0 | |
171 | || (HAVE_POST_INCREMENT | |
172 | && pre == 0 && (inc_code = POST_INC, increment == size)) | |
173 | || (HAVE_PRE_INCREMENT | |
174 | && pre == 1 && (inc_code = PRE_INC, increment == size)) | |
175 | || (HAVE_POST_DECREMENT | |
176 | && pre == 0 && (inc_code = POST_DEC, increment == -size)) | |
177 | || (HAVE_PRE_DECREMENT | |
178 | && pre == 1 && (inc_code = PRE_DEC, increment == -size)) | |
179 | ) | |
180 | { | |
181 | if (inc_insn_set) | |
182 | validate_change | |
183 | (inc_insn, | |
184 | &SET_SRC (inc_insn_set), | |
185 | XEXP (SET_SRC (inc_insn_set), 0), 1); | |
186 | validate_change (insn, &XEXP (use, 0), | |
d4ebfa65 BE |
187 | gen_rtx_fmt_e (inc_code, |
188 | GET_MODE (XEXP (use, 0)), reg), | |
189 | 1); | |
2af2dbdc VM |
190 | if (apply_change_group ()) |
191 | { | |
192 | /* If there is a REG_DEAD note on this insn, we must | |
193 | change this not to REG_UNUSED meaning that the register | |
194 | is set, but the value is dead. Failure to do so will | |
195 | result in sched1 dying -- when it recomputes lifetime | |
196 | information, the number of REG_DEAD notes will have | |
197 | changed. */ | |
198 | rtx note = find_reg_note (insn, REG_DEAD, reg); | |
199 | if (note) | |
32e8bb8e | 200 | PUT_REG_NOTE_KIND (note, REG_UNUSED); |
2af2dbdc VM |
201 | |
202 | add_reg_note (insn, REG_INC, reg); | |
203 | ||
204 | if (! inc_insn_set) | |
205 | delete_insn (inc_insn); | |
206 | return 1; | |
207 | } | |
208 | } | |
209 | } | |
210 | } | |
211 | return 0; | |
212 | } | |
213 | #endif | |
214 | ||
215 | \f | |
216 | static int *regno_src_regno; | |
217 | ||
1230327b R |
218 | /* INSN is a copy from SRC to DEST, both registers, and SRC does not die |
219 | in INSN. | |
220 | ||
221 | Search forward to see if SRC dies before either it or DEST is modified, | |
222 | but don't scan past the end of a basic block. If so, we can replace SRC | |
174fa2c4 | 223 | with DEST and let SRC die in INSN. |
1230327b R |
224 | |
225 | This will reduce the number of registers live in that range and may enable | |
226 | DEST to be tied to SRC, thus often saving one register in addition to a | |
227 | register-register copy. */ | |
228 | ||
229 | static int | |
0c20a65f | 230 | optimize_reg_copy_1 (rtx insn, rtx dest, rtx src) |
1230327b R |
231 | { |
232 | rtx p, q; | |
233 | rtx note; | |
234 | rtx dest_death = 0; | |
235 | int sregno = REGNO (src); | |
236 | int dregno = REGNO (dest); | |
0340f2ba | 237 | basic_block bb = BLOCK_FOR_INSN (insn); |
1230327b | 238 | |
dc297297 | 239 | /* We don't want to mess with hard regs if register classes are small. */ |
1230327b | 240 | if (sregno == dregno |
42db504c | 241 | || (targetm.small_register_classes_for_mode_p (GET_MODE (src)) |
1230327b R |
242 | && (sregno < FIRST_PSEUDO_REGISTER |
243 | || dregno < FIRST_PSEUDO_REGISTER)) | |
244 | /* We don't see all updates to SP if they are in an auto-inc memory | |
245 | reference, so we must disallow this optimization on them. */ | |
246 | || sregno == STACK_POINTER_REGNUM || dregno == STACK_POINTER_REGNUM) | |
247 | return 0; | |
248 | ||
249 | for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p)) | |
250 | { | |
0340f2ba | 251 | if (! INSN_P (p)) |
1230327b | 252 | continue; |
0340f2ba SB |
253 | if (BLOCK_FOR_INSN (p) != bb) |
254 | break; | |
1230327b R |
255 | |
256 | if (reg_set_p (src, p) || reg_set_p (dest, p) | |
51928907 HPN |
257 | /* If SRC is an asm-declared register, it must not be replaced |
258 | in any asm. Unfortunately, the REG_EXPR tree for the asm | |
259 | variable may be absent in the SRC rtx, so we can't check the | |
260 | actual register declaration easily (the asm operand will have | |
261 | it, though). To avoid complicating the test for a rare case, | |
262 | we just don't perform register replacement for a hard reg | |
263 | mentioned in an asm. */ | |
264 | || (sregno < FIRST_PSEUDO_REGISTER | |
265 | && asm_noperands (PATTERN (p)) >= 0 | |
266 | && reg_overlap_mentioned_p (src, PATTERN (p))) | |
97b69e51 DJ |
267 | /* Don't change hard registers used by a call. */ |
268 | || (CALL_P (p) && sregno < FIRST_PSEUDO_REGISTER | |
269 | && find_reg_fusage (p, USE, src)) | |
1230327b R |
270 | /* Don't change a USE of a register. */ |
271 | || (GET_CODE (PATTERN (p)) == USE | |
272 | && reg_overlap_mentioned_p (src, XEXP (PATTERN (p), 0)))) | |
273 | break; | |
274 | ||
275 | /* See if all of SRC dies in P. This test is slightly more | |
276 | conservative than it needs to be. */ | |
277 | if ((note = find_regno_note (p, REG_DEAD, sregno)) != 0 | |
278 | && GET_MODE (XEXP (note, 0)) == GET_MODE (src)) | |
279 | { | |
280 | int failed = 0; | |
1230327b | 281 | int d_length = 0; |
89098dc1 | 282 | int s_length = 0; |
1230327b | 283 | int d_n_calls = 0; |
89098dc1 | 284 | int s_n_calls = 0; |
a03c6d64 JH |
285 | int s_freq_calls = 0; |
286 | int d_freq_calls = 0; | |
1230327b R |
287 | |
288 | /* We can do the optimization. Scan forward from INSN again, | |
289 | replacing regs as we go. Set FAILED if a replacement can't | |
290 | be done. In that case, we can't move the death note for SRC. | |
291 | This should be rare. */ | |
292 | ||
293 | /* Set to stop at next insn. */ | |
294 | for (q = next_real_insn (insn); | |
295 | q != next_real_insn (p); | |
296 | q = next_real_insn (q)) | |
297 | { | |
298 | if (reg_overlap_mentioned_p (src, PATTERN (q))) | |
299 | { | |
300 | /* If SRC is a hard register, we might miss some | |
301 | overlapping registers with validate_replace_rtx, | |
302 | so we would have to undo it. We can't if DEST is | |
303 | present in the insn, so fail in that combination | |
304 | of cases. */ | |
305 | if (sregno < FIRST_PSEUDO_REGISTER | |
306 | && reg_mentioned_p (dest, PATTERN (q))) | |
307 | failed = 1; | |
b8698a0f | 308 | |
040f69eb AK |
309 | /* Attempt to replace all uses. */ |
310 | else if (!validate_replace_rtx (src, dest, q)) | |
311 | failed = 1; | |
1230327b | 312 | |
040f69eb AK |
313 | /* If this succeeded, but some part of the register |
314 | is still present, undo the replacement. */ | |
315 | else if (sregno < FIRST_PSEUDO_REGISTER | |
316 | && reg_overlap_mentioned_p (src, PATTERN (q))) | |
1230327b R |
317 | { |
318 | validate_replace_rtx (dest, src, q); | |
319 | failed = 1; | |
320 | } | |
321 | } | |
322 | ||
89098dc1 JL |
323 | /* For SREGNO, count the total number of insns scanned. |
324 | For DREGNO, count the total number of insns scanned after | |
325 | passing the death note for DREGNO. */ | |
b5b8b0ac AO |
326 | if (!DEBUG_INSN_P (p)) |
327 | { | |
328 | s_length++; | |
329 | if (dest_death) | |
330 | d_length++; | |
331 | } | |
1230327b R |
332 | |
333 | /* If the insn in which SRC dies is a CALL_INSN, don't count it | |
334 | as a call that has been crossed. Otherwise, count it. */ | |
4b4bf941 | 335 | if (q != p && CALL_P (q)) |
1230327b | 336 | { |
89098dc1 JL |
337 | /* Similarly, total calls for SREGNO, total calls beyond |
338 | the death note for DREGNO. */ | |
339 | s_n_calls++; | |
a03c6d64 | 340 | s_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); |
1230327b | 341 | if (dest_death) |
a03c6d64 JH |
342 | { |
343 | d_n_calls++; | |
344 | d_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); | |
345 | } | |
1230327b R |
346 | } |
347 | ||
348 | /* If DEST dies here, remove the death note and save it for | |
349 | later. Make sure ALL of DEST dies here; again, this is | |
350 | overly conservative. */ | |
351 | if (dest_death == 0 | |
352 | && (dest_death = find_regno_note (q, REG_DEAD, dregno)) != 0) | |
353 | { | |
354 | if (GET_MODE (XEXP (dest_death, 0)) != GET_MODE (dest)) | |
355 | failed = 1, dest_death = 0; | |
356 | else | |
357 | remove_note (q, dest_death); | |
358 | } | |
359 | } | |
360 | ||
361 | if (! failed) | |
362 | { | |
89098dc1 JL |
363 | /* These counters need to be updated if and only if we are |
364 | going to move the REG_DEAD note. */ | |
1230327b R |
365 | if (sregno >= FIRST_PSEUDO_REGISTER) |
366 | { | |
367 | if (REG_LIVE_LENGTH (sregno) >= 0) | |
368 | { | |
89098dc1 | 369 | REG_LIVE_LENGTH (sregno) -= s_length; |
1230327b R |
370 | /* REG_LIVE_LENGTH is only an approximation after |
371 | combine if sched is not run, so make sure that we | |
372 | still have a reasonable value. */ | |
373 | if (REG_LIVE_LENGTH (sregno) < 2) | |
374 | REG_LIVE_LENGTH (sregno) = 2; | |
375 | } | |
376 | ||
89098dc1 | 377 | REG_N_CALLS_CROSSED (sregno) -= s_n_calls; |
a03c6d64 | 378 | REG_FREQ_CALLS_CROSSED (sregno) -= s_freq_calls; |
1230327b R |
379 | } |
380 | ||
381 | /* Move death note of SRC from P to INSN. */ | |
382 | remove_note (p, note); | |
383 | XEXP (note, 1) = REG_NOTES (insn); | |
384 | REG_NOTES (insn) = note; | |
385 | } | |
386 | ||
124d535f JW |
387 | /* DEST is also dead if INSN has a REG_UNUSED note for DEST. */ |
388 | if (! dest_death | |
389 | && (dest_death = find_regno_note (insn, REG_UNUSED, dregno))) | |
390 | { | |
391 | PUT_REG_NOTE_KIND (dest_death, REG_DEAD); | |
392 | remove_note (insn, dest_death); | |
393 | } | |
394 | ||
1230327b R |
395 | /* Put death note of DEST on P if we saw it die. */ |
396 | if (dest_death) | |
397 | { | |
398 | XEXP (dest_death, 1) = REG_NOTES (p); | |
399 | REG_NOTES (p) = dest_death; | |
89098dc1 JL |
400 | |
401 | if (dregno >= FIRST_PSEUDO_REGISTER) | |
402 | { | |
403 | /* If and only if we are moving the death note for DREGNO, | |
404 | then we need to update its counters. */ | |
405 | if (REG_LIVE_LENGTH (dregno) >= 0) | |
406 | REG_LIVE_LENGTH (dregno) += d_length; | |
407 | REG_N_CALLS_CROSSED (dregno) += d_n_calls; | |
a03c6d64 | 408 | REG_FREQ_CALLS_CROSSED (dregno) += d_freq_calls; |
89098dc1 | 409 | } |
1230327b R |
410 | } |
411 | ||
412 | return ! failed; | |
413 | } | |
414 | ||
415 | /* If SRC is a hard register which is set or killed in some other | |
416 | way, we can't do this optimization. */ | |
417 | else if (sregno < FIRST_PSEUDO_REGISTER | |
418 | && dead_or_set_p (p, src)) | |
419 | break; | |
420 | } | |
421 | return 0; | |
422 | } | |
423 | \f | |
424 | /* INSN is a copy of SRC to DEST, in which SRC dies. See if we now have | |
425 | a sequence of insns that modify DEST followed by an insn that sets | |
426 | SRC to DEST in which DEST dies, with no prior modification of DEST. | |
427 | (There is no need to check if the insns in between actually modify | |
428 | DEST. We should not have cases where DEST is not modified, but | |
429 | the optimization is safe if no such modification is detected.) | |
430 | In that case, we can replace all uses of DEST, starting with INSN and | |
431 | ending with the set of SRC to DEST, with SRC. We do not do this | |
432 | optimization if a CALL_INSN is crossed unless SRC already crosses a | |
433 | call or if DEST dies before the copy back to SRC. | |
434 | ||
435 | It is assumed that DEST and SRC are pseudos; it is too complicated to do | |
436 | this for hard registers since the substitutions we may make might fail. */ | |
437 | ||
438 | static void | |
0c20a65f | 439 | optimize_reg_copy_2 (rtx insn, rtx dest, rtx src) |
1230327b R |
440 | { |
441 | rtx p, q; | |
442 | rtx set; | |
443 | int sregno = REGNO (src); | |
444 | int dregno = REGNO (dest); | |
0340f2ba | 445 | basic_block bb = BLOCK_FOR_INSN (insn); |
1230327b R |
446 | |
447 | for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p)) | |
448 | { | |
0340f2ba | 449 | if (! INSN_P (p)) |
1230327b | 450 | continue; |
0340f2ba SB |
451 | if (BLOCK_FOR_INSN (p) != bb) |
452 | break; | |
1230327b R |
453 | |
454 | set = single_set (p); | |
455 | if (set && SET_SRC (set) == dest && SET_DEST (set) == src | |
456 | && find_reg_note (p, REG_DEAD, dest)) | |
457 | { | |
458 | /* We can do the optimization. Scan forward from INSN again, | |
459 | replacing regs as we go. */ | |
460 | ||
461 | /* Set to stop at next insn. */ | |
462 | for (q = insn; q != NEXT_INSN (p); q = NEXT_INSN (q)) | |
2c3c49de | 463 | if (INSN_P (q)) |
1230327b R |
464 | { |
465 | if (reg_mentioned_p (dest, PATTERN (q))) | |
6fb5fa3c | 466 | { |
d3a5ecb5 KK |
467 | rtx note; |
468 | ||
6fb5fa3c | 469 | PATTERN (q) = replace_rtx (PATTERN (q), dest, src); |
d3a5ecb5 KK |
470 | note = FIND_REG_INC_NOTE (q, dest); |
471 | if (note) | |
472 | { | |
473 | remove_note (q, note); | |
474 | add_reg_note (q, REG_INC, src); | |
475 | } | |
6fb5fa3c DB |
476 | df_insn_rescan (q); |
477 | } | |
1230327b | 478 | |
c7a0240a SB |
479 | if (CALL_P (q)) |
480 | { | |
a03c6d64 | 481 | int freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); |
c7a0240a SB |
482 | REG_N_CALLS_CROSSED (dregno)--; |
483 | REG_N_CALLS_CROSSED (sregno)++; | |
a03c6d64 JH |
484 | REG_FREQ_CALLS_CROSSED (dregno) -= freq; |
485 | REG_FREQ_CALLS_CROSSED (sregno) += freq; | |
c7a0240a | 486 | } |
1230327b R |
487 | } |
488 | ||
489 | remove_note (p, find_reg_note (p, REG_DEAD, dest)); | |
490 | REG_N_DEATHS (dregno)--; | |
491 | remove_note (insn, find_reg_note (insn, REG_DEAD, src)); | |
492 | REG_N_DEATHS (sregno)--; | |
493 | return; | |
494 | } | |
495 | ||
496 | if (reg_set_p (src, p) | |
497 | || find_reg_note (p, REG_DEAD, dest) | |
4b4bf941 | 498 | || (CALL_P (p) && REG_N_CALLS_CROSSED (sregno) == 0)) |
1230327b R |
499 | break; |
500 | } | |
501 | } | |
c7a0240a | 502 | |
184bb750 R |
503 | /* INSN is a ZERO_EXTEND or SIGN_EXTEND of SRC to DEST. |
504 | Look if SRC dies there, and if it is only set once, by loading | |
3d042e77 | 505 | it from memory. If so, try to incorporate the zero/sign extension |
184bb750 R |
506 | into the memory read, change SRC to the mode of DEST, and alter |
507 | the remaining accesses to use the appropriate SUBREG. This allows | |
508 | SRC and DEST to be tied later. */ | |
509 | static void | |
0c20a65f | 510 | optimize_reg_copy_3 (rtx insn, rtx dest, rtx src) |
184bb750 R |
511 | { |
512 | rtx src_reg = XEXP (src, 0); | |
513 | int src_no = REGNO (src_reg); | |
514 | int dst_no = REGNO (dest); | |
638cd7aa | 515 | rtx p, set, set_insn; |
184bb750 | 516 | enum machine_mode old_mode; |
0340f2ba | 517 | basic_block bb = BLOCK_FOR_INSN (insn); |
184bb750 R |
518 | |
519 | if (src_no < FIRST_PSEUDO_REGISTER | |
520 | || dst_no < FIRST_PSEUDO_REGISTER | |
521 | || ! find_reg_note (insn, REG_DEAD, src_reg) | |
6d80a854 | 522 | || REG_N_DEATHS (src_no) != 1 |
184bb750 R |
523 | || REG_N_SETS (src_no) != 1) |
524 | return; | |
0340f2ba | 525 | |
9c07e479 | 526 | for (p = PREV_INSN (insn); p && ! reg_set_p (src_reg, p); p = PREV_INSN (p)) |
0340f2ba | 527 | if (INSN_P (p) && BLOCK_FOR_INSN (p) != bb) |
a1c1fdd0 | 528 | break; |
b8698a0f | 529 | |
0340f2ba | 530 | if (! p || BLOCK_FOR_INSN (p) != bb) |
9c07e479 BK |
531 | return; |
532 | ||
184bb750 | 533 | if (! (set = single_set (p)) |
3c0cb5de | 534 | || !MEM_P (SET_SRC (set)) |
4fb3cbd7 BS |
535 | /* If there's a REG_EQUIV note, this must be an insn that loads an |
536 | argument. Prefer keeping the note over doing this optimization. */ | |
537 | || find_reg_note (p, REG_EQUIV, NULL_RTX) | |
184bb750 R |
538 | || SET_DEST (set) != src_reg) |
539 | return; | |
937e37cc | 540 | |
14b493d6 | 541 | /* Be conservative: although this optimization is also valid for |
972b320c R |
542 | volatile memory references, that could cause trouble in later passes. */ |
543 | if (MEM_VOLATILE_P (SET_SRC (set))) | |
544 | return; | |
545 | ||
937e37cc JL |
546 | /* Do not use a SUBREG to truncate from one mode to another if truncation |
547 | is not a nop. */ | |
548 | if (GET_MODE_BITSIZE (GET_MODE (src_reg)) <= GET_MODE_BITSIZE (GET_MODE (src)) | |
d0edd768 | 549 | && !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (src), GET_MODE (src_reg))) |
937e37cc JL |
550 | return; |
551 | ||
638cd7aa | 552 | set_insn = p; |
184bb750 R |
553 | old_mode = GET_MODE (src_reg); |
554 | PUT_MODE (src_reg, GET_MODE (src)); | |
555 | XEXP (src, 0) = SET_SRC (set); | |
e757da5e JL |
556 | |
557 | /* Include this change in the group so that it's easily undone if | |
558 | one of the changes in the group is invalid. */ | |
559 | validate_change (p, &SET_SRC (set), src, 1); | |
560 | ||
561 | /* Now walk forward making additional replacements. We want to be able | |
562 | to undo all the changes if a later substitution fails. */ | |
184bb750 R |
563 | while (p = NEXT_INSN (p), p != insn) |
564 | { | |
2c3c49de | 565 | if (! INSN_P (p)) |
184bb750 | 566 | continue; |
e757da5e | 567 | |
2067c116 | 568 | /* Make a tentative change. */ |
15ee342b EB |
569 | validate_replace_rtx_group (src_reg, |
570 | gen_lowpart_SUBREG (old_mode, src_reg), | |
571 | p); | |
e757da5e JL |
572 | } |
573 | ||
574 | validate_replace_rtx_group (src, src_reg, insn); | |
575 | ||
576 | /* Now see if all the changes are valid. */ | |
577 | if (! apply_change_group ()) | |
578 | { | |
579 | /* One or more changes were no good. Back out everything. */ | |
580 | PUT_MODE (src_reg, old_mode); | |
581 | XEXP (src, 0) = src_reg; | |
184bb750 | 582 | } |
4fb3cbd7 BS |
583 | else |
584 | { | |
638cd7aa | 585 | rtx note = find_reg_note (set_insn, REG_EQUAL, NULL_RTX); |
4fb3cbd7 | 586 | if (note) |
638cd7aa JJ |
587 | { |
588 | if (rtx_equal_p (XEXP (note, 0), XEXP (src, 0))) | |
589 | { | |
590 | XEXP (note, 0) | |
591 | = gen_rtx_fmt_e (GET_CODE (src), GET_MODE (src), | |
592 | XEXP (note, 0)); | |
593 | df_notes_rescan (set_insn); | |
594 | } | |
595 | else | |
596 | remove_note (set_insn, note); | |
597 | } | |
4fb3cbd7 | 598 | } |
184bb750 R |
599 | } |
600 | ||
ddc8bed2 MM |
601 | \f |
602 | /* If we were not able to update the users of src to use dest directly, try | |
603 | instead moving the value to dest directly before the operation. */ | |
604 | ||
cab634f2 | 605 | static void |
a78f3e71 | 606 | copy_src_to_dest (rtx insn, rtx src, rtx dest) |
ddc8bed2 MM |
607 | { |
608 | rtx seq; | |
609 | rtx link; | |
610 | rtx next; | |
611 | rtx set; | |
612 | rtx move_insn; | |
613 | rtx *p_insn_notes; | |
614 | rtx *p_move_notes; | |
ddc8bed2 MM |
615 | int src_regno; |
616 | int dest_regno; | |
ddc8bed2 MM |
617 | |
618 | /* A REG_LIVE_LENGTH of -1 indicates the register is equivalent to a constant | |
619 | or memory location and is used infrequently; a REG_LIVE_LENGTH of -2 is | |
620 | parameter when there is no frame pointer that is not allocated a register. | |
621 | For now, we just reject them, rather than incrementing the live length. */ | |
622 | ||
f8cfc6aa | 623 | if (REG_P (src) |
3ac3da71 | 624 | && REG_LIVE_LENGTH (REGNO (src)) > 0 |
f8cfc6aa | 625 | && REG_P (dest) |
3ac3da71 | 626 | && REG_LIVE_LENGTH (REGNO (dest)) > 0 |
ddc8bed2 | 627 | && (set = single_set (insn)) != NULL_RTX |
9d2106a4 R |
628 | && !reg_mentioned_p (dest, SET_SRC (set)) |
629 | && GET_MODE (src) == GET_MODE (dest)) | |
ddc8bed2 | 630 | { |
1a8fca8a R |
631 | int old_num_regs = reg_rtx_no; |
632 | ||
ddc8bed2 MM |
633 | /* Generate the src->dest move. */ |
634 | start_sequence (); | |
635 | emit_move_insn (dest, src); | |
2f937369 | 636 | seq = get_insns (); |
ddc8bed2 | 637 | end_sequence (); |
1a8fca8a R |
638 | /* If this sequence uses new registers, we may not use it. */ |
639 | if (old_num_regs != reg_rtx_no | |
640 | || ! validate_replace_rtx (src, dest, insn)) | |
641 | { | |
642 | /* We have to restore reg_rtx_no to its old value, lest | |
643 | recompute_reg_usage will try to compute the usage of the | |
644 | new regs, yet reg_n_info is not valid for them. */ | |
645 | reg_rtx_no = old_num_regs; | |
646 | return; | |
647 | } | |
ddc8bed2 MM |
648 | emit_insn_before (seq, insn); |
649 | move_insn = PREV_INSN (insn); | |
650 | p_move_notes = ®_NOTES (move_insn); | |
651 | p_insn_notes = ®_NOTES (insn); | |
652 | ||
3eae4643 | 653 | /* Move any notes mentioning src to the move instruction. */ |
ddc8bed2 MM |
654 | for (link = REG_NOTES (insn); link != NULL_RTX; link = next) |
655 | { | |
656 | next = XEXP (link, 1); | |
657 | if (XEXP (link, 0) == src) | |
658 | { | |
659 | *p_move_notes = link; | |
660 | p_move_notes = &XEXP (link, 1); | |
661 | } | |
662 | else | |
663 | { | |
664 | *p_insn_notes = link; | |
665 | p_insn_notes = &XEXP (link, 1); | |
666 | } | |
667 | } | |
668 | ||
669 | *p_move_notes = NULL_RTX; | |
670 | *p_insn_notes = NULL_RTX; | |
671 | ||
ddc8bed2 MM |
672 | /* Update the various register tables. */ |
673 | dest_regno = REGNO (dest); | |
6fb5fa3c | 674 | INC_REG_N_SETS (dest_regno, 1); |
ddc8bed2 | 675 | REG_LIVE_LENGTH (dest_regno)++; |
ddc8bed2 MM |
676 | src_regno = REGNO (src); |
677 | if (! find_reg_note (move_insn, REG_DEAD, src)) | |
678 | REG_LIVE_LENGTH (src_regno)++; | |
ddc8bed2 MM |
679 | } |
680 | } | |
681 | ||
65d169d9 JH |
682 | /* reg_set_in_bb[REGNO] points to basic block iff the register is set |
683 | only once in the given block and has REG_EQUAL note. */ | |
684 | ||
2af2dbdc | 685 | static basic_block *reg_set_in_bb; |
65d169d9 JH |
686 | |
687 | /* Size of reg_set_in_bb array. */ | |
688 | static unsigned int max_reg_computed; | |
689 | ||
ddc8bed2 | 690 | \f |
184bb750 R |
691 | /* Return whether REG is set in only one location, and is set to a |
692 | constant, but is set in a different basic block from INSN (an | |
693 | instructions which uses REG). In this case REG is equivalent to a | |
694 | constant, and we don't want to break that equivalence, because that | |
695 | may increase register pressure and make reload harder. If REG is | |
696 | set in the same basic block as INSN, we don't worry about it, | |
697 | because we'll probably need a register anyhow (??? but what if REG | |
a78f3e71 | 698 | is used in a different basic block as well as this one?). */ |
184bb750 | 699 | |
65d169d9 JH |
700 | static bool |
701 | reg_is_remote_constant_p (rtx reg, rtx insn) | |
184bb750 | 702 | { |
65d169d9 | 703 | basic_block bb; |
b3694847 | 704 | rtx p; |
65d169d9 | 705 | int max; |
184bb750 | 706 | |
65d169d9 | 707 | if (!reg_set_in_bb) |
184bb750 | 708 | { |
65d169d9 | 709 | max_reg_computed = max = max_reg_num (); |
1634b18f | 710 | reg_set_in_bb = XCNEWVEC (basic_block, max); |
184bb750 | 711 | |
65d169d9 | 712 | FOR_EACH_BB (bb) |
a78f3e71 SB |
713 | FOR_BB_INSNS (bb, p) |
714 | { | |
715 | rtx s; | |
716 | ||
717 | if (!INSN_P (p)) | |
718 | continue; | |
719 | s = single_set (p); | |
720 | /* This is the instruction which sets REG. If there is a | |
721 | REG_EQUAL note, then REG is equivalent to a constant. */ | |
722 | if (s != 0 | |
723 | && REG_P (SET_DEST (s)) | |
724 | && REG_N_SETS (REGNO (SET_DEST (s))) == 1 | |
725 | && find_reg_note (p, REG_EQUAL, NULL_RTX)) | |
726 | reg_set_in_bb[REGNO (SET_DEST (s))] = bb; | |
727 | } | |
184bb750 | 728 | } |
a78f3e71 | 729 | |
65d169d9 JH |
730 | gcc_assert (REGNO (reg) < max_reg_computed); |
731 | if (reg_set_in_bb[REGNO (reg)] == NULL) | |
732 | return false; | |
a78f3e71 | 733 | return (reg_set_in_bb[REGNO (reg)] != BLOCK_FOR_INSN (insn)); |
184bb750 R |
734 | } |
735 | ||
b1a7d591 JW |
736 | /* INSN is adding a CONST_INT to a REG. We search backwards looking for |
737 | another add immediate instruction with the same source and dest registers, | |
738 | and if we find one, we change INSN to an increment, and return 1. If | |
739 | no changes are made, we return 0. | |
740 | ||
741 | This changes | |
742 | (set (reg100) (plus reg1 offset1)) | |
743 | ... | |
744 | (set (reg100) (plus reg1 offset2)) | |
745 | to | |
746 | (set (reg100) (plus reg1 offset1)) | |
747 | ... | |
748 | (set (reg100) (plus reg100 offset2-offset1)) */ | |
749 | ||
750 | /* ??? What does this comment mean? */ | |
14b493d6 | 751 | /* cse disrupts preincrement / postdecrement sequences when it finds a |
184bb750 | 752 | hard register as ultimate source, like the frame pointer. */ |
b1a7d591 | 753 | |
95d75019 | 754 | static int |
10d22567 | 755 | fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset) |
184bb750 R |
756 | { |
757 | rtx p, dst_death = 0; | |
a03c6d64 | 758 | int length, num_calls = 0, freq_calls = 0; |
0340f2ba | 759 | basic_block bb = BLOCK_FOR_INSN (insn); |
184bb750 R |
760 | |
761 | /* If SRC dies in INSN, we'd have to move the death note. This is | |
762 | considered to be very unlikely, so we just skip the optimization | |
763 | in this case. */ | |
764 | if (find_regno_note (insn, REG_DEAD, REGNO (src))) | |
765 | return 0; | |
766 | ||
767 | /* Scan backward to find the first instruction that sets DST. */ | |
768 | ||
769 | for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p)) | |
770 | { | |
771 | rtx pset; | |
772 | ||
0340f2ba | 773 | if (! INSN_P (p)) |
a6a2274a | 774 | continue; |
0340f2ba SB |
775 | if (BLOCK_FOR_INSN (p) != bb) |
776 | break; | |
184bb750 | 777 | |
7bf825d2 JW |
778 | if (find_regno_note (p, REG_DEAD, REGNO (dst))) |
779 | dst_death = p; | |
b5b8b0ac | 780 | if (! dst_death && !DEBUG_INSN_P (p)) |
7bf825d2 | 781 | length++; |
184bb750 R |
782 | |
783 | pset = single_set (p); | |
784 | if (pset && SET_DEST (pset) == dst | |
785 | && GET_CODE (SET_SRC (pset)) == PLUS | |
786 | && XEXP (SET_SRC (pset), 0) == src | |
481683e1 | 787 | && CONST_INT_P (XEXP (SET_SRC (pset), 1))) |
a6a2274a | 788 | { |
184bb750 R |
789 | HOST_WIDE_INT newconst |
790 | = INTVAL (offset) - INTVAL (XEXP (SET_SRC (pset), 1)); | |
1a29f703 R |
791 | rtx add = gen_add3_insn (dst, dst, GEN_INT (newconst)); |
792 | ||
793 | if (add && validate_change (insn, &PATTERN (insn), add, 0)) | |
184bb750 R |
794 | { |
795 | /* Remove the death note for DST from DST_DEATH. */ | |
796 | if (dst_death) | |
797 | { | |
798 | remove_death (REGNO (dst), dst_death); | |
799 | REG_LIVE_LENGTH (REGNO (dst)) += length; | |
800 | REG_N_CALLS_CROSSED (REGNO (dst)) += num_calls; | |
a03c6d64 | 801 | REG_FREQ_CALLS_CROSSED (REGNO (dst)) += freq_calls; |
184bb750 R |
802 | } |
803 | ||
10d22567 ZD |
804 | if (dump_file) |
805 | fprintf (dump_file, | |
184bb750 R |
806 | "Fixed operand of insn %d.\n", |
807 | INSN_UID (insn)); | |
808 | ||
809 | #ifdef AUTO_INC_DEC | |
810 | for (p = PREV_INSN (insn); p; p = PREV_INSN (p)) | |
811 | { | |
2c3c49de | 812 | if (! INSN_P (p)) |
e27a5106 | 813 | continue; |
0340f2ba SB |
814 | if (BLOCK_FOR_INSN (p) != bb) |
815 | break; | |
184bb750 R |
816 | if (reg_overlap_mentioned_p (dst, PATTERN (p))) |
817 | { | |
818 | if (try_auto_increment (p, insn, 0, dst, newconst, 0)) | |
819 | return 1; | |
820 | break; | |
821 | } | |
822 | } | |
823 | for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p)) | |
824 | { | |
2c3c49de | 825 | if (! INSN_P (p)) |
8543c01e | 826 | continue; |
0340f2ba SB |
827 | if (BLOCK_FOR_INSN (p) != bb) |
828 | break; | |
184bb750 R |
829 | if (reg_overlap_mentioned_p (dst, PATTERN (p))) |
830 | { | |
831 | try_auto_increment (p, insn, 0, dst, newconst, 1); | |
832 | break; | |
833 | } | |
834 | } | |
835 | #endif | |
836 | return 1; | |
837 | } | |
a6a2274a | 838 | } |
184bb750 R |
839 | |
840 | if (reg_set_p (dst, PATTERN (p))) | |
a6a2274a | 841 | break; |
184bb750 R |
842 | |
843 | /* If we have passed a call instruction, and the | |
844 | pseudo-reg SRC is not already live across a call, | |
845 | then don't perform the optimization. */ | |
846 | /* reg_set_p is overly conservative for CALL_INSNS, thinks that all | |
847 | hard regs are clobbered. Thus, we only use it for src for | |
848 | non-call insns. */ | |
4b4bf941 | 849 | if (CALL_P (p)) |
a6a2274a | 850 | { |
184bb750 | 851 | if (! dst_death) |
a03c6d64 JH |
852 | { |
853 | num_calls++; | |
854 | freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); | |
855 | } | |
184bb750 | 856 | |
a6a2274a KH |
857 | if (REG_N_CALLS_CROSSED (REGNO (src)) == 0) |
858 | break; | |
184bb750 | 859 | |
c2db543b | 860 | if ((HARD_REGISTER_P (dst) && call_used_regs [REGNO (dst)]) |
184bb750 R |
861 | || find_reg_fusage (p, CLOBBER, dst)) |
862 | break; | |
a6a2274a | 863 | } |
184bb750 | 864 | else if (reg_set_p (src, PATTERN (p))) |
a6a2274a | 865 | break; |
8c660648 | 866 | } |
184bb750 | 867 | |
8c660648 JL |
868 | return 0; |
869 | } | |
8c660648 | 870 | |
0340f2ba | 871 | /* A forward pass. Replace output operands with input operands. */ |
3721581a | 872 | |
0340f2ba SB |
873 | static void |
874 | regmove_forward_pass (void) | |
8c660648 | 875 | { |
0340f2ba | 876 | basic_block bb; |
8c660648 | 877 | rtx insn; |
184bb750 | 878 | |
0340f2ba SB |
879 | if (! flag_expensive_optimizations) |
880 | return; | |
ddc8bed2 | 881 | |
0340f2ba SB |
882 | if (dump_file) |
883 | fprintf (dump_file, "Starting forward pass...\n"); | |
8c660648 | 884 | |
0340f2ba | 885 | FOR_EACH_BB (bb) |
8c660648 | 886 | { |
0340f2ba | 887 | FOR_BB_INSNS (bb, insn) |
8c660648 | 888 | { |
62d049cf | 889 | rtx set = single_set (insn); |
184bb750 R |
890 | if (! set) |
891 | continue; | |
8c660648 | 892 | |
62d049cf PB |
893 | if ((GET_CODE (SET_SRC (set)) == SIGN_EXTEND |
894 | || GET_CODE (SET_SRC (set)) == ZERO_EXTEND) | |
f8cfc6aa JQ |
895 | && REG_P (XEXP (SET_SRC (set), 0)) |
896 | && REG_P (SET_DEST (set))) | |
184bb750 R |
897 | optimize_reg_copy_3 (insn, SET_DEST (set), SET_SRC (set)); |
898 | ||
62d049cf | 899 | if (REG_P (SET_SRC (set)) |
f8cfc6aa | 900 | && REG_P (SET_DEST (set))) |
184bb750 R |
901 | { |
902 | /* If this is a register-register copy where SRC is not dead, | |
903 | see if we can optimize it. If this optimization succeeds, | |
904 | it will become a copy where SRC is dead. */ | |
905 | if ((find_reg_note (insn, REG_DEAD, SET_SRC (set)) | |
906 | || optimize_reg_copy_1 (insn, SET_DEST (set), SET_SRC (set))) | |
907 | && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER) | |
8c660648 | 908 | { |
184bb750 R |
909 | /* Similarly for a pseudo-pseudo copy when SRC is dead. */ |
910 | if (REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER) | |
911 | optimize_reg_copy_2 (insn, SET_DEST (set), SET_SRC (set)); | |
912 | if (regno_src_regno[REGNO (SET_DEST (set))] < 0 | |
913 | && SET_SRC (set) != SET_DEST (set)) | |
8c660648 | 914 | { |
8e2e89f7 | 915 | int srcregno = REGNO (SET_SRC (set)); |
184bb750 R |
916 | if (regno_src_regno[srcregno] >= 0) |
917 | srcregno = regno_src_regno[srcregno]; | |
918 | regno_src_regno[REGNO (SET_DEST (set))] = srcregno; | |
8c660648 JL |
919 | } |
920 | } | |
184bb750 | 921 | } |
8c660648 JL |
922 | } |
923 | } | |
0340f2ba | 924 | } |
8c660648 | 925 | |
0340f2ba SB |
926 | /* A backward pass. Replace input operands with output operands. */ |
927 | ||
928 | static void | |
929 | regmove_backward_pass (void) | |
930 | { | |
931 | basic_block bb; | |
932 | rtx insn, prev; | |
8c660648 | 933 | |
10d22567 ZD |
934 | if (dump_file) |
935 | fprintf (dump_file, "Starting backward pass...\n"); | |
8c660648 | 936 | |
0340f2ba | 937 | FOR_EACH_BB_REVERSE (bb) |
8c660648 | 938 | { |
0340f2ba | 939 | /* ??? Use the safe iterator because fixup_match_2 can remove |
b8698a0f | 940 | insns via try_auto_increment. */ |
0340f2ba | 941 | FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev) |
8c660648 | 942 | { |
0340f2ba SB |
943 | struct match match; |
944 | rtx copy_src, copy_dst; | |
0eadeb15 | 945 | int op_no, match_no; |
ddc8bed2 | 946 | int success = 0; |
0eadeb15 | 947 | |
0340f2ba SB |
948 | if (! INSN_P (insn)) |
949 | continue; | |
950 | ||
3363316f | 951 | if (! find_matches (insn, &match)) |
8c660648 JL |
952 | continue; |
953 | ||
8c660648 JL |
954 | /* Now scan through the operands looking for a destination operand |
955 | which is supposed to match a source operand. | |
956 | Then scan backward for an instruction which sets the source | |
957 | operand. If safe, then replace the source operand with the | |
958 | dest operand in both instructions. */ | |
959 | ||
ddc8bed2 MM |
960 | copy_src = NULL_RTX; |
961 | copy_dst = NULL_RTX; | |
1ccbefce | 962 | for (op_no = 0; op_no < recog_data.n_operands; op_no++) |
8c660648 | 963 | { |
184bb750 R |
964 | rtx set, p, src, dst; |
965 | rtx src_note, dst_note; | |
a03c6d64 | 966 | int num_calls = 0, freq_calls = 0; |
184bb750 R |
967 | enum reg_class src_class, dst_class; |
968 | int length; | |
8c660648 | 969 | |
0eadeb15 | 970 | match_no = match.with[op_no]; |
8c660648 | 971 | |
184bb750 | 972 | /* Nothing to do if the two operands aren't supposed to match. */ |
0eadeb15 | 973 | if (match_no < 0) |
184bb750 | 974 | continue; |
8c660648 | 975 | |
1ccbefce RH |
976 | dst = recog_data.operand[match_no]; |
977 | src = recog_data.operand[op_no]; | |
8c660648 | 978 | |
f8cfc6aa | 979 | if (!REG_P (src)) |
184bb750 | 980 | continue; |
8c660648 | 981 | |
f8cfc6aa | 982 | if (!REG_P (dst) |
184bb750 | 983 | || REGNO (dst) < FIRST_PSEUDO_REGISTER |
3721581a | 984 | || REG_LIVE_LENGTH (REGNO (dst)) < 0 |
41b3243e | 985 | || GET_MODE (src) != GET_MODE (dst)) |
184bb750 | 986 | continue; |
8c660648 | 987 | |
dc297297 | 988 | /* If the operands already match, then there is nothing to do. */ |
1ccbefce | 989 | if (operands_match_p (src, dst)) |
184bb750 | 990 | continue; |
8c660648 | 991 | |
1ccbefce RH |
992 | if (match.commutative[op_no] >= 0) |
993 | { | |
994 | rtx comm = recog_data.operand[match.commutative[op_no]]; | |
995 | if (operands_match_p (comm, dst)) | |
996 | continue; | |
997 | } | |
998 | ||
184bb750 R |
999 | set = single_set (insn); |
1000 | if (! set) | |
1001 | continue; | |
8c660648 | 1002 | |
bb948ad3 RZ |
1003 | /* Note that single_set ignores parts of a parallel set for |
1004 | which one of the destinations is REG_UNUSED. We can't | |
1005 | handle that here, since we can wind up rewriting things | |
1006 | such that a single register is set twice within a single | |
1007 | parallel. */ | |
1008 | if (reg_set_p (src, insn)) | |
1009 | continue; | |
1010 | ||
0eadeb15 | 1011 | /* match_no/dst must be a write-only operand, and |
184bb750 | 1012 | operand_operand/src must be a read-only operand. */ |
0eadeb15 BS |
1013 | if (match.use[op_no] != READ |
1014 | || match.use[match_no] != WRITE) | |
184bb750 | 1015 | continue; |
8c660648 | 1016 | |
0eadeb15 | 1017 | if (match.early_clobber[match_no] |
4b983fdc | 1018 | && count_occurrences (PATTERN (insn), src, 0) > 1) |
184bb750 | 1019 | continue; |
8c660648 | 1020 | |
0eadeb15 | 1021 | /* Make sure match_no is the destination. */ |
1ccbefce | 1022 | if (recog_data.operand[match_no] != SET_DEST (set)) |
184bb750 | 1023 | continue; |
8c660648 | 1024 | |
184bb750 R |
1025 | if (REGNO (src) < FIRST_PSEUDO_REGISTER) |
1026 | { | |
1027 | if (GET_CODE (SET_SRC (set)) == PLUS | |
481683e1 | 1028 | && CONST_INT_P (XEXP (SET_SRC (set), 1)) |
184bb750 R |
1029 | && XEXP (SET_SRC (set), 0) == src |
1030 | && fixup_match_2 (insn, dst, src, | |
10d22567 | 1031 | XEXP (SET_SRC (set), 1))) |
184bb750 R |
1032 | break; |
1033 | continue; | |
1034 | } | |
1035 | src_class = reg_preferred_class (REGNO (src)); | |
1036 | dst_class = reg_preferred_class (REGNO (dst)); | |
fd973d56 JH |
1037 | |
1038 | if (! (src_note = find_reg_note (insn, REG_DEAD, src))) | |
ddc8bed2 | 1039 | { |
fd973d56 JH |
1040 | /* We used to force the copy here like in other cases, but |
1041 | it produces worse code, as it eliminates no copy | |
1042 | instructions and the copy emitted will be produced by | |
1043 | reload anyway. On patterns with multiple alternatives, | |
14b493d6 | 1044 | there may be better solution available. |
fd973d56 JH |
1045 | |
1046 | In particular this change produced slower code for numeric | |
1047 | i387 programs. */ | |
1048 | ||
ddc8bed2 MM |
1049 | continue; |
1050 | } | |
8c660648 | 1051 | |
fd973d56 | 1052 | if (! regclass_compatible_p (src_class, dst_class)) |
ddc8bed2 MM |
1053 | { |
1054 | if (!copy_src) | |
1055 | { | |
1056 | copy_src = src; | |
1057 | copy_dst = dst; | |
1058 | } | |
1059 | continue; | |
1060 | } | |
1061 | ||
fd973d56 JH |
1062 | /* Can not modify an earlier insn to set dst if this insn |
1063 | uses an old value in the source. */ | |
1064 | if (reg_overlap_mentioned_p (dst, SET_SRC (set))) | |
ddc8bed2 MM |
1065 | { |
1066 | if (!copy_src) | |
1067 | { | |
1068 | copy_src = src; | |
1069 | copy_dst = dst; | |
1070 | } | |
1071 | continue; | |
1072 | } | |
8c660648 | 1073 | |
184bb750 R |
1074 | /* If src is set once in a different basic block, |
1075 | and is set equal to a constant, then do not use | |
1076 | it for this optimization, as this would make it | |
1077 | no longer equivalent to a constant. */ | |
ddc8bed2 | 1078 | |
65d169d9 | 1079 | if (reg_is_remote_constant_p (src, insn)) |
ddc8bed2 MM |
1080 | { |
1081 | if (!copy_src) | |
1082 | { | |
1083 | copy_src = src; | |
1084 | copy_dst = dst; | |
1085 | } | |
1086 | continue; | |
1087 | } | |
1088 | ||
1089 | ||
10d22567 ZD |
1090 | if (dump_file) |
1091 | fprintf (dump_file, | |
ddc8bed2 | 1092 | "Could fix operand %d of insn %d matching operand %d.\n", |
0eadeb15 | 1093 | op_no, INSN_UID (insn), match_no); |
8c660648 | 1094 | |
184bb750 R |
1095 | /* Scan backward to find the first instruction that uses |
1096 | the input operand. If the operand is set here, then | |
0eadeb15 | 1097 | replace it in both instructions with match_no. */ |
184bb750 R |
1098 | |
1099 | for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p)) | |
1100 | { | |
1101 | rtx pset; | |
1102 | ||
0340f2ba | 1103 | if (! INSN_P (p)) |
184bb750 | 1104 | continue; |
0340f2ba SB |
1105 | if (BLOCK_FOR_INSN (p) != bb) |
1106 | break; | |
8c660648 | 1107 | |
b5b8b0ac AO |
1108 | if (!DEBUG_INSN_P (p)) |
1109 | length++; | |
8c660648 | 1110 | |
184bb750 R |
1111 | /* ??? See if all of SRC is set in P. This test is much |
1112 | more conservative than it needs to be. */ | |
1113 | pset = single_set (p); | |
1114 | if (pset && SET_DEST (pset) == src) | |
1115 | { | |
1116 | /* We use validate_replace_rtx, in case there | |
b5b8b0ac AO |
1117 | are multiple identical source operands. All |
1118 | of them have to be changed at the same time: | |
1119 | when validate_replace_rtx() calls | |
1120 | apply_change_group(). */ | |
1121 | validate_change (p, &SET_DEST (pset), dst, 1); | |
184bb750 | 1122 | if (validate_replace_rtx (src, dst, insn)) |
b5b8b0ac | 1123 | success = 1; |
184bb750 R |
1124 | break; |
1125 | } | |
1126 | ||
968e5728 AO |
1127 | /* We can't make this change if DST is mentioned at |
1128 | all in P, since we are going to change its value. | |
1129 | We can't make this change if SRC is read or | |
1e4c6dc5 | 1130 | partially written in P, since we are going to |
968e5728 AO |
1131 | eliminate SRC. However, if it's a debug insn, we |
1132 | can't refrain from making the change, for this | |
1133 | would cause codegen differences, so instead we | |
1134 | invalidate debug expressions that reference DST, | |
1135 | and adjust references to SRC in them so that they | |
1136 | become references to DST. */ | |
1137 | if (reg_mentioned_p (dst, PATTERN (p))) | |
b5b8b0ac AO |
1138 | { |
1139 | if (DEBUG_INSN_P (p)) | |
968e5728 AO |
1140 | validate_change (p, &INSN_VAR_LOCATION_LOC (p), |
1141 | gen_rtx_UNKNOWN_VAR_LOC (), 1); | |
b5b8b0ac AO |
1142 | else |
1143 | break; | |
1144 | } | |
968e5728 | 1145 | if (reg_overlap_mentioned_p (src, PATTERN (p))) |
b5b8b0ac AO |
1146 | { |
1147 | if (DEBUG_INSN_P (p)) | |
968e5728 | 1148 | validate_replace_rtx_group (src, dst, p); |
b5b8b0ac AO |
1149 | else |
1150 | break; | |
1151 | } | |
8c660648 | 1152 | |
184bb750 R |
1153 | /* If we have passed a call instruction, and the |
1154 | pseudo-reg DST is not already live across a call, | |
1155 | then don't perform the optimization. */ | |
4b4bf941 | 1156 | if (CALL_P (p)) |
184bb750 R |
1157 | { |
1158 | num_calls++; | |
a03c6d64 | 1159 | freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); |
184bb750 R |
1160 | |
1161 | if (REG_N_CALLS_CROSSED (REGNO (dst)) == 0) | |
8c660648 | 1162 | break; |
184bb750 R |
1163 | } |
1164 | } | |
8c660648 | 1165 | |
184bb750 R |
1166 | if (success) |
1167 | { | |
1168 | int dstno, srcno; | |
8c660648 | 1169 | |
184bb750 R |
1170 | /* Remove the death note for SRC from INSN. */ |
1171 | remove_note (insn, src_note); | |
1172 | /* Move the death note for SRC to P if it is used | |
1173 | there. */ | |
1174 | if (reg_overlap_mentioned_p (src, PATTERN (p))) | |
1175 | { | |
1176 | XEXP (src_note, 1) = REG_NOTES (p); | |
1177 | REG_NOTES (p) = src_note; | |
8c660648 | 1178 | } |
184bb750 R |
1179 | /* If there is a REG_DEAD note for DST on P, then remove |
1180 | it, because DST is now set there. */ | |
5e9defae | 1181 | if ((dst_note = find_reg_note (p, REG_DEAD, dst))) |
184bb750 R |
1182 | remove_note (p, dst_note); |
1183 | ||
1184 | dstno = REGNO (dst); | |
1185 | srcno = REGNO (src); | |
1186 | ||
6fb5fa3c DB |
1187 | INC_REG_N_SETS (dstno, 1); |
1188 | INC_REG_N_SETS (srcno, -1); | |
8c660648 | 1189 | |
184bb750 R |
1190 | REG_N_CALLS_CROSSED (dstno) += num_calls; |
1191 | REG_N_CALLS_CROSSED (srcno) -= num_calls; | |
a03c6d64 JH |
1192 | REG_FREQ_CALLS_CROSSED (dstno) += freq_calls; |
1193 | REG_FREQ_CALLS_CROSSED (srcno) -= freq_calls; | |
184bb750 R |
1194 | |
1195 | REG_LIVE_LENGTH (dstno) += length; | |
1196 | if (REG_LIVE_LENGTH (srcno) >= 0) | |
8c660648 | 1197 | { |
184bb750 R |
1198 | REG_LIVE_LENGTH (srcno) -= length; |
1199 | /* REG_LIVE_LENGTH is only an approximation after | |
1200 | combine if sched is not run, so make sure that we | |
1201 | still have a reasonable value. */ | |
1202 | if (REG_LIVE_LENGTH (srcno) < 2) | |
1203 | REG_LIVE_LENGTH (srcno) = 2; | |
1204 | } | |
8c660648 | 1205 | |
10d22567 ZD |
1206 | if (dump_file) |
1207 | fprintf (dump_file, | |
184bb750 | 1208 | "Fixed operand %d of insn %d matching operand %d.\n", |
0eadeb15 | 1209 | op_no, INSN_UID (insn), match_no); |
8c660648 | 1210 | |
184bb750 | 1211 | break; |
8c660648 | 1212 | } |
b5b8b0ac AO |
1213 | else if (num_changes_pending () > 0) |
1214 | cancel_changes (0); | |
8c660648 | 1215 | } |
ddc8bed2 MM |
1216 | |
1217 | /* If we weren't able to replace any of the alternatives, try an | |
14b493d6 | 1218 | alternative approach of copying the source to the destination. */ |
ddc8bed2 | 1219 | if (!success && copy_src != NULL_RTX) |
a78f3e71 | 1220 | copy_src_to_dest (insn, copy_src, copy_dst); |
8c660648 JL |
1221 | } |
1222 | } | |
0340f2ba SB |
1223 | } |
1224 | ||
1225 | /* Main entry for the register move optimization. */ | |
1226 | ||
1227 | static unsigned int | |
1228 | regmove_optimize (void) | |
1229 | { | |
1230 | int i; | |
1231 | int nregs = max_reg_num (); | |
1232 | ||
1233 | df_note_add_problem (); | |
1234 | df_analyze (); | |
1235 | ||
99710245 VM |
1236 | regstat_init_n_sets_and_refs (); |
1237 | regstat_compute_ri (); | |
1238 | ||
1756cb66 VM |
1239 | if (flag_ira_loop_pressure) |
1240 | ira_set_pseudo_classes (dump_file); | |
1241 | ||
0340f2ba SB |
1242 | regno_src_regno = XNEWVEC (int, nregs); |
1243 | for (i = nregs; --i >= 0; ) | |
1244 | regno_src_regno[i] = -1; | |
1245 | ||
1246 | /* A forward pass. Replace output operands with input operands. */ | |
1247 | regmove_forward_pass (); | |
1248 | ||
1249 | /* A backward pass. Replace input operands with output operands. */ | |
1250 | regmove_backward_pass (); | |
961d4119 | 1251 | |
4da896b2 MM |
1252 | /* Clean up. */ |
1253 | free (regno_src_regno); | |
65d169d9 JH |
1254 | if (reg_set_in_bb) |
1255 | { | |
1256 | free (reg_set_in_bb); | |
1257 | reg_set_in_bb = NULL; | |
1258 | } | |
6fb5fa3c DB |
1259 | regstat_free_n_sets_and_refs (); |
1260 | regstat_free_ri (); | |
1833192f VM |
1261 | if (flag_ira_loop_pressure) |
1262 | free_reg_info (); | |
62d049cf | 1263 | return 0; |
8c660648 JL |
1264 | } |
1265 | ||
0eadeb15 BS |
1266 | /* Returns nonzero if INSN's pattern has matching constraints for any operand. |
1267 | Returns 0 if INSN can't be recognized, or if the alternative can't be | |
1268 | determined. | |
b1a7d591 JW |
1269 | |
1270 | Initialize the info in MATCHP based on the constraints. */ | |
184bb750 R |
1271 | |
1272 | static int | |
0c20a65f | 1273 | find_matches (rtx insn, struct match *matchp) |
184bb750 R |
1274 | { |
1275 | int likely_spilled[MAX_RECOG_OPERANDS]; | |
0eadeb15 | 1276 | int op_no; |
184bb750 R |
1277 | int any_matches = 0; |
1278 | ||
0eadeb15 BS |
1279 | extract_insn (insn); |
1280 | if (! constrain_operands (0)) | |
1281 | return 0; | |
184bb750 R |
1282 | |
1283 | /* Must initialize this before main loop, because the code for | |
1284 | the commutative case may set matches for operands other than | |
1285 | the current one. */ | |
1ccbefce | 1286 | for (op_no = recog_data.n_operands; --op_no >= 0; ) |
0eadeb15 | 1287 | matchp->with[op_no] = matchp->commutative[op_no] = -1; |
184bb750 | 1288 | |
1ccbefce | 1289 | for (op_no = 0; op_no < recog_data.n_operands; op_no++) |
184bb750 | 1290 | { |
9b3142b3 KG |
1291 | const char *p; |
1292 | char c; | |
184bb750 R |
1293 | int i = 0; |
1294 | ||
1ccbefce | 1295 | p = recog_data.constraints[op_no]; |
184bb750 | 1296 | |
0eadeb15 BS |
1297 | likely_spilled[op_no] = 0; |
1298 | matchp->use[op_no] = READ; | |
1299 | matchp->early_clobber[op_no] = 0; | |
184bb750 | 1300 | if (*p == '=') |
0eadeb15 | 1301 | matchp->use[op_no] = WRITE; |
184bb750 | 1302 | else if (*p == '+') |
0eadeb15 | 1303 | matchp->use[op_no] = READWRITE; |
184bb750 R |
1304 | |
1305 | for (;*p && i < which_alternative; p++) | |
1306 | if (*p == ',') | |
1307 | i++; | |
1308 | ||
97488870 R |
1309 | while ((c = *p) != '\0' && c != ',') |
1310 | { | |
1311 | switch (c) | |
84b72302 | 1312 | { |
97488870 R |
1313 | case '=': |
1314 | break; | |
1315 | case '+': | |
1316 | break; | |
1317 | case '&': | |
1318 | matchp->early_clobber[op_no] = 1; | |
1319 | break; | |
1320 | case '%': | |
1321 | matchp->commutative[op_no] = op_no + 1; | |
1322 | matchp->commutative[op_no + 1] = op_no; | |
1323 | break; | |
1324 | ||
1325 | case '0': case '1': case '2': case '3': case '4': | |
1326 | case '5': case '6': case '7': case '8': case '9': | |
1327 | { | |
1328 | char *end; | |
1329 | unsigned long match_ul = strtoul (p, &end, 10); | |
1330 | int match = match_ul; | |
2cc2d4bb | 1331 | |
97488870 | 1332 | p = end; |
84b72302 | 1333 | |
97488870 R |
1334 | if (match < op_no && likely_spilled[match]) |
1335 | continue; | |
1336 | matchp->with[op_no] = match; | |
1337 | any_matches = 1; | |
1338 | if (matchp->commutative[op_no] >= 0) | |
1339 | matchp->with[matchp->commutative[op_no]] = match; | |
1340 | } | |
1341 | continue; | |
84b72302 | 1342 | |
184bb750 R |
1343 | case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h': |
1344 | case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u': | |
1345 | case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B': | |
1346 | case 'C': case 'D': case 'W': case 'Y': case 'Z': | |
07b8f0a8 | 1347 | if (targetm.class_likely_spilled_p (REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p))) |
0eadeb15 | 1348 | likely_spilled[op_no] = 1; |
184bb750 R |
1349 | break; |
1350 | } | |
97488870 R |
1351 | p += CONSTRAINT_LEN (c, p); |
1352 | } | |
184bb750 | 1353 | } |
0eadeb15 | 1354 | return any_matches; |
184bb750 R |
1355 | } |
1356 | ||
1e7f0a48 | 1357 | \f |
1e7f0a48 | 1358 | |
ef330312 PB |
1359 | static bool |
1360 | gate_handle_regmove (void) | |
1361 | { | |
1362 | return (optimize > 0 && flag_regmove); | |
1363 | } | |
1364 | ||
ef330312 | 1365 | |
8ddbbcae | 1366 | struct rtl_opt_pass pass_regmove = |
ef330312 | 1367 | { |
8ddbbcae JH |
1368 | { |
1369 | RTL_PASS, | |
ef330312 PB |
1370 | "regmove", /* name */ |
1371 | gate_handle_regmove, /* gate */ | |
62d049cf | 1372 | regmove_optimize, /* execute */ |
ef330312 PB |
1373 | NULL, /* sub */ |
1374 | NULL, /* next */ | |
1375 | 0, /* static_pass_number */ | |
1376 | TV_REGMOVE, /* tv_id */ | |
1377 | 0, /* properties_required */ | |
1378 | 0, /* properties_provided */ | |
1379 | 0, /* properties_destroyed */ | |
1380 | 0, /* todo_flags_start */ | |
a36b8a1e | 1381 | TODO_df_finish | TODO_verify_rtl_sharing | |
8ddbbcae JH |
1382 | TODO_ggc_collect /* todo_flags_finish */ |
1383 | } | |
ef330312 | 1384 | }; |