annotate gcc/regrename.c @ 120:f93fa5091070

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