Mercurial > hg > CbC > CbC_gcc
annotate gcc/resource.c @ 116:367f9f4f266e
fix gimple.h
author | mir3636 |
---|---|
date | Tue, 28 Nov 2017 20:22:01 +0900 |
parents | 04ced10e8804 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* Definitions for computing resource usage of specific insns. |
111 | 2 Copyright (C) 1999-2017 Free Software Foundation, Inc. |
0 | 3 |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify it under | |
7 the terms of the GNU General Public License as published by the Free | |
8 Software Foundation; either version 3, or (at your option) any later | |
9 version. | |
10 | |
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GCC; see the file COPYING3. If not see | |
18 <http://www.gnu.org/licenses/>. */ | |
19 | |
20 #include "config.h" | |
21 #include "system.h" | |
22 #include "coretypes.h" | |
111 | 23 #include "backend.h" |
0 | 24 #include "rtl.h" |
111 | 25 #include "df.h" |
26 #include "memmodel.h" | |
0 | 27 #include "tm_p.h" |
28 #include "regs.h" | |
111 | 29 #include "emit-rtl.h" |
0 | 30 #include "resource.h" |
31 #include "insn-attr.h" | |
32 #include "params.h" | |
33 | |
34 /* This structure is used to record liveness information at the targets or | |
35 fallthrough insns of branches. We will most likely need the information | |
36 at targets again, so save them in a hash table rather than recomputing them | |
37 each time. */ | |
38 | |
39 struct target_info | |
40 { | |
41 int uid; /* INSN_UID of target. */ | |
42 struct target_info *next; /* Next info for same hash bucket. */ | |
43 HARD_REG_SET live_regs; /* Registers live at target. */ | |
44 int block; /* Basic block number containing target. */ | |
45 int bb_tick; /* Generation count of basic block info. */ | |
46 }; | |
47 | |
48 #define TARGET_HASH_PRIME 257 | |
49 | |
50 /* Indicates what resources are required at the beginning of the epilogue. */ | |
51 static struct resources start_of_epilogue_needs; | |
52 | |
53 /* Indicates what resources are required at function end. */ | |
54 static struct resources end_of_function_needs; | |
55 | |
56 /* Define the hash table itself. */ | |
57 static struct target_info **target_hash_table = NULL; | |
58 | |
59 /* For each basic block, we maintain a generation number of its basic | |
60 block info, which is updated each time we move an insn from the | |
61 target of a jump. This is the generation number indexed by block | |
62 number. */ | |
63 | |
64 static int *bb_ticks; | |
65 | |
66 /* Marks registers possibly live at the current place being scanned by | |
67 mark_target_live_regs. Also used by update_live_status. */ | |
68 | |
69 static HARD_REG_SET current_live_regs; | |
70 | |
71 /* Marks registers for which we have seen a REG_DEAD note but no assignment. | |
72 Also only used by the next two functions. */ | |
73 | |
74 static HARD_REG_SET pending_dead_regs; | |
75 | |
76 static void update_live_status (rtx, const_rtx, void *); | |
111 | 77 static int find_basic_block (rtx_insn *, int); |
78 static rtx_insn *next_insn_no_annul (rtx_insn *); | |
79 static rtx_insn *find_dead_or_set_registers (rtx_insn *, struct resources*, | |
80 rtx *, int, struct resources, | |
81 struct resources); | |
0 | 82 |
83 /* Utility function called from mark_target_live_regs via note_stores. | |
84 It deadens any CLOBBERed registers and livens any SET registers. */ | |
85 | |
86 static void | |
87 update_live_status (rtx dest, const_rtx x, void *data ATTRIBUTE_UNUSED) | |
88 { | |
89 int first_regno, last_regno; | |
90 int i; | |
91 | |
92 if (!REG_P (dest) | |
93 && (GET_CODE (dest) != SUBREG || !REG_P (SUBREG_REG (dest)))) | |
94 return; | |
95 | |
96 if (GET_CODE (dest) == SUBREG) | |
97 { | |
98 first_regno = subreg_regno (dest); | |
99 last_regno = first_regno + subreg_nregs (dest); | |
100 | |
101 } | |
102 else | |
103 { | |
104 first_regno = REGNO (dest); | |
111 | 105 last_regno = END_REGNO (dest); |
0 | 106 } |
107 | |
108 if (GET_CODE (x) == CLOBBER) | |
109 for (i = first_regno; i < last_regno; i++) | |
110 CLEAR_HARD_REG_BIT (current_live_regs, i); | |
111 else | |
112 for (i = first_regno; i < last_regno; i++) | |
113 { | |
114 SET_HARD_REG_BIT (current_live_regs, i); | |
115 CLEAR_HARD_REG_BIT (pending_dead_regs, i); | |
116 } | |
117 } | |
118 | |
119 /* Find the number of the basic block with correct live register | |
120 information that starts closest to INSN. Return -1 if we couldn't | |
121 find such a basic block or the beginning is more than | |
122 SEARCH_LIMIT instructions before INSN. Use SEARCH_LIMIT = -1 for | |
123 an unlimited search. | |
124 | |
125 The delay slot filling code destroys the control-flow graph so, | |
126 instead of finding the basic block containing INSN, we search | |
127 backwards toward a BARRIER where the live register information is | |
128 correct. */ | |
129 | |
130 static int | |
111 | 131 find_basic_block (rtx_insn *insn, int search_limit) |
0 | 132 { |
133 /* Scan backwards to the previous BARRIER. Then see if we can find a | |
134 label that starts a basic block. Return the basic block number. */ | |
135 for (insn = prev_nonnote_insn (insn); | |
136 insn && !BARRIER_P (insn) && search_limit != 0; | |
137 insn = prev_nonnote_insn (insn), --search_limit) | |
138 ; | |
139 | |
140 /* The closest BARRIER is too far away. */ | |
141 if (search_limit == 0) | |
142 return -1; | |
143 | |
144 /* The start of the function. */ | |
145 else if (insn == 0) | |
111 | 146 return ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->index; |
0 | 147 |
148 /* See if any of the upcoming CODE_LABELs start a basic block. If we reach | |
149 anything other than a CODE_LABEL or note, we can't find this code. */ | |
150 for (insn = next_nonnote_insn (insn); | |
151 insn && LABEL_P (insn); | |
152 insn = next_nonnote_insn (insn)) | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
153 if (BLOCK_FOR_INSN (insn)) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
154 return BLOCK_FOR_INSN (insn)->index; |
0 | 155 |
156 return -1; | |
157 } | |
158 | |
159 /* Similar to next_insn, but ignores insns in the delay slots of | |
160 an annulled branch. */ | |
161 | |
111 | 162 static rtx_insn * |
163 next_insn_no_annul (rtx_insn *insn) | |
0 | 164 { |
165 if (insn) | |
166 { | |
167 /* If INSN is an annulled branch, skip any insns from the target | |
168 of the branch. */ | |
111 | 169 if (JUMP_P (insn) |
0 | 170 && INSN_ANNULLED_BRANCH_P (insn) |
171 && NEXT_INSN (PREV_INSN (insn)) != insn) | |
172 { | |
111 | 173 rtx_insn *next = NEXT_INSN (insn); |
0 | 174 |
111 | 175 while ((NONJUMP_INSN_P (next) || JUMP_P (next) || CALL_P (next)) |
0 | 176 && INSN_FROM_TARGET_P (next)) |
177 { | |
178 insn = next; | |
179 next = NEXT_INSN (insn); | |
180 } | |
181 } | |
182 | |
183 insn = NEXT_INSN (insn); | |
184 if (insn && NONJUMP_INSN_P (insn) | |
185 && GET_CODE (PATTERN (insn)) == SEQUENCE) | |
111 | 186 insn = as_a <rtx_sequence *> (PATTERN (insn))->insn (0); |
0 | 187 } |
188 | |
189 return insn; | |
190 } | |
191 | |
192 /* Given X, some rtl, and RES, a pointer to a `struct resource', mark | |
193 which resources are referenced by the insn. If INCLUDE_DELAYED_EFFECTS | |
194 is TRUE, resources used by the called routine will be included for | |
195 CALL_INSNs. */ | |
196 | |
197 void | |
198 mark_referenced_resources (rtx x, struct resources *res, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
199 bool include_delayed_effects) |
0 | 200 { |
201 enum rtx_code code = GET_CODE (x); | |
202 int i, j; | |
203 unsigned int r; | |
204 const char *format_ptr; | |
205 | |
206 /* Handle leaf items for which we set resource flags. Also, special-case | |
207 CALL, SET and CLOBBER operators. */ | |
208 switch (code) | |
209 { | |
210 case CONST: | |
111 | 211 CASE_CONST_ANY: |
0 | 212 case PC: |
213 case SYMBOL_REF: | |
214 case LABEL_REF: | |
215 return; | |
216 | |
217 case SUBREG: | |
218 if (!REG_P (SUBREG_REG (x))) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
219 mark_referenced_resources (SUBREG_REG (x), res, false); |
0 | 220 else |
221 { | |
222 unsigned int regno = subreg_regno (x); | |
223 unsigned int last_regno = regno + subreg_nregs (x); | |
224 | |
225 gcc_assert (last_regno <= FIRST_PSEUDO_REGISTER); | |
226 for (r = regno; r < last_regno; r++) | |
227 SET_HARD_REG_BIT (res->regs, r); | |
228 } | |
229 return; | |
230 | |
231 case REG: | |
232 gcc_assert (HARD_REGISTER_P (x)); | |
233 add_to_hard_reg_set (&res->regs, GET_MODE (x), REGNO (x)); | |
234 return; | |
235 | |
236 case MEM: | |
237 /* If this memory shouldn't change, it really isn't referencing | |
238 memory. */ | |
111 | 239 if (! MEM_READONLY_P (x)) |
0 | 240 res->memory = 1; |
241 res->volatil |= MEM_VOLATILE_P (x); | |
242 | |
243 /* Mark registers used to access memory. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
244 mark_referenced_resources (XEXP (x, 0), res, false); |
0 | 245 return; |
246 | |
247 case CC0: | |
248 res->cc = 1; | |
249 return; | |
250 | |
251 case UNSPEC_VOLATILE: | |
252 case TRAP_IF: | |
253 case ASM_INPUT: | |
254 /* Traditional asm's are always volatile. */ | |
255 res->volatil = 1; | |
256 break; | |
257 | |
258 case ASM_OPERANDS: | |
259 res->volatil |= MEM_VOLATILE_P (x); | |
260 | |
261 /* For all ASM_OPERANDS, we must traverse the vector of input operands. | |
262 We can not just fall through here since then we would be confused | |
263 by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate | |
264 traditional asms unlike their normal usage. */ | |
265 | |
266 for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
267 mark_referenced_resources (ASM_OPERANDS_INPUT (x, i), res, false); |
0 | 268 return; |
269 | |
270 case CALL: | |
271 /* The first operand will be a (MEM (xxx)) but doesn't really reference | |
272 memory. The second operand may be referenced, though. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
273 mark_referenced_resources (XEXP (XEXP (x, 0), 0), res, false); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
274 mark_referenced_resources (XEXP (x, 1), res, false); |
0 | 275 return; |
276 | |
277 case SET: | |
278 /* Usually, the first operand of SET is set, not referenced. But | |
279 registers used to access memory are referenced. SET_DEST is | |
280 also referenced if it is a ZERO_EXTRACT. */ | |
281 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
282 mark_referenced_resources (SET_SRC (x), res, false); |
0 | 283 |
284 x = SET_DEST (x); | |
285 if (GET_CODE (x) == ZERO_EXTRACT | |
286 || GET_CODE (x) == STRICT_LOW_PART) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
287 mark_referenced_resources (x, res, false); |
0 | 288 else if (GET_CODE (x) == SUBREG) |
289 x = SUBREG_REG (x); | |
290 if (MEM_P (x)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
291 mark_referenced_resources (XEXP (x, 0), res, false); |
0 | 292 return; |
293 | |
294 case CLOBBER: | |
295 return; | |
296 | |
297 case CALL_INSN: | |
298 if (include_delayed_effects) | |
299 { | |
300 /* A CALL references memory, the frame pointer if it exists, the | |
301 stack pointer, any global registers and any registers given in | |
302 USE insns immediately in front of the CALL. | |
303 | |
304 However, we may have moved some of the parameter loading insns | |
305 into the delay slot of this CALL. If so, the USE's for them | |
306 don't count and should be skipped. */ | |
111 | 307 rtx_insn *insn = PREV_INSN (as_a <rtx_insn *> (x)); |
308 rtx_sequence *sequence = 0; | |
0 | 309 int seq_size = 0; |
310 int i; | |
311 | |
312 /* If we are part of a delay slot sequence, point at the SEQUENCE. */ | |
313 if (NEXT_INSN (insn) != x) | |
314 { | |
111 | 315 sequence = as_a <rtx_sequence *> (PATTERN (NEXT_INSN (insn))); |
316 seq_size = sequence->len (); | |
0 | 317 gcc_assert (GET_CODE (sequence) == SEQUENCE); |
318 } | |
319 | |
320 res->memory = 1; | |
321 SET_HARD_REG_BIT (res->regs, STACK_POINTER_REGNUM); | |
322 if (frame_pointer_needed) | |
323 { | |
324 SET_HARD_REG_BIT (res->regs, FRAME_POINTER_REGNUM); | |
111 | 325 if (!HARD_FRAME_POINTER_IS_FRAME_POINTER) |
326 SET_HARD_REG_BIT (res->regs, HARD_FRAME_POINTER_REGNUM); | |
0 | 327 } |
328 | |
329 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
330 if (global_regs[i]) | |
331 SET_HARD_REG_BIT (res->regs, i); | |
332 | |
333 /* Check for a REG_SETJMP. If it exists, then we must | |
334 assume that this call can need any register. | |
335 | |
336 This is done to be more conservative about how we handle setjmp. | |
337 We assume that they both use and set all registers. Using all | |
338 registers ensures that a register will not be considered dead | |
339 just because it crosses a setjmp call. A register should be | |
340 considered dead only if the setjmp call returns nonzero. */ | |
341 if (find_reg_note (x, REG_SETJMP, NULL)) | |
342 SET_HARD_REG_SET (res->regs); | |
343 | |
344 { | |
345 rtx link; | |
346 | |
347 for (link = CALL_INSN_FUNCTION_USAGE (x); | |
348 link; | |
349 link = XEXP (link, 1)) | |
350 if (GET_CODE (XEXP (link, 0)) == USE) | |
351 { | |
352 for (i = 1; i < seq_size; i++) | |
353 { | |
111 | 354 rtx slot_pat = PATTERN (sequence->element (i)); |
0 | 355 if (GET_CODE (slot_pat) == SET |
356 && rtx_equal_p (SET_DEST (slot_pat), | |
357 XEXP (XEXP (link, 0), 0))) | |
358 break; | |
359 } | |
360 if (i >= seq_size) | |
361 mark_referenced_resources (XEXP (XEXP (link, 0), 0), | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
362 res, false); |
0 | 363 } |
364 } | |
365 } | |
366 | |
367 /* ... fall through to other INSN processing ... */ | |
111 | 368 gcc_fallthrough (); |
0 | 369 |
370 case INSN: | |
371 case JUMP_INSN: | |
372 | |
111 | 373 if (GET_CODE (PATTERN (x)) == COND_EXEC) |
374 /* In addition to the usual references, also consider all outputs | |
375 as referenced, to compensate for mark_set_resources treating | |
376 them as killed. This is similar to ZERO_EXTRACT / STRICT_LOW_PART | |
377 handling, execpt that we got a partial incidence instead of a partial | |
378 width. */ | |
379 mark_set_resources (x, res, 0, | |
380 include_delayed_effects | |
381 ? MARK_SRC_DEST_CALL : MARK_SRC_DEST); | |
382 | |
0 | 383 if (! include_delayed_effects |
111 | 384 && INSN_REFERENCES_ARE_DELAYED (as_a <rtx_insn *> (x))) |
0 | 385 return; |
386 | |
387 /* No special processing, just speed up. */ | |
388 mark_referenced_resources (PATTERN (x), res, include_delayed_effects); | |
389 return; | |
390 | |
391 default: | |
392 break; | |
393 } | |
394 | |
395 /* Process each sub-expression and flag what it needs. */ | |
396 format_ptr = GET_RTX_FORMAT (code); | |
397 for (i = 0; i < GET_RTX_LENGTH (code); i++) | |
398 switch (*format_ptr++) | |
399 { | |
400 case 'e': | |
401 mark_referenced_resources (XEXP (x, i), res, include_delayed_effects); | |
402 break; | |
403 | |
404 case 'E': | |
405 for (j = 0; j < XVECLEN (x, i); j++) | |
406 mark_referenced_resources (XVECEXP (x, i, j), res, | |
407 include_delayed_effects); | |
408 break; | |
409 } | |
410 } | |
411 | |
412 /* A subroutine of mark_target_live_regs. Search forward from TARGET | |
413 looking for registers that are set before they are used. These are dead. | |
414 Stop after passing a few conditional jumps, and/or a small | |
415 number of unconditional branches. */ | |
416 | |
111 | 417 static rtx_insn * |
418 find_dead_or_set_registers (rtx_insn *target, struct resources *res, | |
0 | 419 rtx *jump_target, int jump_count, |
420 struct resources set, struct resources needed) | |
421 { | |
422 HARD_REG_SET scratch; | |
111 | 423 rtx_insn *insn; |
424 rtx_insn *next_insn; | |
425 rtx_insn *jump_insn = 0; | |
0 | 426 int i; |
427 | |
111 | 428 for (insn = target; insn; insn = next_insn) |
0 | 429 { |
111 | 430 rtx_insn *this_insn = insn; |
0 | 431 |
111 | 432 next_insn = NEXT_INSN (insn); |
0 | 433 |
434 /* If this instruction can throw an exception, then we don't | |
435 know where we might end up next. That means that we have to | |
436 assume that whatever we have already marked as live really is | |
437 live. */ | |
438 if (can_throw_internal (insn)) | |
439 break; | |
440 | |
441 switch (GET_CODE (insn)) | |
442 { | |
443 case CODE_LABEL: | |
444 /* After a label, any pending dead registers that weren't yet | |
445 used can be made dead. */ | |
446 AND_COMPL_HARD_REG_SET (pending_dead_regs, needed.regs); | |
447 AND_COMPL_HARD_REG_SET (res->regs, pending_dead_regs); | |
448 CLEAR_HARD_REG_SET (pending_dead_regs); | |
449 | |
450 continue; | |
451 | |
452 case BARRIER: | |
453 case NOTE: | |
454 continue; | |
455 | |
456 case INSN: | |
457 if (GET_CODE (PATTERN (insn)) == USE) | |
458 { | |
459 /* If INSN is a USE made by update_block, we care about the | |
460 underlying insn. Any registers set by the underlying insn | |
461 are live since the insn is being done somewhere else. */ | |
462 if (INSN_P (XEXP (PATTERN (insn), 0))) | |
463 mark_set_resources (XEXP (PATTERN (insn), 0), res, 0, | |
464 MARK_SRC_DEST_CALL); | |
465 | |
466 /* All other USE insns are to be ignored. */ | |
467 continue; | |
468 } | |
469 else if (GET_CODE (PATTERN (insn)) == CLOBBER) | |
470 continue; | |
111 | 471 else if (rtx_sequence *seq = |
472 dyn_cast <rtx_sequence *> (PATTERN (insn))) | |
0 | 473 { |
474 /* An unconditional jump can be used to fill the delay slot | |
475 of a call, so search for a JUMP_INSN in any position. */ | |
111 | 476 for (i = 0; i < seq->len (); i++) |
0 | 477 { |
111 | 478 this_insn = seq->insn (i); |
479 if (JUMP_P (this_insn)) | |
0 | 480 break; |
481 } | |
482 } | |
483 | |
484 default: | |
485 break; | |
486 } | |
487 | |
111 | 488 if (rtx_jump_insn *this_jump_insn = |
489 dyn_cast <rtx_jump_insn *> (this_insn)) | |
0 | 490 { |
491 if (jump_count++ < 10) | |
492 { | |
493 if (any_uncondjump_p (this_jump_insn) | |
111 | 494 || ANY_RETURN_P (PATTERN (this_jump_insn))) |
0 | 495 { |
111 | 496 rtx lab_or_return = this_jump_insn->jump_label (); |
497 if (ANY_RETURN_P (lab_or_return)) | |
498 next_insn = NULL; | |
499 else | |
500 next_insn = as_a <rtx_insn *> (lab_or_return); | |
0 | 501 if (jump_insn == 0) |
502 { | |
503 jump_insn = insn; | |
504 if (jump_target) | |
505 *jump_target = JUMP_LABEL (this_jump_insn); | |
506 } | |
507 } | |
508 else if (any_condjump_p (this_jump_insn)) | |
509 { | |
510 struct resources target_set, target_res; | |
511 struct resources fallthrough_res; | |
512 | |
513 /* We can handle conditional branches here by following | |
514 both paths, and then IOR the results of the two paths | |
515 together, which will give us registers that are dead | |
516 on both paths. Since this is expensive, we give it | |
517 a much higher cost than unconditional branches. The | |
518 cost was chosen so that we will follow at most 1 | |
519 conditional branch. */ | |
520 | |
521 jump_count += 4; | |
522 if (jump_count >= 10) | |
523 break; | |
524 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
525 mark_referenced_resources (insn, &needed, true); |
0 | 526 |
527 /* For an annulled branch, mark_set_resources ignores slots | |
528 filled by instructions from the target. This is correct | |
529 if the branch is not taken. Since we are following both | |
530 paths from the branch, we must also compute correct info | |
531 if the branch is taken. We do this by inverting all of | |
532 the INSN_FROM_TARGET_P bits, calling mark_set_resources, | |
533 and then inverting the INSN_FROM_TARGET_P bits again. */ | |
534 | |
535 if (GET_CODE (PATTERN (insn)) == SEQUENCE | |
536 && INSN_ANNULLED_BRANCH_P (this_jump_insn)) | |
537 { | |
111 | 538 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn)); |
539 for (i = 1; i < seq->len (); i++) | |
540 INSN_FROM_TARGET_P (seq->element (i)) | |
541 = ! INSN_FROM_TARGET_P (seq->element (i)); | |
0 | 542 |
543 target_set = set; | |
544 mark_set_resources (insn, &target_set, 0, | |
545 MARK_SRC_DEST_CALL); | |
546 | |
111 | 547 for (i = 1; i < seq->len (); i++) |
548 INSN_FROM_TARGET_P (seq->element (i)) | |
549 = ! INSN_FROM_TARGET_P (seq->element (i)); | |
0 | 550 |
551 mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); | |
552 } | |
553 else | |
554 { | |
555 mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); | |
556 target_set = set; | |
557 } | |
558 | |
559 target_res = *res; | |
560 COPY_HARD_REG_SET (scratch, target_set.regs); | |
561 AND_COMPL_HARD_REG_SET (scratch, needed.regs); | |
562 AND_COMPL_HARD_REG_SET (target_res.regs, scratch); | |
563 | |
564 fallthrough_res = *res; | |
565 COPY_HARD_REG_SET (scratch, set.regs); | |
566 AND_COMPL_HARD_REG_SET (scratch, needed.regs); | |
567 AND_COMPL_HARD_REG_SET (fallthrough_res.regs, scratch); | |
568 | |
111 | 569 if (!ANY_RETURN_P (this_jump_insn->jump_label ())) |
570 find_dead_or_set_registers | |
571 (this_jump_insn->jump_target (), | |
572 &target_res, 0, jump_count, target_set, needed); | |
573 find_dead_or_set_registers (next_insn, | |
0 | 574 &fallthrough_res, 0, jump_count, |
575 set, needed); | |
576 IOR_HARD_REG_SET (fallthrough_res.regs, target_res.regs); | |
577 AND_HARD_REG_SET (res->regs, fallthrough_res.regs); | |
578 break; | |
579 } | |
580 else | |
581 break; | |
582 } | |
583 else | |
584 { | |
585 /* Don't try this optimization if we expired our jump count | |
586 above, since that would mean there may be an infinite loop | |
587 in the function being compiled. */ | |
588 jump_insn = 0; | |
589 break; | |
590 } | |
591 } | |
592 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
593 mark_referenced_resources (insn, &needed, true); |
0 | 594 mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); |
595 | |
596 COPY_HARD_REG_SET (scratch, set.regs); | |
597 AND_COMPL_HARD_REG_SET (scratch, needed.regs); | |
598 AND_COMPL_HARD_REG_SET (res->regs, scratch); | |
599 } | |
600 | |
601 return jump_insn; | |
602 } | |
603 | |
604 /* Given X, a part of an insn, and a pointer to a `struct resource', | |
605 RES, indicate which resources are modified by the insn. If | |
606 MARK_TYPE is MARK_SRC_DEST_CALL, also mark resources potentially | |
607 set by the called routine. | |
608 | |
609 If IN_DEST is nonzero, it means we are inside a SET. Otherwise, | |
610 objects are being referenced instead of set. | |
611 | |
612 We never mark the insn as modifying the condition code unless it explicitly | |
613 SETs CC0 even though this is not totally correct. The reason for this is | |
614 that we require a SET of CC0 to immediately precede the reference to CC0. | |
615 So if some other insn sets CC0 as a side-effect, we know it cannot affect | |
616 our computation and thus may be placed in a delay slot. */ | |
617 | |
618 void | |
619 mark_set_resources (rtx x, struct resources *res, int in_dest, | |
620 enum mark_resource_type mark_type) | |
621 { | |
622 enum rtx_code code; | |
623 int i, j; | |
624 unsigned int r; | |
625 const char *format_ptr; | |
626 | |
627 restart: | |
628 | |
629 code = GET_CODE (x); | |
630 | |
631 switch (code) | |
632 { | |
633 case NOTE: | |
634 case BARRIER: | |
635 case CODE_LABEL: | |
636 case USE: | |
111 | 637 CASE_CONST_ANY: |
0 | 638 case LABEL_REF: |
639 case SYMBOL_REF: | |
640 case CONST: | |
641 case PC: | |
642 /* These don't set any resources. */ | |
643 return; | |
644 | |
645 case CC0: | |
646 if (in_dest) | |
647 res->cc = 1; | |
648 return; | |
649 | |
650 case CALL_INSN: | |
651 /* Called routine modifies the condition code, memory, any registers | |
652 that aren't saved across calls, global registers and anything | |
653 explicitly CLOBBERed immediately after the CALL_INSN. */ | |
654 | |
655 if (mark_type == MARK_SRC_DEST_CALL) | |
656 { | |
111 | 657 rtx_call_insn *call_insn = as_a <rtx_call_insn *> (x); |
0 | 658 rtx link; |
111 | 659 HARD_REG_SET regs; |
0 | 660 |
661 res->cc = res->memory = 1; | |
662 | |
111 | 663 get_call_reg_set_usage (call_insn, ®s, regs_invalidated_by_call); |
664 IOR_HARD_REG_SET (res->regs, regs); | |
0 | 665 |
111 | 666 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); |
0 | 667 link; link = XEXP (link, 1)) |
668 if (GET_CODE (XEXP (link, 0)) == CLOBBER) | |
669 mark_set_resources (SET_DEST (XEXP (link, 0)), res, 1, | |
670 MARK_SRC_DEST); | |
671 | |
672 /* Check for a REG_SETJMP. If it exists, then we must | |
673 assume that this call can clobber any register. */ | |
111 | 674 if (find_reg_note (call_insn, REG_SETJMP, NULL)) |
0 | 675 SET_HARD_REG_SET (res->regs); |
676 } | |
677 | |
678 /* ... and also what its RTL says it modifies, if anything. */ | |
111 | 679 gcc_fallthrough (); |
0 | 680 |
681 case JUMP_INSN: | |
682 case INSN: | |
683 | |
684 /* An insn consisting of just a CLOBBER (or USE) is just for flow | |
685 and doesn't actually do anything, so we ignore it. */ | |
686 | |
687 if (mark_type != MARK_SRC_DEST_CALL | |
111 | 688 && INSN_SETS_ARE_DELAYED (as_a <rtx_insn *> (x))) |
0 | 689 return; |
690 | |
691 x = PATTERN (x); | |
692 if (GET_CODE (x) != USE && GET_CODE (x) != CLOBBER) | |
693 goto restart; | |
694 return; | |
695 | |
696 case SET: | |
697 /* If the source of a SET is a CALL, this is actually done by | |
698 the called routine. So only include it if we are to include the | |
699 effects of the calling routine. */ | |
700 | |
701 mark_set_resources (SET_DEST (x), res, | |
702 (mark_type == MARK_SRC_DEST_CALL | |
703 || GET_CODE (SET_SRC (x)) != CALL), | |
704 mark_type); | |
705 | |
706 mark_set_resources (SET_SRC (x), res, 0, MARK_SRC_DEST); | |
707 return; | |
708 | |
709 case CLOBBER: | |
710 mark_set_resources (XEXP (x, 0), res, 1, MARK_SRC_DEST); | |
711 return; | |
712 | |
713 case SEQUENCE: | |
111 | 714 { |
715 rtx_sequence *seq = as_a <rtx_sequence *> (x); | |
716 rtx control = seq->element (0); | |
717 bool annul_p = JUMP_P (control) && INSN_ANNULLED_BRANCH_P (control); | |
718 | |
719 mark_set_resources (control, res, 0, mark_type); | |
720 for (i = seq->len () - 1; i >= 0; --i) | |
721 { | |
722 rtx elt = seq->element (i); | |
723 if (!annul_p && INSN_FROM_TARGET_P (elt)) | |
724 mark_set_resources (elt, res, 0, mark_type); | |
725 } | |
726 } | |
0 | 727 return; |
728 | |
729 case POST_INC: | |
730 case PRE_INC: | |
731 case POST_DEC: | |
732 case PRE_DEC: | |
733 mark_set_resources (XEXP (x, 0), res, 1, MARK_SRC_DEST); | |
734 return; | |
735 | |
736 case PRE_MODIFY: | |
737 case POST_MODIFY: | |
738 mark_set_resources (XEXP (x, 0), res, 1, MARK_SRC_DEST); | |
739 mark_set_resources (XEXP (XEXP (x, 1), 0), res, 0, MARK_SRC_DEST); | |
740 mark_set_resources (XEXP (XEXP (x, 1), 1), res, 0, MARK_SRC_DEST); | |
741 return; | |
742 | |
743 case SIGN_EXTRACT: | |
744 case ZERO_EXTRACT: | |
745 mark_set_resources (XEXP (x, 0), res, in_dest, MARK_SRC_DEST); | |
746 mark_set_resources (XEXP (x, 1), res, 0, MARK_SRC_DEST); | |
747 mark_set_resources (XEXP (x, 2), res, 0, MARK_SRC_DEST); | |
748 return; | |
749 | |
750 case MEM: | |
751 if (in_dest) | |
752 { | |
753 res->memory = 1; | |
754 res->volatil |= MEM_VOLATILE_P (x); | |
755 } | |
756 | |
757 mark_set_resources (XEXP (x, 0), res, 0, MARK_SRC_DEST); | |
758 return; | |
759 | |
760 case SUBREG: | |
761 if (in_dest) | |
762 { | |
763 if (!REG_P (SUBREG_REG (x))) | |
764 mark_set_resources (SUBREG_REG (x), res, in_dest, mark_type); | |
765 else | |
766 { | |
767 unsigned int regno = subreg_regno (x); | |
768 unsigned int last_regno = regno + subreg_nregs (x); | |
769 | |
770 gcc_assert (last_regno <= FIRST_PSEUDO_REGISTER); | |
771 for (r = regno; r < last_regno; r++) | |
772 SET_HARD_REG_BIT (res->regs, r); | |
773 } | |
774 } | |
775 return; | |
776 | |
777 case REG: | |
778 if (in_dest) | |
779 { | |
780 gcc_assert (HARD_REGISTER_P (x)); | |
781 add_to_hard_reg_set (&res->regs, GET_MODE (x), REGNO (x)); | |
782 } | |
783 return; | |
784 | |
785 case UNSPEC_VOLATILE: | |
786 case ASM_INPUT: | |
787 /* Traditional asm's are always volatile. */ | |
788 res->volatil = 1; | |
789 return; | |
790 | |
791 case TRAP_IF: | |
792 res->volatil = 1; | |
793 break; | |
794 | |
795 case ASM_OPERANDS: | |
796 res->volatil |= MEM_VOLATILE_P (x); | |
797 | |
798 /* For all ASM_OPERANDS, we must traverse the vector of input operands. | |
799 We can not just fall through here since then we would be confused | |
800 by the ASM_INPUT rtx inside ASM_OPERANDS, which do not indicate | |
801 traditional asms unlike their normal usage. */ | |
802 | |
803 for (i = 0; i < ASM_OPERANDS_INPUT_LENGTH (x); i++) | |
804 mark_set_resources (ASM_OPERANDS_INPUT (x, i), res, in_dest, | |
805 MARK_SRC_DEST); | |
806 return; | |
807 | |
808 default: | |
809 break; | |
810 } | |
811 | |
812 /* Process each sub-expression and flag what it needs. */ | |
813 format_ptr = GET_RTX_FORMAT (code); | |
814 for (i = 0; i < GET_RTX_LENGTH (code); i++) | |
815 switch (*format_ptr++) | |
816 { | |
817 case 'e': | |
818 mark_set_resources (XEXP (x, i), res, in_dest, mark_type); | |
819 break; | |
820 | |
821 case 'E': | |
822 for (j = 0; j < XVECLEN (x, i); j++) | |
823 mark_set_resources (XVECEXP (x, i, j), res, in_dest, mark_type); | |
824 break; | |
825 } | |
826 } | |
827 | |
828 /* Return TRUE if INSN is a return, possibly with a filled delay slot. */ | |
829 | |
830 static bool | |
831 return_insn_p (const_rtx insn) | |
832 { | |
111 | 833 if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn))) |
0 | 834 return true; |
835 | |
836 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE) | |
837 return return_insn_p (XVECEXP (PATTERN (insn), 0, 0)); | |
838 | |
839 return false; | |
840 } | |
841 | |
842 /* Set the resources that are live at TARGET. | |
843 | |
844 If TARGET is zero, we refer to the end of the current function and can | |
845 return our precomputed value. | |
846 | |
847 Otherwise, we try to find out what is live by consulting the basic block | |
848 information. This is tricky, because we must consider the actions of | |
849 reload and jump optimization, which occur after the basic block information | |
850 has been computed. | |
851 | |
852 Accordingly, we proceed as follows:: | |
853 | |
854 We find the previous BARRIER and look at all immediately following labels | |
855 (with no intervening active insns) to see if any of them start a basic | |
856 block. If we hit the start of the function first, we use block 0. | |
857 | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
858 Once we have found a basic block and a corresponding first insn, we can |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
859 accurately compute the live status (by starting at a label following a |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
860 BARRIER, we are immune to actions taken by reload and jump.) Then we |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
861 scan all insns between that point and our target. For each CLOBBER (or |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
862 for call-clobbered regs when we pass a CALL_INSN), mark the appropriate |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
863 registers are dead. For a SET, mark them as live. |
0 | 864 |
865 We have to be careful when using REG_DEAD notes because they are not | |
866 updated by such things as find_equiv_reg. So keep track of registers | |
867 marked as dead that haven't been assigned to, and mark them dead at the | |
868 next CODE_LABEL since reload and jump won't propagate values across labels. | |
869 | |
870 If we cannot find the start of a basic block (should be a very rare | |
871 case, if it can happen at all), mark everything as potentially live. | |
872 | |
873 Next, scan forward from TARGET looking for things set or clobbered | |
874 before they are used. These are not live. | |
875 | |
876 Because we can be called many times on the same target, save our results | |
877 in a hash table indexed by INSN_UID. This is only done if the function | |
878 init_resource_info () was invoked before we are called. */ | |
879 | |
880 void | |
111 | 881 mark_target_live_regs (rtx_insn *insns, rtx target_maybe_return, struct resources *res) |
0 | 882 { |
883 int b = -1; | |
884 unsigned int i; | |
885 struct target_info *tinfo = NULL; | |
111 | 886 rtx_insn *insn; |
0 | 887 rtx jump_target; |
888 HARD_REG_SET scratch; | |
889 struct resources set, needed; | |
890 | |
891 /* Handle end of function. */ | |
111 | 892 if (target_maybe_return == 0 || ANY_RETURN_P (target_maybe_return)) |
0 | 893 { |
894 *res = end_of_function_needs; | |
895 return; | |
896 } | |
897 | |
111 | 898 /* We've handled the case of RETURN/SIMPLE_RETURN; we should now have an |
899 instruction. */ | |
900 rtx_insn *target = as_a <rtx_insn *> (target_maybe_return); | |
901 | |
0 | 902 /* Handle return insn. */ |
111 | 903 if (return_insn_p (target)) |
0 | 904 { |
905 *res = end_of_function_needs; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
906 mark_referenced_resources (target, res, false); |
0 | 907 return; |
908 } | |
909 | |
910 /* We have to assume memory is needed, but the CC isn't. */ | |
911 res->memory = 1; | |
111 | 912 res->volatil = 0; |
0 | 913 res->cc = 0; |
914 | |
915 /* See if we have computed this value already. */ | |
916 if (target_hash_table != NULL) | |
917 { | |
918 for (tinfo = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME]; | |
919 tinfo; tinfo = tinfo->next) | |
920 if (tinfo->uid == INSN_UID (target)) | |
921 break; | |
922 | |
923 /* Start by getting the basic block number. If we have saved | |
924 information, we can get it from there unless the insn at the | |
925 start of the basic block has been deleted. */ | |
926 if (tinfo && tinfo->block != -1 | |
111 | 927 && ! BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, tinfo->block))->deleted ()) |
0 | 928 b = tinfo->block; |
929 } | |
930 | |
931 if (b == -1) | |
932 b = find_basic_block (target, MAX_DELAY_SLOT_LIVE_SEARCH); | |
933 | |
934 if (target_hash_table != NULL) | |
935 { | |
936 if (tinfo) | |
937 { | |
938 /* If the information is up-to-date, use it. Otherwise, we will | |
939 update it below. */ | |
940 if (b == tinfo->block && b != -1 && tinfo->bb_tick == bb_ticks[b]) | |
941 { | |
942 COPY_HARD_REG_SET (res->regs, tinfo->live_regs); | |
943 return; | |
944 } | |
945 } | |
946 else | |
947 { | |
948 /* Allocate a place to put our results and chain it into the | |
949 hash table. */ | |
950 tinfo = XNEW (struct target_info); | |
951 tinfo->uid = INSN_UID (target); | |
952 tinfo->block = b; | |
953 tinfo->next | |
954 = target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME]; | |
955 target_hash_table[INSN_UID (target) % TARGET_HASH_PRIME] = tinfo; | |
956 } | |
957 } | |
958 | |
959 CLEAR_HARD_REG_SET (pending_dead_regs); | |
960 | |
961 /* If we found a basic block, get the live registers from it and update | |
962 them with anything set or killed between its start and the insn before | |
36 | 963 TARGET; this custom life analysis is really about registers so we need |
964 to use the LR problem. Otherwise, we must assume everything is live. */ | |
0 | 965 if (b != -1) |
966 { | |
111 | 967 regset regs_live = DF_LR_IN (BASIC_BLOCK_FOR_FN (cfun, b)); |
968 rtx_insn *start_insn, *stop_insn; | |
0 | 969 |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
970 /* Compute hard regs live at start of block. */ |
0 | 971 REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live); |
972 | |
973 /* Get starting and ending insn, handling the case where each might | |
974 be a SEQUENCE. */ | |
111 | 975 start_insn = (b == ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb->index ? |
976 insns : BB_HEAD (BASIC_BLOCK_FOR_FN (cfun, b))); | |
0 | 977 stop_insn = target; |
978 | |
979 if (NONJUMP_INSN_P (start_insn) | |
980 && GET_CODE (PATTERN (start_insn)) == SEQUENCE) | |
111 | 981 start_insn = as_a <rtx_sequence *> (PATTERN (start_insn))->insn (0); |
0 | 982 |
983 if (NONJUMP_INSN_P (stop_insn) | |
984 && GET_CODE (PATTERN (stop_insn)) == SEQUENCE) | |
985 stop_insn = next_insn (PREV_INSN (stop_insn)); | |
986 | |
987 for (insn = start_insn; insn != stop_insn; | |
988 insn = next_insn_no_annul (insn)) | |
989 { | |
990 rtx link; | |
111 | 991 rtx_insn *real_insn = insn; |
0 | 992 enum rtx_code code = GET_CODE (insn); |
993 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
994 if (DEBUG_INSN_P (insn)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
995 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
996 |
0 | 997 /* If this insn is from the target of a branch, it isn't going to |
998 be used in the sequel. If it is used in both cases, this | |
999 test will not be true. */ | |
1000 if ((code == INSN || code == JUMP_INSN || code == CALL_INSN) | |
1001 && INSN_FROM_TARGET_P (insn)) | |
1002 continue; | |
1003 | |
1004 /* If this insn is a USE made by update_block, we care about the | |
1005 underlying insn. */ | |
111 | 1006 if (code == INSN |
1007 && GET_CODE (PATTERN (insn)) == USE | |
0 | 1008 && INSN_P (XEXP (PATTERN (insn), 0))) |
111 | 1009 real_insn = as_a <rtx_insn *> (XEXP (PATTERN (insn), 0)); |
0 | 1010 |
1011 if (CALL_P (real_insn)) | |
1012 { | |
111 | 1013 /* Values in call-clobbered registers survive a COND_EXEC CALL |
1014 if that is not executed; this matters for resoure use because | |
1015 they may be used by a complementarily (or more strictly) | |
1016 predicated instruction, or if the CALL is NORETURN. */ | |
1017 if (GET_CODE (PATTERN (real_insn)) != COND_EXEC) | |
1018 { | |
1019 HARD_REG_SET regs_invalidated_by_this_call; | |
1020 get_call_reg_set_usage (real_insn, | |
1021 ®s_invalidated_by_this_call, | |
1022 regs_invalidated_by_call); | |
1023 /* CALL clobbers all call-used regs that aren't fixed except | |
1024 sp, ap, and fp. Do this before setting the result of the | |
1025 call live. */ | |
1026 AND_COMPL_HARD_REG_SET (current_live_regs, | |
1027 regs_invalidated_by_this_call); | |
1028 } | |
0 | 1029 |
1030 /* A CALL_INSN sets any global register live, since it may | |
1031 have been modified by the call. */ | |
1032 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1033 if (global_regs[i]) | |
1034 SET_HARD_REG_BIT (current_live_regs, i); | |
1035 } | |
1036 | |
1037 /* Mark anything killed in an insn to be deadened at the next | |
1038 label. Ignore USE insns; the only REG_DEAD notes will be for | |
1039 parameters. But they might be early. A CALL_INSN will usually | |
1040 clobber registers used for parameters. It isn't worth bothering | |
1041 with the unlikely case when it won't. */ | |
1042 if ((NONJUMP_INSN_P (real_insn) | |
1043 && GET_CODE (PATTERN (real_insn)) != USE | |
1044 && GET_CODE (PATTERN (real_insn)) != CLOBBER) | |
1045 || JUMP_P (real_insn) | |
1046 || CALL_P (real_insn)) | |
1047 { | |
1048 for (link = REG_NOTES (real_insn); link; link = XEXP (link, 1)) | |
1049 if (REG_NOTE_KIND (link) == REG_DEAD | |
1050 && REG_P (XEXP (link, 0)) | |
1051 && REGNO (XEXP (link, 0)) < FIRST_PSEUDO_REGISTER) | |
1052 add_to_hard_reg_set (&pending_dead_regs, | |
1053 GET_MODE (XEXP (link, 0)), | |
1054 REGNO (XEXP (link, 0))); | |
1055 | |
1056 note_stores (PATTERN (real_insn), update_live_status, NULL); | |
1057 | |
1058 /* If any registers were unused after this insn, kill them. | |
1059 These notes will always be accurate. */ | |
1060 for (link = REG_NOTES (real_insn); link; link = XEXP (link, 1)) | |
1061 if (REG_NOTE_KIND (link) == REG_UNUSED | |
1062 && REG_P (XEXP (link, 0)) | |
1063 && REGNO (XEXP (link, 0)) < FIRST_PSEUDO_REGISTER) | |
1064 remove_from_hard_reg_set (¤t_live_regs, | |
1065 GET_MODE (XEXP (link, 0)), | |
1066 REGNO (XEXP (link, 0))); | |
1067 } | |
1068 | |
1069 else if (LABEL_P (real_insn)) | |
1070 { | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1071 basic_block bb; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1072 |
0 | 1073 /* A label clobbers the pending dead registers since neither |
1074 reload nor jump will propagate a value across a label. */ | |
1075 AND_COMPL_HARD_REG_SET (current_live_regs, pending_dead_regs); | |
1076 CLEAR_HARD_REG_SET (pending_dead_regs); | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1077 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1078 /* We must conservatively assume that all registers that used |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1079 to be live here still are. The fallthrough edge may have |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1080 left a live register uninitialized. */ |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1081 bb = BLOCK_FOR_INSN (real_insn); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1082 if (bb) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1083 { |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1084 HARD_REG_SET extra_live; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1085 |
36 | 1086 REG_SET_TO_HARD_REG_SET (extra_live, DF_LR_IN (bb)); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1087 IOR_HARD_REG_SET (current_live_regs, extra_live); |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1088 } |
0 | 1089 } |
1090 | |
1091 /* The beginning of the epilogue corresponds to the end of the | |
1092 RTL chain when there are no epilogue insns. Certain resources | |
1093 are implicitly required at that point. */ | |
1094 else if (NOTE_P (real_insn) | |
1095 && NOTE_KIND (real_insn) == NOTE_INSN_EPILOGUE_BEG) | |
1096 IOR_HARD_REG_SET (current_live_regs, start_of_epilogue_needs.regs); | |
1097 } | |
1098 | |
1099 COPY_HARD_REG_SET (res->regs, current_live_regs); | |
1100 if (tinfo != NULL) | |
1101 { | |
1102 tinfo->block = b; | |
1103 tinfo->bb_tick = bb_ticks[b]; | |
1104 } | |
1105 } | |
1106 else | |
1107 /* We didn't find the start of a basic block. Assume everything | |
1108 in use. This should happen only extremely rarely. */ | |
1109 SET_HARD_REG_SET (res->regs); | |
1110 | |
1111 CLEAR_RESOURCE (&set); | |
1112 CLEAR_RESOURCE (&needed); | |
1113 | |
111 | 1114 rtx_insn *jump_insn = find_dead_or_set_registers (target, res, &jump_target, |
1115 0, set, needed); | |
0 | 1116 |
1117 /* If we hit an unconditional branch, we have another way of finding out | |
1118 what is live: we can see what is live at the branch target and include | |
1119 anything used but not set before the branch. We add the live | |
1120 resources found using the test below to those found until now. */ | |
1121 | |
1122 if (jump_insn) | |
1123 { | |
1124 struct resources new_resources; | |
111 | 1125 rtx_insn *stop_insn = next_active_insn (jump_insn); |
0 | 1126 |
111 | 1127 if (!ANY_RETURN_P (jump_target)) |
1128 jump_target = next_active_insn (as_a<rtx_insn *> (jump_target)); | |
1129 mark_target_live_regs (insns, jump_target, &new_resources); | |
0 | 1130 CLEAR_RESOURCE (&set); |
1131 CLEAR_RESOURCE (&needed); | |
1132 | |
1133 /* Include JUMP_INSN in the needed registers. */ | |
1134 for (insn = target; insn != stop_insn; insn = next_active_insn (insn)) | |
1135 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1136 mark_referenced_resources (insn, &needed, true); |
0 | 1137 |
1138 COPY_HARD_REG_SET (scratch, needed.regs); | |
1139 AND_COMPL_HARD_REG_SET (scratch, set.regs); | |
1140 IOR_HARD_REG_SET (new_resources.regs, scratch); | |
1141 | |
1142 mark_set_resources (insn, &set, 0, MARK_SRC_DEST_CALL); | |
1143 } | |
1144 | |
1145 IOR_HARD_REG_SET (res->regs, new_resources.regs); | |
1146 } | |
1147 | |
1148 if (tinfo != NULL) | |
1149 { | |
1150 COPY_HARD_REG_SET (tinfo->live_regs, res->regs); | |
1151 } | |
1152 } | |
1153 | |
1154 /* Initialize the resources required by mark_target_live_regs (). | |
1155 This should be invoked before the first call to mark_target_live_regs. */ | |
1156 | |
1157 void | |
111 | 1158 init_resource_info (rtx_insn *epilogue_insn) |
0 | 1159 { |
1160 int i; | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1161 basic_block bb; |
0 | 1162 |
1163 /* Indicate what resources are required to be valid at the end of the current | |
111 | 1164 function. The condition code never is and memory always is. |
1165 The stack pointer is needed unless EXIT_IGNORE_STACK is true | |
1166 and there is an epilogue that restores the original stack pointer | |
1167 from the frame pointer. Registers used to return the function value | |
1168 are needed. Registers holding global variables are needed. */ | |
0 | 1169 |
1170 end_of_function_needs.cc = 0; | |
1171 end_of_function_needs.memory = 1; | |
1172 CLEAR_HARD_REG_SET (end_of_function_needs.regs); | |
1173 | |
1174 if (frame_pointer_needed) | |
1175 { | |
1176 SET_HARD_REG_BIT (end_of_function_needs.regs, FRAME_POINTER_REGNUM); | |
111 | 1177 if (!HARD_FRAME_POINTER_IS_FRAME_POINTER) |
1178 SET_HARD_REG_BIT (end_of_function_needs.regs, | |
1179 HARD_FRAME_POINTER_REGNUM); | |
0 | 1180 } |
111 | 1181 if (!(frame_pointer_needed |
1182 && EXIT_IGNORE_STACK | |
1183 && epilogue_insn | |
1184 && !crtl->sp_is_unchanging)) | |
0 | 1185 SET_HARD_REG_BIT (end_of_function_needs.regs, STACK_POINTER_REGNUM); |
1186 | |
1187 if (crtl->return_rtx != 0) | |
1188 mark_referenced_resources (crtl->return_rtx, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1189 &end_of_function_needs, true); |
0 | 1190 |
1191 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
111 | 1192 if (global_regs[i] || EPILOGUE_USES (i)) |
0 | 1193 SET_HARD_REG_BIT (end_of_function_needs.regs, i); |
1194 | |
1195 /* The registers required to be live at the end of the function are | |
1196 represented in the flow information as being dead just prior to | |
1197 reaching the end of the function. For example, the return of a value | |
1198 might be represented by a USE of the return register immediately | |
1199 followed by an unconditional jump to the return label where the | |
1200 return label is the end of the RTL chain. The end of the RTL chain | |
1201 is then taken to mean that the return register is live. | |
1202 | |
1203 This sequence is no longer maintained when epilogue instructions are | |
1204 added to the RTL chain. To reconstruct the original meaning, the | |
1205 start of the epilogue (NOTE_INSN_EPILOGUE_BEG) is regarded as the | |
1206 point where these registers become live (start_of_epilogue_needs). | |
1207 If epilogue instructions are present, the registers set by those | |
1208 instructions won't have been processed by flow. Thus, those | |
1209 registers are additionally required at the end of the RTL chain | |
1210 (end_of_function_needs). */ | |
1211 | |
1212 start_of_epilogue_needs = end_of_function_needs; | |
1213 | |
1214 while ((epilogue_insn = next_nonnote_insn (epilogue_insn))) | |
1215 { | |
1216 mark_set_resources (epilogue_insn, &end_of_function_needs, 0, | |
1217 MARK_SRC_DEST_CALL); | |
1218 if (return_insn_p (epilogue_insn)) | |
1219 break; | |
1220 } | |
1221 | |
1222 /* Allocate and initialize the tables used by mark_target_live_regs. */ | |
1223 target_hash_table = XCNEWVEC (struct target_info *, TARGET_HASH_PRIME); | |
111 | 1224 bb_ticks = XCNEWVEC (int, last_basic_block_for_fn (cfun)); |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1225 |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1226 /* Set the BLOCK_FOR_INSN of each label that starts a basic block. */ |
111 | 1227 FOR_EACH_BB_FN (bb, cfun) |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1228 if (LABEL_P (BB_HEAD (bb))) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1229 BLOCK_FOR_INSN (BB_HEAD (bb)) = bb; |
0 | 1230 } |
1231 | |
1232 /* Free up the resources allocated to mark_target_live_regs (). This | |
1233 should be invoked after the last call to mark_target_live_regs (). */ | |
1234 | |
1235 void | |
1236 free_resource_info (void) | |
1237 { | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1238 basic_block bb; |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1239 |
0 | 1240 if (target_hash_table != NULL) |
1241 { | |
1242 int i; | |
1243 | |
1244 for (i = 0; i < TARGET_HASH_PRIME; ++i) | |
1245 { | |
1246 struct target_info *ti = target_hash_table[i]; | |
1247 | |
1248 while (ti) | |
1249 { | |
1250 struct target_info *next = ti->next; | |
1251 free (ti); | |
1252 ti = next; | |
1253 } | |
1254 } | |
1255 | |
1256 free (target_hash_table); | |
1257 target_hash_table = NULL; | |
1258 } | |
1259 | |
1260 if (bb_ticks != NULL) | |
1261 { | |
1262 free (bb_ticks); | |
1263 bb_ticks = NULL; | |
1264 } | |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1265 |
111 | 1266 FOR_EACH_BB_FN (bb, cfun) |
19
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1267 if (LABEL_P (BB_HEAD (bb))) |
58ad6c70ea60
update gcc from 4.4.0 to 4.4.1.
kent@firefly.cr.ie.u-ryukyu.ac.jp
parents:
0
diff
changeset
|
1268 BLOCK_FOR_INSN (BB_HEAD (bb)) = NULL; |
0 | 1269 } |
1270 | |
1271 /* Clear any hashed information that we have stored for INSN. */ | |
1272 | |
1273 void | |
111 | 1274 clear_hashed_info_for_insn (rtx_insn *insn) |
0 | 1275 { |
1276 struct target_info *tinfo; | |
1277 | |
1278 if (target_hash_table != NULL) | |
1279 { | |
1280 for (tinfo = target_hash_table[INSN_UID (insn) % TARGET_HASH_PRIME]; | |
1281 tinfo; tinfo = tinfo->next) | |
1282 if (tinfo->uid == INSN_UID (insn)) | |
1283 break; | |
1284 | |
1285 if (tinfo) | |
1286 tinfo->block = -1; | |
1287 } | |
1288 } | |
1289 | |
1290 /* Increment the tick count for the basic block that contains INSN. */ | |
1291 | |
1292 void | |
111 | 1293 incr_ticks_for_insn (rtx_insn *insn) |
0 | 1294 { |
1295 int b = find_basic_block (insn, MAX_DELAY_SLOT_LIVE_SEARCH); | |
1296 | |
1297 if (b != -1) | |
1298 bb_ticks[b]++; | |
1299 } | |
1300 | |
1301 /* Add TRIAL to the set of resources used at the end of the current | |
1302 function. */ | |
1303 void | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
36
diff
changeset
|
1304 mark_end_of_function_resources (rtx trial, bool include_delayed_effects) |
0 | 1305 { |
1306 mark_referenced_resources (trial, &end_of_function_needs, | |
1307 include_delayed_effects); | |
1308 } |