Mercurial > hg > CbC > CbC_gcc
annotate gcc/regmove.c @ 59:5b5b9ea5b220
fix
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 15 Feb 2010 17:22:24 +0900 |
parents | 77e2b8dfacca |
children | b7f97abdc517 |
rev | line source |
---|---|
0 | 1 /* Move registers around to reduce number of move instructions needed. |
2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, | |
3 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 | |
4 Free Software Foundation, Inc. | |
5 | |
6 This file is part of GCC. | |
7 | |
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 | |
10 Software Foundation; either version 3, or (at your option) any later | |
11 version. | |
12 | |
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. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with GCC; see the file COPYING3. If not see | |
20 <http://www.gnu.org/licenses/>. */ | |
21 | |
22 | |
23 /* This module makes some simple RTL code transformations which | |
24 improve the subsequent register allocation. */ | |
25 | |
26 #include "config.h" | |
27 #include "system.h" | |
28 #include "coretypes.h" | |
29 #include "tm.h" | |
30 #include "rtl.h" /* stdio.h must precede rtl.h for FFS. */ | |
31 #include "tm_p.h" | |
32 #include "insn-config.h" | |
33 #include "recog.h" | |
34 #include "output.h" | |
35 #include "regs.h" | |
36 #include "hard-reg-set.h" | |
37 #include "flags.h" | |
38 #include "function.h" | |
39 #include "expr.h" | |
40 #include "basic-block.h" | |
41 #include "except.h" | |
42 #include "toplev.h" | |
43 #include "reload.h" | |
44 #include "timevar.h" | |
45 #include "tree-pass.h" | |
46 #include "df.h" | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
47 #include "ira.h" |
0 | 48 |
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); | |
52 static void copy_src_to_dest (rtx, rtx, rtx); | |
53 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
54 enum match_use |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
55 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
56 READ, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
57 WRITE, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
58 READWRITE |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
59 }; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
60 |
0 | 61 struct match { |
62 int with[MAX_RECOG_OPERANDS]; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
63 enum match_use use[MAX_RECOG_OPERANDS]; |
0 | 64 int commutative[MAX_RECOG_OPERANDS]; |
65 int early_clobber[MAX_RECOG_OPERANDS]; | |
66 }; | |
67 | |
68 static int find_matches (rtx, struct match *); | |
69 static int fixup_match_2 (rtx, rtx, rtx, rtx); | |
70 | |
71 /* Return nonzero if registers with CLASS1 and CLASS2 can be merged without | |
72 causing too much register allocation problems. */ | |
73 static int | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
74 regclass_compatible_p (enum reg_class class0, enum reg_class class1) |
0 | 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 | |
83 | |
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) | |
97 { | |
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; | |
103 | |
104 if (code == MEM && XEXP (x, 0) == reg && plusconst == 0) | |
105 return x; | |
106 | |
107 if (code == MEM && GET_CODE (XEXP (x, 0)) == PLUS | |
108 && XEXP (XEXP (x, 0), 0) == reg | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
109 && CONST_INT_P (XEXP (XEXP (x, 0), 1)) |
0 | 110 && INTVAL (XEXP (XEXP (x, 0), 1)) == plusconst) |
111 return x; | |
112 | |
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 } | |
120 | |
121 if (x == reg) | |
122 return (rtx) (size_t) 1; | |
123 | |
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 } | |
147 | |
148 return value; | |
149 } | |
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), | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
188 gen_rtx_fmt_e (inc_code, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
189 GET_MODE (XEXP (use, 0)), reg), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
190 1); |
0 | 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) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
201 PUT_REG_NOTE_KIND (note, REG_UNUSED); |
0 | 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 | |
217 static int *regno_src_regno; | |
218 | |
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 | |
224 with DEST and let SRC die in INSN. | |
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 | |
231 optimize_reg_copy_1 (rtx insn, rtx dest, rtx src) | |
232 { | |
233 rtx p, q; | |
234 rtx note; | |
235 rtx dest_death = 0; | |
236 int sregno = REGNO (src); | |
237 int dregno = REGNO (dest); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
238 basic_block bb = BLOCK_FOR_INSN (insn); |
0 | 239 |
240 /* We don't want to mess with hard regs if register classes are small. */ | |
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 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
252 if (! INSN_P (p)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
253 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
254 if (BLOCK_FOR_INSN (p) != bb) |
0 | 255 break; |
256 | |
257 if (reg_set_p (src, p) || reg_set_p (dest, p) | |
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))) | |
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)) | |
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; | |
282 int d_length = 0; | |
283 int s_length = 0; | |
284 int d_n_calls = 0; | |
285 int s_n_calls = 0; | |
286 int s_freq_calls = 0; | |
287 int d_freq_calls = 0; | |
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; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
309 |
0 | 310 /* Attempt to replace all uses. */ |
311 else if (!validate_replace_rtx (src, dest, q)) | |
312 failed = 1; | |
313 | |
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))) | |
318 { | |
319 validate_replace_rtx (dest, src, q); | |
320 failed = 1; | |
321 } | |
322 } | |
323 | |
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. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
327 if (!DEBUG_INSN_P (p)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
328 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
329 s_length++; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
330 if (dest_death) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
331 d_length++; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
332 } |
0 | 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. */ | |
336 if (q != p && CALL_P (q)) | |
337 { | |
338 /* Similarly, total calls for SREGNO, total calls beyond | |
339 the death note for DREGNO. */ | |
340 s_n_calls++; | |
341 s_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); | |
342 if (dest_death) | |
343 { | |
344 d_n_calls++; | |
345 d_freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); | |
346 } | |
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 { | |
364 /* These counters need to be updated if and only if we are | |
365 going to move the REG_DEAD note. */ | |
366 if (sregno >= FIRST_PSEUDO_REGISTER) | |
367 { | |
368 if (REG_LIVE_LENGTH (sregno) >= 0) | |
369 { | |
370 REG_LIVE_LENGTH (sregno) -= s_length; | |
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 | |
378 REG_N_CALLS_CROSSED (sregno) -= s_n_calls; | |
379 REG_FREQ_CALLS_CROSSED (sregno) -= s_freq_calls; | |
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 | |
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 | |
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; | |
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; | |
409 REG_FREQ_CALLS_CROSSED (dregno) += d_freq_calls; | |
410 } | |
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 | |
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 | |
440 optimize_reg_copy_2 (rtx insn, rtx dest, rtx src) | |
441 { | |
442 rtx p, q; | |
443 rtx set; | |
444 int sregno = REGNO (src); | |
445 int dregno = REGNO (dest); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
446 basic_block bb = BLOCK_FOR_INSN (insn); |
0 | 447 |
448 for (p = NEXT_INSN (insn); p; p = NEXT_INSN (p)) | |
449 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
450 if (! INSN_P (p)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
451 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
452 if (BLOCK_FOR_INSN (p) != bb) |
0 | 453 break; |
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)) | |
464 if (INSN_P (q)) | |
465 { | |
466 if (reg_mentioned_p (dest, PATTERN (q))) | |
467 { | |
468 rtx note; | |
469 | |
470 PATTERN (q) = replace_rtx (PATTERN (q), dest, src); | |
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 } | |
477 df_insn_rescan (q); | |
478 } | |
479 | |
480 if (CALL_P (q)) | |
481 { | |
482 int freq = REG_FREQ_FROM_BB (BLOCK_FOR_INSN (q)); | |
483 REG_N_CALLS_CROSSED (dregno)--; | |
484 REG_N_CALLS_CROSSED (sregno)++; | |
485 REG_FREQ_CALLS_CROSSED (dregno) -= freq; | |
486 REG_FREQ_CALLS_CROSSED (sregno) += freq; | |
487 } | |
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) | |
499 || (CALL_P (p) && REG_N_CALLS_CROSSED (sregno) == 0)) | |
500 break; | |
501 } | |
502 } | |
503 | |
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 | |
506 it from memory. If so, try to incorporate the zero/sign extension | |
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 | |
511 optimize_reg_copy_3 (rtx insn, rtx dest, rtx src) | |
512 { | |
513 rtx src_reg = XEXP (src, 0); | |
514 int src_no = REGNO (src_reg); | |
515 int dst_no = REGNO (dest); | |
516 rtx p, set; | |
517 enum machine_mode old_mode; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
518 basic_block bb = BLOCK_FOR_INSN (insn); |
0 | 519 |
520 if (src_no < FIRST_PSEUDO_REGISTER | |
521 || dst_no < FIRST_PSEUDO_REGISTER | |
522 || ! find_reg_note (insn, REG_DEAD, src_reg) | |
523 || REG_N_DEATHS (src_no) != 1 | |
524 || REG_N_SETS (src_no) != 1) | |
525 return; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
526 |
0 | 527 for (p = PREV_INSN (insn); p && ! reg_set_p (src_reg, p); p = PREV_INSN (p)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
528 if (INSN_P (p) && BLOCK_FOR_INSN (p) != bb) |
0 | 529 break; |
530 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
531 if (! p || BLOCK_FOR_INSN (p) != bb) |
0 | 532 return; |
533 | |
534 if (! (set = single_set (p)) | |
535 || !MEM_P (SET_SRC (set)) | |
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) | |
539 || SET_DEST (set) != src_reg) | |
540 return; | |
541 | |
542 /* Be conservative: although this optimization is also valid for | |
543 volatile memory references, that could cause trouble in later passes. */ | |
544 if (MEM_VOLATILE_P (SET_SRC (set))) | |
545 return; | |
546 | |
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 | |
554 old_mode = GET_MODE (src_reg); | |
555 PUT_MODE (src_reg, GET_MODE (src)); | |
556 XEXP (src, 0) = SET_SRC (set); | |
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. */ | |
564 while (p = NEXT_INSN (p), p != insn) | |
565 { | |
566 if (! INSN_P (p)) | |
567 continue; | |
568 | |
569 /* Make a tentative change. */ | |
570 validate_replace_rtx_group (src_reg, | |
571 gen_lowpart_SUBREG (old_mode, src_reg), | |
572 p); | |
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; | |
583 } | |
584 else | |
585 { | |
586 rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX); | |
587 if (note) | |
588 remove_note (p, note); | |
589 } | |
590 } | |
591 | |
592 | |
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 | |
596 static void | |
597 copy_src_to_dest (rtx insn, rtx src, rtx dest) | |
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; | |
606 int src_regno; | |
607 int dest_regno; | |
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 | |
614 if (REG_P (src) | |
615 && REG_LIVE_LENGTH (REGNO (src)) > 0 | |
616 && REG_P (dest) | |
617 && REG_LIVE_LENGTH (REGNO (dest)) > 0 | |
618 && (set = single_set (insn)) != NULL_RTX | |
619 && !reg_mentioned_p (dest, SET_SRC (set)) | |
620 && GET_MODE (src) == GET_MODE (dest)) | |
621 { | |
622 int old_num_regs = reg_rtx_no; | |
623 | |
624 /* Generate the src->dest move. */ | |
625 start_sequence (); | |
626 emit_move_insn (dest, src); | |
627 seq = get_insns (); | |
628 end_sequence (); | |
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 } | |
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 | |
644 /* Move any notes mentioning src to the move instruction. */ | |
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 | |
663 /* Update the various register tables. */ | |
664 dest_regno = REGNO (dest); | |
665 INC_REG_N_SETS (dest_regno, 1); | |
666 REG_LIVE_LENGTH (dest_regno)++; | |
667 src_regno = REGNO (src); | |
668 if (! find_reg_note (move_insn, REG_DEAD, src)) | |
669 REG_LIVE_LENGTH (src_regno)++; | |
670 } | |
671 } | |
672 | |
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 | |
676 static basic_block *reg_set_in_bb; | |
677 | |
678 /* Size of reg_set_in_bb array. */ | |
679 static unsigned int max_reg_computed; | |
680 | |
681 | |
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 | |
689 is used in a different basic block as well as this one?). */ | |
690 | |
691 static bool | |
692 reg_is_remote_constant_p (rtx reg, rtx insn) | |
693 { | |
694 basic_block bb; | |
695 rtx p; | |
696 int max; | |
697 | |
698 if (!reg_set_in_bb) | |
699 { | |
700 max_reg_computed = max = max_reg_num (); | |
701 reg_set_in_bb = XCNEWVEC (basic_block, max); | |
702 | |
703 FOR_EACH_BB (bb) | |
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 } | |
719 } | |
720 | |
721 gcc_assert (REGNO (reg) < max_reg_computed); | |
722 if (reg_set_in_bb[REGNO (reg)] == NULL) | |
723 return false; | |
724 return (reg_set_in_bb[REGNO (reg)] != BLOCK_FOR_INSN (insn)); | |
725 } | |
726 | |
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? */ | |
742 /* cse disrupts preincrement / postdecrement sequences when it finds a | |
743 hard register as ultimate source, like the frame pointer. */ | |
744 | |
745 static int | |
746 fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset) | |
747 { | |
748 rtx p, dst_death = 0; | |
749 int length, num_calls = 0, freq_calls = 0; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
750 basic_block bb = BLOCK_FOR_INSN (insn); |
0 | 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 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
764 if (! INSN_P (p)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
765 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
766 if (BLOCK_FOR_INSN (p) != bb) |
0 | 767 break; |
768 | |
769 if (find_regno_note (p, REG_DEAD, REGNO (dst))) | |
770 dst_death = p; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
771 if (! dst_death && !DEBUG_INSN_P (p)) |
0 | 772 length++; |
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 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
778 && CONST_INT_P (XEXP (SET_SRC (pset), 1))) |
0 | 779 { |
780 HOST_WIDE_INT newconst | |
781 = INTVAL (offset) - INTVAL (XEXP (SET_SRC (pset), 1)); | |
782 rtx add = gen_add3_insn (dst, dst, GEN_INT (newconst)); | |
783 | |
784 if (add && validate_change (insn, &PATTERN (insn), add, 0)) | |
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; | |
792 REG_FREQ_CALLS_CROSSED (REGNO (dst)) += freq_calls; | |
793 } | |
794 | |
795 if (dump_file) | |
796 fprintf (dump_file, | |
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 { | |
803 if (! INSN_P (p)) | |
804 continue; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
805 if (BLOCK_FOR_INSN (p) != bb) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
806 break; |
0 | 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 { | |
816 if (! INSN_P (p)) | |
817 continue; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
818 if (BLOCK_FOR_INSN (p) != bb) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
819 break; |
0 | 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 } | |
829 } | |
830 | |
831 if (reg_set_p (dst, PATTERN (p))) | |
832 break; | |
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. */ | |
840 if (CALL_P (p)) | |
841 { | |
842 if (! dst_death) | |
843 { | |
844 num_calls++; | |
845 freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); | |
846 } | |
847 | |
848 if (REG_N_CALLS_CROSSED (REGNO (src)) == 0) | |
849 break; | |
850 | |
851 if (call_used_regs [REGNO (dst)] | |
852 || find_reg_fusage (p, CLOBBER, dst)) | |
853 break; | |
854 } | |
855 else if (reg_set_p (src, PATTERN (p))) | |
856 break; | |
857 } | |
858 | |
859 return 0; | |
860 } | |
861 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
862 /* A forward pass. Replace output operands with input operands. */ |
0 | 863 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
864 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
865 regmove_forward_pass (void) |
0 | 866 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
867 basic_block bb; |
0 | 868 rtx insn; |
869 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
870 if (! flag_expensive_optimizations) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
871 return; |
0 | 872 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
873 if (dump_file) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
874 fprintf (dump_file, "Starting forward pass...\n"); |
0 | 875 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
876 FOR_EACH_BB (bb) |
0 | 877 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
878 FOR_BB_INSNS (bb, insn) |
0 | 879 { |
880 rtx set = single_set (insn); | |
881 if (! set) | |
882 continue; | |
883 | |
884 if ((GET_CODE (SET_SRC (set)) == SIGN_EXTEND | |
885 || GET_CODE (SET_SRC (set)) == ZERO_EXTEND) | |
886 && REG_P (XEXP (SET_SRC (set), 0)) | |
887 && REG_P (SET_DEST (set))) | |
888 optimize_reg_copy_3 (insn, SET_DEST (set), SET_SRC (set)); | |
889 | |
890 if (REG_P (SET_SRC (set)) | |
891 && REG_P (SET_DEST (set))) | |
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) | |
899 { | |
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)) | |
905 { | |
906 int srcregno = REGNO (SET_SRC (set)); | |
907 if (regno_src_regno[srcregno] >= 0) | |
908 srcregno = regno_src_regno[srcregno]; | |
909 regno_src_regno[REGNO (SET_DEST (set))] = srcregno; | |
910 } | |
911 } | |
912 } | |
913 } | |
914 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
915 } |
0 | 916 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
917 /* A backward pass. Replace input operands with output operands. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
918 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
919 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
920 regmove_backward_pass (void) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
921 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
922 basic_block bb; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
923 rtx insn, prev; |
0 | 924 |
925 if (dump_file) | |
926 fprintf (dump_file, "Starting backward pass...\n"); | |
927 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
928 FOR_EACH_BB_REVERSE (bb) |
0 | 929 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
930 /* ??? Use the safe iterator because fixup_match_2 can remove |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
931 insns via try_auto_increment. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
932 FOR_BB_INSNS_REVERSE_SAFE (bb, insn, prev) |
0 | 933 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
934 struct match match; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
935 rtx copy_src, copy_dst; |
0 | 936 int op_no, match_no; |
937 int success = 0; | |
938 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
939 if (! INSN_P (insn)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
940 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
941 |
0 | 942 if (! find_matches (insn, &match)) |
943 continue; | |
944 | |
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 | |
951 copy_src = NULL_RTX; | |
952 copy_dst = NULL_RTX; | |
953 for (op_no = 0; op_no < recog_data.n_operands; op_no++) | |
954 { | |
955 rtx set, p, src, dst; | |
956 rtx src_note, dst_note; | |
957 int num_calls = 0, freq_calls = 0; | |
958 enum reg_class src_class, dst_class; | |
959 int length; | |
960 | |
961 match_no = match.with[op_no]; | |
962 | |
963 /* Nothing to do if the two operands aren't supposed to match. */ | |
964 if (match_no < 0) | |
965 continue; | |
966 | |
967 dst = recog_data.operand[match_no]; | |
968 src = recog_data.operand[op_no]; | |
969 | |
970 if (!REG_P (src)) | |
971 continue; | |
972 | |
973 if (!REG_P (dst) | |
974 || REGNO (dst) < FIRST_PSEUDO_REGISTER | |
975 || REG_LIVE_LENGTH (REGNO (dst)) < 0 | |
976 || GET_MODE (src) != GET_MODE (dst)) | |
977 continue; | |
978 | |
979 /* If the operands already match, then there is nothing to do. */ | |
980 if (operands_match_p (src, dst)) | |
981 continue; | |
982 | |
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 | |
990 set = single_set (insn); | |
991 if (! set) | |
992 continue; | |
993 | |
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 | |
1002 /* match_no/dst must be a write-only operand, and | |
1003 operand_operand/src must be a read-only operand. */ | |
1004 if (match.use[op_no] != READ | |
1005 || match.use[match_no] != WRITE) | |
1006 continue; | |
1007 | |
1008 if (match.early_clobber[match_no] | |
1009 && count_occurrences (PATTERN (insn), src, 0) > 1) | |
1010 continue; | |
1011 | |
1012 /* Make sure match_no is the destination. */ | |
1013 if (recog_data.operand[match_no] != SET_DEST (set)) | |
1014 continue; | |
1015 | |
1016 if (REGNO (src) < FIRST_PSEUDO_REGISTER) | |
1017 { | |
1018 if (GET_CODE (SET_SRC (set)) == PLUS | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1019 && CONST_INT_P (XEXP (SET_SRC (set), 1)) |
0 | 1020 && XEXP (SET_SRC (set), 0) == src |
1021 && fixup_match_2 (insn, dst, src, | |
1022 XEXP (SET_SRC (set), 1))) | |
1023 break; | |
1024 continue; | |
1025 } | |
1026 src_class = reg_preferred_class (REGNO (src)); | |
1027 dst_class = reg_preferred_class (REGNO (dst)); | |
1028 | |
1029 if (! (src_note = find_reg_note (insn, REG_DEAD, src))) | |
1030 { | |
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, | |
1035 there may be better solution available. | |
1036 | |
1037 In particular this change produced slower code for numeric | |
1038 i387 programs. */ | |
1039 | |
1040 continue; | |
1041 } | |
1042 | |
1043 if (! regclass_compatible_p (src_class, dst_class)) | |
1044 { | |
1045 if (!copy_src) | |
1046 { | |
1047 copy_src = src; | |
1048 copy_dst = dst; | |
1049 } | |
1050 continue; | |
1051 } | |
1052 | |
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))) | |
1056 { | |
1057 if (!copy_src) | |
1058 { | |
1059 copy_src = src; | |
1060 copy_dst = dst; | |
1061 } | |
1062 continue; | |
1063 } | |
1064 | |
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. */ | |
1069 | |
1070 if (reg_is_remote_constant_p (src, insn)) | |
1071 { | |
1072 if (!copy_src) | |
1073 { | |
1074 copy_src = src; | |
1075 copy_dst = dst; | |
1076 } | |
1077 continue; | |
1078 } | |
1079 | |
1080 | |
1081 if (dump_file) | |
1082 fprintf (dump_file, | |
1083 "Could fix operand %d of insn %d matching operand %d.\n", | |
1084 op_no, INSN_UID (insn), match_no); | |
1085 | |
1086 /* Scan backward to find the first instruction that uses | |
1087 the input operand. If the operand is set here, then | |
1088 replace it in both instructions with match_no. */ | |
1089 | |
1090 for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p)) | |
1091 { | |
1092 rtx pset; | |
1093 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1094 if (! INSN_P (p)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1095 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1096 if (BLOCK_FOR_INSN (p) != bb) |
0 | 1097 break; |
1098 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1099 if (!DEBUG_INSN_P (p)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1100 length++; |
0 | 1101 |
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 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1108 are multiple identical source operands. All |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1109 of them have to be changed at the same time: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1110 when validate_replace_rtx() calls |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1111 apply_change_group(). */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1112 validate_change (p, &SET_DEST (pset), dst, 1); |
0 | 1113 if (validate_replace_rtx (src, dst, insn)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1114 success = 1; |
0 | 1115 break; |
1116 } | |
1117 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1118 /* We can't make this change if DST is mentioned at |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1119 all in P, since we are going to change its value. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1120 We can't make this change if SRC is read or |
0 | 1121 partially written in P, since we are going to |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1122 eliminate SRC. However, if it's a debug insn, we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1123 can't refrain from making the change, for this |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1124 would cause codegen differences, so instead we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1125 invalidate debug expressions that reference DST, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1126 and adjust references to SRC in them so that they |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1127 become references to DST. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1128 if (reg_mentioned_p (dst, PATTERN (p))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1129 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1130 if (DEBUG_INSN_P (p)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1131 validate_change (p, &INSN_VAR_LOCATION_LOC (p), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1132 gen_rtx_UNKNOWN_VAR_LOC (), 1); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1133 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1134 break; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1135 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1136 if (reg_overlap_mentioned_p (src, PATTERN (p))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1137 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1138 if (DEBUG_INSN_P (p)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1139 validate_replace_rtx_group (src, dst, p); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1140 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1141 break; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1142 } |
0 | 1143 |
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. */ | |
1147 if (CALL_P (p)) | |
1148 { | |
1149 num_calls++; | |
1150 freq_calls += REG_FREQ_FROM_BB (BLOCK_FOR_INSN (p)); | |
1151 | |
1152 if (REG_N_CALLS_CROSSED (REGNO (dst)) == 0) | |
1153 break; | |
1154 } | |
1155 } | |
1156 | |
1157 if (success) | |
1158 { | |
1159 int dstno, srcno; | |
1160 | |
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; | |
1169 } | |
1170 /* If there is a REG_DEAD note for DST on P, then remove | |
1171 it, because DST is now set there. */ | |
1172 if ((dst_note = find_reg_note (p, REG_DEAD, dst))) | |
1173 remove_note (p, dst_note); | |
1174 | |
1175 dstno = REGNO (dst); | |
1176 srcno = REGNO (src); | |
1177 | |
1178 INC_REG_N_SETS (dstno, 1); | |
1179 INC_REG_N_SETS (srcno, -1); | |
1180 | |
1181 REG_N_CALLS_CROSSED (dstno) += num_calls; | |
1182 REG_N_CALLS_CROSSED (srcno) -= num_calls; | |
1183 REG_FREQ_CALLS_CROSSED (dstno) += freq_calls; | |
1184 REG_FREQ_CALLS_CROSSED (srcno) -= freq_calls; | |
1185 | |
1186 REG_LIVE_LENGTH (dstno) += length; | |
1187 if (REG_LIVE_LENGTH (srcno) >= 0) | |
1188 { | |
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 } | |
1196 | |
1197 if (dump_file) | |
1198 fprintf (dump_file, | |
1199 "Fixed operand %d of insn %d matching operand %d.\n", | |
1200 op_no, INSN_UID (insn), match_no); | |
1201 | |
1202 break; | |
1203 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1204 else if (num_changes_pending () > 0) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1205 cancel_changes (0); |
0 | 1206 } |
1207 | |
1208 /* If we weren't able to replace any of the alternatives, try an | |
1209 alternative approach of copying the source to the destination. */ | |
1210 if (!success && copy_src != NULL_RTX) | |
1211 copy_src_to_dest (insn, copy_src, copy_dst); | |
1212 } | |
1213 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1214 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1215 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1216 /* Main entry for the register move optimization. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1217 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1218 static unsigned int |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1219 regmove_optimize (void) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1220 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1221 int i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1222 int nregs = max_reg_num (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1223 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1224 df_note_add_problem (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1225 df_analyze (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1226 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1227 if (flag_ira_loop_pressure) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1228 ira_set_pseudo_classes (dump_file); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1229 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1230 regstat_init_n_sets_and_refs (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1231 regstat_compute_ri (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1232 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1233 regno_src_regno = XNEWVEC (int, nregs); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1234 for (i = nregs; --i >= 0; ) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1235 regno_src_regno[i] = -1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1236 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1237 /* A forward pass. Replace output operands with input operands. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1238 regmove_forward_pass (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1239 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1240 /* A backward pass. Replace input operands with output operands. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1241 regmove_backward_pass (); |
0 | 1242 |
1243 /* Clean up. */ | |
1244 free (regno_src_regno); | |
1245 if (reg_set_in_bb) | |
1246 { | |
1247 free (reg_set_in_bb); | |
1248 reg_set_in_bb = NULL; | |
1249 } | |
1250 regstat_free_n_sets_and_refs (); | |
1251 regstat_free_ri (); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1252 if (flag_ira_loop_pressure) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1253 free_reg_info (); |
0 | 1254 return 0; |
1255 } | |
1256 | |
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. | |
1260 | |
1261 Initialize the info in MATCHP based on the constraints. */ | |
1262 | |
1263 static int | |
1264 find_matches (rtx insn, struct match *matchp) | |
1265 { | |
1266 int likely_spilled[MAX_RECOG_OPERANDS]; | |
1267 int op_no; | |
1268 int any_matches = 0; | |
1269 | |
1270 extract_insn (insn); | |
1271 if (! constrain_operands (0)) | |
1272 return 0; | |
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. */ | |
1277 for (op_no = recog_data.n_operands; --op_no >= 0; ) | |
1278 matchp->with[op_no] = matchp->commutative[op_no] = -1; | |
1279 | |
1280 for (op_no = 0; op_no < recog_data.n_operands; op_no++) | |
1281 { | |
1282 const char *p; | |
1283 char c; | |
1284 int i = 0; | |
1285 | |
1286 p = recog_data.constraints[op_no]; | |
1287 | |
1288 likely_spilled[op_no] = 0; | |
1289 matchp->use[op_no] = READ; | |
1290 matchp->early_clobber[op_no] = 0; | |
1291 if (*p == '=') | |
1292 matchp->use[op_no] = WRITE; | |
1293 else if (*p == '+') | |
1294 matchp->use[op_no] = READWRITE; | |
1295 | |
1296 for (;*p && i < which_alternative; p++) | |
1297 if (*p == ',') | |
1298 i++; | |
1299 | |
1300 while ((c = *p) != '\0' && c != ',') | |
1301 { | |
1302 switch (c) | |
1303 { | |
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; | |
1322 | |
1323 p = end; | |
1324 | |
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; | |
1333 | |
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': | |
1338 if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p) )) | |
1339 likely_spilled[op_no] = 1; | |
1340 break; | |
1341 } | |
1342 p += CONSTRAINT_LEN (c, p); | |
1343 } | |
1344 } | |
1345 return any_matches; | |
1346 } | |
1347 | |
1348 | |
1349 | |
1350 static bool | |
1351 gate_handle_regmove (void) | |
1352 { | |
1353 return (optimize > 0 && flag_regmove); | |
1354 } | |
1355 | |
1356 | |
1357 struct rtl_opt_pass pass_regmove = | |
1358 { | |
1359 { | |
1360 RTL_PASS, | |
1361 "regmove", /* name */ | |
1362 gate_handle_regmove, /* gate */ | |
1363 regmove_optimize, /* execute */ | |
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 */ | |
1372 TODO_df_finish | TODO_verify_rtl_sharing | | |
1373 TODO_dump_func | | |
1374 TODO_ggc_collect /* todo_flags_finish */ | |
1375 } | |
1376 }; |