Mercurial > hg > CbC > CbC_gcc
annotate gcc/regrename.c @ 158:494b0b89df80 default tip
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 18:13:55 +0900 |
parents | 1830386684a0 |
children |
rev | line source |
---|---|
0 | 1 /* Register renaming for the GNU compiler. |
145 | 2 Copyright (C) 2000-2020 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 | |
7 under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 3, or (at your option) | |
9 any later version. | |
10 | |
11 GCC is distributed in the hope that it will be useful, but WITHOUT | |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | |
14 License 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" |
24 #include "target.h" | |
25 #include "rtl.h" | |
26 #include "df.h" | |
27 #include "memmodel.h" | |
0 | 28 #include "tm_p.h" |
29 #include "insn-config.h" | |
30 #include "regs.h" | |
111 | 31 #include "emit-rtl.h" |
0 | 32 #include "recog.h" |
111 | 33 #include "addresses.h" |
34 #include "cfganal.h" | |
0 | 35 #include "tree-pass.h" |
145 | 36 #include "function-abi.h" |
111 | 37 #include "regrename.h" |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
38 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
39 /* This file implements the RTL register renaming pass of the compiler. It is |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
40 a semi-local pass whose goal is to maximize the usage of the register file |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
41 of the processor by substituting registers for others in the solution given |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
42 by the register allocator. The algorithm is as follows: |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
43 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
44 1. Local def/use chains are built: within each basic block, chains are |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
45 opened and closed; if a chain isn't closed at the end of the block, |
111 | 46 it is dropped. We pre-open chains if we have already examined a |
47 predecessor block and found chains live at the end which match | |
48 live registers at the start of the new block. | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
49 |
111 | 50 2. We try to combine the local chains across basic block boundaries by |
51 comparing chains that were open at the start or end of a block to | |
52 those in successor/predecessor blocks. | |
53 | |
54 3. For each chain, the set of possible renaming registers is computed. | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
55 This takes into account the renaming of previously processed chains. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
56 Optionally, a preferred class is computed for the renaming register. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
57 |
111 | 58 4. The best renaming register is computed for the chain in the above set, |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
59 using a round-robin allocation. If a preferred class exists, then the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
60 round-robin allocation is done within the class first, if possible. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
61 The round-robin allocation of renaming registers itself is global. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
62 |
111 | 63 5. If a renaming register has been found, it is substituted in the chain. |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
64 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
65 Targets can parameterize the pass by specifying a preferred class for the |
111 | 66 renaming register for a given (super)class of registers to be renamed. |
67 | |
68 DEBUG_INSNs are treated specially, in particular registers occurring inside | |
69 them are treated as requiring ALL_REGS as a class. */ | |
0 | 70 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
71 #if HOST_BITS_PER_WIDE_INT <= MAX_RECOG_OPERANDS |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
72 #error "Use a different bitmap implementation for untracked_operands." |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
73 #endif |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
74 |
0 | 75 enum scan_actions |
76 { | |
77 terminate_write, | |
78 terminate_dead, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
79 mark_all_read, |
0 | 80 mark_read, |
81 mark_write, | |
82 /* mark_access is for marking the destination regs in | |
83 REG_FRAME_RELATED_EXPR notes (as if they were read) so that the | |
84 note is updated properly. */ | |
85 mark_access | |
86 }; | |
87 | |
88 static const char * const scan_actions_name[] = | |
89 { | |
90 "terminate_write", | |
91 "terminate_dead", | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
92 "mark_all_read", |
0 | 93 "mark_read", |
94 "mark_write", | |
95 "mark_access" | |
96 }; | |
97 | |
111 | 98 /* TICK and THIS_TICK are used to record the last time we saw each |
99 register. */ | |
100 static int tick[FIRST_PSEUDO_REGISTER]; | |
101 static int this_tick = 0; | |
102 | |
0 | 103 static struct obstack rename_obstack; |
104 | |
111 | 105 /* If nonnull, the code calling into the register renamer requested |
106 information about insn operands, and we store it here. */ | |
107 vec<insn_rr_info> insn_rr; | |
108 | |
109 static void scan_rtx (rtx_insn *, rtx *, enum reg_class, enum scan_actions, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
110 enum op_type); |
111 | 111 static bool build_def_use (basic_block); |
112 | |
113 /* The id to be given to the next opened chain. */ | |
114 static unsigned current_id; | |
115 | |
116 /* A mapping of unique id numbers to chains. */ | |
117 static vec<du_head_p> id_to_chain; | |
118 | |
119 /* List of currently open chains. */ | |
145 | 120 static class du_head *open_chains; |
111 | 121 |
122 /* Bitmap of open chains. The bits set always match the list found in | |
123 open_chains. */ | |
124 static bitmap_head open_chains_set; | |
125 | |
126 /* Record the registers being tracked in open_chains. */ | |
127 static HARD_REG_SET live_in_chains; | |
128 | |
129 /* Record the registers that are live but not tracked. The intersection | |
130 between this and live_in_chains is empty. */ | |
131 static HARD_REG_SET live_hard_regs; | |
132 | |
133 /* Set while scanning RTL if INSN_RR is nonnull, i.e. if the current analysis | |
134 is for a caller that requires operand data. Used in | |
135 record_operand_use. */ | |
136 static operand_rr_info *cur_operand; | |
137 | |
138 /* Set while scanning RTL if a register dies. Used to tie chains. */ | |
145 | 139 static class du_head *terminated_this_insn; |
0 | 140 |
111 | 141 /* Return the chain corresponding to id number ID. Take into account that |
142 chains may have been merged. */ | |
143 du_head_p | |
144 regrename_chain_from_id (unsigned int id) | |
145 { | |
146 du_head_p first_chain = id_to_chain[id]; | |
147 du_head_p chain = first_chain; | |
148 while (chain->id != id) | |
149 { | |
150 id = chain->id; | |
151 chain = id_to_chain[id]; | |
152 } | |
153 first_chain->id = id; | |
154 return chain; | |
155 } | |
156 | |
157 /* Dump all def/use chains, starting at id FROM. */ | |
158 | |
159 static void | |
160 dump_def_use_chain (int from) | |
161 { | |
162 du_head_p head; | |
163 int i; | |
164 FOR_EACH_VEC_ELT_FROM (id_to_chain, i, head, from) | |
165 { | |
166 struct du_chain *this_du = head->first; | |
167 | |
168 fprintf (dump_file, "Register %s (%d):", | |
169 reg_names[head->regno], head->nregs); | |
170 while (this_du) | |
171 { | |
172 fprintf (dump_file, " %d [%s]", INSN_UID (this_du->insn), | |
173 reg_class_names[this_du->cl]); | |
174 this_du = this_du->next_use; | |
175 } | |
176 fprintf (dump_file, "\n"); | |
177 head = head->next_chain; | |
178 } | |
179 } | |
0 | 180 |
181 static void | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
182 free_chain_data (void) |
0 | 183 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
184 int i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
185 du_head_p ptr; |
111 | 186 for (i = 0; id_to_chain.iterate (i, &ptr); i++) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
187 bitmap_clear (&ptr->conflicts); |
0 | 188 |
111 | 189 id_to_chain.release (); |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
190 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
191 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
192 /* Walk all chains starting with CHAINS and record that they conflict with |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
193 another chain whose id is ID. */ |
0 | 194 |
195 static void | |
145 | 196 mark_conflict (class du_head *chains, unsigned id) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
197 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
198 while (chains) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
199 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
200 bitmap_set_bit (&chains->conflicts, id); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
201 chains = chains->next_chain; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
202 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
203 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
204 |
111 | 205 /* Examine cur_operand, and if it is nonnull, record information about the |
206 use THIS_DU which is part of the chain HEAD. */ | |
207 | |
208 static void | |
145 | 209 record_operand_use (class du_head *head, struct du_chain *this_du) |
111 | 210 { |
211 if (cur_operand == NULL || cur_operand->failed) | |
212 return; | |
213 if (head->cannot_rename) | |
214 { | |
215 cur_operand->failed = true; | |
216 return; | |
217 } | |
218 gcc_assert (cur_operand->n_chains < MAX_REGS_PER_ADDRESS); | |
219 cur_operand->heads[cur_operand->n_chains] = head; | |
220 cur_operand->chains[cur_operand->n_chains++] = this_du; | |
221 } | |
222 | |
223 /* Create a new chain for THIS_NREGS registers starting at THIS_REGNO, | |
224 and record its occurrence in *LOC, which is being written to in INSN. | |
225 This access requires a register of class CL. */ | |
226 | |
227 static du_head_p | |
228 create_new_chain (unsigned this_regno, unsigned this_nregs, rtx *loc, | |
229 rtx_insn *insn, enum reg_class cl) | |
230 { | |
145 | 231 class du_head *head = XOBNEW (&rename_obstack, class du_head); |
111 | 232 struct du_chain *this_du; |
233 int nregs; | |
234 | |
145 | 235 memset ((void *)head, 0, sizeof *head); |
111 | 236 head->next_chain = open_chains; |
237 head->regno = this_regno; | |
238 head->nregs = this_nregs; | |
239 | |
240 id_to_chain.safe_push (head); | |
241 head->id = current_id++; | |
242 | |
243 bitmap_initialize (&head->conflicts, &bitmap_default_obstack); | |
244 bitmap_copy (&head->conflicts, &open_chains_set); | |
245 mark_conflict (open_chains, head->id); | |
246 | |
247 /* Since we're tracking this as a chain now, remove it from the | |
248 list of conflicting live hard registers and track it in | |
249 live_in_chains instead. */ | |
250 nregs = head->nregs; | |
251 while (nregs-- > 0) | |
252 { | |
253 SET_HARD_REG_BIT (live_in_chains, head->regno + nregs); | |
254 CLEAR_HARD_REG_BIT (live_hard_regs, head->regno + nregs); | |
255 } | |
256 | |
145 | 257 head->hard_conflicts = live_hard_regs; |
111 | 258 bitmap_set_bit (&open_chains_set, head->id); |
259 | |
260 open_chains = head; | |
261 | |
262 if (dump_file) | |
263 { | |
264 fprintf (dump_file, "Creating chain %s (%d)", | |
265 reg_names[head->regno], head->id); | |
266 if (insn != NULL_RTX) | |
267 fprintf (dump_file, " at insn %d", INSN_UID (insn)); | |
268 fprintf (dump_file, "\n"); | |
269 } | |
270 | |
271 if (insn == NULL_RTX) | |
272 { | |
273 head->first = head->last = NULL; | |
274 return head; | |
275 } | |
276 | |
277 this_du = XOBNEW (&rename_obstack, struct du_chain); | |
278 head->first = head->last = this_du; | |
279 | |
280 this_du->next_use = 0; | |
281 this_du->loc = loc; | |
282 this_du->insn = insn; | |
283 this_du->cl = cl; | |
284 record_operand_use (head, this_du); | |
285 return head; | |
286 } | |
287 | |
288 /* For a def-use chain HEAD, find which registers overlap its lifetime and | |
289 set the corresponding bits in *PSET. */ | |
290 | |
291 static void | |
145 | 292 merge_overlapping_regs (HARD_REG_SET *pset, class du_head *head) |
111 | 293 { |
294 bitmap_iterator bi; | |
295 unsigned i; | |
145 | 296 *pset |= head->hard_conflicts; |
111 | 297 EXECUTE_IF_SET_IN_BITMAP (&head->conflicts, 0, i, bi) |
298 { | |
299 du_head_p other = regrename_chain_from_id (i); | |
300 unsigned j = other->nregs; | |
301 gcc_assert (other != head); | |
302 while (j-- > 0) | |
303 SET_HARD_REG_BIT (*pset, other->regno + j); | |
304 } | |
305 } | |
306 | |
145 | 307 /* Return true if (reg:MODE REGNO) would be clobbered by a call covered |
308 by THIS_HEAD. */ | |
309 | |
310 static bool | |
311 call_clobbered_in_chain_p (du_head *this_head, machine_mode mode, | |
312 unsigned int regno) | |
313 { | |
314 return call_clobbered_in_region_p (this_head->call_abis, | |
315 this_head->call_clobber_mask, | |
316 mode, regno); | |
317 } | |
318 | |
111 | 319 /* Check if NEW_REG can be the candidate register to rename for |
320 REG in THIS_HEAD chain. THIS_UNAVAILABLE is a set of unavailable hard | |
321 registers. */ | |
322 | |
323 static bool | |
324 check_new_reg_p (int reg ATTRIBUTE_UNUSED, int new_reg, | |
145 | 325 class du_head *this_head, HARD_REG_SET this_unavailable) |
111 | 326 { |
327 machine_mode mode = GET_MODE (*this_head->first->loc); | |
328 int nregs = hard_regno_nregs (new_reg, mode); | |
329 int i; | |
330 struct du_chain *tmp; | |
331 | |
332 for (i = nregs - 1; i >= 0; --i) | |
333 if (TEST_HARD_REG_BIT (this_unavailable, new_reg + i) | |
334 || fixed_regs[new_reg + i] | |
335 || global_regs[new_reg + i] | |
336 /* Can't use regs which aren't saved by the prologue. */ | |
337 || (! df_regs_ever_live_p (new_reg + i) | |
145 | 338 && ! crtl->abi->clobbers_full_reg_p (new_reg + i)) |
111 | 339 #ifdef LEAF_REGISTERS |
340 /* We can't use a non-leaf register if we're in a | |
341 leaf function. */ | |
342 || (crtl->is_leaf | |
343 && !LEAF_REGISTERS[new_reg + i]) | |
344 #endif | |
345 || ! HARD_REGNO_RENAME_OK (reg + i, new_reg + i)) | |
346 return false; | |
347 | |
348 /* See whether it accepts all modes that occur in | |
349 definition and uses. */ | |
350 for (tmp = this_head->first; tmp; tmp = tmp->next_use) | |
351 if ((!targetm.hard_regno_mode_ok (new_reg, GET_MODE (*tmp->loc)) | |
352 && ! DEBUG_INSN_P (tmp->insn)) | |
145 | 353 || call_clobbered_in_chain_p (this_head, GET_MODE (*tmp->loc), |
354 new_reg)) | |
111 | 355 return false; |
356 | |
357 return true; | |
358 } | |
359 | |
360 /* For the chain THIS_HEAD, compute and return the best register to | |
361 rename to. SUPER_CLASS is the superunion of register classes in | |
362 the chain. UNAVAILABLE is a set of registers that cannot be used. | |
363 OLD_REG is the register currently used for the chain. BEST_RENAME | |
364 controls whether the register chosen must be better than the | |
365 current one or just respect the given constraint. */ | |
366 | |
367 int | |
368 find_rename_reg (du_head_p this_head, enum reg_class super_class, | |
369 HARD_REG_SET *unavailable, int old_reg, bool best_rename) | |
370 { | |
371 bool has_preferred_class; | |
372 enum reg_class preferred_class; | |
373 int pass; | |
374 int best_new_reg = old_reg; | |
375 | |
376 /* Mark registers that overlap this chain's lifetime as unavailable. */ | |
377 merge_overlapping_regs (unavailable, this_head); | |
378 | |
379 /* Compute preferred rename class of super union of all the classes | |
380 in the chain. */ | |
381 preferred_class | |
382 = (enum reg_class) targetm.preferred_rename_class (super_class); | |
383 | |
384 /* Pick and check the register from the tied chain iff the tied chain | |
385 is not renamed. */ | |
386 if (this_head->tied_chain && !this_head->tied_chain->renamed | |
387 && check_new_reg_p (old_reg, this_head->tied_chain->regno, | |
388 this_head, *unavailable)) | |
389 return this_head->tied_chain->regno; | |
390 | |
391 /* If PREFERRED_CLASS is not NO_REGS, we iterate in the first pass | |
392 over registers that belong to PREFERRED_CLASS and try to find the | |
393 best register within the class. If that failed, we iterate in | |
394 the second pass over registers that don't belong to the class. | |
395 If PREFERRED_CLASS is NO_REGS, we iterate over all registers in | |
396 ascending order without any preference. */ | |
397 has_preferred_class = (preferred_class != NO_REGS); | |
398 for (pass = (has_preferred_class ? 0 : 1); pass < 2; pass++) | |
399 { | |
400 int new_reg; | |
401 for (new_reg = 0; new_reg < FIRST_PSEUDO_REGISTER; new_reg++) | |
402 { | |
403 if (has_preferred_class | |
404 && (pass == 0) | |
405 != TEST_HARD_REG_BIT (reg_class_contents[preferred_class], | |
406 new_reg)) | |
407 continue; | |
408 | |
409 if (!check_new_reg_p (old_reg, new_reg, this_head, *unavailable)) | |
410 continue; | |
411 | |
412 if (!best_rename) | |
413 return new_reg; | |
414 | |
415 /* In the first pass, we force the renaming of registers that | |
416 don't belong to PREFERRED_CLASS to registers that do, even | |
417 though the latters were used not very long ago. */ | |
418 if ((pass == 0 | |
419 && !TEST_HARD_REG_BIT (reg_class_contents[preferred_class], | |
420 best_new_reg)) | |
421 || tick[best_new_reg] > tick[new_reg]) | |
422 best_new_reg = new_reg; | |
423 } | |
424 if (pass == 0 && best_new_reg != old_reg) | |
425 break; | |
426 } | |
427 return best_new_reg; | |
428 } | |
429 | |
430 /* Iterate over elements in the chain HEAD in order to: | |
431 1. Count number of uses, storing it in *PN_USES. | |
432 2. Narrow the set of registers we can use for renaming, adding | |
433 unavailable registers to *PUNAVAILABLE, which must be | |
434 initialized by the caller. | |
435 3. Compute the superunion of register classes in this chain | |
436 and return it. */ | |
437 reg_class | |
438 regrename_find_superclass (du_head_p head, int *pn_uses, | |
439 HARD_REG_SET *punavailable) | |
440 { | |
441 int n_uses = 0; | |
442 reg_class super_class = NO_REGS; | |
443 for (du_chain *tmp = head->first; tmp; tmp = tmp->next_use) | |
444 { | |
445 if (DEBUG_INSN_P (tmp->insn)) | |
446 continue; | |
447 n_uses++; | |
145 | 448 *punavailable |= ~reg_class_contents[tmp->cl]; |
111 | 449 super_class |
450 = reg_class_superunion[(int) super_class][(int) tmp->cl]; | |
451 } | |
452 *pn_uses = n_uses; | |
453 return super_class; | |
454 } | |
455 | |
456 /* Perform register renaming on the current function. */ | |
457 static void | |
458 rename_chains (void) | |
459 { | |
460 HARD_REG_SET unavailable; | |
461 du_head_p this_head; | |
462 int i; | |
463 | |
464 memset (tick, 0, sizeof tick); | |
465 | |
466 CLEAR_HARD_REG_SET (unavailable); | |
467 /* Don't clobber traceback for noreturn functions. */ | |
468 if (frame_pointer_needed) | |
469 { | |
470 add_to_hard_reg_set (&unavailable, Pmode, FRAME_POINTER_REGNUM); | |
471 if (!HARD_FRAME_POINTER_IS_FRAME_POINTER) | |
472 add_to_hard_reg_set (&unavailable, Pmode, HARD_FRAME_POINTER_REGNUM); | |
473 } | |
474 | |
475 FOR_EACH_VEC_ELT (id_to_chain, i, this_head) | |
476 { | |
477 int best_new_reg; | |
478 int n_uses; | |
479 HARD_REG_SET this_unavailable; | |
480 int reg = this_head->regno; | |
481 | |
482 if (this_head->cannot_rename) | |
483 continue; | |
484 | |
485 if (fixed_regs[reg] || global_regs[reg] | |
486 || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed | |
487 && reg == HARD_FRAME_POINTER_REGNUM) | |
488 || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed | |
489 && reg == FRAME_POINTER_REGNUM)) | |
490 continue; | |
491 | |
145 | 492 this_unavailable = unavailable; |
111 | 493 |
494 reg_class super_class = regrename_find_superclass (this_head, &n_uses, | |
495 &this_unavailable); | |
496 if (n_uses < 2) | |
497 continue; | |
498 | |
499 best_new_reg = find_rename_reg (this_head, super_class, | |
500 &this_unavailable, reg, true); | |
501 | |
502 if (dump_file) | |
503 { | |
504 fprintf (dump_file, "Register %s in insn %d", | |
505 reg_names[reg], INSN_UID (this_head->first->insn)); | |
145 | 506 if (this_head->call_abis) |
111 | 507 fprintf (dump_file, " crosses a call"); |
508 } | |
509 | |
510 if (best_new_reg == reg) | |
511 { | |
512 tick[reg] = ++this_tick; | |
513 if (dump_file) | |
514 fprintf (dump_file, "; no available better choice\n"); | |
515 continue; | |
516 } | |
517 | |
518 if (regrename_do_replace (this_head, best_new_reg)) | |
519 { | |
520 if (dump_file) | |
521 fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]); | |
522 tick[best_new_reg] = ++this_tick; | |
523 df_set_regs_ever_live (best_new_reg, true); | |
524 } | |
525 else | |
526 { | |
527 if (dump_file) | |
528 fprintf (dump_file, ", renaming as %s failed\n", | |
529 reg_names[best_new_reg]); | |
530 tick[reg] = ++this_tick; | |
531 } | |
532 } | |
533 } | |
534 | |
535 /* A structure to record information for each hard register at the start of | |
536 a basic block. */ | |
537 struct incoming_reg_info { | |
538 /* Holds the number of registers used in the chain that gave us information | |
539 about this register. Zero means no information known yet, while a | |
540 negative value is used for something that is part of, but not the first | |
541 register in a multi-register value. */ | |
542 int nregs; | |
543 /* Set to true if we have accesses that conflict in the number of registers | |
544 used. */ | |
545 bool unusable; | |
546 }; | |
547 | |
548 /* A structure recording information about each basic block. It is saved | |
549 and restored around basic block boundaries. | |
550 A pointer to such a structure is stored in each basic block's aux field | |
551 during regrename_analyze, except for blocks we know can't be optimized | |
552 (such as entry and exit blocks). */ | |
145 | 553 class bb_rename_info |
111 | 554 { |
145 | 555 public: |
111 | 556 /* The basic block corresponding to this structure. */ |
557 basic_block bb; | |
558 /* Copies of the global information. */ | |
559 bitmap_head open_chains_set; | |
560 bitmap_head incoming_open_chains_set; | |
561 struct incoming_reg_info incoming[FIRST_PSEUDO_REGISTER]; | |
562 }; | |
563 | |
564 /* Initialize a rename_info structure P for basic block BB, which starts a new | |
565 scan. */ | |
566 static void | |
145 | 567 init_rename_info (class bb_rename_info *p, basic_block bb) |
111 | 568 { |
569 int i; | |
570 df_ref def; | |
571 HARD_REG_SET start_chains_set; | |
572 | |
573 p->bb = bb; | |
574 bitmap_initialize (&p->open_chains_set, &bitmap_default_obstack); | |
575 bitmap_initialize (&p->incoming_open_chains_set, &bitmap_default_obstack); | |
576 | |
577 open_chains = NULL; | |
578 bitmap_clear (&open_chains_set); | |
579 | |
580 CLEAR_HARD_REG_SET (live_in_chains); | |
581 REG_SET_TO_HARD_REG_SET (live_hard_regs, df_get_live_in (bb)); | |
582 FOR_EACH_ARTIFICIAL_DEF (def, bb->index) | |
583 if (DF_REF_FLAGS (def) & DF_REF_AT_TOP) | |
584 SET_HARD_REG_BIT (live_hard_regs, DF_REF_REGNO (def)); | |
585 | |
586 /* Open chains based on information from (at least one) predecessor | |
587 block. This gives us a chance later on to combine chains across | |
588 basic block boundaries. Inconsistencies (in access sizes) will | |
589 be caught normally and dealt with conservatively by disabling the | |
590 chain for renaming, and there is no risk of losing optimization | |
591 opportunities by opening chains either: if we did not open the | |
592 chains, we'd have to track the live register as a hard reg, and | |
593 we'd be unable to rename it in any case. */ | |
594 CLEAR_HARD_REG_SET (start_chains_set); | |
595 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
596 { | |
597 struct incoming_reg_info *iri = p->incoming + i; | |
598 if (iri->nregs > 0 && !iri->unusable | |
599 && range_in_hard_reg_set_p (live_hard_regs, i, iri->nregs)) | |
600 { | |
601 SET_HARD_REG_BIT (start_chains_set, i); | |
602 remove_range_from_hard_reg_set (&live_hard_regs, i, iri->nregs); | |
603 } | |
604 } | |
605 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
606 { | |
607 struct incoming_reg_info *iri = p->incoming + i; | |
608 if (TEST_HARD_REG_BIT (start_chains_set, i)) | |
609 { | |
610 du_head_p chain; | |
611 if (dump_file) | |
612 fprintf (dump_file, "opening incoming chain\n"); | |
613 chain = create_new_chain (i, iri->nregs, NULL, NULL, NO_REGS); | |
614 bitmap_set_bit (&p->incoming_open_chains_set, chain->id); | |
615 } | |
616 } | |
617 } | |
618 | |
619 /* Record in RI that the block corresponding to it has an incoming | |
620 live value, described by CHAIN. */ | |
621 static void | |
145 | 622 set_incoming_from_chain (class bb_rename_info *ri, du_head_p chain) |
111 | 623 { |
624 int i; | |
625 int incoming_nregs = ri->incoming[chain->regno].nregs; | |
626 int nregs; | |
627 | |
628 /* If we've recorded the same information before, everything is fine. */ | |
629 if (incoming_nregs == chain->nregs) | |
630 { | |
631 if (dump_file) | |
632 fprintf (dump_file, "reg %d/%d already recorded\n", | |
633 chain->regno, chain->nregs); | |
634 return; | |
635 } | |
636 | |
637 /* If we have no information for any of the involved registers, update | |
638 the incoming array. */ | |
639 nregs = chain->nregs; | |
640 while (nregs-- > 0) | |
641 if (ri->incoming[chain->regno + nregs].nregs != 0 | |
642 || ri->incoming[chain->regno + nregs].unusable) | |
643 break; | |
644 if (nregs < 0) | |
645 { | |
646 nregs = chain->nregs; | |
647 ri->incoming[chain->regno].nregs = nregs; | |
648 while (nregs-- > 1) | |
649 ri->incoming[chain->regno + nregs].nregs = -nregs; | |
650 if (dump_file) | |
651 fprintf (dump_file, "recorded reg %d/%d\n", | |
652 chain->regno, chain->nregs); | |
653 return; | |
654 } | |
655 | |
656 /* There must be some kind of conflict. Prevent both the old and | |
657 new ranges from being used. */ | |
658 if (incoming_nregs < 0) | |
659 ri->incoming[chain->regno + incoming_nregs].unusable = true; | |
660 for (i = 0; i < chain->nregs; i++) | |
661 ri->incoming[chain->regno + i].unusable = true; | |
662 } | |
663 | |
664 /* Merge the two chains C1 and C2 so that all conflict information is | |
665 recorded and C1, and the id of C2 is changed to that of C1. */ | |
666 static void | |
667 merge_chains (du_head_p c1, du_head_p c2) | |
668 { | |
669 if (c1 == c2) | |
670 return; | |
671 | |
672 if (c2->first != NULL) | |
673 { | |
674 if (c1->first == NULL) | |
675 c1->first = c2->first; | |
676 else | |
677 c1->last->next_use = c2->first; | |
678 c1->last = c2->last; | |
679 } | |
680 | |
681 c2->first = c2->last = NULL; | |
682 c2->id = c1->id; | |
683 | |
145 | 684 c1->hard_conflicts |= c2->hard_conflicts; |
111 | 685 bitmap_ior_into (&c1->conflicts, &c2->conflicts); |
686 | |
145 | 687 c1->call_clobber_mask |= c2->call_clobber_mask; |
688 c1->call_abis |= c2->call_abis; | |
111 | 689 c1->cannot_rename |= c2->cannot_rename; |
690 } | |
691 | |
692 /* Analyze the current function and build chains for renaming. */ | |
693 | |
694 void | |
695 regrename_analyze (bitmap bb_mask) | |
696 { | |
145 | 697 class bb_rename_info *rename_info; |
111 | 698 int i; |
699 basic_block bb; | |
700 int n_bbs; | |
701 int *inverse_postorder; | |
702 | |
703 inverse_postorder = XNEWVEC (int, last_basic_block_for_fn (cfun)); | |
704 n_bbs = pre_and_rev_post_order_compute (NULL, inverse_postorder, false); | |
705 | |
706 /* Gather some information about the blocks in this function. */ | |
145 | 707 rename_info = XCNEWVEC (class bb_rename_info, n_basic_blocks_for_fn (cfun)); |
111 | 708 i = 0; |
709 FOR_EACH_BB_FN (bb, cfun) | |
710 { | |
145 | 711 class bb_rename_info *ri = rename_info + i; |
111 | 712 ri->bb = bb; |
713 if (bb_mask != NULL && !bitmap_bit_p (bb_mask, bb->index)) | |
714 bb->aux = NULL; | |
715 else | |
716 bb->aux = ri; | |
717 i++; | |
718 } | |
719 | |
720 current_id = 0; | |
721 id_to_chain.create (0); | |
722 bitmap_initialize (&open_chains_set, &bitmap_default_obstack); | |
723 | |
724 /* The order in which we visit blocks ensures that whenever | |
725 possible, we only process a block after at least one of its | |
726 predecessors, which provides a "seeding" effect to make the logic | |
727 in set_incoming_from_chain and init_rename_info useful. */ | |
728 | |
729 for (i = 0; i < n_bbs; i++) | |
730 { | |
731 basic_block bb1 = BASIC_BLOCK_FOR_FN (cfun, inverse_postorder[i]); | |
145 | 732 class bb_rename_info *this_info; |
111 | 733 bool success; |
734 edge e; | |
735 edge_iterator ei; | |
736 int old_length = id_to_chain.length (); | |
737 | |
145 | 738 this_info = (class bb_rename_info *) bb1->aux; |
111 | 739 if (this_info == NULL) |
740 continue; | |
741 | |
742 if (dump_file) | |
743 fprintf (dump_file, "\nprocessing block %d:\n", bb1->index); | |
744 | |
745 init_rename_info (this_info, bb1); | |
746 | |
747 success = build_def_use (bb1); | |
748 if (!success) | |
749 { | |
750 if (dump_file) | |
751 fprintf (dump_file, "failed\n"); | |
752 bb1->aux = NULL; | |
753 id_to_chain.truncate (old_length); | |
754 current_id = old_length; | |
755 bitmap_clear (&this_info->incoming_open_chains_set); | |
756 open_chains = NULL; | |
757 if (insn_rr.exists ()) | |
758 { | |
759 rtx_insn *insn; | |
760 FOR_BB_INSNS (bb1, insn) | |
761 { | |
762 insn_rr_info *p = &insn_rr[INSN_UID (insn)]; | |
763 p->op_info = NULL; | |
764 } | |
765 } | |
766 continue; | |
767 } | |
768 | |
769 if (dump_file) | |
770 dump_def_use_chain (old_length); | |
771 bitmap_copy (&this_info->open_chains_set, &open_chains_set); | |
772 | |
773 /* Add successor blocks to the worklist if necessary, and record | |
774 data about our own open chains at the end of this block, which | |
775 will be used to pre-open chains when processing the successors. */ | |
776 FOR_EACH_EDGE (e, ei, bb1->succs) | |
777 { | |
145 | 778 class bb_rename_info *dest_ri; |
779 class du_head *chain; | |
111 | 780 |
781 if (dump_file) | |
782 fprintf (dump_file, "successor block %d\n", e->dest->index); | |
783 | |
784 if (e->flags & (EDGE_EH | EDGE_ABNORMAL)) | |
785 continue; | |
145 | 786 dest_ri = (class bb_rename_info *)e->dest->aux; |
111 | 787 if (dest_ri == NULL) |
788 continue; | |
789 for (chain = open_chains; chain; chain = chain->next_chain) | |
790 set_incoming_from_chain (dest_ri, chain); | |
791 } | |
792 } | |
793 | |
794 free (inverse_postorder); | |
795 | |
796 /* Now, combine the chains data we have gathered across basic block | |
797 boundaries. | |
798 | |
799 For every basic block, there may be chains open at the start, or at the | |
800 end. Rather than exclude them from renaming, we look for open chains | |
801 with matching registers at the other side of the CFG edge. | |
802 | |
803 For a given chain using register R, open at the start of block B, we | |
804 must find an open chain using R on the other side of every edge leading | |
805 to B, if the register is live across this edge. In the code below, | |
806 N_PREDS_USED counts the number of edges where the register is live, and | |
807 N_PREDS_JOINED counts those where we found an appropriate chain for | |
808 joining. | |
809 | |
810 We perform the analysis for both incoming and outgoing edges, but we | |
811 only need to merge once (in the second part, after verifying outgoing | |
812 edges). */ | |
813 FOR_EACH_BB_FN (bb, cfun) | |
814 { | |
145 | 815 class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux; |
111 | 816 unsigned j; |
817 bitmap_iterator bi; | |
818 | |
819 if (bb_ri == NULL) | |
820 continue; | |
821 | |
822 if (dump_file) | |
823 fprintf (dump_file, "processing bb %d in edges\n", bb->index); | |
824 | |
825 EXECUTE_IF_SET_IN_BITMAP (&bb_ri->incoming_open_chains_set, 0, j, bi) | |
826 { | |
827 edge e; | |
828 edge_iterator ei; | |
145 | 829 class du_head *chain = regrename_chain_from_id (j); |
111 | 830 int n_preds_used = 0, n_preds_joined = 0; |
831 | |
832 FOR_EACH_EDGE (e, ei, bb->preds) | |
833 { | |
145 | 834 class bb_rename_info *src_ri; |
111 | 835 unsigned k; |
836 bitmap_iterator bi2; | |
837 HARD_REG_SET live; | |
838 bool success = false; | |
839 | |
840 REG_SET_TO_HARD_REG_SET (live, df_get_live_out (e->src)); | |
841 if (!range_overlaps_hard_reg_set_p (live, chain->regno, | |
842 chain->nregs)) | |
843 continue; | |
844 n_preds_used++; | |
845 | |
846 if (e->flags & (EDGE_EH | EDGE_ABNORMAL)) | |
847 continue; | |
848 | |
145 | 849 src_ri = (class bb_rename_info *)e->src->aux; |
111 | 850 if (src_ri == NULL) |
851 continue; | |
852 | |
853 EXECUTE_IF_SET_IN_BITMAP (&src_ri->open_chains_set, | |
854 0, k, bi2) | |
855 { | |
145 | 856 class du_head *outgoing_chain = regrename_chain_from_id (k); |
111 | 857 |
858 if (outgoing_chain->regno == chain->regno | |
859 && outgoing_chain->nregs == chain->nregs) | |
860 { | |
861 n_preds_joined++; | |
862 success = true; | |
863 break; | |
864 } | |
865 } | |
866 if (!success && dump_file) | |
867 fprintf (dump_file, "failure to match with pred block %d\n", | |
868 e->src->index); | |
869 } | |
870 if (n_preds_joined < n_preds_used) | |
871 { | |
872 if (dump_file) | |
873 fprintf (dump_file, "cannot rename chain %d\n", j); | |
874 chain->cannot_rename = 1; | |
875 } | |
876 } | |
877 } | |
878 FOR_EACH_BB_FN (bb, cfun) | |
879 { | |
145 | 880 class bb_rename_info *bb_ri = (class bb_rename_info *) bb->aux; |
111 | 881 unsigned j; |
882 bitmap_iterator bi; | |
883 | |
884 if (bb_ri == NULL) | |
885 continue; | |
886 | |
887 if (dump_file) | |
888 fprintf (dump_file, "processing bb %d out edges\n", bb->index); | |
889 | |
890 EXECUTE_IF_SET_IN_BITMAP (&bb_ri->open_chains_set, 0, j, bi) | |
891 { | |
892 edge e; | |
893 edge_iterator ei; | |
145 | 894 class du_head *chain = regrename_chain_from_id (j); |
111 | 895 int n_succs_used = 0, n_succs_joined = 0; |
896 | |
897 FOR_EACH_EDGE (e, ei, bb->succs) | |
898 { | |
899 bool printed = false; | |
145 | 900 class bb_rename_info *dest_ri; |
111 | 901 unsigned k; |
902 bitmap_iterator bi2; | |
903 HARD_REG_SET live; | |
904 | |
905 REG_SET_TO_HARD_REG_SET (live, df_get_live_in (e->dest)); | |
906 if (!range_overlaps_hard_reg_set_p (live, chain->regno, | |
907 chain->nregs)) | |
908 continue; | |
909 | |
910 n_succs_used++; | |
911 | |
145 | 912 dest_ri = (class bb_rename_info *)e->dest->aux; |
111 | 913 if (dest_ri == NULL) |
914 continue; | |
915 | |
916 EXECUTE_IF_SET_IN_BITMAP (&dest_ri->incoming_open_chains_set, | |
917 0, k, bi2) | |
918 { | |
145 | 919 class du_head *incoming_chain = regrename_chain_from_id (k); |
111 | 920 |
921 if (incoming_chain->regno == chain->regno | |
922 && incoming_chain->nregs == chain->nregs) | |
923 { | |
924 if (dump_file) | |
925 { | |
926 if (!printed) | |
927 fprintf (dump_file, | |
928 "merging blocks for edge %d -> %d\n", | |
929 e->src->index, e->dest->index); | |
930 printed = true; | |
931 fprintf (dump_file, | |
932 " merging chains %d (->%d) and %d (->%d) [%s]\n", | |
933 k, incoming_chain->id, j, chain->id, | |
934 reg_names[incoming_chain->regno]); | |
935 } | |
936 | |
937 merge_chains (chain, incoming_chain); | |
938 n_succs_joined++; | |
939 break; | |
940 } | |
941 } | |
942 } | |
943 if (n_succs_joined < n_succs_used) | |
944 { | |
945 if (dump_file) | |
946 fprintf (dump_file, "cannot rename chain %d\n", | |
947 j); | |
948 chain->cannot_rename = 1; | |
949 } | |
950 } | |
951 } | |
952 | |
953 free (rename_info); | |
954 | |
955 FOR_EACH_BB_FN (bb, cfun) | |
956 bb->aux = NULL; | |
957 } | |
958 | |
959 /* Attempt to replace all uses of the register in the chain beginning with | |
960 HEAD with REG. Returns true on success and false if the replacement is | |
961 rejected because the insns would not validate. The latter can happen | |
962 e.g. if a match_parallel predicate enforces restrictions on register | |
963 numbering in its subpatterns. */ | |
964 | |
965 bool | |
145 | 966 regrename_do_replace (class du_head *head, int reg) |
111 | 967 { |
968 struct du_chain *chain; | |
969 unsigned int base_regno = head->regno; | |
970 machine_mode mode; | |
131 | 971 rtx last_reg = NULL_RTX, last_repl = NULL_RTX; |
111 | 972 |
973 for (chain = head->first; chain; chain = chain->next_use) | |
974 { | |
975 unsigned int regno = ORIGINAL_REGNO (*chain->loc); | |
145 | 976 class reg_attrs *attr = REG_ATTRS (*chain->loc); |
111 | 977 int reg_ptr = REG_POINTER (*chain->loc); |
978 | |
979 if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno) | |
980 validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)), | |
981 gen_rtx_UNKNOWN_VAR_LOC (), true); | |
982 else | |
983 { | |
131 | 984 if (*chain->loc != last_reg) |
985 { | |
986 last_repl = gen_raw_REG (GET_MODE (*chain->loc), reg); | |
987 if (regno >= FIRST_PSEUDO_REGISTER) | |
988 ORIGINAL_REGNO (last_repl) = regno; | |
989 REG_ATTRS (last_repl) = attr; | |
990 REG_POINTER (last_repl) = reg_ptr; | |
991 last_reg = *chain->loc; | |
992 } | |
993 validate_change (chain->insn, chain->loc, last_repl, true); | |
111 | 994 } |
995 } | |
996 | |
997 if (!apply_change_group ()) | |
998 return false; | |
999 | |
1000 mode = GET_MODE (*head->first->loc); | |
1001 head->renamed = 1; | |
1002 head->regno = reg; | |
1003 head->nregs = hard_regno_nregs (reg, mode); | |
1004 return true; | |
1005 } | |
1006 | |
1007 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1008 /* True if we found a register with a size mismatch, which means that we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1009 can't track its lifetime accurately. If so, we abort the current block |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1010 without renaming. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1011 static bool fail_current_block; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1012 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1013 /* Return true if OP is a reg for which all bits are set in PSET, false |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1014 if all bits are clear. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1015 In other cases, set fail_current_block and return false. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1016 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1017 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1018 verify_reg_in_set (rtx op, HARD_REG_SET *pset) |
0 | 1019 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1020 unsigned regno, nregs; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1021 bool all_live, all_dead; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1022 if (!REG_P (op)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1023 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1024 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1025 regno = REGNO (op); |
111 | 1026 nregs = REG_NREGS (op); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1027 all_live = all_dead = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1028 while (nregs-- > 0) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1029 if (TEST_HARD_REG_BIT (*pset, regno + nregs)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1030 all_dead = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1031 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1032 all_live = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1033 if (!all_dead && !all_live) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1034 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1035 fail_current_block = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1036 return false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1037 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1038 return all_live; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1039 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1040 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1041 /* Return true if OP is a reg that is being tracked already in some form. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1042 May set fail_current_block if it sees an unhandled case of overlap. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1043 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1044 static bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1045 verify_reg_tracked (rtx op) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1046 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1047 return (verify_reg_in_set (op, &live_hard_regs) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1048 || verify_reg_in_set (op, &live_in_chains)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1049 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1050 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1051 /* Called through note_stores. DATA points to a rtx_code, either SET or |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1052 CLOBBER, which tells us which kind of rtx to look at. If we have a |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1053 match, record the set register in live_hard_regs and in the hard_conflicts |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1054 bitmap of open chains. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1055 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1056 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1057 note_sets_clobbers (rtx x, const_rtx set, void *data) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1058 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1059 enum rtx_code code = *(enum rtx_code *)data; |
145 | 1060 class du_head *chain; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1061 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1062 if (GET_CODE (x) == SUBREG) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1063 x = SUBREG_REG (x); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1064 if (!REG_P (x) || GET_CODE (set) != code) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1065 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1066 /* There must not be pseudos at this point. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1067 gcc_assert (HARD_REGISTER_P (x)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1068 add_to_hard_reg_set (&live_hard_regs, GET_MODE (x), REGNO (x)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1069 for (chain = open_chains; chain; chain = chain->next_chain) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1070 add_to_hard_reg_set (&chain->hard_conflicts, GET_MODE (x), REGNO (x)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1071 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1072 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1073 static void |
111 | 1074 scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action, |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1075 enum op_type type) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1076 { |
145 | 1077 class du_head **p; |
0 | 1078 rtx x = *loc; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1079 unsigned this_regno = REGNO (x); |
111 | 1080 int this_nregs = REG_NREGS (x); |
0 | 1081 |
1082 if (action == mark_write) | |
1083 { | |
1084 if (type == OP_OUT) | |
111 | 1085 { |
1086 du_head_p c; | |
1087 rtx pat = PATTERN (insn); | |
1088 | |
1089 c = create_new_chain (this_regno, this_nregs, loc, insn, cl); | |
1090 | |
1091 /* We try to tie chains in a move instruction for | |
1092 a single output. */ | |
1093 if (recog_data.n_operands == 2 | |
1094 && GET_CODE (pat) == SET | |
1095 && GET_CODE (SET_DEST (pat)) == REG | |
1096 && GET_CODE (SET_SRC (pat)) == REG | |
1097 && terminated_this_insn | |
1098 && terminated_this_insn->nregs | |
1099 == REG_NREGS (recog_data.operand[1])) | |
1100 { | |
1101 gcc_assert (terminated_this_insn->regno | |
1102 == REGNO (recog_data.operand[1])); | |
1103 | |
1104 c->tied_chain = terminated_this_insn; | |
1105 terminated_this_insn->tied_chain = c; | |
1106 | |
1107 if (dump_file) | |
1108 fprintf (dump_file, "Tying chain %s (%d) with %s (%d)\n", | |
1109 reg_names[c->regno], c->id, | |
1110 reg_names[terminated_this_insn->regno], | |
1111 terminated_this_insn->id); | |
1112 } | |
1113 } | |
1114 | |
0 | 1115 return; |
1116 } | |
1117 | |
1118 if ((type == OP_OUT) != (action == terminate_write || action == mark_access)) | |
1119 return; | |
1120 | |
1121 for (p = &open_chains; *p;) | |
1122 { | |
145 | 1123 class du_head *head = *p; |
1124 class du_head *next = head->next_chain; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1125 int exact_match = (head->regno == this_regno |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1126 && head->nregs == this_nregs); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1127 int superset = (this_regno <= head->regno |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1128 && this_regno + this_nregs >= head->regno + head->nregs); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1129 int subset = (this_regno >= head->regno |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1130 && this_regno + this_nregs <= head->regno + head->nregs); |
0 | 1131 |
111 | 1132 if (!bitmap_bit_p (&open_chains_set, head->id) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1133 || head->regno + head->nregs <= this_regno |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1134 || this_regno + this_nregs <= head->regno) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1135 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1136 p = &head->next_chain; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1137 continue; |
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 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1140 if (action == mark_read || action == mark_access) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1141 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1142 /* ??? Class NO_REGS can happen if the md file makes use of |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1143 EXTRA_CONSTRAINTS to match registers. Which is arguably |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1144 wrong, but there we are. */ |
0 | 1145 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1146 if (cl == NO_REGS || (!exact_match && !DEBUG_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
|
1147 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1148 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
|
1149 fprintf (dump_file, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1150 "Cannot rename chain %s (%d) at insn %d (%s)\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1151 reg_names[head->regno], head->id, INSN_UID (insn), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1152 scan_actions_name[(int) action]); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1153 head->cannot_rename = 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1154 if (superset) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1155 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1156 unsigned nregs = this_nregs; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1157 head->regno = this_regno; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1158 head->nregs = this_nregs; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1159 while (nregs-- > 0) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1160 SET_HARD_REG_BIT (live_in_chains, head->regno + nregs); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1161 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
|
1162 fprintf (dump_file, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1163 "Widening register in chain %s (%d) at insn %d\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1164 reg_names[head->regno], head->id, INSN_UID (insn)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1165 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1166 else if (!subset) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1167 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1168 fail_current_block = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1169 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
|
1170 fprintf (dump_file, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1171 "Failing basic block due to unhandled overlap\n"); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1172 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1173 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1174 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1175 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1176 struct du_chain *this_du; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1177 this_du = XOBNEW (&rename_obstack, struct du_chain); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1178 this_du->next_use = 0; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1179 this_du->loc = loc; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1180 this_du->insn = insn; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1181 this_du->cl = cl; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1182 if (head->first == NULL) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1183 head->first = this_du; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1184 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1185 head->last->next_use = this_du; |
111 | 1186 record_operand_use (head, this_du); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1187 head->last = this_du; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1188 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1189 /* Avoid adding the same location in a DEBUG_INSN multiple times, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1190 which could happen with non-exact overlap. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1191 if (DEBUG_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
|
1192 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1193 /* Otherwise, find any other chains that do not match exactly; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1194 ensure they all get marked unrenamable. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1195 p = &head->next_chain; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1196 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1197 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1198 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1199 /* Whether the terminated chain can be used for renaming |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1200 depends on the action and this being an exact match. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1201 In either case, we remove this element from open_chains. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1202 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1203 if ((action == terminate_dead || action == terminate_write) |
111 | 1204 && (superset || subset)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1205 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1206 unsigned nregs; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1207 |
111 | 1208 if (subset && !superset) |
1209 head->cannot_rename = 1; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1210 bitmap_clear_bit (&open_chains_set, head->id); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1211 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1212 nregs = head->nregs; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1213 while (nregs-- > 0) |
111 | 1214 { |
1215 CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs); | |
1216 if (subset && !superset | |
1217 && (head->regno + nregs < this_regno | |
1218 || head->regno + nregs >= this_regno + this_nregs)) | |
1219 SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs); | |
1220 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1221 |
111 | 1222 if (action == terminate_dead) |
1223 terminated_this_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
|
1224 *p = next; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1225 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
|
1226 fprintf (dump_file, |
111 | 1227 "Closing chain %s (%d) at insn %d (%s%s)\n", |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1228 reg_names[head->regno], head->id, INSN_UID (insn), |
111 | 1229 scan_actions_name[(int) action], |
1230 superset ? ", superset" : subset ? ", subset" : ""); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1231 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1232 else if (action == terminate_dead || action == terminate_write) |
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 /* In this case, tracking liveness gets too hard. Fail the |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1235 entire basic block. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1236 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
|
1237 fprintf (dump_file, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1238 "Failing basic block due to unhandled overlap\n"); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1239 fail_current_block = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1240 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1241 } |
0 | 1242 else |
1243 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1244 head->cannot_rename = 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1245 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
|
1246 fprintf (dump_file, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1247 "Cannot rename chain %s (%d) at insn %d (%s)\n", |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1248 reg_names[head->regno], head->id, INSN_UID (insn), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1249 scan_actions_name[(int) action]); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1250 p = &head->next_chain; |
0 | 1251 } |
1252 } | |
1253 } | |
1254 | |
111 | 1255 /* A wrapper around base_reg_class which returns ALL_REGS if INSN is a |
1256 DEBUG_INSN. The arguments MODE, AS, CODE and INDEX_CODE are as for | |
1257 base_reg_class. */ | |
1258 | |
1259 static reg_class | |
1260 base_reg_class_for_rename (rtx_insn *insn, machine_mode mode, addr_space_t as, | |
1261 rtx_code code, rtx_code index_code) | |
1262 { | |
1263 if (DEBUG_INSN_P (insn)) | |
1264 return ALL_REGS; | |
1265 return base_reg_class (mode, as, code, index_code); | |
1266 } | |
1267 | |
0 | 1268 /* Adapted from find_reloads_address_1. CL is INDEX_REG_CLASS or |
1269 BASE_REG_CLASS depending on how the register is being considered. */ | |
1270 | |
1271 static void | |
111 | 1272 scan_rtx_address (rtx_insn *insn, rtx *loc, enum reg_class cl, |
1273 enum scan_actions action, machine_mode mode, | |
1274 addr_space_t as) | |
0 | 1275 { |
1276 rtx x = *loc; | |
1277 RTX_CODE code = GET_CODE (x); | |
1278 const char *fmt; | |
1279 int i, j; | |
1280 | |
1281 if (action == mark_write || action == mark_access) | |
1282 return; | |
1283 | |
1284 switch (code) | |
1285 { | |
1286 case PLUS: | |
1287 { | |
1288 rtx orig_op0 = XEXP (x, 0); | |
1289 rtx orig_op1 = XEXP (x, 1); | |
1290 RTX_CODE code0 = GET_CODE (orig_op0); | |
1291 RTX_CODE code1 = GET_CODE (orig_op1); | |
1292 rtx op0 = orig_op0; | |
1293 rtx op1 = orig_op1; | |
1294 rtx *locI = NULL; | |
1295 rtx *locB = NULL; | |
1296 enum rtx_code index_code = SCRATCH; | |
1297 | |
1298 if (GET_CODE (op0) == SUBREG) | |
1299 { | |
1300 op0 = SUBREG_REG (op0); | |
1301 code0 = GET_CODE (op0); | |
1302 } | |
1303 | |
1304 if (GET_CODE (op1) == SUBREG) | |
1305 { | |
1306 op1 = SUBREG_REG (op1); | |
1307 code1 = GET_CODE (op1); | |
1308 } | |
1309 | |
1310 if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE | |
1311 || code0 == ZERO_EXTEND || code1 == MEM) | |
1312 { | |
1313 locI = &XEXP (x, 0); | |
1314 locB = &XEXP (x, 1); | |
1315 index_code = GET_CODE (*locI); | |
1316 } | |
1317 else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE | |
1318 || code1 == ZERO_EXTEND || code0 == MEM) | |
1319 { | |
1320 locI = &XEXP (x, 1); | |
1321 locB = &XEXP (x, 0); | |
1322 index_code = GET_CODE (*locI); | |
1323 } | |
1324 else if (code0 == CONST_INT || code0 == CONST | |
1325 || code0 == SYMBOL_REF || code0 == LABEL_REF) | |
1326 { | |
1327 locB = &XEXP (x, 1); | |
1328 index_code = GET_CODE (XEXP (x, 0)); | |
1329 } | |
1330 else if (code1 == CONST_INT || code1 == CONST | |
1331 || code1 == SYMBOL_REF || code1 == LABEL_REF) | |
1332 { | |
1333 locB = &XEXP (x, 0); | |
1334 index_code = GET_CODE (XEXP (x, 1)); | |
1335 } | |
1336 else if (code0 == REG && code1 == REG) | |
1337 { | |
1338 int index_op; | |
1339 unsigned regno0 = REGNO (op0), regno1 = REGNO (op1); | |
1340 | |
1341 if (REGNO_OK_FOR_INDEX_P (regno1) | |
111 | 1342 && regno_ok_for_base_p (regno0, mode, as, PLUS, REG)) |
0 | 1343 index_op = 1; |
1344 else if (REGNO_OK_FOR_INDEX_P (regno0) | |
111 | 1345 && regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) |
0 | 1346 index_op = 0; |
111 | 1347 else if (regno_ok_for_base_p (regno0, mode, as, PLUS, REG) |
0 | 1348 || REGNO_OK_FOR_INDEX_P (regno1)) |
1349 index_op = 1; | |
111 | 1350 else if (regno_ok_for_base_p (regno1, mode, as, PLUS, REG)) |
0 | 1351 index_op = 0; |
1352 else | |
1353 index_op = 1; | |
1354 | |
1355 locI = &XEXP (x, index_op); | |
1356 locB = &XEXP (x, !index_op); | |
1357 index_code = GET_CODE (*locI); | |
1358 } | |
1359 else if (code0 == REG) | |
1360 { | |
1361 locI = &XEXP (x, 0); | |
1362 locB = &XEXP (x, 1); | |
1363 index_code = GET_CODE (*locI); | |
1364 } | |
1365 else if (code1 == REG) | |
1366 { | |
1367 locI = &XEXP (x, 1); | |
1368 locB = &XEXP (x, 0); | |
1369 index_code = GET_CODE (*locI); | |
1370 } | |
1371 | |
1372 if (locI) | |
111 | 1373 { |
1374 reg_class iclass = DEBUG_INSN_P (insn) ? ALL_REGS : INDEX_REG_CLASS; | |
1375 scan_rtx_address (insn, locI, iclass, action, mode, as); | |
1376 } | |
0 | 1377 if (locB) |
111 | 1378 { |
1379 reg_class bclass = base_reg_class_for_rename (insn, mode, as, PLUS, | |
1380 index_code); | |
1381 scan_rtx_address (insn, locB, bclass, action, mode, as); | |
1382 } | |
0 | 1383 return; |
1384 } | |
1385 | |
1386 case POST_INC: | |
1387 case POST_DEC: | |
1388 case POST_MODIFY: | |
1389 case PRE_INC: | |
1390 case PRE_DEC: | |
1391 case PRE_MODIFY: | |
1392 /* If the target doesn't claim to handle autoinc, this must be | |
1393 something special, like a stack push. Kill this chain. */ | |
111 | 1394 if (!AUTO_INC_DEC) |
1395 action = mark_all_read; | |
1396 | |
0 | 1397 break; |
1398 | |
1399 case MEM: | |
111 | 1400 { |
1401 reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x), | |
1402 MEM_ADDR_SPACE (x), | |
1403 MEM, SCRATCH); | |
1404 scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x), | |
1405 MEM_ADDR_SPACE (x)); | |
1406 } | |
0 | 1407 return; |
1408 | |
1409 case REG: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1410 scan_rtx_reg (insn, loc, cl, action, OP_IN); |
0 | 1411 return; |
1412 | |
1413 default: | |
1414 break; | |
1415 } | |
1416 | |
1417 fmt = GET_RTX_FORMAT (code); | |
1418 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
1419 { | |
1420 if (fmt[i] == 'e') | |
111 | 1421 scan_rtx_address (insn, &XEXP (x, i), cl, action, mode, as); |
0 | 1422 else if (fmt[i] == 'E') |
1423 for (j = XVECLEN (x, i) - 1; j >= 0; j--) | |
111 | 1424 scan_rtx_address (insn, &XVECEXP (x, i, j), cl, action, mode, as); |
0 | 1425 } |
1426 } | |
1427 | |
1428 static void | |
111 | 1429 scan_rtx (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action, |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1430 enum op_type type) |
0 | 1431 { |
1432 const char *fmt; | |
1433 rtx x = *loc; | |
1434 int i, j; | |
1435 | |
145 | 1436 enum rtx_code code = GET_CODE (x); |
0 | 1437 switch (code) |
1438 { | |
1439 case CONST: | |
111 | 1440 CASE_CONST_ANY: |
0 | 1441 case SYMBOL_REF: |
1442 case LABEL_REF: | |
1443 case CC0: | |
1444 case PC: | |
1445 return; | |
1446 | |
1447 case REG: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1448 scan_rtx_reg (insn, loc, cl, action, type); |
0 | 1449 return; |
1450 | |
1451 case MEM: | |
111 | 1452 { |
1453 reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x), | |
1454 MEM_ADDR_SPACE (x), | |
1455 MEM, SCRATCH); | |
1456 | |
1457 scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x), | |
1458 MEM_ADDR_SPACE (x)); | |
1459 } | |
0 | 1460 return; |
1461 | |
1462 case SET: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1463 scan_rtx (insn, &SET_SRC (x), cl, action, OP_IN); |
0 | 1464 scan_rtx (insn, &SET_DEST (x), cl, action, |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1465 (GET_CODE (PATTERN (insn)) == COND_EXEC |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1466 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT); |
0 | 1467 return; |
1468 | |
1469 case STRICT_LOW_PART: | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1470 scan_rtx (insn, &XEXP (x, 0), cl, action, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1471 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT); |
0 | 1472 return; |
1473 | |
1474 case ZERO_EXTRACT: | |
1475 case SIGN_EXTRACT: | |
1476 scan_rtx (insn, &XEXP (x, 0), cl, action, | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1477 (type == OP_IN ? OP_IN : |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1478 verify_reg_tracked (XEXP (x, 0)) ? OP_INOUT : OP_OUT)); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1479 scan_rtx (insn, &XEXP (x, 1), cl, action, OP_IN); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1480 scan_rtx (insn, &XEXP (x, 2), cl, action, OP_IN); |
0 | 1481 return; |
1482 | |
1483 case POST_INC: | |
1484 case PRE_INC: | |
1485 case POST_DEC: | |
1486 case PRE_DEC: | |
1487 case POST_MODIFY: | |
1488 case PRE_MODIFY: | |
1489 /* Should only happen inside MEM. */ | |
1490 gcc_unreachable (); | |
1491 | |
1492 case CLOBBER: | |
1493 scan_rtx (insn, &SET_DEST (x), cl, action, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1494 (GET_CODE (PATTERN (insn)) == COND_EXEC |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1495 && verify_reg_tracked (SET_DEST (x))) ? OP_INOUT : OP_OUT); |
0 | 1496 return; |
1497 | |
1498 case EXPR_LIST: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1499 scan_rtx (insn, &XEXP (x, 0), cl, action, type); |
0 | 1500 if (XEXP (x, 1)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1501 scan_rtx (insn, &XEXP (x, 1), cl, action, type); |
0 | 1502 return; |
1503 | |
1504 default: | |
1505 break; | |
1506 } | |
1507 | |
1508 fmt = GET_RTX_FORMAT (code); | |
1509 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
1510 { | |
1511 if (fmt[i] == 'e') | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1512 scan_rtx (insn, &XEXP (x, i), cl, action, type); |
0 | 1513 else if (fmt[i] == 'E') |
1514 for (j = XVECLEN (x, i) - 1; j >= 0; j--) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1515 scan_rtx (insn, &XVECEXP (x, i, j), cl, action, type); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1516 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1517 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1518 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1519 /* Hide operands of the current insn (of which there are N_OPS) by |
145 | 1520 substituting pc for them. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1521 Previous values are stored in the OLD_OPERANDS and OLD_DUPS. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1522 For every bit set in DO_NOT_HIDE, we leave the operand alone. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1523 If INOUT_AND_EC_ONLY is set, we only do this for OP_INOUT type operands |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1524 and earlyclobbers. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1525 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1526 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1527 hide_operands (int n_ops, rtx *old_operands, rtx *old_dups, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1528 unsigned HOST_WIDE_INT do_not_hide, bool inout_and_ec_only) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1529 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1530 int i; |
111 | 1531 const operand_alternative *op_alt = which_op_alt (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1532 for (i = 0; i < n_ops; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1533 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1534 old_operands[i] = recog_data.operand[i]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1535 /* Don't squash match_operator or match_parallel here, since |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1536 we don't know that all of the contained registers are |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1537 reachable by proper operands. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1538 if (recog_data.constraints[i][0] == '\0') |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1539 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1540 if (do_not_hide & (1 << i)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1541 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1542 if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT |
111 | 1543 || op_alt[i].earlyclobber) |
145 | 1544 *recog_data.operand_loc[i] = pc_rtx; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1545 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1546 for (i = 0; i < recog_data.n_dups; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1547 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1548 int opn = recog_data.dup_num[i]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1549 old_dups[i] = *recog_data.dup_loc[i]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1550 if (do_not_hide & (1 << opn)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1551 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1552 if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT |
111 | 1553 || op_alt[opn].earlyclobber) |
145 | 1554 *recog_data.dup_loc[i] = pc_rtx; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1555 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1556 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1557 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1558 /* Undo the substitution performed by hide_operands. INSN is the insn we |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1559 are processing; the arguments are the same as in hide_operands. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1560 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1561 static void |
111 | 1562 restore_operands (rtx_insn *insn, int n_ops, rtx *old_operands, rtx *old_dups) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1563 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1564 int i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1565 for (i = 0; i < recog_data.n_dups; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1566 *recog_data.dup_loc[i] = old_dups[i]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1567 for (i = 0; i < n_ops; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1568 *recog_data.operand_loc[i] = old_operands[i]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1569 if (recog_data.n_dups) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1570 df_insn_rescan (insn); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1571 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1572 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1573 /* For each output operand of INSN, call scan_rtx to create a new |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1574 open chain. Do this only for normal or earlyclobber outputs, |
111 | 1575 depending on EARLYCLOBBER. If INSN_INFO is nonnull, use it to |
1576 record information about the operands in the insn. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1577 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1578 static void |
111 | 1579 record_out_operands (rtx_insn *insn, bool earlyclobber, insn_rr_info *insn_info) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1580 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1581 int n_ops = recog_data.n_operands; |
111 | 1582 const operand_alternative *op_alt = which_op_alt (); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1583 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1584 int i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1585 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1586 for (i = 0; i < n_ops + recog_data.n_dups; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1587 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1588 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops]; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1589 rtx *loc = (i < n_ops |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1590 ? recog_data.operand_loc[opn] |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1591 : recog_data.dup_loc[i - n_ops]); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1592 rtx op = *loc; |
111 | 1593 enum reg_class cl = alternative_class (op_alt, opn); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1594 |
145 | 1595 class du_head *prev_open; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1596 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1597 if (recog_data.operand_type[opn] != OP_OUT |
111 | 1598 || op_alt[opn].earlyclobber != earlyclobber) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1599 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1600 |
111 | 1601 if (insn_info) |
1602 cur_operand = insn_info->op_info + i; | |
1603 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1604 prev_open = open_chains; |
111 | 1605 if (earlyclobber) |
1606 scan_rtx (insn, loc, cl, terminate_write, OP_OUT); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1607 scan_rtx (insn, loc, cl, mark_write, OP_OUT); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1608 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1609 /* ??? Many targets have output constraints on the SET_DEST |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1610 of a call insn, which is stupid, since these are certainly |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1611 ABI defined hard registers. For these, and for asm operands |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1612 that originally referenced hard registers, we must record that |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1613 the chain cannot be renamed. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1614 if (CALL_P (insn) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1615 || (asm_noperands (PATTERN (insn)) > 0 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1616 && REG_P (op) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1617 && REGNO (op) == ORIGINAL_REGNO (op))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1618 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1619 if (prev_open != open_chains) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1620 open_chains->cannot_rename = 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1621 } |
0 | 1622 } |
111 | 1623 cur_operand = NULL; |
0 | 1624 } |
1625 | |
1626 /* Build def/use chain. */ | |
1627 | |
111 | 1628 static bool |
0 | 1629 build_def_use (basic_block bb) |
1630 { | |
111 | 1631 rtx_insn *insn; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1632 unsigned HOST_WIDE_INT untracked_operands; |
0 | 1633 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1634 fail_current_block = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1635 |
0 | 1636 for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn)) |
1637 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1638 if (NONDEBUG_INSN_P (insn)) |
0 | 1639 { |
1640 int n_ops; | |
1641 rtx note; | |
1642 rtx old_operands[MAX_RECOG_OPERANDS]; | |
1643 rtx old_dups[MAX_DUP_OPERANDS]; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1644 int i; |
0 | 1645 int predicated; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1646 enum rtx_code set_code = SET; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1647 enum rtx_code clobber_code = CLOBBER; |
111 | 1648 insn_rr_info *insn_info = NULL; |
1649 terminated_this_insn = NULL; | |
0 | 1650 |
1651 /* Process the insn, determining its effect on the def-use | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1652 chains and live hard registers. We perform the following |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1653 steps with the register references in the insn, simulating |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1654 its effect: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1655 (1) Deal with earlyclobber operands and CLOBBERs of non-operands |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1656 by creating chains and marking hard regs live. |
0 | 1657 (2) Any read outside an operand causes any chain it overlaps |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1658 with to be marked unrenamable. |
0 | 1659 (3) Any read inside an operand is added if there's already |
1660 an open chain for it. | |
1661 (4) For any REG_DEAD note we find, close open chains that | |
1662 overlap it. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1663 (5) For any non-earlyclobber write we find, close open chains |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1664 that overlap it. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1665 (6) For any non-earlyclobber write we find in an operand, make |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1666 a new chain or mark the hard register as live. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1667 (7) For any REG_UNUSED, close any chains we just opened. |
131 | 1668 (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain |
1669 containing its dest. | |
0 | 1670 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1671 We cannot deal with situations where we track a reg in one mode |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1672 and see a reference in another mode; these will cause the chain |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1673 to be marked unrenamable or even cause us to abort the entire |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1674 basic block. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1675 |
111 | 1676 extract_constrain_insn (insn); |
1677 preprocess_constraints (insn); | |
1678 const operand_alternative *op_alt = which_op_alt (); | |
0 | 1679 n_ops = recog_data.n_operands; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1680 untracked_operands = 0; |
0 | 1681 |
111 | 1682 if (insn_rr.exists ()) |
1683 { | |
1684 insn_info = &insn_rr[INSN_UID (insn)]; | |
1685 insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info, | |
1686 recog_data.n_operands); | |
1687 memset (insn_info->op_info, 0, | |
1688 sizeof (operand_rr_info) * recog_data.n_operands); | |
1689 } | |
1690 | |
1691 /* Simplify the code below by promoting OP_OUT to OP_INOUT in | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1692 predicated instructions, but only for register operands |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1693 that are already tracked, so that we can create a chain |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1694 when the first SET makes a register live. */ |
0 | 1695 |
1696 predicated = GET_CODE (PATTERN (insn)) == COND_EXEC; | |
1697 for (i = 0; i < n_ops; ++i) | |
1698 { | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1699 rtx op = recog_data.operand[i]; |
111 | 1700 int matches = op_alt[i].matches; |
1701 if (matches >= 0 || op_alt[i].matched >= 0 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1702 || (predicated && recog_data.operand_type[i] == OP_OUT)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1703 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1704 recog_data.operand_type[i] = OP_INOUT; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1705 /* A special case to deal with instruction patterns that |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1706 have matching operands with different modes. If we're |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1707 not already tracking such a reg, we won't start here, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1708 and we must instead make sure to make the operand visible |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1709 to the machinery that tracks hard registers. */ |
131 | 1710 machine_mode i_mode = recog_data.operand_mode[i]; |
1711 if (matches >= 0) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1712 { |
131 | 1713 machine_mode matches_mode |
1714 = recog_data.operand_mode[matches]; | |
1715 | |
1716 if (maybe_ne (GET_MODE_SIZE (i_mode), | |
1717 GET_MODE_SIZE (matches_mode)) | |
1718 && !verify_reg_in_set (op, &live_in_chains)) | |
1719 { | |
1720 untracked_operands |= 1 << i; | |
1721 untracked_operands |= 1 << matches; | |
1722 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1723 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1724 } |
111 | 1725 #ifdef STACK_REGS |
1726 if (regstack_completed | |
1727 && REG_P (op) | |
1728 && IN_RANGE (REGNO (op), FIRST_STACK_REG, LAST_STACK_REG)) | |
1729 untracked_operands |= 1 << i; | |
1730 #endif | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1731 /* If there's an in-out operand with a register that is not |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1732 being tracked at all yet, open a chain. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1733 if (recog_data.operand_type[i] == OP_INOUT |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1734 && !(untracked_operands & (1 << i)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1735 && REG_P (op) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1736 && !verify_reg_tracked (op)) |
111 | 1737 create_new_chain (REGNO (op), REG_NREGS (op), NULL, NULL, |
1738 NO_REGS); | |
0 | 1739 } |
1740 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1741 if (fail_current_block) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1742 break; |
0 | 1743 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1744 /* Step 1a: Mark hard registers that are clobbered in this insn, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1745 outside an operand, as live. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1746 hide_operands (n_ops, old_operands, old_dups, untracked_operands, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1747 false); |
145 | 1748 note_stores (insn, note_sets_clobbers, &clobber_code); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1749 restore_operands (insn, n_ops, old_operands, old_dups); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1750 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1751 /* Step 1b: Begin new chains for earlyclobbered writes inside |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1752 operands. */ |
111 | 1753 record_out_operands (insn, true, insn_info); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1754 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1755 /* Step 2: Mark chains for which we have reads outside operands |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1756 as unrenamable. |
145 | 1757 We do this by munging all operands into PC, and closing |
0 | 1758 everything remaining. */ |
1759 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1760 hide_operands (n_ops, old_operands, old_dups, untracked_operands, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1761 false); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1762 scan_rtx (insn, &PATTERN (insn), NO_REGS, mark_all_read, OP_IN); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1763 restore_operands (insn, n_ops, old_operands, old_dups); |
0 | 1764 |
1765 /* Step 2B: Can't rename function call argument registers. */ | |
1766 if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn)) | |
1767 scan_rtx (insn, &CALL_INSN_FUNCTION_USAGE (insn), | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1768 NO_REGS, mark_all_read, OP_IN); |
0 | 1769 |
1770 /* Step 2C: Can't rename asm operands that were originally | |
1771 hard registers. */ | |
1772 if (asm_noperands (PATTERN (insn)) > 0) | |
1773 for (i = 0; i < n_ops; i++) | |
1774 { | |
1775 rtx *loc = recog_data.operand_loc[i]; | |
1776 rtx op = *loc; | |
1777 | |
1778 if (REG_P (op) | |
1779 && REGNO (op) == ORIGINAL_REGNO (op) | |
1780 && (recog_data.operand_type[i] == OP_IN | |
1781 || recog_data.operand_type[i] == OP_INOUT)) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1782 scan_rtx (insn, loc, NO_REGS, mark_all_read, OP_IN); |
0 | 1783 } |
1784 | |
1785 /* Step 3: Append to chains for reads inside operands. */ | |
1786 for (i = 0; i < n_ops + recog_data.n_dups; i++) | |
1787 { | |
1788 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops]; | |
1789 rtx *loc = (i < n_ops | |
1790 ? recog_data.operand_loc[opn] | |
1791 : recog_data.dup_loc[i - n_ops]); | |
111 | 1792 enum reg_class cl = alternative_class (op_alt, opn); |
0 | 1793 enum op_type type = recog_data.operand_type[opn]; |
1794 | |
1795 /* Don't scan match_operand here, since we've no reg class | |
1796 information to pass down. Any operands that we could | |
1797 substitute in will be represented elsewhere. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1798 if (recog_data.constraints[opn][0] == '\0' |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1799 || untracked_operands & (1 << opn)) |
0 | 1800 continue; |
1801 | |
111 | 1802 if (insn_info) |
1803 cur_operand = i == opn ? insn_info->op_info + i : NULL; | |
1804 if (op_alt[opn].is_address) | |
1805 scan_rtx_address (insn, loc, cl, mark_read, | |
1806 VOIDmode, ADDR_SPACE_GENERIC); | |
0 | 1807 else |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1808 scan_rtx (insn, loc, cl, mark_read, type); |
0 | 1809 } |
111 | 1810 cur_operand = NULL; |
0 | 1811 |
1812 /* Step 3B: Record updates for regs in REG_INC notes, and | |
1813 source regs in REG_FRAME_RELATED_EXPR notes. */ | |
1814 for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) | |
1815 if (REG_NOTE_KIND (note) == REG_INC | |
1816 || REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR) | |
1817 scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_read, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1818 OP_INOUT); |
0 | 1819 |
111 | 1820 /* Step 4: Close chains for registers that die here, unless |
1821 the register is mentioned in a REG_UNUSED note. In that | |
1822 case we keep the chain open until step #7 below to ensure | |
1823 it conflicts with other output operands of this insn. | |
1824 See PR 52573. Arguably the insn should not have both | |
1825 notes; it has proven difficult to fix that without | |
1826 other undesirable side effects. */ | |
0 | 1827 for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) |
111 | 1828 if (REG_NOTE_KIND (note) == REG_DEAD |
1829 && !find_regno_note (insn, REG_UNUSED, REGNO (XEXP (note, 0)))) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1830 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1831 remove_from_hard_reg_set (&live_hard_regs, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1832 GET_MODE (XEXP (note, 0)), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1833 REGNO (XEXP (note, 0))); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1834 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1835 OP_IN); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1836 } |
0 | 1837 |
1838 /* Step 4B: If this is a call, any chain live at this point | |
1839 requires a caller-saved reg. */ | |
1840 if (CALL_P (insn)) | |
1841 { | |
145 | 1842 function_abi callee_abi = insn_callee_abi (insn); |
1843 class du_head *p; | |
0 | 1844 for (p = open_chains; p; p = p->next_chain) |
145 | 1845 { |
1846 p->call_abis |= (1 << callee_abi.id ()); | |
1847 p->call_clobber_mask | |
1848 |= callee_abi.full_and_partial_reg_clobbers (); | |
1849 p->hard_conflicts |= callee_abi.full_reg_clobbers (); | |
1850 } | |
0 | 1851 } |
1852 | |
1853 /* Step 5: Close open chains that overlap writes. Similar to | |
1854 step 2, we hide in-out operands, since we do not want to | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1855 close these chains. We also hide earlyclobber operands, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1856 since we've opened chains for them in step 1, and earlier |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1857 chains they would overlap with must have been closed at |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1858 the previous insn at the latest, as such operands cannot |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1859 possibly overlap with any input operands. */ |
0 | 1860 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1861 hide_operands (n_ops, old_operands, old_dups, untracked_operands, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1862 true); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1863 scan_rtx (insn, &PATTERN (insn), NO_REGS, terminate_write, OP_IN); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1864 restore_operands (insn, n_ops, old_operands, old_dups); |
0 | 1865 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1866 /* Step 6a: Mark hard registers that are set in this insn, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1867 outside an operand, as live. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1868 hide_operands (n_ops, old_operands, old_dups, untracked_operands, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1869 false); |
145 | 1870 note_stores (insn, note_sets_clobbers, &set_code); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1871 restore_operands (insn, n_ops, old_operands, old_dups); |
0 | 1872 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1873 /* Step 6b: Begin new chains for writes inside operands. */ |
111 | 1874 record_out_operands (insn, false, insn_info); |
0 | 1875 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1876 /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR |
0 | 1877 notes for update. */ |
1878 for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) | |
1879 if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR) | |
1880 scan_rtx (insn, &XEXP (note, 0), ALL_REGS, mark_access, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1881 OP_INOUT); |
0 | 1882 |
1883 /* Step 7: Close chains for registers that were never | |
1884 really used here. */ | |
1885 for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) | |
1886 if (REG_NOTE_KIND (note) == REG_UNUSED) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1887 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1888 remove_from_hard_reg_set (&live_hard_regs, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1889 GET_MODE (XEXP (note, 0)), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1890 REGNO (XEXP (note, 0))); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1891 scan_rtx (insn, &XEXP (note, 0), NO_REGS, terminate_dead, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1892 OP_IN); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1893 } |
111 | 1894 |
1895 /* Step 8: Kill the chains involving register restores. Those | |
131 | 1896 should restore _that_ register. Similar for REG_CFA_REGISTER. */ |
111 | 1897 for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) |
131 | 1898 if (REG_NOTE_KIND (note) == REG_CFA_RESTORE |
1899 || REG_NOTE_KIND (note) == REG_CFA_REGISTER) | |
1900 { | |
1901 rtx *x = &XEXP (note, 0); | |
1902 if (!*x) | |
1903 x = &PATTERN (insn); | |
1904 if (GET_CODE (*x) == PARALLEL) | |
1905 x = &XVECEXP (*x, 0, 0); | |
1906 if (GET_CODE (*x) == SET) | |
1907 x = &SET_DEST (*x); | |
1908 scan_rtx (insn, x, NO_REGS, mark_all_read, OP_IN); | |
1909 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1910 } |
131 | 1911 else if (DEBUG_BIND_INSN_P (insn) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1912 && !VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn))) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1913 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1914 scan_rtx (insn, &INSN_VAR_LOCATION_LOC (insn), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1915 ALL_REGS, mark_read, OP_IN); |
0 | 1916 } |
1917 if (insn == BB_END (bb)) | |
1918 break; | |
1919 } | |
1920 | |
111 | 1921 if (fail_current_block) |
1922 return false; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1923 |
111 | 1924 return true; |
1925 } | |
1926 | |
1927 /* Initialize the register renamer. If INSN_INFO is true, ensure that | |
1928 insn_rr is nonnull. */ | |
1929 void | |
1930 regrename_init (bool insn_info) | |
1931 { | |
1932 gcc_obstack_init (&rename_obstack); | |
1933 insn_rr.create (0); | |
1934 if (insn_info) | |
1935 insn_rr.safe_grow_cleared (get_max_uid ()); | |
1936 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
1937 |
111 | 1938 /* Free all global data used by the register renamer. */ |
1939 void | |
1940 regrename_finish (void) | |
1941 { | |
1942 insn_rr.release (); | |
1943 free_chain_data (); | |
1944 obstack_free (&rename_obstack, NULL); | |
0 | 1945 } |
1946 | |
111 | 1947 /* Perform register renaming on the current function. */ |
0 | 1948 |
111 | 1949 static unsigned int |
1950 regrename_optimize (void) | |
0 | 1951 { |
111 | 1952 df_set_flags (DF_LR_RUN_DCE); |
1953 df_note_add_problem (); | |
1954 df_analyze (); | |
1955 df_set_flags (DF_DEFER_INSN_RESCAN); | |
1956 | |
1957 regrename_init (false); | |
1958 | |
1959 regrename_analyze (NULL); | |
1960 | |
1961 rename_chains (); | |
1962 | |
1963 regrename_finish (); | |
1964 | |
1965 return 0; | |
0 | 1966 } |
1967 | |
111 | 1968 namespace { |
0 | 1969 |
111 | 1970 const pass_data pass_data_regrename = |
0 | 1971 { |
111 | 1972 RTL_PASS, /* type */ |
1973 "rnreg", /* name */ | |
1974 OPTGROUP_NONE, /* optinfo_flags */ | |
1975 TV_RENAME_REGISTERS, /* tv_id */ | |
1976 0, /* properties_required */ | |
1977 0, /* properties_provided */ | |
1978 0, /* properties_destroyed */ | |
1979 0, /* todo_flags_start */ | |
1980 TODO_df_finish, /* todo_flags_finish */ | |
0 | 1981 }; |
1982 | |
111 | 1983 class pass_regrename : public rtl_opt_pass |
1984 { | |
1985 public: | |
1986 pass_regrename (gcc::context *ctxt) | |
1987 : rtl_opt_pass (pass_data_regrename, ctxt) | |
1988 {} | |
1989 | |
1990 /* opt_pass methods: */ | |
1991 virtual bool gate (function *) | |
1992 { | |
1993 return (optimize > 0 && (flag_rename_registers)); | |
1994 } | |
1995 | |
1996 virtual unsigned int execute (function *) { return regrename_optimize (); } | |
1997 | |
1998 }; // class pass_regrename | |
1999 | |
2000 } // anon namespace | |
2001 | |
2002 rtl_opt_pass * | |
2003 make_pass_regrename (gcc::context *ctxt) | |
2004 { | |
2005 return new pass_regrename (ctxt); | |
2006 } |