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