annotate gcc/regrename.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
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.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
2 Copyright (C) 2000-2018 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;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
966 rtx last_reg = NULL_RTX, last_repl = NULL_RTX;
111
kono
parents: 67
diff changeset
967
kono
parents: 67
diff changeset
968 for (chain = head->first; chain; chain = chain->next_use)
kono
parents: 67
diff changeset
969 {
kono
parents: 67
diff changeset
970 unsigned int regno = ORIGINAL_REGNO (*chain->loc);
kono
parents: 67
diff changeset
971 struct reg_attrs *attr = REG_ATTRS (*chain->loc);
kono
parents: 67
diff changeset
972 int reg_ptr = REG_POINTER (*chain->loc);
kono
parents: 67
diff changeset
973
kono
parents: 67
diff changeset
974 if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno)
kono
parents: 67
diff changeset
975 validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)),
kono
parents: 67
diff changeset
976 gen_rtx_UNKNOWN_VAR_LOC (), true);
kono
parents: 67
diff changeset
977 else
kono
parents: 67
diff changeset
978 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
979 if (*chain->loc != last_reg)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
980 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
981 last_repl = gen_raw_REG (GET_MODE (*chain->loc), reg);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
982 if (regno >= FIRST_PSEUDO_REGISTER)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
983 ORIGINAL_REGNO (last_repl) = regno;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
984 REG_ATTRS (last_repl) = attr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
985 REG_POINTER (last_repl) = reg_ptr;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
986 last_reg = *chain->loc;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
987 }
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
988 validate_change (chain->insn, chain->loc, last_repl, true);
111
kono
parents: 67
diff changeset
989 }
kono
parents: 67
diff changeset
990 }
kono
parents: 67
diff changeset
991
kono
parents: 67
diff changeset
992 if (!apply_change_group ())
kono
parents: 67
diff changeset
993 return false;
kono
parents: 67
diff changeset
994
kono
parents: 67
diff changeset
995 mode = GET_MODE (*head->first->loc);
kono
parents: 67
diff changeset
996 head->renamed = 1;
kono
parents: 67
diff changeset
997 head->regno = reg;
kono
parents: 67
diff changeset
998 head->nregs = hard_regno_nregs (reg, mode);
kono
parents: 67
diff changeset
999 return true;
kono
parents: 67
diff changeset
1000 }
kono
parents: 67
diff changeset
1001
kono
parents: 67
diff changeset
1002
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1003 /* 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
1004 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
1005 without renaming. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1006 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
1007
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1008 /* 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
1009 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
1010 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
1011
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1012 static bool
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1013 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
1014 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1015 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
1016 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
1017 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
1018 return false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1019
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1020 regno = REGNO (op);
111
kono
parents: 67
diff changeset
1021 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
1022 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
1023 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
1024 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
1025 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
1026 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1027 all_live = false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1028 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
1029 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1030 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
1031 return false;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1032 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1033 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
1034 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1035
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1036 /* 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
1037 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
1038
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1039 static bool
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1040 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
1041 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1042 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
1043 || 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
1044 }
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 /* 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
1047 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
1048 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
1049 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
1050
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1051 static void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1052 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
1053 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1054 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
1055 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
1056
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1057 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
1058 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
1059 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
1060 return;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1061 /* 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
1062 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
1063 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
1064 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
1065 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
1066 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1067
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1068 static void
111
kono
parents: 67
diff changeset
1069 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
1070 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
1071 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1072 struct du_head **p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1073 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
1074 unsigned this_regno = REGNO (x);
111
kono
parents: 67
diff changeset
1075 int this_nregs = REG_NREGS (x);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1076
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1077 if (action == mark_write)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1078 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1079 if (type == OP_OUT)
111
kono
parents: 67
diff changeset
1080 {
kono
parents: 67
diff changeset
1081 du_head_p c;
kono
parents: 67
diff changeset
1082 rtx pat = PATTERN (insn);
kono
parents: 67
diff changeset
1083
kono
parents: 67
diff changeset
1084 c = create_new_chain (this_regno, this_nregs, loc, insn, cl);
kono
parents: 67
diff changeset
1085
kono
parents: 67
diff changeset
1086 /* We try to tie chains in a move instruction for
kono
parents: 67
diff changeset
1087 a single output. */
kono
parents: 67
diff changeset
1088 if (recog_data.n_operands == 2
kono
parents: 67
diff changeset
1089 && GET_CODE (pat) == SET
kono
parents: 67
diff changeset
1090 && GET_CODE (SET_DEST (pat)) == REG
kono
parents: 67
diff changeset
1091 && GET_CODE (SET_SRC (pat)) == REG
kono
parents: 67
diff changeset
1092 && terminated_this_insn
kono
parents: 67
diff changeset
1093 && terminated_this_insn->nregs
kono
parents: 67
diff changeset
1094 == REG_NREGS (recog_data.operand[1]))
kono
parents: 67
diff changeset
1095 {
kono
parents: 67
diff changeset
1096 gcc_assert (terminated_this_insn->regno
kono
parents: 67
diff changeset
1097 == REGNO (recog_data.operand[1]));
kono
parents: 67
diff changeset
1098
kono
parents: 67
diff changeset
1099 c->tied_chain = terminated_this_insn;
kono
parents: 67
diff changeset
1100 terminated_this_insn->tied_chain = c;
kono
parents: 67
diff changeset
1101
kono
parents: 67
diff changeset
1102 if (dump_file)
kono
parents: 67
diff changeset
1103 fprintf (dump_file, "Tying chain %s (%d) with %s (%d)\n",
kono
parents: 67
diff changeset
1104 reg_names[c->regno], c->id,
kono
parents: 67
diff changeset
1105 reg_names[terminated_this_insn->regno],
kono
parents: 67
diff changeset
1106 terminated_this_insn->id);
kono
parents: 67
diff changeset
1107 }
kono
parents: 67
diff changeset
1108 }
kono
parents: 67
diff changeset
1109
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1110 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1111 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1112
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1113 if ((type == OP_OUT) != (action == terminate_write || action == mark_access))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1114 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1115
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1116 for (p = &open_chains; *p;)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1117 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1118 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
1119 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
1120 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
1121 && 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
1122 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
1123 && 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
1124 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
1125 && this_regno + this_nregs <= head->regno + head->nregs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1126
111
kono
parents: 67
diff changeset
1127 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
1128 || 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
1129 || 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
1130 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1131 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
1132 continue;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1133 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1134
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1135 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
1136 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1137 /* ??? 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
1138 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
1139 wrong, but there we are. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1140
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1141 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
1142 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1143 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
1144 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
1145 "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
1146 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
1147 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
1148 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
1149 if (superset)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1150 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1151 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
1152 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
1153 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
1154 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
1155 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
1156 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
1157 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
1158 "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
1159 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
1160 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1161 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
1162 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1163 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
1164 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
1165 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
1166 "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
1167 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1168 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1169 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1170 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1171 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
1172 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
1173 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
1174 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
1175 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
1176 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
1177 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
1178 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
1179 else
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1180 head->last->next_use = this_du;
111
kono
parents: 67
diff changeset
1181 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
1182 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
1183 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1184 /* 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
1185 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
1186 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
1187 return;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1188 /* 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
1189 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
1190 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
1191 continue;
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
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1194 /* 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
1195 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
1196 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
1197
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1198 if ((action == terminate_dead || action == terminate_write)
111
kono
parents: 67
diff changeset
1199 && (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
1200 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1201 unsigned nregs;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1202
111
kono
parents: 67
diff changeset
1203 if (subset && !superset)
kono
parents: 67
diff changeset
1204 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
1205 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
1206
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1207 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
1208 while (nregs-- > 0)
111
kono
parents: 67
diff changeset
1209 {
kono
parents: 67
diff changeset
1210 CLEAR_HARD_REG_BIT (live_in_chains, head->regno + nregs);
kono
parents: 67
diff changeset
1211 if (subset && !superset
kono
parents: 67
diff changeset
1212 && (head->regno + nregs < this_regno
kono
parents: 67
diff changeset
1213 || head->regno + nregs >= this_regno + this_nregs))
kono
parents: 67
diff changeset
1214 SET_HARD_REG_BIT (live_hard_regs, head->regno + nregs);
kono
parents: 67
diff changeset
1215 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1216
111
kono
parents: 67
diff changeset
1217 if (action == terminate_dead)
kono
parents: 67
diff changeset
1218 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
1219 *p = next;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1220 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
1221 fprintf (dump_file,
111
kono
parents: 67
diff changeset
1222 "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
1223 reg_names[head->regno], head->id, INSN_UID (insn),
111
kono
parents: 67
diff changeset
1224 scan_actions_name[(int) action],
kono
parents: 67
diff changeset
1225 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
1226 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1227 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
1228 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1229 /* 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
1230 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
1231 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
1232 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
1233 "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
1234 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
1235 return;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1236 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1237 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1238 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1239 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
1240 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
1241 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
1242 "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
1243 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
1244 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
1245 p = &head->next_chain;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1246 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1247 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1248 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1249
111
kono
parents: 67
diff changeset
1250 /* A wrapper around base_reg_class which returns ALL_REGS if INSN is a
kono
parents: 67
diff changeset
1251 DEBUG_INSN. The arguments MODE, AS, CODE and INDEX_CODE are as for
kono
parents: 67
diff changeset
1252 base_reg_class. */
kono
parents: 67
diff changeset
1253
kono
parents: 67
diff changeset
1254 static reg_class
kono
parents: 67
diff changeset
1255 base_reg_class_for_rename (rtx_insn *insn, machine_mode mode, addr_space_t as,
kono
parents: 67
diff changeset
1256 rtx_code code, rtx_code index_code)
kono
parents: 67
diff changeset
1257 {
kono
parents: 67
diff changeset
1258 if (DEBUG_INSN_P (insn))
kono
parents: 67
diff changeset
1259 return ALL_REGS;
kono
parents: 67
diff changeset
1260 return base_reg_class (mode, as, code, index_code);
kono
parents: 67
diff changeset
1261 }
kono
parents: 67
diff changeset
1262
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1263 /* 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
1264 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
1265
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1266 static void
111
kono
parents: 67
diff changeset
1267 scan_rtx_address (rtx_insn *insn, rtx *loc, enum reg_class cl,
kono
parents: 67
diff changeset
1268 enum scan_actions action, machine_mode mode,
kono
parents: 67
diff changeset
1269 addr_space_t as)
0
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 rtx x = *loc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1272 RTX_CODE code = GET_CODE (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1273 const char *fmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1274 int i, j;
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 if (action == mark_write || action == mark_access)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1277 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1278
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1279 switch (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1280 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1281 case PLUS:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1282 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1283 rtx orig_op0 = XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1284 rtx orig_op1 = XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1285 RTX_CODE code0 = GET_CODE (orig_op0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1286 RTX_CODE code1 = GET_CODE (orig_op1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1287 rtx op0 = orig_op0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1288 rtx op1 = orig_op1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1289 rtx *locI = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1290 rtx *locB = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1291 enum rtx_code index_code = SCRATCH;
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 if (GET_CODE (op0) == SUBREG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1294 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1295 op0 = SUBREG_REG (op0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1296 code0 = GET_CODE (op0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1297 }
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 if (GET_CODE (op1) == SUBREG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1300 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1301 op1 = SUBREG_REG (op1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1302 code1 = GET_CODE (op1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1303 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1304
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1305 if (code0 == MULT || code0 == SIGN_EXTEND || code0 == TRUNCATE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1306 || code0 == ZERO_EXTEND || code1 == MEM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1307 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1308 locI = &XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1309 locB = &XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1310 index_code = GET_CODE (*locI);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1311 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1312 else if (code1 == MULT || code1 == SIGN_EXTEND || code1 == TRUNCATE
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1313 || code1 == ZERO_EXTEND || code0 == MEM)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1314 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1315 locI = &XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1316 locB = &XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1317 index_code = GET_CODE (*locI);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1318 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1319 else if (code0 == CONST_INT || code0 == CONST
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1320 || code0 == SYMBOL_REF || code0 == LABEL_REF)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1321 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1322 locB = &XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1323 index_code = GET_CODE (XEXP (x, 0));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1324 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1325 else if (code1 == CONST_INT || code1 == CONST
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1326 || code1 == SYMBOL_REF || code1 == LABEL_REF)
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 locB = &XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1329 index_code = GET_CODE (XEXP (x, 1));
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 else if (code0 == REG && code1 == REG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1332 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1333 int index_op;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1334 unsigned regno0 = REGNO (op0), regno1 = REGNO (op1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1335
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1336 if (REGNO_OK_FOR_INDEX_P (regno1)
111
kono
parents: 67
diff changeset
1337 && 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 index_op = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1339 else if (REGNO_OK_FOR_INDEX_P (regno0)
111
kono
parents: 67
diff changeset
1340 && 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;
111
kono
parents: 67
diff changeset
1342 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
1343 || REGNO_OK_FOR_INDEX_P (regno1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1344 index_op = 1;
111
kono
parents: 67
diff changeset
1345 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
1346 index_op = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1347 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1348 index_op = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1349
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1350 locI = &XEXP (x, index_op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1351 locB = &XEXP (x, !index_op);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1352 index_code = GET_CODE (*locI);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1353 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1354 else if (code0 == REG)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1355 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1356 locI = &XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1357 locB = &XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1358 index_code = GET_CODE (*locI);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1359 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1360 else if (code1 == REG)
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 locI = &XEXP (x, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1363 locB = &XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1364 index_code = GET_CODE (*locI);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1365 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1366
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1367 if (locI)
111
kono
parents: 67
diff changeset
1368 {
kono
parents: 67
diff changeset
1369 reg_class iclass = DEBUG_INSN_P (insn) ? ALL_REGS : INDEX_REG_CLASS;
kono
parents: 67
diff changeset
1370 scan_rtx_address (insn, locI, iclass, action, mode, as);
kono
parents: 67
diff changeset
1371 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1372 if (locB)
111
kono
parents: 67
diff changeset
1373 {
kono
parents: 67
diff changeset
1374 reg_class bclass = base_reg_class_for_rename (insn, mode, as, PLUS,
kono
parents: 67
diff changeset
1375 index_code);
kono
parents: 67
diff changeset
1376 scan_rtx_address (insn, locB, bclass, action, mode, as);
kono
parents: 67
diff changeset
1377 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1378 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1379 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1380
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1381 case POST_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1382 case POST_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1383 case POST_MODIFY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1384 case PRE_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1385 case PRE_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1386 case PRE_MODIFY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1387 /* 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
1388 something special, like a stack push. Kill this chain. */
111
kono
parents: 67
diff changeset
1389 if (!AUTO_INC_DEC)
kono
parents: 67
diff changeset
1390 action = mark_all_read;
kono
parents: 67
diff changeset
1391
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1392 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1393
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1394 case MEM:
111
kono
parents: 67
diff changeset
1395 {
kono
parents: 67
diff changeset
1396 reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
kono
parents: 67
diff changeset
1397 MEM_ADDR_SPACE (x),
kono
parents: 67
diff changeset
1398 MEM, SCRATCH);
kono
parents: 67
diff changeset
1399 scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
kono
parents: 67
diff changeset
1400 MEM_ADDR_SPACE (x));
kono
parents: 67
diff changeset
1401 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1402 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1403
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1404 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
1405 scan_rtx_reg (insn, loc, cl, action, OP_IN);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1406 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1407
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1408 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1409 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1410 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1411
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1412 fmt = GET_RTX_FORMAT (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1413 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1414 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1415 if (fmt[i] == 'e')
111
kono
parents: 67
diff changeset
1416 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
1417 else if (fmt[i] == 'E')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1418 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
111
kono
parents: 67
diff changeset
1419 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
1420 }
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
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1423 static void
111
kono
parents: 67
diff changeset
1424 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
1425 enum op_type type)
0
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 const char *fmt;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1428 rtx x = *loc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1429 enum rtx_code code = GET_CODE (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1430 int i, j;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1431
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1432 code = GET_CODE (x);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1433 switch (code)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1434 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1435 case CONST:
111
kono
parents: 67
diff changeset
1436 CASE_CONST_ANY:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1437 case SYMBOL_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1438 case LABEL_REF:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1439 case CC0:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1440 case PC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1441 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1442
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1443 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
1444 scan_rtx_reg (insn, loc, cl, action, type);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1445 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1446
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1447 case MEM:
111
kono
parents: 67
diff changeset
1448 {
kono
parents: 67
diff changeset
1449 reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
kono
parents: 67
diff changeset
1450 MEM_ADDR_SPACE (x),
kono
parents: 67
diff changeset
1451 MEM, SCRATCH);
kono
parents: 67
diff changeset
1452
kono
parents: 67
diff changeset
1453 scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
kono
parents: 67
diff changeset
1454 MEM_ADDR_SPACE (x));
kono
parents: 67
diff changeset
1455 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1456 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1457
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1458 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
1459 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
1460 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
1461 (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
1462 && 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
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 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
1466 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
1467 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
1468 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1469
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1470 case ZERO_EXTRACT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1471 case SIGN_EXTRACT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1472 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
1473 (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
1474 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
1475 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
1476 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
1477 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1478
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1479 case POST_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1480 case PRE_INC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1481 case POST_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1482 case PRE_DEC:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1483 case POST_MODIFY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1484 case PRE_MODIFY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1485 /* Should only happen inside MEM. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1486 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1487
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1488 case CLOBBER:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1489 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
1490 (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
1491 && 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
1492 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1493
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1494 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
1495 scan_rtx (insn, &XEXP (x, 0), cl, action, type);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1496 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
1497 scan_rtx (insn, &XEXP (x, 1), cl, action, type);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1498 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1499
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1500 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1501 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1502 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1503
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1504 fmt = GET_RTX_FORMAT (code);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1505 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1506 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1507 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
1508 scan_rtx (insn, &XEXP (x, i), cl, action, type);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1509 else if (fmt[i] == 'E')
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1510 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
1511 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
1512 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1513 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1514
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1515 /* 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
1516 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
1517 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
1518 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
1519 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
1520 and earlyclobbers. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1521
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1522 static void
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1523 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
1524 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
1525 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1526 int i;
111
kono
parents: 67
diff changeset
1527 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
1528 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
1529 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1530 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
1531 /* 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
1532 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
1533 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
1534 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
1535 continue;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1536 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
1537 continue;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1538 if (!inout_and_ec_only || recog_data.operand_type[i] == OP_INOUT
111
kono
parents: 67
diff changeset
1539 || 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
1540 *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
1541 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1542 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
1543 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1544 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
1545 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
1546 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
1547 continue;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1548 if (!inout_and_ec_only || recog_data.operand_type[opn] == OP_INOUT
111
kono
parents: 67
diff changeset
1549 || 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
1550 *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
1551 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1552 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1553
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1554 /* 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
1555 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
1556
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1557 static void
111
kono
parents: 67
diff changeset
1558 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
1559 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1560 int i;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1561 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
1562 *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
1563 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
1564 *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
1565 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
1566 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
1567 }
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 /* 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
1570 open chain. Do this only for normal or earlyclobber outputs,
111
kono
parents: 67
diff changeset
1571 depending on EARLYCLOBBER. If INSN_INFO is nonnull, use it to
kono
parents: 67
diff changeset
1572 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
1573
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1574 static void
111
kono
parents: 67
diff changeset
1575 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
1576 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1577 int n_ops = recog_data.n_operands;
111
kono
parents: 67
diff changeset
1578 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
1579
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1580 int i;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1581
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1582 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
1583 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1584 int 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
1585 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
1586 ? 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
1587 : 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
1588 rtx op = *loc;
111
kono
parents: 67
diff changeset
1589 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
1590
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1591 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
1592
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1593 if (recog_data.operand_type[opn] != OP_OUT
111
kono
parents: 67
diff changeset
1594 || 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
1595 continue;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1596
111
kono
parents: 67
diff changeset
1597 if (insn_info)
kono
parents: 67
diff changeset
1598 cur_operand = insn_info->op_info + i;
kono
parents: 67
diff changeset
1599
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1600 prev_open = open_chains;
111
kono
parents: 67
diff changeset
1601 if (earlyclobber)
kono
parents: 67
diff changeset
1602 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
1603 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
1604
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1605 /* ??? 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
1606 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
1607 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
1608 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
1609 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
1610 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
1611 || (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
1612 && 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
1613 && 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
1614 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1615 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
1616 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
1617 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1618 }
111
kono
parents: 67
diff changeset
1619 cur_operand = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1620 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1621
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1622 /* Build def/use chain. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1623
111
kono
parents: 67
diff changeset
1624 static bool
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1625 build_def_use (basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1626 {
111
kono
parents: 67
diff changeset
1627 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
1628 unsigned HOST_WIDE_INT untracked_operands;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1629
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1630 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
1631
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1632 for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1633 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1634 if (NONDEBUG_INSN_P (insn))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1635 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1636 int n_ops;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1637 rtx note;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1638 rtx old_operands[MAX_RECOG_OPERANDS];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1639 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
1640 int i;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1641 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
1642 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
1643 enum rtx_code clobber_code = CLOBBER;
111
kono
parents: 67
diff changeset
1644 insn_rr_info *insn_info = NULL;
kono
parents: 67
diff changeset
1645 terminated_this_insn = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1646
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1647 /* 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
1648 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
1649 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
1650 its effect:
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1651 (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
1652 by creating chains and marking hard regs live.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1653 (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
1654 with to be marked unrenamable.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1655 (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
1656 an open chain for it.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1657 (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
1658 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
1659 (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
1660 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
1661 (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
1662 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
1663 (7) For any REG_UNUSED, close any chains we just opened.
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1664 (8) For any REG_CFA_RESTORE or REG_CFA_REGISTER, kill any chain
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1665 containing its dest.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1666
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1667 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
1668 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
1669 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
1670 basic block. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1671
111
kono
parents: 67
diff changeset
1672 extract_constrain_insn (insn);
kono
parents: 67
diff changeset
1673 preprocess_constraints (insn);
kono
parents: 67
diff changeset
1674 const operand_alternative *op_alt = which_op_alt ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1675 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
1676 untracked_operands = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1677
111
kono
parents: 67
diff changeset
1678 if (insn_rr.exists ())
kono
parents: 67
diff changeset
1679 {
kono
parents: 67
diff changeset
1680 insn_info = &insn_rr[INSN_UID (insn)];
kono
parents: 67
diff changeset
1681 insn_info->op_info = XOBNEWVEC (&rename_obstack, operand_rr_info,
kono
parents: 67
diff changeset
1682 recog_data.n_operands);
kono
parents: 67
diff changeset
1683 memset (insn_info->op_info, 0,
kono
parents: 67
diff changeset
1684 sizeof (operand_rr_info) * recog_data.n_operands);
kono
parents: 67
diff changeset
1685 }
kono
parents: 67
diff changeset
1686
kono
parents: 67
diff changeset
1687 /* 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
1688 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
1689 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
1690 when the first SET makes a register live. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1691
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1692 predicated = GET_CODE (PATTERN (insn)) == COND_EXEC;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1693 for (i = 0; i < n_ops; ++i)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1694 {
63
b7f97abdc517 update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
1695 rtx op = recog_data.operand[i];
111
kono
parents: 67
diff changeset
1696 int matches = op_alt[i].matches;
kono
parents: 67
diff changeset
1697 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
1698 || (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
1699 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1700 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
1701 /* 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
1702 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
1703 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
1704 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
1705 to the machinery that tracks hard registers. */
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1706 machine_mode i_mode = recog_data.operand_mode[i];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1707 if (matches >= 0)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1708 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1709 machine_mode matches_mode
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1710 = recog_data.operand_mode[matches];
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1711
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1712 if (maybe_ne (GET_MODE_SIZE (i_mode),
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1713 GET_MODE_SIZE (matches_mode))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1714 && !verify_reg_in_set (op, &live_in_chains))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1715 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1716 untracked_operands |= 1 << i;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1717 untracked_operands |= 1 << matches;
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1718 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1719 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1720 }
111
kono
parents: 67
diff changeset
1721 #ifdef STACK_REGS
kono
parents: 67
diff changeset
1722 if (regstack_completed
kono
parents: 67
diff changeset
1723 && REG_P (op)
kono
parents: 67
diff changeset
1724 && IN_RANGE (REGNO (op), FIRST_STACK_REG, LAST_STACK_REG))
kono
parents: 67
diff changeset
1725 untracked_operands |= 1 << i;
kono
parents: 67
diff changeset
1726 #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
1727 /* 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
1728 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
1729 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
1730 && !(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
1731 && 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
1732 && !verify_reg_tracked (op))
111
kono
parents: 67
diff changeset
1733 create_new_chain (REGNO (op), REG_NREGS (op), NULL, NULL,
kono
parents: 67
diff changeset
1734 NO_REGS);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1735 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1736
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1737 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
1738 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1739
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1740 /* 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
1741 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
1742 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
1743 false);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1744 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
1745 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
1746
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1747 /* 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
1748 operands. */
111
kono
parents: 67
diff changeset
1749 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
1750
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1751 /* Step 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
1752 as unrenamable.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1753 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
1754 everything remaining. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1755
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1756 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
1757 false);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1758 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
1759 restore_operands (insn, n_ops, old_operands, old_dups);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1760
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1761 /* Step 2B: Can't rename function call argument registers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1762 if (CALL_P (insn) && CALL_INSN_FUNCTION_USAGE (insn))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1763 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
1764 NO_REGS, mark_all_read, OP_IN);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1765
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1766 /* Step 2C: Can't rename asm operands that were originally
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1767 hard registers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1768 if (asm_noperands (PATTERN (insn)) > 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1769 for (i = 0; i < n_ops; i++)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1770 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1771 rtx *loc = recog_data.operand_loc[i];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1772 rtx op = *loc;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1773
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1774 if (REG_P (op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1775 && REGNO (op) == ORIGINAL_REGNO (op)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1776 && (recog_data.operand_type[i] == OP_IN
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1777 || 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
1778 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
1779 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1780
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1781 /* Step 3: Append to chains for reads inside operands. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1782 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
1783 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1784 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
1785 rtx *loc = (i < n_ops
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1786 ? recog_data.operand_loc[opn]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1787 : recog_data.dup_loc[i - n_ops]);
111
kono
parents: 67
diff changeset
1788 enum reg_class cl = alternative_class (op_alt, opn);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1789 enum op_type type = recog_data.operand_type[opn];
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1790
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1791 /* 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
1792 information to pass down. Any operands that we could
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1793 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
1794 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
1795 || untracked_operands & (1 << opn))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1796 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1797
111
kono
parents: 67
diff changeset
1798 if (insn_info)
kono
parents: 67
diff changeset
1799 cur_operand = i == opn ? insn_info->op_info + i : NULL;
kono
parents: 67
diff changeset
1800 if (op_alt[opn].is_address)
kono
parents: 67
diff changeset
1801 scan_rtx_address (insn, loc, cl, mark_read,
kono
parents: 67
diff changeset
1802 VOIDmode, ADDR_SPACE_GENERIC);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1803 else
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1804 scan_rtx (insn, loc, cl, mark_read, type);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1805 }
111
kono
parents: 67
diff changeset
1806 cur_operand = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1807
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1808 /* 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
1809 source regs in REG_FRAME_RELATED_EXPR notes. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1810 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1811 if (REG_NOTE_KIND (note) == REG_INC
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1812 || REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1813 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
1814 OP_INOUT);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1815
111
kono
parents: 67
diff changeset
1816 /* Step 4: Close chains for registers that die here, unless
kono
parents: 67
diff changeset
1817 the register is mentioned in a REG_UNUSED note. In that
kono
parents: 67
diff changeset
1818 case we keep the chain open until step #7 below to ensure
kono
parents: 67
diff changeset
1819 it conflicts with other output operands of this insn.
kono
parents: 67
diff changeset
1820 See PR 52573. Arguably the insn should not have both
kono
parents: 67
diff changeset
1821 notes; it has proven difficult to fix that without
kono
parents: 67
diff changeset
1822 other undesirable side effects. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1823 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
111
kono
parents: 67
diff changeset
1824 if (REG_NOTE_KIND (note) == REG_DEAD
kono
parents: 67
diff changeset
1825 && !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
1826 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1827 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
1828 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
1829 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
1830 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
1831 OP_IN);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1832 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1833
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1834 /* 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
1835 requires a caller-saved reg. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1836 if (CALL_P (insn))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1837 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1838 struct du_head *p;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1839 for (p = open_chains; p; p = p->next_chain)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1840 p->need_caller_save_reg = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1841 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1842
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1843 /* Step 5: Close open chains that overlap writes. Similar to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1844 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
1845 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
1846 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
1847 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
1848 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
1849 possibly overlap with any input operands. */
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 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
1852 true);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1853 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
1854 restore_operands (insn, n_ops, old_operands, old_dups);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1855
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1856 /* 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
1857 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
1858 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
1859 false);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1860 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
1861 restore_operands (insn, n_ops, old_operands, old_dups);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1862
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1863 /* Step 6b: Begin new chains for writes inside operands. */
111
kono
parents: 67
diff changeset
1864 record_out_operands (insn, false, insn_info);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1865
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1866 /* Step 6c: Record destination regs in REG_FRAME_RELATED_EXPR
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1867 notes for update. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1868 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1869 if (REG_NOTE_KIND (note) == REG_FRAME_RELATED_EXPR)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1870 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
1871 OP_INOUT);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1872
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1873 /* Step 7: Close chains for registers that were never
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1874 really used here. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1875 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1876 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
1877 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1878 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
1879 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
1880 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
1881 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
1882 OP_IN);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1883 }
111
kono
parents: 67
diff changeset
1884
kono
parents: 67
diff changeset
1885 /* Step 8: Kill the chains involving register restores. Those
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1886 should restore _that_ register. Similar for REG_CFA_REGISTER. */
111
kono
parents: 67
diff changeset
1887 for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1888 if (REG_NOTE_KIND (note) == REG_CFA_RESTORE
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1889 || REG_NOTE_KIND (note) == REG_CFA_REGISTER)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1890 {
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1891 rtx *x = &XEXP (note, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1892 if (!*x)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1893 x = &PATTERN (insn);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1894 if (GET_CODE (*x) == PARALLEL)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1895 x = &XVECEXP (*x, 0, 0);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1896 if (GET_CODE (*x) == SET)
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1897 x = &SET_DEST (*x);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1898 scan_rtx (insn, x, NO_REGS, mark_all_read, OP_IN);
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1899 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1900 }
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1901 else if (DEBUG_BIND_INSN_P (insn)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1902 && !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
1903 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1904 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
1905 ALL_REGS, mark_read, OP_IN);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1906 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1907 if (insn == BB_END (bb))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1908 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1909 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1910
111
kono
parents: 67
diff changeset
1911 if (fail_current_block)
kono
parents: 67
diff changeset
1912 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
1913
111
kono
parents: 67
diff changeset
1914 return true;
kono
parents: 67
diff changeset
1915 }
kono
parents: 67
diff changeset
1916
kono
parents: 67
diff changeset
1917 /* Initialize the register renamer. If INSN_INFO is true, ensure that
kono
parents: 67
diff changeset
1918 insn_rr is nonnull. */
kono
parents: 67
diff changeset
1919 void
kono
parents: 67
diff changeset
1920 regrename_init (bool insn_info)
kono
parents: 67
diff changeset
1921 {
kono
parents: 67
diff changeset
1922 gcc_obstack_init (&rename_obstack);
kono
parents: 67
diff changeset
1923 insn_rr.create (0);
kono
parents: 67
diff changeset
1924 if (insn_info)
kono
parents: 67
diff changeset
1925 insn_rr.safe_grow_cleared (get_max_uid ());
kono
parents: 67
diff changeset
1926 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
1927
111
kono
parents: 67
diff changeset
1928 /* Free all global data used by the register renamer. */
kono
parents: 67
diff changeset
1929 void
kono
parents: 67
diff changeset
1930 regrename_finish (void)
kono
parents: 67
diff changeset
1931 {
kono
parents: 67
diff changeset
1932 insn_rr.release ();
kono
parents: 67
diff changeset
1933 free_chain_data ();
kono
parents: 67
diff changeset
1934 obstack_free (&rename_obstack, NULL);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1935 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1936
111
kono
parents: 67
diff changeset
1937 /* Perform register renaming on the current function. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1938
111
kono
parents: 67
diff changeset
1939 static unsigned int
kono
parents: 67
diff changeset
1940 regrename_optimize (void)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1941 {
111
kono
parents: 67
diff changeset
1942 df_set_flags (DF_LR_RUN_DCE);
kono
parents: 67
diff changeset
1943 df_note_add_problem ();
kono
parents: 67
diff changeset
1944 df_analyze ();
kono
parents: 67
diff changeset
1945 df_set_flags (DF_DEFER_INSN_RESCAN);
kono
parents: 67
diff changeset
1946
kono
parents: 67
diff changeset
1947 regrename_init (false);
kono
parents: 67
diff changeset
1948
kono
parents: 67
diff changeset
1949 regrename_analyze (NULL);
kono
parents: 67
diff changeset
1950
kono
parents: 67
diff changeset
1951 rename_chains ();
kono
parents: 67
diff changeset
1952
kono
parents: 67
diff changeset
1953 regrename_finish ();
kono
parents: 67
diff changeset
1954
kono
parents: 67
diff changeset
1955 return 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1956 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1957
111
kono
parents: 67
diff changeset
1958 namespace {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1959
111
kono
parents: 67
diff changeset
1960 const pass_data pass_data_regrename =
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1961 {
111
kono
parents: 67
diff changeset
1962 RTL_PASS, /* type */
kono
parents: 67
diff changeset
1963 "rnreg", /* name */
kono
parents: 67
diff changeset
1964 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
1965 TV_RENAME_REGISTERS, /* tv_id */
kono
parents: 67
diff changeset
1966 0, /* properties_required */
kono
parents: 67
diff changeset
1967 0, /* properties_provided */
kono
parents: 67
diff changeset
1968 0, /* properties_destroyed */
kono
parents: 67
diff changeset
1969 0, /* todo_flags_start */
kono
parents: 67
diff changeset
1970 TODO_df_finish, /* todo_flags_finish */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1971 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1972
111
kono
parents: 67
diff changeset
1973 class pass_regrename : public rtl_opt_pass
kono
parents: 67
diff changeset
1974 {
kono
parents: 67
diff changeset
1975 public:
kono
parents: 67
diff changeset
1976 pass_regrename (gcc::context *ctxt)
kono
parents: 67
diff changeset
1977 : rtl_opt_pass (pass_data_regrename, ctxt)
kono
parents: 67
diff changeset
1978 {}
kono
parents: 67
diff changeset
1979
kono
parents: 67
diff changeset
1980 /* opt_pass methods: */
kono
parents: 67
diff changeset
1981 virtual bool gate (function *)
kono
parents: 67
diff changeset
1982 {
kono
parents: 67
diff changeset
1983 return (optimize > 0 && (flag_rename_registers));
kono
parents: 67
diff changeset
1984 }
kono
parents: 67
diff changeset
1985
kono
parents: 67
diff changeset
1986 virtual unsigned int execute (function *) { return regrename_optimize (); }
kono
parents: 67
diff changeset
1987
kono
parents: 67
diff changeset
1988 }; // class pass_regrename
kono
parents: 67
diff changeset
1989
kono
parents: 67
diff changeset
1990 } // anon namespace
kono
parents: 67
diff changeset
1991
kono
parents: 67
diff changeset
1992 rtl_opt_pass *
kono
parents: 67
diff changeset
1993 make_pass_regrename (gcc::context *ctxt)
kono
parents: 67
diff changeset
1994 {
kono
parents: 67
diff changeset
1995 return new pass_regrename (ctxt);
kono
parents: 67
diff changeset
1996 }