annotate gcc/regrename.c @ 158:494b0b89df80 default tip

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