Mercurial > hg > CbC > CbC_gcc
annotate gcc/cselib.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
rev | line source |
---|---|
0 | 1 /* Common subexpression elimination library for GNU compiler. |
111 | 2 Copyright (C) 1987-2017 Free Software Foundation, Inc. |
0 | 3 |
4 This file is part of GCC. | |
5 | |
6 GCC is free software; you can redistribute it and/or modify it under | |
7 the terms of the GNU General Public License as published by the Free | |
8 Software Foundation; either version 3, or (at your option) any later | |
9 version. | |
10 | |
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
14 for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GCC; see the file COPYING3. If not see | |
18 <http://www.gnu.org/licenses/>. */ | |
19 | |
20 #include "config.h" | |
21 #include "system.h" | |
22 #include "coretypes.h" | |
111 | 23 #include "backend.h" |
24 #include "target.h" | |
0 | 25 #include "rtl.h" |
111 | 26 #include "tree.h" |
27 #include "df.h" | |
28 #include "memmodel.h" | |
0 | 29 #include "tm_p.h" |
30 #include "regs.h" | |
31 #include "emit-rtl.h" | |
111 | 32 #include "dumpfile.h" |
0 | 33 #include "cselib.h" |
34 #include "params.h" | |
35 | |
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
|
36 /* A list of cselib_val structures. */ |
111 | 37 struct elt_list |
38 { | |
39 struct elt_list *next; | |
40 cselib_val *elt; | |
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
|
41 }; |
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 |
0 | 43 static bool cselib_record_memory; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
44 static bool cselib_preserve_constants; |
111 | 45 static bool cselib_any_perm_equivs; |
46 static inline void promote_debug_loc (struct elt_loc_list *l); | |
0 | 47 static struct elt_list *new_elt_list (struct elt_list *, cselib_val *); |
111 | 48 static void new_elt_loc_list (cselib_val *, rtx); |
0 | 49 static void unchain_one_value (cselib_val *); |
50 static void unchain_one_elt_list (struct elt_list **); | |
51 static void unchain_one_elt_loc_list (struct elt_loc_list **); | |
52 static void remove_useless_values (void); | |
111 | 53 static unsigned int cselib_hash_rtx (rtx, int, machine_mode); |
54 static cselib_val *new_cselib_val (unsigned int, machine_mode, rtx); | |
0 | 55 static void add_mem_for_addr (cselib_val *, cselib_val *, rtx); |
56 static cselib_val *cselib_lookup_mem (rtx, int); | |
111 | 57 static void cselib_invalidate_regno (unsigned int, machine_mode); |
0 | 58 static void cselib_invalidate_mem (rtx); |
59 static void cselib_record_set (rtx, cselib_val *, cselib_val *); | |
111 | 60 static void cselib_record_sets (rtx_insn *); |
0 | 61 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
62 struct expand_value_data |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
63 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
64 bitmap regs_active; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
65 cselib_expand_callback callback; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
66 void *callback_arg; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
67 bool dummy; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
68 }; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
69 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
70 static rtx cselib_expand_value_rtx_1 (rtx, struct expand_value_data *, int); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
71 |
0 | 72 /* There are three ways in which cselib can look up an rtx: |
73 - for a REG, the reg_values table (which is indexed by regno) is used | |
74 - for a MEM, we recursively look up its address and then follow the | |
75 addr_list of that value | |
76 - for everything else, we compute a hash value and go through the hash | |
77 table. Since different rtx's can still have the same hash value, | |
78 this involves walking the table entries for a given value and comparing | |
79 the locations of the entries with the rtx we are looking up. */ | |
80 | |
111 | 81 struct cselib_hasher : nofree_ptr_hash <cselib_val> |
82 { | |
83 struct key { | |
84 /* The rtx value and its mode (needed separately for constant | |
85 integers). */ | |
86 machine_mode mode; | |
87 rtx x; | |
88 /* The mode of the contaning MEM, if any, otherwise VOIDmode. */ | |
89 machine_mode memmode; | |
90 }; | |
91 typedef key *compare_type; | |
92 static inline hashval_t hash (const cselib_val *); | |
93 static inline bool equal (const cselib_val *, const key *); | |
94 }; | |
95 | |
96 /* The hash function for our hash table. The value is always computed with | |
97 cselib_hash_rtx when adding an element; this function just extracts the | |
98 hash value from a cselib_val structure. */ | |
99 | |
100 inline hashval_t | |
101 cselib_hasher::hash (const cselib_val *v) | |
102 { | |
103 return v->hash; | |
104 } | |
105 | |
106 /* The equality test for our hash table. The first argument V is a table | |
107 element (i.e. a cselib_val), while the second arg X is an rtx. We know | |
108 that all callers of htab_find_slot_with_hash will wrap CONST_INTs into a | |
109 CONST of an appropriate mode. */ | |
110 | |
111 inline bool | |
112 cselib_hasher::equal (const cselib_val *v, const key *x_arg) | |
113 { | |
114 struct elt_loc_list *l; | |
115 rtx x = x_arg->x; | |
116 machine_mode mode = x_arg->mode; | |
117 machine_mode memmode = x_arg->memmode; | |
118 | |
119 if (mode != GET_MODE (v->val_rtx)) | |
120 return false; | |
121 | |
122 if (GET_CODE (x) == VALUE) | |
123 return x == v->val_rtx; | |
124 | |
125 /* We don't guarantee that distinct rtx's have different hash values, | |
126 so we need to do a comparison. */ | |
127 for (l = v->locs; l; l = l->next) | |
128 if (rtx_equal_for_cselib_1 (l->loc, x, memmode, 0)) | |
129 { | |
130 promote_debug_loc (l); | |
131 return true; | |
132 } | |
133 | |
134 return false; | |
135 } | |
136 | |
0 | 137 /* A table that enables us to look up elts by their value. */ |
111 | 138 static hash_table<cselib_hasher> *cselib_hash_table; |
139 | |
140 /* A table to hold preserved values. */ | |
141 static hash_table<cselib_hasher> *cselib_preserved_hash_table; | |
0 | 142 |
143 /* This is a global so we don't have to pass this through every function. | |
144 It is used in new_elt_loc_list to set SETTING_INSN. */ | |
111 | 145 static rtx_insn *cselib_current_insn; |
0 | 146 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
147 /* The unique id that the next create value will take. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
148 static unsigned int next_uid; |
0 | 149 |
150 /* The number of registers we had when the varrays were last resized. */ | |
151 static unsigned int cselib_nregs; | |
152 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
153 /* Count values without known locations, or with only locations that |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
154 wouldn't have been known except for debug insns. Whenever this |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
155 grows too big, we remove these useless values from the table. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
156 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
157 Counting values with only debug values is a bit tricky. We don't |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
158 want to increment n_useless_values when we create a value for a |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
159 debug insn, for this would get n_useless_values out of sync, but we |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
160 want increment it if all locs in the list that were ever referenced |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
161 in nondebug insns are removed from the list. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
162 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
163 In the general case, once we do that, we'd have to stop accepting |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
164 nondebug expressions in the loc list, to avoid having two values |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
165 equivalent that, without debug insns, would have been made into |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
166 separate values. However, because debug insns never introduce |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
167 equivalences themselves (no assignments), the only means for |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
168 growing loc lists is through nondebug assignments. If the locs |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
169 also happen to be referenced in debug insns, it will work just fine. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
170 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
171 A consequence of this is that there's at most one debug-only loc in |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
172 each loc list. If we keep it in the first entry, testing whether |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
173 we have a debug-only loc list takes O(1). |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
174 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
175 Furthermore, since any additional entry in a loc list containing a |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
176 debug loc would have to come from an assignment (nondebug) that |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
177 references both the initial debug loc and the newly-equivalent loc, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
178 the initial debug loc would be promoted to a nondebug loc, and the |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
179 loc list would not contain debug locs any more. |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
180 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
181 So the only case we have to be careful with in order to keep |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
182 n_useless_values in sync between debug and nondebug compilations is |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
183 to avoid incrementing n_useless_values when removing the single loc |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
184 from a value that turns out to not appear outside debug values. We |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
185 increment n_useless_debug_values instead, and leave such values |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
186 alone until, for other reasons, we garbage-collect useless |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
187 values. */ |
0 | 188 static int n_useless_values; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
189 static int n_useless_debug_values; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
190 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
191 /* Count values whose locs have been taken exclusively from debug |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
192 insns for the entire life of the value. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
193 static int n_debug_values; |
0 | 194 |
195 /* Number of useless values before we remove them from the hash table. */ | |
196 #define MAX_USELESS_VALUES 32 | |
197 | |
198 /* This table maps from register number to values. It does not | |
199 contain pointers to cselib_val structures, but rather elt_lists. | |
200 The purpose is to be able to refer to the same register in | |
201 different modes. The first element of the list defines the mode in | |
202 which the register was set; if the mode is unknown or the value is | |
203 no longer valid in that mode, ELT will be NULL for the first | |
204 element. */ | |
205 static struct elt_list **reg_values; | |
206 static unsigned int reg_values_size; | |
207 #define REG_VALUES(i) reg_values[i] | |
208 | |
209 /* The largest number of hard regs used by any entry added to the | |
210 REG_VALUES table. Cleared on each cselib_clear_table() invocation. */ | |
211 static unsigned int max_value_regs; | |
212 | |
213 /* Here the set of indices I with REG_VALUES(I) != 0 is saved. This is used | |
214 in cselib_clear_table() for fast emptying. */ | |
215 static unsigned int *used_regs; | |
216 static unsigned int n_used_regs; | |
217 | |
218 /* We pass this to cselib_invalidate_mem to invalidate all of | |
219 memory for a non-const call instruction. */ | |
220 static GTY(()) rtx callmem; | |
221 | |
222 /* Set by discard_useless_locs if it deleted the last location of any | |
223 value. */ | |
224 static int values_became_useless; | |
225 | |
226 /* Used as stop element of the containing_mem list so we can check | |
227 presence in the list by checking the next pointer. */ | |
228 static cselib_val dummy_val; | |
229 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
230 /* If non-NULL, value of the eliminated arg_pointer_rtx or frame_pointer_rtx |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
231 that is constant through the whole function and should never be |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
232 eliminated. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
233 static cselib_val *cfa_base_preserved_val; |
111 | 234 static unsigned int cfa_base_preserved_regno = INVALID_REGNUM; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
235 |
0 | 236 /* Used to list all values that contain memory reference. |
237 May or may not contain the useless values - the list is compacted | |
238 each time memory is invalidated. */ | |
239 static cselib_val *first_containing_mem = &dummy_val; | |
111 | 240 |
241 static object_allocator<elt_list> elt_list_pool ("elt_list"); | |
242 static object_allocator<elt_loc_list> elt_loc_list_pool ("elt_loc_list"); | |
243 static object_allocator<cselib_val> cselib_val_pool ("cselib_val_list"); | |
244 | |
245 static pool_allocator value_pool ("value", RTX_CODE_SIZE (VALUE)); | |
0 | 246 |
247 /* If nonnull, cselib will call this function before freeing useless | |
248 VALUEs. A VALUE is deemed useless if its "locs" field is null. */ | |
249 void (*cselib_discard_hook) (cselib_val *); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
250 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
251 /* If nonnull, cselib will call this function before recording sets or |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
252 even clobbering outputs of INSN. All the recorded sets will be |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
253 represented in the array sets[n_sets]. new_val_min can be used to |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
254 tell whether values present in sets are introduced by this |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
255 instruction. */ |
111 | 256 void (*cselib_record_sets_hook) (rtx_insn *insn, struct cselib_set *sets, |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
257 int n_sets); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
258 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
259 #define PRESERVED_VALUE_P(RTX) \ |
111 | 260 (RTL_FLAG_CHECK1 ("PRESERVED_VALUE_P", (RTX), VALUE)->unchanging) |
261 | |
262 #define SP_BASED_VALUE_P(RTX) \ | |
263 (RTL_FLAG_CHECK1 ("SP_BASED_VALUE_P", (RTX), VALUE)->jump) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
264 |
0 | 265 |
266 | |
267 /* Allocate a struct elt_list and fill in its two elements with the | |
268 arguments. */ | |
269 | |
270 static inline struct elt_list * | |
271 new_elt_list (struct elt_list *next, cselib_val *elt) | |
272 { | |
111 | 273 elt_list *el = elt_list_pool.allocate (); |
0 | 274 el->next = next; |
275 el->elt = elt; | |
276 return el; | |
277 } | |
278 | |
111 | 279 /* Allocate a struct elt_loc_list with LOC and prepend it to VAL's loc |
280 list. */ | |
281 | |
282 static inline void | |
283 new_elt_loc_list (cselib_val *val, rtx loc) | |
0 | 284 { |
111 | 285 struct elt_loc_list *el, *next = val->locs; |
286 | |
287 gcc_checking_assert (!next || !next->setting_insn | |
288 || !DEBUG_INSN_P (next->setting_insn) | |
289 || cselib_current_insn == next->setting_insn); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
290 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
291 /* If we're creating the first loc in a debug insn context, we've |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
292 just created a debug value. Count it. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
293 if (!next && cselib_current_insn && DEBUG_INSN_P (cselib_current_insn)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
294 n_debug_values++; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
295 |
111 | 296 val = canonical_cselib_val (val); |
297 next = val->locs; | |
298 | |
299 if (GET_CODE (loc) == VALUE) | |
300 { | |
301 loc = canonical_cselib_val (CSELIB_VAL_PTR (loc))->val_rtx; | |
302 | |
303 gcc_checking_assert (PRESERVED_VALUE_P (loc) | |
304 == PRESERVED_VALUE_P (val->val_rtx)); | |
305 | |
306 if (val->val_rtx == loc) | |
307 return; | |
308 else if (val->uid > CSELIB_VAL_PTR (loc)->uid) | |
309 { | |
310 /* Reverse the insertion. */ | |
311 new_elt_loc_list (CSELIB_VAL_PTR (loc), val->val_rtx); | |
312 return; | |
313 } | |
314 | |
315 gcc_checking_assert (val->uid < CSELIB_VAL_PTR (loc)->uid); | |
316 | |
317 if (CSELIB_VAL_PTR (loc)->locs) | |
318 { | |
319 /* Bring all locs from LOC to VAL. */ | |
320 for (el = CSELIB_VAL_PTR (loc)->locs; el->next; el = el->next) | |
321 { | |
322 /* Adjust values that have LOC as canonical so that VAL | |
323 becomes their canonical. */ | |
324 if (el->loc && GET_CODE (el->loc) == VALUE) | |
325 { | |
326 gcc_checking_assert (CSELIB_VAL_PTR (el->loc)->locs->loc | |
327 == loc); | |
328 CSELIB_VAL_PTR (el->loc)->locs->loc = val->val_rtx; | |
329 } | |
330 } | |
331 el->next = val->locs; | |
332 next = val->locs = CSELIB_VAL_PTR (loc)->locs; | |
333 } | |
334 | |
335 if (CSELIB_VAL_PTR (loc)->addr_list) | |
336 { | |
337 /* Bring in addr_list into canonical node. */ | |
338 struct elt_list *last = CSELIB_VAL_PTR (loc)->addr_list; | |
339 while (last->next) | |
340 last = last->next; | |
341 last->next = val->addr_list; | |
342 val->addr_list = CSELIB_VAL_PTR (loc)->addr_list; | |
343 CSELIB_VAL_PTR (loc)->addr_list = NULL; | |
344 } | |
345 | |
346 if (CSELIB_VAL_PTR (loc)->next_containing_mem != NULL | |
347 && val->next_containing_mem == NULL) | |
348 { | |
349 /* Add VAL to the containing_mem list after LOC. LOC will | |
350 be removed when we notice it doesn't contain any | |
351 MEMs. */ | |
352 val->next_containing_mem = CSELIB_VAL_PTR (loc)->next_containing_mem; | |
353 CSELIB_VAL_PTR (loc)->next_containing_mem = val; | |
354 } | |
355 | |
356 /* Chain LOC back to VAL. */ | |
357 el = elt_loc_list_pool.allocate (); | |
358 el->loc = val->val_rtx; | |
359 el->setting_insn = cselib_current_insn; | |
360 el->next = NULL; | |
361 CSELIB_VAL_PTR (loc)->locs = el; | |
362 } | |
363 | |
364 el = elt_loc_list_pool.allocate (); | |
365 el->loc = loc; | |
366 el->setting_insn = cselib_current_insn; | |
367 el->next = next; | |
368 val->locs = el; | |
0 | 369 } |
370 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
371 /* Promote loc L to a nondebug cselib_current_insn if L is marked as |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
372 originating from a debug insn, maintaining the debug values |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
373 count. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
374 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
375 static inline void |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
376 promote_debug_loc (struct elt_loc_list *l) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
377 { |
111 | 378 if (l && l->setting_insn && DEBUG_INSN_P (l->setting_insn) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
379 && (!cselib_current_insn || !DEBUG_INSN_P (cselib_current_insn))) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
380 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
381 n_debug_values--; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
382 l->setting_insn = cselib_current_insn; |
111 | 383 if (cselib_preserve_constants && l->next) |
384 { | |
385 gcc_assert (l->next->setting_insn | |
386 && DEBUG_INSN_P (l->next->setting_insn) | |
387 && !l->next->next); | |
388 l->next->setting_insn = cselib_current_insn; | |
389 } | |
390 else | |
391 gcc_assert (!l->next); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
392 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
393 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
394 |
0 | 395 /* The elt_list at *PL is no longer needed. Unchain it and free its |
396 storage. */ | |
397 | |
398 static inline void | |
399 unchain_one_elt_list (struct elt_list **pl) | |
400 { | |
401 struct elt_list *l = *pl; | |
402 | |
403 *pl = l->next; | |
111 | 404 elt_list_pool.remove (l); |
0 | 405 } |
406 | |
407 /* Likewise for elt_loc_lists. */ | |
408 | |
409 static void | |
410 unchain_one_elt_loc_list (struct elt_loc_list **pl) | |
411 { | |
412 struct elt_loc_list *l = *pl; | |
413 | |
414 *pl = l->next; | |
111 | 415 elt_loc_list_pool.remove (l); |
0 | 416 } |
417 | |
418 /* Likewise for cselib_vals. This also frees the addr_list associated with | |
419 V. */ | |
420 | |
421 static void | |
422 unchain_one_value (cselib_val *v) | |
423 { | |
424 while (v->addr_list) | |
425 unchain_one_elt_list (&v->addr_list); | |
426 | |
111 | 427 cselib_val_pool.remove (v); |
0 | 428 } |
429 | |
430 /* Remove all entries from the hash table. Also used during | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
431 initialization. */ |
0 | 432 |
433 void | |
434 cselib_clear_table (void) | |
435 { | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
436 cselib_reset_table (1); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
437 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
438 |
111 | 439 /* Return TRUE if V is a constant, a function invariant or a VALUE |
440 equivalence; FALSE otherwise. */ | |
441 | |
442 static bool | |
443 invariant_or_equiv_p (cselib_val *v) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
444 { |
111 | 445 struct elt_loc_list *l; |
446 | |
447 if (v == cfa_base_preserved_val) | |
448 return true; | |
449 | |
450 /* Keep VALUE equivalences around. */ | |
451 for (l = v->locs; l; l = l->next) | |
452 if (GET_CODE (l->loc) == VALUE) | |
453 return true; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
454 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
455 if (v->locs != NULL |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
456 && v->locs->next == NULL) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
457 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
458 if (CONSTANT_P (v->locs->loc) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
459 && (GET_CODE (v->locs->loc) != CONST |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
460 || !references_value_p (v->locs->loc, 0))) |
111 | 461 return true; |
462 /* Although a debug expr may be bound to different expressions, | |
463 we can preserve it as if it was constant, to get unification | |
464 and proper merging within var-tracking. */ | |
465 if (GET_CODE (v->locs->loc) == DEBUG_EXPR | |
466 || GET_CODE (v->locs->loc) == DEBUG_IMPLICIT_PTR | |
467 || GET_CODE (v->locs->loc) == ENTRY_VALUE | |
468 || GET_CODE (v->locs->loc) == DEBUG_PARAMETER_REF) | |
469 return true; | |
470 | |
471 /* (plus (value V) (const_int C)) is invariant iff V is invariant. */ | |
472 if (GET_CODE (v->locs->loc) == PLUS | |
473 && CONST_INT_P (XEXP (v->locs->loc, 1)) | |
474 && GET_CODE (XEXP (v->locs->loc, 0)) == VALUE | |
475 && invariant_or_equiv_p (CSELIB_VAL_PTR (XEXP (v->locs->loc, 0)))) | |
476 return true; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
477 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
478 |
111 | 479 return false; |
480 } | |
481 | |
482 /* Remove from hash table all VALUEs except constants, function | |
483 invariants and VALUE equivalences. */ | |
484 | |
485 int | |
486 preserve_constants_and_equivs (cselib_val **x, void *info ATTRIBUTE_UNUSED) | |
487 { | |
488 cselib_val *v = *x; | |
489 | |
490 if (invariant_or_equiv_p (v)) | |
491 { | |
492 cselib_hasher::key lookup = { | |
493 GET_MODE (v->val_rtx), v->val_rtx, VOIDmode | |
494 }; | |
495 cselib_val **slot | |
496 = cselib_preserved_hash_table->find_slot_with_hash (&lookup, | |
497 v->hash, INSERT); | |
498 gcc_assert (!*slot); | |
499 *slot = v; | |
500 } | |
501 | |
502 cselib_hash_table->clear_slot (x); | |
503 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
504 return 1; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
505 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
506 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
507 /* Remove all entries from the hash table, arranging for the next |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
508 value to be numbered NUM. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
509 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
510 void |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
511 cselib_reset_table (unsigned int num) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
512 { |
0 | 513 unsigned int i; |
514 | |
515 max_value_regs = 0; | |
516 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
517 if (cfa_base_preserved_val) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
518 { |
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
|
519 unsigned int regno = cfa_base_preserved_regno; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
520 unsigned int new_used_regs = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
521 for (i = 0; i < n_used_regs; i++) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
522 if (used_regs[i] == regno) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
523 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
524 new_used_regs = 1; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
525 continue; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
526 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
527 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
528 REG_VALUES (used_regs[i]) = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
529 gcc_assert (new_used_regs == 1); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
530 n_used_regs = new_used_regs; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
531 used_regs[0] = regno; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
532 max_value_regs |
111 | 533 = hard_regno_nregs (regno, |
534 GET_MODE (cfa_base_preserved_val->locs->loc)); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
535 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
536 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
537 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
538 for (i = 0; i < n_used_regs; i++) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
539 REG_VALUES (used_regs[i]) = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
540 n_used_regs = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
541 } |
0 | 542 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
543 if (cselib_preserve_constants) |
111 | 544 cselib_hash_table->traverse <void *, preserve_constants_and_equivs> |
545 (NULL); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
546 else |
111 | 547 { |
548 cselib_hash_table->empty (); | |
549 gcc_checking_assert (!cselib_any_perm_equivs); | |
550 } | |
0 | 551 |
552 n_useless_values = 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
|
553 n_useless_debug_values = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
554 n_debug_values = 0; |
0 | 555 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
556 next_uid = num; |
0 | 557 |
558 first_containing_mem = &dummy_val; | |
559 } | |
560 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
561 /* Return the number of the next value that will be generated. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
562 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
563 unsigned int |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
564 cselib_get_next_uid (void) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
565 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
566 return next_uid; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
567 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
568 |
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
|
569 /* Search for X, whose hashcode is HASH, in CSELIB_HASH_TABLE, |
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
|
570 INSERTing if requested. When X is part of the address of a MEM, |
111 | 571 MEMMODE should specify the mode of the MEM. */ |
572 | |
573 static cselib_val ** | |
574 cselib_find_slot (machine_mode mode, rtx x, hashval_t hash, | |
575 enum insert_option insert, machine_mode memmode) | |
0 | 576 { |
111 | 577 cselib_val **slot = NULL; |
578 cselib_hasher::key lookup = { mode, x, memmode }; | |
579 if (cselib_preserve_constants) | |
580 slot = cselib_preserved_hash_table->find_slot_with_hash (&lookup, hash, | |
581 NO_INSERT); | |
582 if (!slot) | |
583 slot = cselib_hash_table->find_slot_with_hash (&lookup, hash, insert); | |
584 return slot; | |
0 | 585 } |
586 | |
587 /* Return true if X contains a VALUE rtx. If ONLY_USELESS is set, we | |
588 only return true for values which point to a cselib_val whose value | |
589 element has been set to zero, which implies the cselib_val will be | |
590 removed. */ | |
591 | |
592 int | |
593 references_value_p (const_rtx x, int only_useless) | |
594 { | |
595 const enum rtx_code code = GET_CODE (x); | |
596 const char *fmt = GET_RTX_FORMAT (code); | |
597 int i, j; | |
598 | |
599 if (GET_CODE (x) == VALUE | |
111 | 600 && (! only_useless || |
601 (CSELIB_VAL_PTR (x)->locs == 0 && !PRESERVED_VALUE_P (x)))) | |
0 | 602 return 1; |
603 | |
604 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
605 { | |
606 if (fmt[i] == 'e' && references_value_p (XEXP (x, i), only_useless)) | |
607 return 1; | |
608 else if (fmt[i] == 'E') | |
609 for (j = 0; j < XVECLEN (x, i); j++) | |
610 if (references_value_p (XVECEXP (x, i, j), only_useless)) | |
611 return 1; | |
612 } | |
613 | |
614 return 0; | |
615 } | |
616 | |
617 /* For all locations found in X, delete locations that reference useless | |
618 values (i.e. values without any location). Called through | |
619 htab_traverse. */ | |
620 | |
111 | 621 int |
622 discard_useless_locs (cselib_val **x, void *info ATTRIBUTE_UNUSED) | |
0 | 623 { |
111 | 624 cselib_val *v = *x; |
0 | 625 struct elt_loc_list **p = &v->locs; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
626 bool had_locs = v->locs != NULL; |
111 | 627 rtx_insn *setting_insn = v->locs ? v->locs->setting_insn : NULL; |
0 | 628 |
629 while (*p) | |
630 { | |
631 if (references_value_p ((*p)->loc, 1)) | |
632 unchain_one_elt_loc_list (p); | |
633 else | |
634 p = &(*p)->next; | |
635 } | |
636 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
637 if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx)) |
0 | 638 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
639 if (setting_insn && DEBUG_INSN_P (setting_insn)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
640 n_useless_debug_values++; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
641 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
642 n_useless_values++; |
0 | 643 values_became_useless = 1; |
644 } | |
645 return 1; | |
646 } | |
647 | |
648 /* If X is a value with no locations, remove it from the hashtable. */ | |
649 | |
111 | 650 int |
651 discard_useless_values (cselib_val **x, void *info ATTRIBUTE_UNUSED) | |
0 | 652 { |
111 | 653 cselib_val *v = *x; |
0 | 654 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
655 if (v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx)) |
0 | 656 { |
657 if (cselib_discard_hook) | |
658 cselib_discard_hook (v); | |
659 | |
660 CSELIB_VAL_PTR (v->val_rtx) = NULL; | |
111 | 661 cselib_hash_table->clear_slot (x); |
0 | 662 unchain_one_value (v); |
663 n_useless_values--; | |
664 } | |
665 | |
666 return 1; | |
667 } | |
668 | |
669 /* Clean out useless values (i.e. those which no longer have locations | |
670 associated with them) from the hash table. */ | |
671 | |
672 static void | |
673 remove_useless_values (void) | |
674 { | |
675 cselib_val **p, *v; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
676 |
0 | 677 /* First pass: eliminate locations that reference the value. That in |
678 turn can make more values useless. */ | |
679 do | |
680 { | |
681 values_became_useless = 0; | |
111 | 682 cselib_hash_table->traverse <void *, discard_useless_locs> (NULL); |
0 | 683 } |
684 while (values_became_useless); | |
685 | |
686 /* Second pass: actually remove the values. */ | |
687 | |
688 p = &first_containing_mem; | |
689 for (v = *p; v != &dummy_val; v = v->next_containing_mem) | |
111 | 690 if (v->locs && v == canonical_cselib_val (v)) |
0 | 691 { |
692 *p = v; | |
693 p = &(*p)->next_containing_mem; | |
694 } | |
695 *p = &dummy_val; | |
696 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
697 n_useless_values += n_useless_debug_values; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
698 n_debug_values -= n_useless_debug_values; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
699 n_useless_debug_values = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
700 |
111 | 701 cselib_hash_table->traverse <void *, discard_useless_values> (NULL); |
0 | 702 |
703 gcc_assert (!n_useless_values); | |
704 } | |
705 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
706 /* Arrange for a value to not be removed from the hash table even if |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
707 it becomes useless. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
708 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
709 void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
710 cselib_preserve_value (cselib_val *v) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
711 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
712 PRESERVED_VALUE_P (v->val_rtx) = 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
713 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
714 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
715 /* Test whether a value is preserved. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
716 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
717 bool |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
718 cselib_preserved_value_p (cselib_val *v) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
719 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
720 return PRESERVED_VALUE_P (v->val_rtx); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
721 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
722 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
723 /* Arrange for a REG value to be assumed constant through the whole function, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
724 never invalidated and preserved across cselib_reset_table calls. */ |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
725 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
726 void |
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
|
727 cselib_preserve_cfa_base_value (cselib_val *v, unsigned int regno) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
728 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
729 if (cselib_preserve_constants |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
730 && v->locs |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
731 && REG_P (v->locs->loc)) |
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
|
732 { |
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
|
733 cfa_base_preserved_val = v; |
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
|
734 cfa_base_preserved_regno = regno; |
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
|
735 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
736 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
737 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
738 /* Clean all non-constant expressions in the hash table, but retain |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
739 their values. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
740 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
741 void |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
742 cselib_preserve_only_values (void) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
743 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
744 int i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
745 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
746 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
747 cselib_invalidate_regno (i, reg_raw_mode[i]); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
748 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
749 cselib_invalidate_mem (callmem); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
750 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
751 remove_useless_values (); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
752 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
753 gcc_assert (first_containing_mem == &dummy_val); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
754 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
755 |
111 | 756 /* Arrange for a value to be marked as based on stack pointer |
757 for find_base_term purposes. */ | |
758 | |
759 void | |
760 cselib_set_value_sp_based (cselib_val *v) | |
761 { | |
762 SP_BASED_VALUE_P (v->val_rtx) = 1; | |
763 } | |
764 | |
765 /* Test whether a value is based on stack pointer for | |
766 find_base_term purposes. */ | |
767 | |
768 bool | |
769 cselib_sp_based_value_p (cselib_val *v) | |
770 { | |
771 return SP_BASED_VALUE_P (v->val_rtx); | |
772 } | |
773 | |
0 | 774 /* Return the mode in which a register was last set. If X is not a |
775 register, return its mode. If the mode in which the register was | |
776 set is not known, or the value was already clobbered, return | |
777 VOIDmode. */ | |
778 | |
111 | 779 machine_mode |
0 | 780 cselib_reg_set_mode (const_rtx x) |
781 { | |
782 if (!REG_P (x)) | |
783 return GET_MODE (x); | |
784 | |
785 if (REG_VALUES (REGNO (x)) == NULL | |
786 || REG_VALUES (REGNO (x))->elt == NULL) | |
787 return VOIDmode; | |
788 | |
789 return GET_MODE (REG_VALUES (REGNO (x))->elt->val_rtx); | |
790 } | |
791 | |
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
|
792 /* If x is a PLUS or an autoinc operation, expand the operation, |
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
|
793 storing the offset, if any, in *OFF. */ |
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
|
794 |
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
|
795 static rtx |
111 | 796 autoinc_split (rtx x, rtx *off, machine_mode memmode) |
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
|
797 { |
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
|
798 switch (GET_CODE (x)) |
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
|
799 { |
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
|
800 case PLUS: |
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
|
801 *off = XEXP (x, 1); |
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
|
802 return XEXP (x, 0); |
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
|
803 |
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
|
804 case PRE_DEC: |
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
|
805 if (memmode == VOIDmode) |
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
|
806 return x; |
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
|
807 |
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
|
808 *off = GEN_INT (-GET_MODE_SIZE (memmode)); |
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
|
809 return XEXP (x, 0); |
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
|
810 |
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
|
811 case PRE_INC: |
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
|
812 if (memmode == VOIDmode) |
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
|
813 return x; |
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
|
814 |
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
|
815 *off = GEN_INT (GET_MODE_SIZE (memmode)); |
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
|
816 return XEXP (x, 0); |
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
|
817 |
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
|
818 case PRE_MODIFY: |
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
|
819 return XEXP (x, 1); |
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
|
820 |
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
|
821 case POST_DEC: |
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
|
822 case POST_INC: |
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
|
823 case POST_MODIFY: |
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
|
824 return XEXP (x, 0); |
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
|
825 |
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
|
826 default: |
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
|
827 return x; |
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
|
828 } |
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
|
829 } |
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
|
830 |
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
|
831 /* Return nonzero if we can prove that X and Y contain the same value, |
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
|
832 taking our gathered information into account. MEMMODE holds 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
|
833 mode of the enclosing MEM, if any, as required to deal with autoinc |
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
|
834 addressing modes. If X and Y are not (known to be) part of |
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
|
835 addresses, MEMMODE should be VOIDmode. */ |
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
|
836 |
111 | 837 int |
838 rtx_equal_for_cselib_1 (rtx x, rtx y, machine_mode memmode, int depth) | |
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
|
839 { |
0 | 840 enum rtx_code code; |
841 const char *fmt; | |
842 int i; | |
843 | |
844 if (REG_P (x) || MEM_P (x)) | |
845 { | |
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
|
846 cselib_val *e = cselib_lookup (x, GET_MODE (x), 0, memmode); |
0 | 847 |
848 if (e) | |
849 x = e->val_rtx; | |
850 } | |
851 | |
852 if (REG_P (y) || MEM_P (y)) | |
853 { | |
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
|
854 cselib_val *e = cselib_lookup (y, GET_MODE (y), 0, memmode); |
0 | 855 |
856 if (e) | |
857 y = e->val_rtx; | |
858 } | |
859 | |
860 if (x == y) | |
861 return 1; | |
862 | |
863 if (GET_CODE (x) == VALUE) | |
864 { | |
111 | 865 cselib_val *e = canonical_cselib_val (CSELIB_VAL_PTR (x)); |
0 | 866 struct elt_loc_list *l; |
867 | |
111 | 868 if (GET_CODE (y) == VALUE) |
869 return e == canonical_cselib_val (CSELIB_VAL_PTR (y)); | |
870 | |
871 if (depth == 128) | |
872 return 0; | |
873 | |
0 | 874 for (l = e->locs; l; l = l->next) |
875 { | |
876 rtx t = l->loc; | |
877 | |
111 | 878 /* Avoid infinite recursion. We know we have the canonical |
879 value, so we can just skip any values in the equivalence | |
880 list. */ | |
881 if (REG_P (t) || MEM_P (t) || GET_CODE (t) == VALUE) | |
0 | 882 continue; |
111 | 883 else if (rtx_equal_for_cselib_1 (t, y, memmode, depth + 1)) |
0 | 884 return 1; |
885 } | |
886 | |
887 return 0; | |
888 } | |
111 | 889 else if (GET_CODE (y) == VALUE) |
0 | 890 { |
111 | 891 cselib_val *e = canonical_cselib_val (CSELIB_VAL_PTR (y)); |
0 | 892 struct elt_loc_list *l; |
893 | |
111 | 894 if (depth == 128) |
895 return 0; | |
896 | |
0 | 897 for (l = e->locs; l; l = l->next) |
898 { | |
899 rtx t = l->loc; | |
900 | |
111 | 901 if (REG_P (t) || MEM_P (t) || GET_CODE (t) == VALUE) |
0 | 902 continue; |
111 | 903 else if (rtx_equal_for_cselib_1 (x, t, memmode, depth + 1)) |
0 | 904 return 1; |
905 } | |
906 | |
907 return 0; | |
908 } | |
909 | |
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
|
910 if (GET_MODE (x) != GET_MODE (y)) |
0 | 911 return 0; |
912 | |
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
|
913 if (GET_CODE (x) != GET_CODE (y)) |
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
|
914 { |
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
|
915 rtx xorig = x, yorig = y; |
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
|
916 rtx xoff = NULL, yoff = NULL; |
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
|
917 |
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
|
918 x = autoinc_split (x, &xoff, memmode); |
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
|
919 y = autoinc_split (y, &yoff, memmode); |
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
|
920 |
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
|
921 if (!xoff != !yoff) |
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
|
922 return 0; |
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
|
923 |
111 | 924 if (xoff && !rtx_equal_for_cselib_1 (xoff, yoff, memmode, depth)) |
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
|
925 return 0; |
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
|
926 |
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
|
927 /* Don't recurse if nothing changed. */ |
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
|
928 if (x != xorig || y != yorig) |
111 | 929 return rtx_equal_for_cselib_1 (x, y, memmode, depth); |
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
|
930 |
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
|
931 return 0; |
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
|
932 } |
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
|
933 |
0 | 934 /* These won't be handled correctly by the code below. */ |
935 switch (GET_CODE (x)) | |
936 { | |
111 | 937 CASE_CONST_UNIQUE: |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
938 case DEBUG_EXPR: |
0 | 939 return 0; |
940 | |
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
|
941 case DEBUG_IMPLICIT_PTR: |
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
|
942 return DEBUG_IMPLICIT_PTR_DECL (x) |
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
|
943 == DEBUG_IMPLICIT_PTR_DECL (y); |
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
|
944 |
111 | 945 case DEBUG_PARAMETER_REF: |
946 return DEBUG_PARAMETER_REF_DECL (x) | |
947 == DEBUG_PARAMETER_REF_DECL (y); | |
948 | |
949 case ENTRY_VALUE: | |
950 /* ENTRY_VALUEs are function invariant, it is thus undesirable to | |
951 use rtx_equal_for_cselib_1 to compare the operands. */ | |
952 return rtx_equal_p (ENTRY_VALUE_EXP (x), ENTRY_VALUE_EXP (y)); | |
953 | |
0 | 954 case LABEL_REF: |
111 | 955 return label_ref_label (x) == label_ref_label (y); |
956 | |
957 case REG: | |
958 return REGNO (x) == REGNO (y); | |
0 | 959 |
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
|
960 case MEM: |
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
|
961 /* We have to compare any autoinc operations in the addresses |
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
|
962 using this MEM's mode. */ |
111 | 963 return rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 0), GET_MODE (x), |
964 depth); | |
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
|
965 |
0 | 966 default: |
967 break; | |
968 } | |
969 | |
970 code = GET_CODE (x); | |
971 fmt = GET_RTX_FORMAT (code); | |
972 | |
973 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
974 { | |
975 int j; | |
976 | |
977 switch (fmt[i]) | |
978 { | |
979 case 'w': | |
980 if (XWINT (x, i) != XWINT (y, i)) | |
981 return 0; | |
982 break; | |
983 | |
984 case 'n': | |
985 case 'i': | |
986 if (XINT (x, i) != XINT (y, i)) | |
987 return 0; | |
988 break; | |
989 | |
990 case 'V': | |
991 case 'E': | |
992 /* Two vectors must have the same length. */ | |
993 if (XVECLEN (x, i) != XVECLEN (y, i)) | |
994 return 0; | |
995 | |
996 /* And the corresponding elements must match. */ | |
997 for (j = 0; j < XVECLEN (x, i); j++) | |
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
|
998 if (! rtx_equal_for_cselib_1 (XVECEXP (x, i, j), |
111 | 999 XVECEXP (y, i, j), memmode, depth)) |
0 | 1000 return 0; |
1001 break; | |
1002 | |
1003 case 'e': | |
1004 if (i == 1 | |
1005 && targetm.commutative_p (x, UNKNOWN) | |
111 | 1006 && rtx_equal_for_cselib_1 (XEXP (x, 1), XEXP (y, 0), memmode, |
1007 depth) | |
1008 && rtx_equal_for_cselib_1 (XEXP (x, 0), XEXP (y, 1), memmode, | |
1009 depth)) | |
0 | 1010 return 1; |
111 | 1011 if (! rtx_equal_for_cselib_1 (XEXP (x, i), XEXP (y, i), memmode, |
1012 depth)) | |
0 | 1013 return 0; |
1014 break; | |
1015 | |
1016 case 'S': | |
1017 case 's': | |
1018 if (strcmp (XSTR (x, i), XSTR (y, i))) | |
1019 return 0; | |
1020 break; | |
1021 | |
1022 case 'u': | |
1023 /* These are just backpointers, so they don't matter. */ | |
1024 break; | |
1025 | |
1026 case '0': | |
1027 case 't': | |
1028 break; | |
1029 | |
1030 /* It is believed that rtx's at this level will never | |
1031 contain anything but integers and other rtx's, | |
1032 except for within LABEL_REFs and SYMBOL_REFs. */ | |
1033 default: | |
1034 gcc_unreachable (); | |
1035 } | |
1036 } | |
1037 return 1; | |
1038 } | |
1039 | |
1040 /* Hash an rtx. Return 0 if we couldn't hash the rtx. | |
1041 For registers and memory locations, we look up their cselib_val structure | |
1042 and return its VALUE element. | |
1043 Possible reasons for return 0 are: the object is volatile, or we couldn't | |
1044 find a register or memory location in the table and CREATE is zero. If | |
1045 CREATE is nonzero, table elts are created for regs and mem. | |
1046 N.B. this hash function returns the same hash value for RTXes that | |
1047 differ only in the order of operands, thus it is suitable for comparisons | |
1048 that take commutativity into account. | |
1049 If we wanted to also support associative rules, we'd have to use a different | |
1050 strategy to avoid returning spurious 0, e.g. return ~(~0U >> 1) . | |
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
|
1051 MEMMODE indicates the mode of an enclosing MEM, and it's only |
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
|
1052 used to compute autoinc values. |
0 | 1053 We used to have a MODE argument for hashing for CONST_INTs, but that |
1054 didn't make sense, since it caused spurious hash differences between | |
1055 (set (reg:SI 1) (const_int)) | |
1056 (plus:SI (reg:SI 2) (reg:SI 1)) | |
1057 and | |
1058 (plus:SI (reg:SI 2) (const_int)) | |
1059 If the mode is important in any context, it must be checked specifically | |
1060 in a comparison anyway, since relying on hash differences is unsafe. */ | |
1061 | |
1062 static unsigned int | |
111 | 1063 cselib_hash_rtx (rtx x, int create, machine_mode memmode) |
0 | 1064 { |
1065 cselib_val *e; | |
1066 int i, j; | |
1067 enum rtx_code code; | |
1068 const char *fmt; | |
1069 unsigned int hash = 0; | |
1070 | |
1071 code = GET_CODE (x); | |
1072 hash += (unsigned) code + (unsigned) GET_MODE (x); | |
1073 | |
1074 switch (code) | |
1075 { | |
111 | 1076 case VALUE: |
1077 e = CSELIB_VAL_PTR (x); | |
1078 return e->hash; | |
1079 | |
0 | 1080 case MEM: |
1081 case REG: | |
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
|
1082 e = cselib_lookup (x, GET_MODE (x), create, memmode); |
0 | 1083 if (! e) |
1084 return 0; | |
1085 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1086 return e->hash; |
0 | 1087 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1088 case DEBUG_EXPR: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1089 hash += ((unsigned) DEBUG_EXPR << 7) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1090 + DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1091 return hash ? hash : (unsigned int) DEBUG_EXPR; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1092 |
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
|
1093 case DEBUG_IMPLICIT_PTR: |
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
|
1094 hash += ((unsigned) DEBUG_IMPLICIT_PTR << 7) |
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
|
1095 + DECL_UID (DEBUG_IMPLICIT_PTR_DECL (x)); |
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
|
1096 return hash ? hash : (unsigned int) DEBUG_IMPLICIT_PTR; |
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
|
1097 |
111 | 1098 case DEBUG_PARAMETER_REF: |
1099 hash += ((unsigned) DEBUG_PARAMETER_REF << 7) | |
1100 + DECL_UID (DEBUG_PARAMETER_REF_DECL (x)); | |
1101 return hash ? hash : (unsigned int) DEBUG_PARAMETER_REF; | |
1102 | |
1103 case ENTRY_VALUE: | |
1104 /* ENTRY_VALUEs are function invariant, thus try to avoid | |
1105 recursing on argument if ENTRY_VALUE is one of the | |
1106 forms emitted by expand_debug_expr, otherwise | |
1107 ENTRY_VALUE hash would depend on the current value | |
1108 in some register or memory. */ | |
1109 if (REG_P (ENTRY_VALUE_EXP (x))) | |
1110 hash += (unsigned int) REG | |
1111 + (unsigned int) GET_MODE (ENTRY_VALUE_EXP (x)) | |
1112 + (unsigned int) REGNO (ENTRY_VALUE_EXP (x)); | |
1113 else if (MEM_P (ENTRY_VALUE_EXP (x)) | |
1114 && REG_P (XEXP (ENTRY_VALUE_EXP (x), 0))) | |
1115 hash += (unsigned int) MEM | |
1116 + (unsigned int) GET_MODE (XEXP (ENTRY_VALUE_EXP (x), 0)) | |
1117 + (unsigned int) REGNO (XEXP (ENTRY_VALUE_EXP (x), 0)); | |
1118 else | |
1119 hash += cselib_hash_rtx (ENTRY_VALUE_EXP (x), create, memmode); | |
1120 return hash ? hash : (unsigned int) ENTRY_VALUE; | |
1121 | |
0 | 1122 case CONST_INT: |
111 | 1123 hash += ((unsigned) CONST_INT << 7) + UINTVAL (x); |
0 | 1124 return hash ? hash : (unsigned int) CONST_INT; |
1125 | |
111 | 1126 case CONST_WIDE_INT: |
1127 for (i = 0; i < CONST_WIDE_INT_NUNITS (x); i++) | |
1128 hash += CONST_WIDE_INT_ELT (x, i); | |
1129 return hash; | |
1130 | |
0 | 1131 case CONST_DOUBLE: |
1132 /* This is like the general case, except that it only counts | |
1133 the integers representing the constant. */ | |
1134 hash += (unsigned) code + (unsigned) GET_MODE (x); | |
111 | 1135 if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (x) == VOIDmode) |
0 | 1136 hash += ((unsigned) CONST_DOUBLE_LOW (x) |
1137 + (unsigned) CONST_DOUBLE_HIGH (x)); | |
111 | 1138 else |
1139 hash += real_hash (CONST_DOUBLE_REAL_VALUE (x)); | |
0 | 1140 return hash ? hash : (unsigned int) CONST_DOUBLE; |
1141 | |
1142 case CONST_FIXED: | |
1143 hash += (unsigned int) code + (unsigned int) GET_MODE (x); | |
1144 hash += fixed_hash (CONST_FIXED_VALUE (x)); | |
1145 return hash ? hash : (unsigned int) CONST_FIXED; | |
1146 | |
1147 case CONST_VECTOR: | |
1148 { | |
1149 int units; | |
1150 rtx elt; | |
1151 | |
1152 units = CONST_VECTOR_NUNITS (x); | |
1153 | |
1154 for (i = 0; i < units; ++i) | |
1155 { | |
1156 elt = CONST_VECTOR_ELT (x, i); | |
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
|
1157 hash += cselib_hash_rtx (elt, 0, memmode); |
0 | 1158 } |
1159 | |
1160 return hash; | |
1161 } | |
1162 | |
1163 /* Assume there is only one rtx object for any given label. */ | |
1164 case LABEL_REF: | |
1165 /* We don't hash on the address of the CODE_LABEL to avoid bootstrap | |
1166 differences and differences between each stage's debugging dumps. */ | |
1167 hash += (((unsigned int) LABEL_REF << 7) | |
111 | 1168 + CODE_LABEL_NUMBER (label_ref_label (x))); |
0 | 1169 return hash ? hash : (unsigned int) LABEL_REF; |
1170 | |
1171 case SYMBOL_REF: | |
1172 { | |
1173 /* Don't hash on the symbol's address to avoid bootstrap differences. | |
1174 Different hash values may cause expressions to be recorded in | |
1175 different orders and thus different registers to be used in the | |
1176 final assembler. This also avoids differences in the dump files | |
1177 between various stages. */ | |
1178 unsigned int h = 0; | |
1179 const unsigned char *p = (const unsigned char *) XSTR (x, 0); | |
1180 | |
1181 while (*p) | |
1182 h += (h << 7) + *p++; /* ??? revisit */ | |
1183 | |
1184 hash += ((unsigned int) SYMBOL_REF << 7) + h; | |
1185 return hash ? hash : (unsigned int) SYMBOL_REF; | |
1186 } | |
1187 | |
1188 case PRE_DEC: | |
1189 case PRE_INC: | |
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
|
1190 /* We can't compute these without knowing the MEM mode. */ |
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
|
1191 gcc_assert (memmode != VOIDmode); |
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
|
1192 i = GET_MODE_SIZE (memmode); |
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
|
1193 if (code == PRE_DEC) |
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
|
1194 i = -i; |
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
|
1195 /* Adjust the hash so that (mem:MEMMODE (pre_* (reg))) hashes |
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
|
1196 like (mem:MEMMODE (plus (reg) (const_int I))). */ |
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
|
1197 hash += (unsigned) PLUS - (unsigned)code |
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
|
1198 + cselib_hash_rtx (XEXP (x, 0), create, memmode) |
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
|
1199 + cselib_hash_rtx (GEN_INT (i), create, memmode); |
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
|
1200 return hash ? hash : 1 + (unsigned) PLUS; |
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
|
1201 |
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
|
1202 case PRE_MODIFY: |
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
|
1203 gcc_assert (memmode != VOIDmode); |
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
|
1204 return cselib_hash_rtx (XEXP (x, 1), create, memmode); |
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
|
1205 |
0 | 1206 case POST_DEC: |
1207 case POST_INC: | |
1208 case POST_MODIFY: | |
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
|
1209 gcc_assert (memmode != VOIDmode); |
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
|
1210 return cselib_hash_rtx (XEXP (x, 0), create, memmode); |
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
|
1211 |
0 | 1212 case PC: |
1213 case CC0: | |
1214 case CALL: | |
1215 case UNSPEC_VOLATILE: | |
1216 return 0; | |
1217 | |
1218 case ASM_OPERANDS: | |
1219 if (MEM_VOLATILE_P (x)) | |
1220 return 0; | |
1221 | |
1222 break; | |
1223 | |
1224 default: | |
1225 break; | |
1226 } | |
1227 | |
1228 i = GET_RTX_LENGTH (code) - 1; | |
1229 fmt = GET_RTX_FORMAT (code); | |
1230 for (; i >= 0; i--) | |
1231 { | |
1232 switch (fmt[i]) | |
1233 { | |
1234 case 'e': | |
1235 { | |
1236 rtx tem = XEXP (x, i); | |
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
|
1237 unsigned int tem_hash = cselib_hash_rtx (tem, create, memmode); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1238 |
0 | 1239 if (tem_hash == 0) |
1240 return 0; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1241 |
0 | 1242 hash += tem_hash; |
1243 } | |
1244 break; | |
1245 case 'E': | |
1246 for (j = 0; j < XVECLEN (x, i); j++) | |
1247 { | |
1248 unsigned int tem_hash | |
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
|
1249 = cselib_hash_rtx (XVECEXP (x, i, j), create, memmode); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1250 |
0 | 1251 if (tem_hash == 0) |
1252 return 0; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1253 |
0 | 1254 hash += tem_hash; |
1255 } | |
1256 break; | |
1257 | |
1258 case 's': | |
1259 { | |
1260 const unsigned char *p = (const unsigned char *) XSTR (x, i); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1261 |
0 | 1262 if (p) |
1263 while (*p) | |
1264 hash += *p++; | |
1265 break; | |
1266 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1267 |
0 | 1268 case 'i': |
1269 hash += XINT (x, i); | |
1270 break; | |
1271 | |
1272 case '0': | |
1273 case 't': | |
1274 /* unused */ | |
1275 break; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1276 |
0 | 1277 default: |
1278 gcc_unreachable (); | |
1279 } | |
1280 } | |
1281 | |
1282 return hash ? hash : 1 + (unsigned int) GET_CODE (x); | |
1283 } | |
1284 | |
1285 /* Create a new value structure for VALUE and initialize it. The mode of the | |
1286 value is MODE. */ | |
1287 | |
1288 static inline cselib_val * | |
111 | 1289 new_cselib_val (unsigned int hash, machine_mode mode, rtx x) |
0 | 1290 { |
111 | 1291 cselib_val *e = cselib_val_pool.allocate (); |
0 | 1292 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1293 gcc_assert (hash); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1294 gcc_assert (next_uid); |
0 | 1295 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1296 e->hash = hash; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1297 e->uid = next_uid++; |
0 | 1298 /* We use an alloc pool to allocate this RTL construct because it |
1299 accounts for about 8% of the overall memory usage. We know | |
1300 precisely when we can have VALUE RTXen (when cselib is active) | |
1301 so we don't need to put them in garbage collected memory. | |
1302 ??? Why should a VALUE be an RTX in the first place? */ | |
111 | 1303 e->val_rtx = (rtx_def*) value_pool.allocate (); |
0 | 1304 memset (e->val_rtx, 0, RTX_HDR_SIZE); |
1305 PUT_CODE (e->val_rtx, VALUE); | |
1306 PUT_MODE (e->val_rtx, mode); | |
1307 CSELIB_VAL_PTR (e->val_rtx) = e; | |
1308 e->addr_list = 0; | |
1309 e->locs = 0; | |
1310 e->next_containing_mem = 0; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1311 |
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
|
1312 if (dump_file && (dump_flags & TDF_CSELIB)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1313 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1314 fprintf (dump_file, "cselib value %u:%u ", e->uid, hash); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1315 if (flag_dump_noaddr || flag_dump_unnumbered) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1316 fputs ("# ", dump_file); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1317 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1318 fprintf (dump_file, "%p ", (void*)e); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1319 print_rtl_single (dump_file, x); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1320 fputc ('\n', dump_file); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1321 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1322 |
0 | 1323 return e; |
1324 } | |
1325 | |
1326 /* ADDR_ELT is a value that is used as address. MEM_ELT is the value that | |
1327 contains the data at this address. X is a MEM that represents the | |
1328 value. Update the two value structures to represent this situation. */ | |
1329 | |
1330 static void | |
1331 add_mem_for_addr (cselib_val *addr_elt, cselib_val *mem_elt, rtx x) | |
1332 { | |
111 | 1333 addr_elt = canonical_cselib_val (addr_elt); |
1334 mem_elt = canonical_cselib_val (mem_elt); | |
0 | 1335 |
1336 /* Avoid duplicates. */ | |
111 | 1337 addr_space_t as = MEM_ADDR_SPACE (x); |
1338 for (elt_loc_list *l = mem_elt->locs; l; l = l->next) | |
0 | 1339 if (MEM_P (l->loc) |
111 | 1340 && CSELIB_VAL_PTR (XEXP (l->loc, 0)) == addr_elt |
1341 && MEM_ADDR_SPACE (l->loc) == as) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1342 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1343 promote_debug_loc (l); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1344 return; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1345 } |
0 | 1346 |
1347 addr_elt->addr_list = new_elt_list (addr_elt->addr_list, mem_elt); | |
111 | 1348 new_elt_loc_list (mem_elt, |
1349 replace_equiv_address_nv (x, addr_elt->val_rtx)); | |
0 | 1350 if (mem_elt->next_containing_mem == NULL) |
1351 { | |
1352 mem_elt->next_containing_mem = first_containing_mem; | |
1353 first_containing_mem = mem_elt; | |
1354 } | |
1355 } | |
1356 | |
1357 /* Subroutine of cselib_lookup. Return a value for X, which is a MEM rtx. | |
1358 If CREATE, make a new one if we haven't seen it before. */ | |
1359 | |
1360 static cselib_val * | |
1361 cselib_lookup_mem (rtx x, int create) | |
1362 { | |
111 | 1363 machine_mode mode = GET_MODE (x); |
1364 machine_mode addr_mode; | |
1365 cselib_val **slot; | |
0 | 1366 cselib_val *addr; |
1367 cselib_val *mem_elt; | |
1368 | |
1369 if (MEM_VOLATILE_P (x) || mode == BLKmode | |
1370 || !cselib_record_memory | |
1371 || (FLOAT_MODE_P (mode) && flag_float_store)) | |
1372 return 0; | |
1373 | |
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
|
1374 addr_mode = GET_MODE (XEXP (x, 0)); |
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
|
1375 if (addr_mode == VOIDmode) |
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
|
1376 addr_mode = Pmode; |
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
|
1377 |
0 | 1378 /* Look up the value for the address. */ |
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
|
1379 addr = cselib_lookup (XEXP (x, 0), addr_mode, create, mode); |
0 | 1380 if (! addr) |
1381 return 0; | |
111 | 1382 addr = canonical_cselib_val (addr); |
0 | 1383 |
1384 /* Find a value that describes a value of our mode at that address. */ | |
111 | 1385 addr_space_t as = MEM_ADDR_SPACE (x); |
1386 for (elt_list *l = addr->addr_list; l; l = l->next) | |
0 | 1387 if (GET_MODE (l->elt->val_rtx) == mode) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1388 { |
111 | 1389 for (elt_loc_list *l2 = l->elt->locs; l2; l2 = l2->next) |
1390 if (MEM_P (l2->loc) && MEM_ADDR_SPACE (l2->loc) == as) | |
1391 { | |
1392 promote_debug_loc (l->elt->locs); | |
1393 return l->elt; | |
1394 } | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1395 } |
0 | 1396 |
1397 if (! create) | |
1398 return 0; | |
1399 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1400 mem_elt = new_cselib_val (next_uid, mode, x); |
0 | 1401 add_mem_for_addr (addr, mem_elt, x); |
111 | 1402 slot = cselib_find_slot (mode, x, mem_elt->hash, INSERT, VOIDmode); |
0 | 1403 *slot = mem_elt; |
1404 return mem_elt; | |
1405 } | |
1406 | |
111 | 1407 /* Search through the possible substitutions in P. We prefer a non reg |
0 | 1408 substitution because this allows us to expand the tree further. If |
1409 we find, just a reg, take the lowest regno. There may be several | |
1410 non-reg results, we just take the first one because they will all | |
1411 expand to the same place. */ | |
1412 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1413 static rtx |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1414 expand_loc (struct elt_loc_list *p, struct expand_value_data *evd, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1415 int max_depth) |
0 | 1416 { |
1417 rtx reg_result = NULL; | |
1418 unsigned int regno = UINT_MAX; | |
1419 struct elt_loc_list *p_in = p; | |
1420 | |
111 | 1421 for (; p; p = p->next) |
0 | 1422 { |
111 | 1423 /* Return these right away to avoid returning stack pointer based |
1424 expressions for frame pointer and vice versa, which is something | |
1425 that would confuse DSE. See the comment in cselib_expand_value_rtx_1 | |
1426 for more details. */ | |
1427 if (REG_P (p->loc) | |
1428 && (REGNO (p->loc) == STACK_POINTER_REGNUM | |
1429 || REGNO (p->loc) == FRAME_POINTER_REGNUM | |
1430 || REGNO (p->loc) == HARD_FRAME_POINTER_REGNUM | |
1431 || REGNO (p->loc) == cfa_base_preserved_regno)) | |
1432 return p->loc; | |
0 | 1433 /* Avoid infinite recursion trying to expand a reg into a |
1434 the same reg. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1435 if ((REG_P (p->loc)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1436 && (REGNO (p->loc) < regno) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1437 && !bitmap_bit_p (evd->regs_active, REGNO (p->loc))) |
0 | 1438 { |
1439 reg_result = p->loc; | |
1440 regno = REGNO (p->loc); | |
1441 } | |
1442 /* Avoid infinite recursion and do not try to expand the | |
1443 value. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1444 else if (GET_CODE (p->loc) == VALUE |
0 | 1445 && CSELIB_VAL_PTR (p->loc)->locs == p_in) |
1446 continue; | |
1447 else if (!REG_P (p->loc)) | |
1448 { | |
1449 rtx result, note; | |
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
|
1450 if (dump_file && (dump_flags & TDF_CSELIB)) |
0 | 1451 { |
1452 print_inline_rtx (dump_file, p->loc, 0); | |
1453 fprintf (dump_file, "\n"); | |
1454 } | |
1455 if (GET_CODE (p->loc) == LO_SUM | |
1456 && GET_CODE (XEXP (p->loc, 1)) == SYMBOL_REF | |
1457 && p->setting_insn | |
1458 && (note = find_reg_note (p->setting_insn, REG_EQUAL, NULL_RTX)) | |
1459 && XEXP (note, 0) == XEXP (p->loc, 1)) | |
1460 return XEXP (p->loc, 1); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1461 result = cselib_expand_value_rtx_1 (p->loc, evd, max_depth - 1); |
0 | 1462 if (result) |
1463 return result; | |
1464 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1465 |
0 | 1466 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1467 |
0 | 1468 if (regno != UINT_MAX) |
1469 { | |
1470 rtx result; | |
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
|
1471 if (dump_file && (dump_flags & TDF_CSELIB)) |
0 | 1472 fprintf (dump_file, "r%d\n", regno); |
1473 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1474 result = cselib_expand_value_rtx_1 (reg_result, evd, max_depth - 1); |
0 | 1475 if (result) |
1476 return result; | |
1477 } | |
1478 | |
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
|
1479 if (dump_file && (dump_flags & TDF_CSELIB)) |
0 | 1480 { |
1481 if (reg_result) | |
1482 { | |
1483 print_inline_rtx (dump_file, reg_result, 0); | |
1484 fprintf (dump_file, "\n"); | |
1485 } | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1486 else |
0 | 1487 fprintf (dump_file, "NULL\n"); |
1488 } | |
1489 return reg_result; | |
1490 } | |
1491 | |
1492 | |
1493 /* Forward substitute and expand an expression out to its roots. | |
1494 This is the opposite of common subexpression. Because local value | |
1495 numbering is such a weak optimization, the expanded expression is | |
1496 pretty much unique (not from a pointer equals point of view but | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1497 from a tree shape point of view. |
0 | 1498 |
1499 This function returns NULL if the expansion fails. The expansion | |
1500 will fail if there is no value number for one of the operands or if | |
1501 one of the operands has been overwritten between the current insn | |
1502 and the beginning of the basic block. For instance x has no | |
1503 expansion in: | |
1504 | |
1505 r1 <- r1 + 3 | |
1506 x <- r1 + 8 | |
1507 | |
1508 REGS_ACTIVE is a scratch bitmap that should be clear when passing in. | |
1509 It is clear on return. */ | |
1510 | |
1511 rtx | |
1512 cselib_expand_value_rtx (rtx orig, bitmap regs_active, int max_depth) | |
1513 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1514 struct expand_value_data evd; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1515 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1516 evd.regs_active = regs_active; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1517 evd.callback = NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1518 evd.callback_arg = NULL; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1519 evd.dummy = false; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1520 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1521 return cselib_expand_value_rtx_1 (orig, &evd, max_depth); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1522 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1523 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1524 /* Same as cselib_expand_value_rtx, but using a callback to try to |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1525 resolve some expressions. The CB function should return ORIG if it |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1526 can't or does not want to deal with a certain RTX. Any other |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1527 return value, including NULL, will be used as the expansion for |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1528 VALUE, without any further changes. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1529 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1530 rtx |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1531 cselib_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1532 cselib_expand_callback cb, void *data) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1533 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1534 struct expand_value_data evd; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1535 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1536 evd.regs_active = regs_active; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1537 evd.callback = cb; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1538 evd.callback_arg = data; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1539 evd.dummy = false; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1540 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1541 return cselib_expand_value_rtx_1 (orig, &evd, max_depth); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1542 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1543 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1544 /* Similar to cselib_expand_value_rtx_cb, but no rtxs are actually copied |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1545 or simplified. Useful to find out whether cselib_expand_value_rtx_cb |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1546 would return NULL or non-NULL, without allocating new rtx. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1547 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1548 bool |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1549 cselib_dummy_expand_value_rtx_cb (rtx orig, bitmap regs_active, int max_depth, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1550 cselib_expand_callback cb, void *data) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1551 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1552 struct expand_value_data evd; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1553 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1554 evd.regs_active = regs_active; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1555 evd.callback = cb; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1556 evd.callback_arg = data; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1557 evd.dummy = true; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1558 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1559 return cselib_expand_value_rtx_1 (orig, &evd, max_depth) != NULL; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1560 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1561 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1562 /* Internal implementation of cselib_expand_value_rtx and |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1563 cselib_expand_value_rtx_cb. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1564 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1565 static rtx |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1566 cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1567 int max_depth) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1568 { |
0 | 1569 rtx copy, scopy; |
1570 int i, j; | |
1571 RTX_CODE code; | |
1572 const char *format_ptr; | |
111 | 1573 machine_mode mode; |
0 | 1574 |
1575 code = GET_CODE (orig); | |
1576 | |
1577 /* For the context of dse, if we end up expand into a huge tree, we | |
1578 will not have a useful address, so we might as well just give up | |
1579 quickly. */ | |
1580 if (max_depth <= 0) | |
1581 return NULL; | |
1582 | |
1583 switch (code) | |
1584 { | |
1585 case REG: | |
1586 { | |
1587 struct elt_list *l = REG_VALUES (REGNO (orig)); | |
1588 | |
1589 if (l && l->elt == NULL) | |
1590 l = l->next; | |
1591 for (; l; l = l->next) | |
1592 if (GET_MODE (l->elt->val_rtx) == GET_MODE (orig)) | |
1593 { | |
1594 rtx result; | |
111 | 1595 unsigned regno = REGNO (orig); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1596 |
0 | 1597 /* The only thing that we are not willing to do (this |
1598 is requirement of dse and if others potential uses | |
1599 need this function we should add a parm to control | |
1600 it) is that we will not substitute the | |
1601 STACK_POINTER_REGNUM, FRAME_POINTER or the | |
1602 HARD_FRAME_POINTER. | |
1603 | |
1604 These expansions confuses the code that notices that | |
1605 stores into the frame go dead at the end of the | |
1606 function and that the frame is not effected by calls | |
1607 to subroutines. If you allow the | |
1608 STACK_POINTER_REGNUM substitution, then dse will | |
1609 think that parameter pushing also goes dead which is | |
1610 wrong. If you allow the FRAME_POINTER or the | |
1611 HARD_FRAME_POINTER then you lose the opportunity to | |
1612 make the frame assumptions. */ | |
1613 if (regno == STACK_POINTER_REGNUM | |
1614 || regno == FRAME_POINTER_REGNUM | |
111 | 1615 || regno == HARD_FRAME_POINTER_REGNUM |
1616 || regno == cfa_base_preserved_regno) | |
0 | 1617 return orig; |
1618 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1619 bitmap_set_bit (evd->regs_active, regno); |
0 | 1620 |
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
|
1621 if (dump_file && (dump_flags & TDF_CSELIB)) |
0 | 1622 fprintf (dump_file, "expanding: r%d into: ", regno); |
1623 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1624 result = expand_loc (l->elt->locs, evd, max_depth); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1625 bitmap_clear_bit (evd->regs_active, regno); |
0 | 1626 |
1627 if (result) | |
1628 return result; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1629 else |
0 | 1630 return orig; |
1631 } | |
111 | 1632 return orig; |
0 | 1633 } |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1634 |
111 | 1635 CASE_CONST_ANY: |
0 | 1636 case SYMBOL_REF: |
1637 case CODE_LABEL: | |
1638 case PC: | |
1639 case CC0: | |
1640 case SCRATCH: | |
1641 /* SCRATCH must be shared because they represent distinct values. */ | |
1642 return orig; | |
1643 case CLOBBER: | |
1644 if (REG_P (XEXP (orig, 0)) && HARD_REGISTER_NUM_P (REGNO (XEXP (orig, 0)))) | |
1645 return orig; | |
1646 break; | |
1647 | |
1648 case CONST: | |
1649 if (shared_const_p (orig)) | |
1650 return orig; | |
1651 break; | |
1652 | |
1653 case SUBREG: | |
1654 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1655 rtx subreg; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1656 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1657 if (evd->callback) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1658 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1659 subreg = evd->callback (orig, evd->regs_active, max_depth, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1660 evd->callback_arg); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1661 if (subreg != orig) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1662 return subreg; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1663 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1664 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1665 subreg = cselib_expand_value_rtx_1 (SUBREG_REG (orig), evd, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1666 max_depth - 1); |
0 | 1667 if (!subreg) |
1668 return NULL; | |
1669 scopy = simplify_gen_subreg (GET_MODE (orig), subreg, | |
1670 GET_MODE (SUBREG_REG (orig)), | |
1671 SUBREG_BYTE (orig)); | |
1672 if (scopy == NULL | |
1673 || (GET_CODE (scopy) == SUBREG | |
1674 && !REG_P (SUBREG_REG (scopy)) | |
1675 && !MEM_P (SUBREG_REG (scopy)))) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1676 return NULL; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1677 |
0 | 1678 return scopy; |
1679 } | |
1680 | |
1681 case VALUE: | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1682 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1683 rtx result; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1684 |
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
|
1685 if (dump_file && (dump_flags & TDF_CSELIB)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1686 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1687 fputs ("\nexpanding ", dump_file); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1688 print_rtl_single (dump_file, orig); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1689 fputs (" into...", dump_file); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1690 } |
0 | 1691 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1692 if (evd->callback) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1693 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1694 result = evd->callback (orig, evd->regs_active, max_depth, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1695 evd->callback_arg); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1696 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1697 if (result != orig) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1698 return result; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1699 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1700 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1701 result = expand_loc (CSELIB_VAL_PTR (orig)->locs, evd, max_depth); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1702 return result; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1703 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1704 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1705 case DEBUG_EXPR: |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1706 if (evd->callback) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1707 return evd->callback (orig, evd->regs_active, max_depth, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1708 evd->callback_arg); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1709 return orig; |
0 | 1710 |
1711 default: | |
1712 break; | |
1713 } | |
1714 | |
1715 /* Copy the various flags, fields, and other information. We assume | |
1716 that all fields need copying, and then clear the fields that should | |
1717 not be copied. That is the sensible default behavior, and forces | |
1718 us to explicitly document why we are *not* copying a flag. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1719 if (evd->dummy) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1720 copy = NULL; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1721 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1722 copy = shallow_copy_rtx (orig); |
0 | 1723 |
1724 format_ptr = GET_RTX_FORMAT (code); | |
1725 | |
1726 for (i = 0; i < GET_RTX_LENGTH (code); i++) | |
1727 switch (*format_ptr++) | |
1728 { | |
1729 case 'e': | |
1730 if (XEXP (orig, i) != NULL) | |
1731 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1732 rtx result = cselib_expand_value_rtx_1 (XEXP (orig, i), evd, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1733 max_depth - 1); |
0 | 1734 if (!result) |
1735 return NULL; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1736 if (copy) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1737 XEXP (copy, i) = result; |
0 | 1738 } |
1739 break; | |
1740 | |
1741 case 'E': | |
1742 case 'V': | |
1743 if (XVEC (orig, i) != NULL) | |
1744 { | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1745 if (copy) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1746 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1747 for (j = 0; j < XVECLEN (orig, i); j++) |
0 | 1748 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1749 rtx result = cselib_expand_value_rtx_1 (XVECEXP (orig, i, j), |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1750 evd, max_depth - 1); |
0 | 1751 if (!result) |
1752 return NULL; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1753 if (copy) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1754 XVECEXP (copy, i, j) = result; |
0 | 1755 } |
1756 } | |
1757 break; | |
1758 | |
1759 case 't': | |
1760 case 'w': | |
1761 case 'i': | |
1762 case 's': | |
1763 case 'S': | |
1764 case 'T': | |
1765 case 'u': | |
1766 case 'B': | |
1767 case '0': | |
1768 /* These are left unchanged. */ | |
1769 break; | |
1770 | |
1771 default: | |
1772 gcc_unreachable (); | |
1773 } | |
1774 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1775 if (evd->dummy) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1776 return orig; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1777 |
0 | 1778 mode = GET_MODE (copy); |
1779 /* If an operand has been simplified into CONST_INT, which doesn't | |
1780 have a mode and the mode isn't derivable from whole rtx's mode, | |
1781 try simplify_*_operation first with mode from original's operand | |
1782 and as a fallback wrap CONST_INT into gen_rtx_CONST. */ | |
1783 scopy = copy; | |
1784 switch (GET_RTX_CLASS (code)) | |
1785 { | |
1786 case RTX_UNARY: | |
1787 if (CONST_INT_P (XEXP (copy, 0)) | |
1788 && GET_MODE (XEXP (orig, 0)) != VOIDmode) | |
1789 { | |
1790 scopy = simplify_unary_operation (code, mode, XEXP (copy, 0), | |
1791 GET_MODE (XEXP (orig, 0))); | |
1792 if (scopy) | |
1793 return scopy; | |
1794 } | |
1795 break; | |
1796 case RTX_COMM_ARITH: | |
1797 case RTX_BIN_ARITH: | |
1798 /* These expressions can derive operand modes from the whole rtx's mode. */ | |
1799 break; | |
1800 case RTX_TERNARY: | |
1801 case RTX_BITFIELD_OPS: | |
1802 if (CONST_INT_P (XEXP (copy, 0)) | |
1803 && GET_MODE (XEXP (orig, 0)) != VOIDmode) | |
1804 { | |
1805 scopy = simplify_ternary_operation (code, mode, | |
1806 GET_MODE (XEXP (orig, 0)), | |
1807 XEXP (copy, 0), XEXP (copy, 1), | |
1808 XEXP (copy, 2)); | |
1809 if (scopy) | |
1810 return scopy; | |
1811 } | |
1812 break; | |
1813 case RTX_COMPARE: | |
1814 case RTX_COMM_COMPARE: | |
1815 if (CONST_INT_P (XEXP (copy, 0)) | |
1816 && GET_MODE (XEXP (copy, 1)) == VOIDmode | |
1817 && (GET_MODE (XEXP (orig, 0)) != VOIDmode | |
1818 || GET_MODE (XEXP (orig, 1)) != VOIDmode)) | |
1819 { | |
1820 scopy = simplify_relational_operation (code, mode, | |
1821 (GET_MODE (XEXP (orig, 0)) | |
1822 != VOIDmode) | |
1823 ? GET_MODE (XEXP (orig, 0)) | |
1824 : GET_MODE (XEXP (orig, 1)), | |
1825 XEXP (copy, 0), | |
1826 XEXP (copy, 1)); | |
1827 if (scopy) | |
1828 return scopy; | |
1829 } | |
1830 break; | |
1831 default: | |
1832 break; | |
1833 } | |
1834 scopy = simplify_rtx (copy); | |
1835 if (scopy) | |
1836 return scopy; | |
1837 return copy; | |
1838 } | |
1839 | |
1840 /* Walk rtx X and replace all occurrences of REG and MEM subexpressions | |
1841 with VALUE expressions. This way, it becomes independent of changes | |
1842 to registers and memory. | |
1843 X isn't actually modified; if modifications are needed, new rtl is | |
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
|
1844 allocated. However, the return value can share rtl with X. |
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
|
1845 If X is within a MEM, MEMMODE must be the mode of the MEM. */ |
0 | 1846 |
1847 rtx | |
111 | 1848 cselib_subst_to_values (rtx x, machine_mode memmode) |
0 | 1849 { |
1850 enum rtx_code code = GET_CODE (x); | |
1851 const char *fmt = GET_RTX_FORMAT (code); | |
1852 cselib_val *e; | |
1853 struct elt_list *l; | |
1854 rtx copy = x; | |
1855 int i; | |
1856 | |
1857 switch (code) | |
1858 { | |
1859 case REG: | |
1860 l = REG_VALUES (REGNO (x)); | |
1861 if (l && l->elt == NULL) | |
1862 l = l->next; | |
1863 for (; l; l = l->next) | |
1864 if (GET_MODE (l->elt->val_rtx) == GET_MODE (x)) | |
1865 return l->elt->val_rtx; | |
1866 | |
1867 gcc_unreachable (); | |
1868 | |
1869 case MEM: | |
1870 e = cselib_lookup_mem (x, 0); | |
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
|
1871 /* This used to happen for autoincrements, but we deal with them |
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
|
1872 properly now. Remove the if stmt for the next release. */ |
0 | 1873 if (! e) |
1874 { | |
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
|
1875 /* Assign a value that doesn't match any other. */ |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1876 e = new_cselib_val (next_uid, GET_MODE (x), x); |
0 | 1877 } |
1878 return e->val_rtx; | |
1879 | |
111 | 1880 case ENTRY_VALUE: |
1881 e = cselib_lookup (x, GET_MODE (x), 0, memmode); | |
1882 if (! e) | |
1883 break; | |
1884 return e->val_rtx; | |
1885 | |
1886 CASE_CONST_ANY: | |
0 | 1887 return x; |
1888 | |
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
|
1889 case PRE_DEC: |
0 | 1890 case PRE_INC: |
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
|
1891 gcc_assert (memmode != VOIDmode); |
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
|
1892 i = GET_MODE_SIZE (memmode); |
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
|
1893 if (code == PRE_DEC) |
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
|
1894 i = -i; |
111 | 1895 return cselib_subst_to_values (plus_constant (GET_MODE (x), |
1896 XEXP (x, 0), i), | |
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
|
1897 memmode); |
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
|
1898 |
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
|
1899 case PRE_MODIFY: |
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
|
1900 gcc_assert (memmode != VOIDmode); |
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
|
1901 return cselib_subst_to_values (XEXP (x, 1), memmode); |
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
|
1902 |
0 | 1903 case POST_DEC: |
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
|
1904 case POST_INC: |
0 | 1905 case POST_MODIFY: |
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
|
1906 gcc_assert (memmode != VOIDmode); |
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
|
1907 return cselib_subst_to_values (XEXP (x, 0), memmode); |
0 | 1908 |
1909 default: | |
1910 break; | |
1911 } | |
1912 | |
1913 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | |
1914 { | |
1915 if (fmt[i] == 'e') | |
1916 { | |
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
|
1917 rtx t = cselib_subst_to_values (XEXP (x, i), memmode); |
0 | 1918 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1919 if (t != XEXP (x, i)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1920 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1921 if (x == copy) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1922 copy = shallow_copy_rtx (x); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1923 XEXP (copy, i) = t; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1924 } |
0 | 1925 } |
1926 else if (fmt[i] == 'E') | |
1927 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1928 int j; |
0 | 1929 |
1930 for (j = 0; j < XVECLEN (x, i); j++) | |
1931 { | |
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
|
1932 rtx t = cselib_subst_to_values (XVECEXP (x, i, j), memmode); |
0 | 1933 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1934 if (t != XVECEXP (x, i, j)) |
0 | 1935 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1936 if (XVEC (x, i) == XVEC (copy, i)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1937 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1938 if (x == copy) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1939 copy = shallow_copy_rtx (x); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1940 XVEC (copy, i) = shallow_copy_rtvec (XVEC (x, i)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1941 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
1942 XVECEXP (copy, i, j) = t; |
0 | 1943 } |
1944 } | |
1945 } | |
1946 } | |
1947 | |
1948 return copy; | |
1949 } | |
1950 | |
111 | 1951 /* Wrapper for cselib_subst_to_values, that indicates X is in INSN. */ |
1952 | |
1953 rtx | |
1954 cselib_subst_to_values_from_insn (rtx x, machine_mode memmode, rtx_insn *insn) | |
1955 { | |
1956 rtx ret; | |
1957 gcc_assert (!cselib_current_insn); | |
1958 cselib_current_insn = insn; | |
1959 ret = cselib_subst_to_values (x, memmode); | |
1960 cselib_current_insn = NULL; | |
1961 return ret; | |
1962 } | |
1963 | |
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
|
1964 /* Look up the rtl expression X in our tables and return the value it |
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
|
1965 has. If CREATE is zero, we return NULL if we don't know the value. |
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
|
1966 Otherwise, we create a new one if possible, using mode MODE if X |
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
|
1967 doesn't have a mode (i.e. because it's a constant). When X is part |
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
|
1968 of an address, MEMMODE should be the mode of the enclosing MEM if |
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
|
1969 we're tracking autoinc expressions. */ |
0 | 1970 |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1971 static cselib_val * |
111 | 1972 cselib_lookup_1 (rtx x, machine_mode mode, |
1973 int create, machine_mode memmode) | |
0 | 1974 { |
111 | 1975 cselib_val **slot; |
0 | 1976 cselib_val *e; |
1977 unsigned int hashval; | |
1978 | |
1979 if (GET_MODE (x) != VOIDmode) | |
1980 mode = GET_MODE (x); | |
1981 | |
1982 if (GET_CODE (x) == VALUE) | |
1983 return CSELIB_VAL_PTR (x); | |
1984 | |
1985 if (REG_P (x)) | |
1986 { | |
1987 struct elt_list *l; | |
1988 unsigned int i = REGNO (x); | |
1989 | |
1990 l = REG_VALUES (i); | |
1991 if (l && l->elt == NULL) | |
1992 l = l->next; | |
1993 for (; l; l = l->next) | |
1994 if (mode == GET_MODE (l->elt->val_rtx)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1995 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1996 promote_debug_loc (l->elt->locs); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1997 return l->elt; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
1998 } |
0 | 1999 |
2000 if (! create) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2001 return 0; |
0 | 2002 |
2003 if (i < FIRST_PSEUDO_REGISTER) | |
2004 { | |
111 | 2005 unsigned int n = hard_regno_nregs (i, mode); |
0 | 2006 |
2007 if (n > max_value_regs) | |
2008 max_value_regs = n; | |
2009 } | |
2010 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2011 e = new_cselib_val (next_uid, GET_MODE (x), x); |
111 | 2012 new_elt_loc_list (e, x); |
2013 | |
2014 scalar_int_mode int_mode; | |
0 | 2015 if (REG_VALUES (i) == 0) |
2016 { | |
2017 /* Maintain the invariant that the first entry of | |
2018 REG_VALUES, if present, must be the value used to set the | |
2019 register, or NULL. */ | |
2020 used_regs[n_used_regs++] = i; | |
2021 REG_VALUES (i) = new_elt_list (REG_VALUES (i), NULL); | |
2022 } | |
111 | 2023 else if (cselib_preserve_constants |
2024 && is_int_mode (mode, &int_mode)) | |
2025 { | |
2026 /* During var-tracking, try harder to find equivalences | |
2027 for SUBREGs. If a setter sets say a DImode register | |
2028 and user uses that register only in SImode, add a lowpart | |
2029 subreg location. */ | |
2030 struct elt_list *lwider = NULL; | |
2031 scalar_int_mode lmode; | |
2032 l = REG_VALUES (i); | |
2033 if (l && l->elt == NULL) | |
2034 l = l->next; | |
2035 for (; l; l = l->next) | |
2036 if (is_int_mode (GET_MODE (l->elt->val_rtx), &lmode) | |
2037 && GET_MODE_SIZE (lmode) > GET_MODE_SIZE (int_mode) | |
2038 && (lwider == NULL | |
2039 || partial_subreg_p (lmode, | |
2040 GET_MODE (lwider->elt->val_rtx)))) | |
2041 { | |
2042 struct elt_loc_list *el; | |
2043 if (i < FIRST_PSEUDO_REGISTER | |
2044 && hard_regno_nregs (i, lmode) != 1) | |
2045 continue; | |
2046 for (el = l->elt->locs; el; el = el->next) | |
2047 if (!REG_P (el->loc)) | |
2048 break; | |
2049 if (el) | |
2050 lwider = l; | |
2051 } | |
2052 if (lwider) | |
2053 { | |
2054 rtx sub = lowpart_subreg (int_mode, lwider->elt->val_rtx, | |
2055 GET_MODE (lwider->elt->val_rtx)); | |
2056 if (sub) | |
2057 new_elt_loc_list (e, sub); | |
2058 } | |
2059 } | |
0 | 2060 REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e); |
111 | 2061 slot = cselib_find_slot (mode, x, e->hash, INSERT, memmode); |
0 | 2062 *slot = e; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2063 return e; |
0 | 2064 } |
2065 | |
2066 if (MEM_P (x)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2067 return cselib_lookup_mem (x, create); |
0 | 2068 |
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
|
2069 hashval = cselib_hash_rtx (x, create, memmode); |
0 | 2070 /* Can't even create if hashing is not possible. */ |
2071 if (! hashval) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2072 return 0; |
0 | 2073 |
111 | 2074 slot = cselib_find_slot (mode, x, hashval, |
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
|
2075 create ? INSERT : NO_INSERT, memmode); |
0 | 2076 if (slot == 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
|
2077 return 0; |
0 | 2078 |
2079 e = (cselib_val *) *slot; | |
2080 if (e) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2081 return e; |
0 | 2082 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2083 e = new_cselib_val (hashval, mode, x); |
0 | 2084 |
2085 /* We have to fill the slot before calling cselib_subst_to_values: | |
2086 the hash table is inconsistent until we do so, and | |
2087 cselib_subst_to_values will need to do lookups. */ | |
111 | 2088 *slot = e; |
2089 new_elt_loc_list (e, cselib_subst_to_values (x, memmode)); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2090 return e; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2091 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2092 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2093 /* Wrapper for cselib_lookup, that indicates X is in INSN. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2094 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2095 cselib_val * |
111 | 2096 cselib_lookup_from_insn (rtx x, machine_mode mode, |
2097 int create, machine_mode memmode, rtx_insn *insn) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2098 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2099 cselib_val *ret; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2100 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2101 gcc_assert (!cselib_current_insn); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2102 cselib_current_insn = insn; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2103 |
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
|
2104 ret = cselib_lookup (x, mode, create, memmode); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2105 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2106 cselib_current_insn = NULL; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2107 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2108 return ret; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2109 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2110 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2111 /* Wrapper for cselib_lookup_1, that logs the lookup result and |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2112 maintains invariants related with debug insns. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2113 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2114 cselib_val * |
111 | 2115 cselib_lookup (rtx x, machine_mode mode, |
2116 int create, machine_mode memmode) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2117 { |
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
|
2118 cselib_val *ret = cselib_lookup_1 (x, mode, create, memmode); |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2119 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2120 /* ??? Should we return NULL if we're not to create an entry, the |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2121 found loc is a debug loc and cselib_current_insn is not DEBUG? |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2122 If so, we should also avoid converting val to non-DEBUG; probably |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2123 easiest setting cselib_current_insn to NULL before the call |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2124 above. */ |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2125 |
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
|
2126 if (dump_file && (dump_flags & TDF_CSELIB)) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2127 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2128 fputs ("cselib lookup ", dump_file); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2129 print_inline_rtx (dump_file, x, 2); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2130 fprintf (dump_file, " => %u:%u\n", |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2131 ret ? ret->uid : 0, |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2132 ret ? ret->hash : 0); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2133 } |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2134 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2135 return ret; |
0 | 2136 } |
2137 | |
2138 /* Invalidate any entries in reg_values that overlap REGNO. This is called | |
2139 if REGNO is changing. MODE is the mode of the assignment to REGNO, which | |
2140 is used to determine how many hard registers are being changed. If MODE | |
2141 is VOIDmode, then only REGNO is being changed; this is used when | |
2142 invalidating call clobbered registers across a call. */ | |
2143 | |
2144 static void | |
111 | 2145 cselib_invalidate_regno (unsigned int regno, machine_mode mode) |
0 | 2146 { |
2147 unsigned int endregno; | |
2148 unsigned int i; | |
2149 | |
2150 /* If we see pseudos after reload, something is _wrong_. */ | |
2151 gcc_assert (!reload_completed || regno < FIRST_PSEUDO_REGISTER | |
2152 || reg_renumber[regno] < 0); | |
2153 | |
2154 /* Determine the range of registers that must be invalidated. For | |
2155 pseudos, only REGNO is affected. For hard regs, we must take MODE | |
2156 into account, and we must also invalidate lower register numbers | |
2157 if they contain values that overlap REGNO. */ | |
2158 if (regno < FIRST_PSEUDO_REGISTER) | |
2159 { | |
2160 gcc_assert (mode != VOIDmode); | |
2161 | |
2162 if (regno < max_value_regs) | |
2163 i = 0; | |
2164 else | |
2165 i = regno - max_value_regs; | |
2166 | |
2167 endregno = end_hard_regno (mode, regno); | |
2168 } | |
2169 else | |
2170 { | |
2171 i = regno; | |
2172 endregno = regno + 1; | |
2173 } | |
2174 | |
2175 for (; i < endregno; i++) | |
2176 { | |
2177 struct elt_list **l = ®_VALUES (i); | |
2178 | |
2179 /* Go through all known values for this reg; if it overlaps the range | |
2180 we're invalidating, remove the value. */ | |
2181 while (*l) | |
2182 { | |
2183 cselib_val *v = (*l)->elt; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2184 bool had_locs; |
111 | 2185 rtx_insn *setting_insn; |
0 | 2186 struct elt_loc_list **p; |
2187 unsigned int this_last = i; | |
2188 | |
2189 if (i < FIRST_PSEUDO_REGISTER && v != NULL) | |
2190 this_last = end_hard_regno (GET_MODE (v->val_rtx), i) - 1; | |
2191 | |
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
|
2192 if (this_last < regno || v == NULL |
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
|
2193 || (v == cfa_base_preserved_val |
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
|
2194 && i == cfa_base_preserved_regno)) |
0 | 2195 { |
2196 l = &(*l)->next; | |
2197 continue; | |
2198 } | |
2199 | |
2200 /* We have an overlap. */ | |
2201 if (*l == REG_VALUES (i)) | |
2202 { | |
2203 /* Maintain the invariant that the first entry of | |
2204 REG_VALUES, if present, must be the value used to set | |
2205 the register, or NULL. This is also nice because | |
2206 then we won't push the same regno onto user_regs | |
2207 multiple times. */ | |
2208 (*l)->elt = NULL; | |
2209 l = &(*l)->next; | |
2210 } | |
2211 else | |
2212 unchain_one_elt_list (l); | |
2213 | |
111 | 2214 v = canonical_cselib_val (v); |
2215 | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2216 had_locs = v->locs != NULL; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2217 setting_insn = v->locs ? v->locs->setting_insn : NULL; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2218 |
0 | 2219 /* Now, we clear the mapping from value to reg. It must exist, so |
2220 this code will crash intentionally if it doesn't. */ | |
2221 for (p = &v->locs; ; p = &(*p)->next) | |
2222 { | |
2223 rtx x = (*p)->loc; | |
2224 | |
2225 if (REG_P (x) && REGNO (x) == i) | |
2226 { | |
2227 unchain_one_elt_loc_list (p); | |
2228 break; | |
2229 } | |
2230 } | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2231 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2232 if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2233 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2234 if (setting_insn && DEBUG_INSN_P (setting_insn)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2235 n_useless_debug_values++; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2236 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2237 n_useless_values++; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2238 } |
0 | 2239 } |
2240 } | |
2241 } | |
2242 | |
2243 /* Invalidate any locations in the table which are changed because of a | |
2244 store to MEM_RTX. If this is called because of a non-const call | |
2245 instruction, MEM_RTX is (mem:BLK const0_rtx). */ | |
2246 | |
2247 static void | |
2248 cselib_invalidate_mem (rtx mem_rtx) | |
2249 { | |
2250 cselib_val **vp, *v, *next; | |
2251 int num_mems = 0; | |
2252 rtx mem_addr; | |
2253 | |
2254 mem_addr = canon_rtx (get_addr (XEXP (mem_rtx, 0))); | |
2255 mem_rtx = canon_rtx (mem_rtx); | |
2256 | |
2257 vp = &first_containing_mem; | |
2258 for (v = *vp; v != &dummy_val; v = next) | |
2259 { | |
2260 bool has_mem = false; | |
2261 struct elt_loc_list **p = &v->locs; | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2262 bool had_locs = v->locs != NULL; |
111 | 2263 rtx_insn *setting_insn = v->locs ? v->locs->setting_insn : NULL; |
0 | 2264 |
2265 while (*p) | |
2266 { | |
2267 rtx x = (*p)->loc; | |
2268 cselib_val *addr; | |
2269 struct elt_list **mem_chain; | |
2270 | |
2271 /* MEMs may occur in locations only at the top level; below | |
2272 that every MEM or REG is substituted by its VALUE. */ | |
2273 if (!MEM_P (x)) | |
2274 { | |
2275 p = &(*p)->next; | |
2276 continue; | |
2277 } | |
2278 if (num_mems < PARAM_VALUE (PARAM_MAX_CSELIB_MEMORY_LOCATIONS) | |
111 | 2279 && ! canon_anti_dependence (x, false, mem_rtx, |
2280 GET_MODE (mem_rtx), mem_addr)) | |
0 | 2281 { |
2282 has_mem = true; | |
2283 num_mems++; | |
2284 p = &(*p)->next; | |
2285 continue; | |
2286 } | |
2287 | |
2288 /* This one overlaps. */ | |
2289 /* We must have a mapping from this MEM's address to the | |
2290 value (E). Remove that, too. */ | |
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
|
2291 addr = cselib_lookup (XEXP (x, 0), VOIDmode, 0, GET_MODE (x)); |
111 | 2292 addr = canonical_cselib_val (addr); |
2293 gcc_checking_assert (v == canonical_cselib_val (v)); | |
0 | 2294 mem_chain = &addr->addr_list; |
2295 for (;;) | |
2296 { | |
111 | 2297 cselib_val *canon = canonical_cselib_val ((*mem_chain)->elt); |
2298 | |
2299 if (canon == v) | |
0 | 2300 { |
2301 unchain_one_elt_list (mem_chain); | |
2302 break; | |
2303 } | |
2304 | |
111 | 2305 /* Record canonicalized elt. */ |
2306 (*mem_chain)->elt = canon; | |
2307 | |
0 | 2308 mem_chain = &(*mem_chain)->next; |
2309 } | |
2310 | |
2311 unchain_one_elt_loc_list (p); | |
2312 } | |
2313 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2314 if (had_locs && v->locs == 0 && !PRESERVED_VALUE_P (v->val_rtx)) |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2315 { |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2316 if (setting_insn && DEBUG_INSN_P (setting_insn)) |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2317 n_useless_debug_values++; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2318 else |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2319 n_useless_values++; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2320 } |
0 | 2321 |
2322 next = v->next_containing_mem; | |
2323 if (has_mem) | |
2324 { | |
2325 *vp = v; | |
2326 vp = &(*vp)->next_containing_mem; | |
2327 } | |
2328 else | |
2329 v->next_containing_mem = NULL; | |
2330 } | |
2331 *vp = &dummy_val; | |
2332 } | |
2333 | |
2334 /* Invalidate DEST, which is being assigned to or clobbered. */ | |
2335 | |
2336 void | |
2337 cselib_invalidate_rtx (rtx dest) | |
2338 { | |
2339 while (GET_CODE (dest) == SUBREG | |
2340 || GET_CODE (dest) == ZERO_EXTRACT | |
2341 || GET_CODE (dest) == STRICT_LOW_PART) | |
2342 dest = XEXP (dest, 0); | |
2343 | |
2344 if (REG_P (dest)) | |
2345 cselib_invalidate_regno (REGNO (dest), GET_MODE (dest)); | |
2346 else if (MEM_P (dest)) | |
2347 cselib_invalidate_mem (dest); | |
2348 } | |
2349 | |
2350 /* A wrapper for cselib_invalidate_rtx to be called via note_stores. */ | |
2351 | |
2352 static void | |
2353 cselib_invalidate_rtx_note_stores (rtx dest, const_rtx ignore ATTRIBUTE_UNUSED, | |
2354 void *data ATTRIBUTE_UNUSED) | |
2355 { | |
2356 cselib_invalidate_rtx (dest); | |
2357 } | |
2358 | |
2359 /* Record the result of a SET instruction. DEST is being set; the source | |
2360 contains the value described by SRC_ELT. If DEST is a MEM, DEST_ADDR_ELT | |
2361 describes its address. */ | |
2362 | |
2363 static void | |
2364 cselib_record_set (rtx dest, cselib_val *src_elt, cselib_val *dest_addr_elt) | |
2365 { | |
2366 if (src_elt == 0 || side_effects_p (dest)) | |
2367 return; | |
2368 | |
111 | 2369 if (REG_P (dest)) |
0 | 2370 { |
111 | 2371 unsigned int dreg = REGNO (dest); |
0 | 2372 if (dreg < FIRST_PSEUDO_REGISTER) |
2373 { | |
111 | 2374 unsigned int n = REG_NREGS (dest); |
0 | 2375 |
2376 if (n > max_value_regs) | |
2377 max_value_regs = n; | |
2378 } | |
2379 | |
2380 if (REG_VALUES (dreg) == 0) | |
2381 { | |
2382 used_regs[n_used_regs++] = dreg; | |
2383 REG_VALUES (dreg) = new_elt_list (REG_VALUES (dreg), src_elt); | |
2384 } | |
2385 else | |
2386 { | |
2387 /* The register should have been invalidated. */ | |
2388 gcc_assert (REG_VALUES (dreg)->elt == 0); | |
2389 REG_VALUES (dreg)->elt = src_elt; | |
2390 } | |
2391 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2392 if (src_elt->locs == 0 && !PRESERVED_VALUE_P (src_elt->val_rtx)) |
0 | 2393 n_useless_values--; |
111 | 2394 new_elt_loc_list (src_elt, dest); |
0 | 2395 } |
2396 else if (MEM_P (dest) && dest_addr_elt != 0 | |
2397 && cselib_record_memory) | |
2398 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2399 if (src_elt->locs == 0 && !PRESERVED_VALUE_P (src_elt->val_rtx)) |
0 | 2400 n_useless_values--; |
2401 add_mem_for_addr (dest_addr_elt, src_elt, dest); | |
2402 } | |
2403 } | |
2404 | |
111 | 2405 /* Make ELT and X's VALUE equivalent to each other at INSN. */ |
2406 | |
2407 void | |
2408 cselib_add_permanent_equiv (cselib_val *elt, rtx x, rtx_insn *insn) | |
2409 { | |
2410 cselib_val *nelt; | |
2411 rtx_insn *save_cselib_current_insn = cselib_current_insn; | |
2412 | |
2413 gcc_checking_assert (elt); | |
2414 gcc_checking_assert (PRESERVED_VALUE_P (elt->val_rtx)); | |
2415 gcc_checking_assert (!side_effects_p (x)); | |
2416 | |
2417 cselib_current_insn = insn; | |
2418 | |
2419 nelt = cselib_lookup (x, GET_MODE (elt->val_rtx), 1, VOIDmode); | |
2420 | |
2421 if (nelt != elt) | |
2422 { | |
2423 cselib_any_perm_equivs = true; | |
2424 | |
2425 if (!PRESERVED_VALUE_P (nelt->val_rtx)) | |
2426 cselib_preserve_value (nelt); | |
2427 | |
2428 new_elt_loc_list (nelt, elt->val_rtx); | |
2429 } | |
2430 | |
2431 cselib_current_insn = save_cselib_current_insn; | |
2432 } | |
2433 | |
2434 /* Return TRUE if any permanent equivalences have been recorded since | |
2435 the table was last initialized. */ | |
2436 bool | |
2437 cselib_have_permanent_equivalences (void) | |
2438 { | |
2439 return cselib_any_perm_equivs; | |
2440 } | |
2441 | |
0 | 2442 /* There is no good way to determine how many elements there can be |
2443 in a PARALLEL. Since it's fairly cheap, use a really large number. */ | |
2444 #define MAX_SETS (FIRST_PSEUDO_REGISTER * 2) | |
2445 | |
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
|
2446 struct cselib_record_autoinc_data |
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
|
2447 { |
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
|
2448 struct cselib_set *sets; |
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
|
2449 int n_sets; |
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
|
2450 }; |
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
|
2451 |
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
|
2452 /* Callback for for_each_inc_dec. Records in ARG the SETs implied by |
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
|
2453 autoinc RTXs: SRC plus SRCOFF if non-NULL is stored in DEST. */ |
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
|
2454 |
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
|
2455 static int |
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
|
2456 cselib_record_autoinc_cb (rtx mem ATTRIBUTE_UNUSED, rtx op ATTRIBUTE_UNUSED, |
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
|
2457 rtx dest, rtx src, rtx srcoff, void *arg) |
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
|
2458 { |
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
|
2459 struct cselib_record_autoinc_data *data; |
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
|
2460 data = (struct cselib_record_autoinc_data *)arg; |
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
|
2461 |
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
|
2462 data->sets[data->n_sets].dest = dest; |
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
|
2463 |
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
|
2464 if (srcoff) |
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
|
2465 data->sets[data->n_sets].src = gen_rtx_PLUS (GET_MODE (src), src, srcoff); |
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
|
2466 else |
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
|
2467 data->sets[data->n_sets].src = src; |
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
|
2468 |
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
|
2469 data->n_sets++; |
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
|
2470 |
111 | 2471 return 0; |
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
|
2472 } |
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
|
2473 |
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
|
2474 /* Record the effects of any sets and autoincs in INSN. */ |
0 | 2475 static void |
111 | 2476 cselib_record_sets (rtx_insn *insn) |
0 | 2477 { |
2478 int n_sets = 0; | |
2479 int i; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2480 struct cselib_set sets[MAX_SETS]; |
0 | 2481 rtx body = PATTERN (insn); |
2482 rtx cond = 0; | |
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
|
2483 int n_sets_before_autoinc; |
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
|
2484 struct cselib_record_autoinc_data data; |
0 | 2485 |
2486 body = PATTERN (insn); | |
2487 if (GET_CODE (body) == COND_EXEC) | |
2488 { | |
2489 cond = COND_EXEC_TEST (body); | |
2490 body = COND_EXEC_CODE (body); | |
2491 } | |
2492 | |
2493 /* Find all sets. */ | |
2494 if (GET_CODE (body) == SET) | |
2495 { | |
2496 sets[0].src = SET_SRC (body); | |
2497 sets[0].dest = SET_DEST (body); | |
2498 n_sets = 1; | |
2499 } | |
2500 else if (GET_CODE (body) == PARALLEL) | |
2501 { | |
2502 /* Look through the PARALLEL and record the values being | |
2503 set, if possible. Also handle any CLOBBERs. */ | |
2504 for (i = XVECLEN (body, 0) - 1; i >= 0; --i) | |
2505 { | |
2506 rtx x = XVECEXP (body, 0, i); | |
2507 | |
2508 if (GET_CODE (x) == SET) | |
2509 { | |
2510 sets[n_sets].src = SET_SRC (x); | |
2511 sets[n_sets].dest = SET_DEST (x); | |
2512 n_sets++; | |
2513 } | |
2514 } | |
2515 } | |
2516 | |
2517 if (n_sets == 1 | |
2518 && MEM_P (sets[0].src) | |
2519 && !cselib_record_memory | |
2520 && MEM_READONLY_P (sets[0].src)) | |
2521 { | |
2522 rtx note = find_reg_equal_equiv_note (insn); | |
2523 | |
2524 if (note && CONSTANT_P (XEXP (note, 0))) | |
2525 sets[0].src = XEXP (note, 0); | |
2526 } | |
2527 | |
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
|
2528 data.sets = sets; |
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
|
2529 data.n_sets = n_sets_before_autoinc = n_sets; |
111 | 2530 for_each_inc_dec (PATTERN (insn), cselib_record_autoinc_cb, &data); |
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
|
2531 n_sets = data.n_sets; |
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
|
2532 |
0 | 2533 /* Look up the values that are read. Do this before invalidating the |
2534 locations that are written. */ | |
2535 for (i = 0; i < n_sets; i++) | |
2536 { | |
2537 rtx dest = sets[i].dest; | |
2538 | |
2539 /* A STRICT_LOW_PART can be ignored; we'll record the equivalence for | |
2540 the low part after invalidating any knowledge about larger modes. */ | |
2541 if (GET_CODE (sets[i].dest) == STRICT_LOW_PART) | |
2542 sets[i].dest = dest = XEXP (dest, 0); | |
2543 | |
2544 /* We don't know how to record anything but REG or MEM. */ | |
2545 if (REG_P (dest) | |
2546 || (MEM_P (dest) && cselib_record_memory)) | |
2547 { | |
2548 rtx src = sets[i].src; | |
2549 if (cond) | |
2550 src = gen_rtx_IF_THEN_ELSE (GET_MODE (dest), cond, src, dest); | |
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
|
2551 sets[i].src_elt = cselib_lookup (src, GET_MODE (dest), 1, VOIDmode); |
0 | 2552 if (MEM_P (dest)) |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2553 { |
111 | 2554 machine_mode address_mode = get_address_mode (dest); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2555 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2556 sets[i].dest_addr_elt = cselib_lookup (XEXP (dest, 0), |
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
|
2557 address_mode, 1, |
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
|
2558 GET_MODE (dest)); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2559 } |
0 | 2560 else |
2561 sets[i].dest_addr_elt = 0; | |
2562 } | |
2563 } | |
2564 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2565 if (cselib_record_sets_hook) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2566 cselib_record_sets_hook (insn, sets, n_sets); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2567 |
0 | 2568 /* Invalidate all locations written by this insn. Note that the elts we |
2569 looked up in the previous loop aren't affected, just some of their | |
2570 locations may go away. */ | |
2571 note_stores (body, cselib_invalidate_rtx_note_stores, NULL); | |
2572 | |
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
|
2573 for (i = n_sets_before_autoinc; i < n_sets; i++) |
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
|
2574 cselib_invalidate_rtx (sets[i].dest); |
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
|
2575 |
0 | 2576 /* If this is an asm, look for duplicate sets. This can happen when the |
2577 user uses the same value as an output multiple times. This is valid | |
2578 if the outputs are not actually used thereafter. Treat this case as | |
2579 if the value isn't actually set. We do this by smashing the destination | |
2580 to pc_rtx, so that we won't record the value later. */ | |
2581 if (n_sets >= 2 && asm_noperands (body) >= 0) | |
2582 { | |
2583 for (i = 0; i < n_sets; i++) | |
2584 { | |
2585 rtx dest = sets[i].dest; | |
2586 if (REG_P (dest) || MEM_P (dest)) | |
2587 { | |
2588 int j; | |
2589 for (j = i + 1; j < n_sets; j++) | |
2590 if (rtx_equal_p (dest, sets[j].dest)) | |
2591 { | |
2592 sets[i].dest = pc_rtx; | |
2593 sets[j].dest = pc_rtx; | |
2594 } | |
2595 } | |
2596 } | |
2597 } | |
2598 | |
2599 /* Now enter the equivalences in our tables. */ | |
2600 for (i = 0; i < n_sets; i++) | |
2601 { | |
2602 rtx dest = sets[i].dest; | |
2603 if (REG_P (dest) | |
2604 || (MEM_P (dest) && cselib_record_memory)) | |
2605 cselib_record_set (dest, sets[i].src_elt, sets[i].dest_addr_elt); | |
2606 } | |
2607 } | |
2608 | |
111 | 2609 /* Return true if INSN in the prologue initializes hard_frame_pointer_rtx. */ |
2610 | |
2611 bool | |
2612 fp_setter_insn (rtx_insn *insn) | |
2613 { | |
2614 rtx expr, pat = NULL_RTX; | |
2615 | |
2616 if (!RTX_FRAME_RELATED_P (insn)) | |
2617 return false; | |
2618 | |
2619 expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX); | |
2620 if (expr) | |
2621 pat = XEXP (expr, 0); | |
2622 if (!modified_in_p (hard_frame_pointer_rtx, pat ? pat : insn)) | |
2623 return false; | |
2624 | |
2625 /* Don't return true for frame pointer restores in the epilogue. */ | |
2626 if (find_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx)) | |
2627 return false; | |
2628 return true; | |
2629 } | |
2630 | |
0 | 2631 /* Record the effects of INSN. */ |
2632 | |
2633 void | |
111 | 2634 cselib_process_insn (rtx_insn *insn) |
0 | 2635 { |
2636 int i; | |
2637 rtx x; | |
2638 | |
2639 cselib_current_insn = insn; | |
2640 | |
111 | 2641 /* Forget everything at a CODE_LABEL or a setjmp. */ |
2642 if ((LABEL_P (insn) | |
2643 || (CALL_P (insn) | |
2644 && find_reg_note (insn, REG_SETJMP, NULL))) | |
2645 && !cselib_preserve_constants) | |
0 | 2646 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2647 cselib_reset_table (next_uid); |
111 | 2648 cselib_current_insn = NULL; |
0 | 2649 return; |
2650 } | |
2651 | |
2652 if (! INSN_P (insn)) | |
2653 { | |
111 | 2654 cselib_current_insn = NULL; |
0 | 2655 return; |
2656 } | |
2657 | |
2658 /* If this is a call instruction, forget anything stored in a | |
2659 call clobbered register, or, if this is not a const call, in | |
2660 memory. */ | |
2661 if (CALL_P (insn)) | |
2662 { | |
2663 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
2664 if (call_used_regs[i] | |
2665 || (REG_VALUES (i) && REG_VALUES (i)->elt | |
111 | 2666 && (targetm.hard_regno_call_part_clobbered |
2667 (i, GET_MODE (REG_VALUES (i)->elt->val_rtx))))) | |
0 | 2668 cselib_invalidate_regno (i, reg_raw_mode[i]); |
2669 | |
2670 /* Since it is not clear how cselib is going to be used, be | |
2671 conservative here and treat looping pure or const functions | |
2672 as if they were regular functions. */ | |
2673 if (RTL_LOOPING_CONST_OR_PURE_CALL_P (insn) | |
2674 || !(RTL_CONST_OR_PURE_CALL_P (insn))) | |
2675 cselib_invalidate_mem (callmem); | |
111 | 2676 else |
2677 /* For const/pure calls, invalidate any argument slots because | |
2678 they are owned by the callee. */ | |
2679 for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1)) | |
2680 if (GET_CODE (XEXP (x, 0)) == USE | |
2681 && MEM_P (XEXP (XEXP (x, 0), 0))) | |
2682 cselib_invalidate_mem (XEXP (XEXP (x, 0), 0)); | |
0 | 2683 } |
2684 | |
2685 cselib_record_sets (insn); | |
2686 | |
2687 /* Look for any CLOBBERs in CALL_INSN_FUNCTION_USAGE, but only | |
2688 after we have processed the insn. */ | |
2689 if (CALL_P (insn)) | |
111 | 2690 { |
2691 for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1)) | |
2692 if (GET_CODE (XEXP (x, 0)) == CLOBBER) | |
2693 cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0)); | |
2694 /* Flush evertything on setjmp. */ | |
2695 if (cselib_preserve_constants | |
2696 && find_reg_note (insn, REG_SETJMP, NULL)) | |
2697 { | |
2698 cselib_preserve_only_values (); | |
2699 cselib_reset_table (next_uid); | |
2700 } | |
2701 } | |
2702 | |
2703 /* On setter of the hard frame pointer if frame_pointer_needed, | |
2704 invalidate stack_pointer_rtx, so that sp and {,h}fp based | |
2705 VALUEs are distinct. */ | |
2706 if (reload_completed | |
2707 && frame_pointer_needed | |
2708 && fp_setter_insn (insn)) | |
2709 cselib_invalidate_rtx (stack_pointer_rtx); | |
2710 | |
2711 cselib_current_insn = NULL; | |
0 | 2712 |
2713 if (n_useless_values > MAX_USELESS_VALUES | |
2714 /* remove_useless_values is linear in the hash table size. Avoid | |
2715 quadratic behavior for very large hashtables with very few | |
2716 useless elements. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2717 && ((unsigned int)n_useless_values |
111 | 2718 > (cselib_hash_table->elements () - n_debug_values) / 4)) |
0 | 2719 remove_useless_values (); |
2720 } | |
2721 | |
2722 /* Initialize cselib for one pass. The caller must also call | |
2723 init_alias_analysis. */ | |
2724 | |
2725 void | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2726 cselib_init (int record_what) |
0 | 2727 { |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2728 cselib_record_memory = record_what & CSELIB_RECORD_MEMORY; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2729 cselib_preserve_constants = record_what & CSELIB_PRESERVE_CONSTANTS; |
111 | 2730 cselib_any_perm_equivs = false; |
0 | 2731 |
2732 /* (mem:BLK (scratch)) is a special mechanism to conflict with everything, | |
2733 see canon_true_dependence. This is only created once. */ | |
2734 if (! callmem) | |
2735 callmem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (VOIDmode)); | |
2736 | |
2737 cselib_nregs = max_reg_num (); | |
2738 | |
2739 /* We preserve reg_values to allow expensive clearing of the whole thing. | |
2740 Reallocate it however if it happens to be too large. */ | |
2741 if (!reg_values || reg_values_size < cselib_nregs | |
2742 || (reg_values_size > 10 && reg_values_size > cselib_nregs * 4)) | |
2743 { | |
111 | 2744 free (reg_values); |
0 | 2745 /* Some space for newly emit instructions so we don't end up |
2746 reallocating in between passes. */ | |
2747 reg_values_size = cselib_nregs + (63 + cselib_nregs) / 16; | |
2748 reg_values = XCNEWVEC (struct elt_list *, reg_values_size); | |
2749 } | |
2750 used_regs = XNEWVEC (unsigned int, cselib_nregs); | |
2751 n_used_regs = 0; | |
111 | 2752 cselib_hash_table = new hash_table<cselib_hasher> (31); |
2753 if (cselib_preserve_constants) | |
2754 cselib_preserved_hash_table = new hash_table<cselib_hasher> (31); | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2755 next_uid = 1; |
0 | 2756 } |
2757 | |
2758 /* Called when the current user is done with cselib. */ | |
2759 | |
2760 void | |
2761 cselib_finish (void) | |
2762 { | |
111 | 2763 bool preserved = cselib_preserve_constants; |
0 | 2764 cselib_discard_hook = NULL; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2765 cselib_preserve_constants = false; |
111 | 2766 cselib_any_perm_equivs = false; |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2767 cfa_base_preserved_val = NULL; |
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
|
2768 cfa_base_preserved_regno = INVALID_REGNUM; |
111 | 2769 elt_list_pool.release (); |
2770 elt_loc_list_pool.release (); | |
2771 cselib_val_pool.release (); | |
2772 value_pool.release (); | |
0 | 2773 cselib_clear_table (); |
111 | 2774 delete cselib_hash_table; |
2775 cselib_hash_table = NULL; | |
2776 if (preserved) | |
2777 delete cselib_preserved_hash_table; | |
2778 cselib_preserved_hash_table = NULL; | |
0 | 2779 free (used_regs); |
2780 used_regs = 0; | |
2781 n_useless_values = 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
|
2782 n_useless_debug_values = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2783 n_debug_values = 0; |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2784 next_uid = 0; |
0 | 2785 } |
2786 | |
111 | 2787 /* Dump the cselib_val *X to FILE *OUT. */ |
2788 | |
2789 int | |
2790 dump_cselib_val (cselib_val **x, FILE *out) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2791 { |
111 | 2792 cselib_val *v = *x; |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2793 bool need_lf = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2794 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2795 print_inline_rtx (out, v->val_rtx, 0); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2796 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2797 if (v->locs) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2798 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2799 struct elt_loc_list *l = v->locs; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2800 if (need_lf) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2801 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2802 fputc ('\n', out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2803 need_lf = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2804 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2805 fputs (" locs:", out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2806 do |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2807 { |
111 | 2808 if (l->setting_insn) |
2809 fprintf (out, "\n from insn %i ", | |
2810 INSN_UID (l->setting_insn)); | |
2811 else | |
2812 fprintf (out, "\n "); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2813 print_inline_rtx (out, l->loc, 4); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2814 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2815 while ((l = l->next)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2816 fputc ('\n', out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2817 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2818 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2819 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2820 fputs (" no locs", out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2821 need_lf = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2822 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2823 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2824 if (v->addr_list) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2825 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2826 struct elt_list *e = v->addr_list; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2827 if (need_lf) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2828 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2829 fputc ('\n', out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2830 need_lf = false; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2831 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2832 fputs (" addr list:", out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2833 do |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2834 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2835 fputs ("\n ", out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2836 print_inline_rtx (out, e->elt->val_rtx, 2); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2837 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2838 while ((e = e->next)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2839 fputc ('\n', out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2840 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2841 else |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2842 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2843 fputs (" no addrs", out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2844 need_lf = true; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2845 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2846 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2847 if (v->next_containing_mem == &dummy_val) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2848 fputs (" last mem\n", out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2849 else if (v->next_containing_mem) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2850 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2851 fputs (" next mem ", out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2852 print_inline_rtx (out, v->next_containing_mem->val_rtx, 2); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2853 fputc ('\n', out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2854 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2855 else if (need_lf) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2856 fputc ('\n', out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2857 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2858 return 1; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2859 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2860 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2861 /* Dump to OUT everything in the CSELIB table. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2862 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2863 void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2864 dump_cselib_table (FILE *out) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2865 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2866 fprintf (out, "cselib hash table:\n"); |
111 | 2867 cselib_hash_table->traverse <FILE *, dump_cselib_val> (out); |
2868 fprintf (out, "cselib preserved hash table:\n"); | |
2869 cselib_preserved_hash_table->traverse <FILE *, dump_cselib_val> (out); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2870 if (first_containing_mem != &dummy_val) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2871 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2872 fputs ("first mem ", out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2873 print_inline_rtx (out, first_containing_mem->val_rtx, 2); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2874 fputc ('\n', out); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2875 } |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2876 fprintf (out, "next uid %i\n", next_uid); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2877 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
19
diff
changeset
|
2878 |
0 | 2879 #include "gt-cselib.h" |