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