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