Mercurial > hg > CbC > CbC_gcc
annotate gcc/tree-ssa-address.c @ 129:002ebcbc1eb4
remove test_env
author | mir3636 |
---|---|
date | Tue, 15 May 2018 18:45:25 +0900 |
parents | f6334be47118 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 /* Memory address lowering and addressing mode selection. |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
2 Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
3 Free Software Foundation, Inc. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
4 |
0 | 5 This file is part of GCC. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
6 |
0 | 7 GCC is free software; you can redistribute it and/or modify it |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 3, or (at your option) any | |
10 later version. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
11 |
0 | 12 GCC is distributed in the hope that it will be useful, but WITHOUT |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
16 |
0 | 17 You should have received a copy of the GNU General Public License |
18 along with GCC; see the file COPYING3. If not see | |
19 <http://www.gnu.org/licenses/>. */ | |
20 | |
21 /* Utility functions for manipulation with TARGET_MEM_REFs -- tree expressions | |
22 that directly map to addressing modes of the target. */ | |
23 | |
24 #include "config.h" | |
25 #include "system.h" | |
26 #include "coretypes.h" | |
27 #include "tm.h" | |
28 #include "tree.h" | |
29 #include "tm_p.h" | |
30 #include "basic-block.h" | |
31 #include "output.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
|
32 #include "tree-pretty-print.h" |
0 | 33 #include "tree-flow.h" |
34 #include "tree-dump.h" | |
35 #include "tree-pass.h" | |
36 #include "timevar.h" | |
37 #include "flags.h" | |
38 #include "tree-inline.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
|
39 #include "tree-affine.h" |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
40 |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
41 /* FIXME: We compute address costs using RTL. */ |
0 | 42 #include "insn-config.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
|
43 #include "rtl.h" |
0 | 44 #include "recog.h" |
45 #include "expr.h" | |
46 #include "ggc.h" | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
47 #include "target.h" |
0 | 48 |
49 /* TODO -- handling of symbols (according to Richard Hendersons | |
50 comments, http://gcc.gnu.org/ml/gcc-patches/2005-04/msg00949.html): | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
51 |
0 | 52 There are at least 5 different kinds of symbols that we can run up against: |
53 | |
54 (1) binds_local_p, small data area. | |
55 (2) binds_local_p, eg local statics | |
56 (3) !binds_local_p, eg global variables | |
57 (4) thread local, local_exec | |
58 (5) thread local, !local_exec | |
59 | |
60 Now, (1) won't appear often in an array context, but it certainly can. | |
61 All you have to do is set -GN high enough, or explicitly mark any | |
62 random object __attribute__((section (".sdata"))). | |
63 | |
64 All of these affect whether or not a symbol is in fact a valid address. | |
65 The only one tested here is (3). And that result may very well | |
66 be incorrect for (4) or (5). | |
67 | |
68 An incorrect result here does not cause incorrect results out the | |
69 back end, because the expander in expr.c validizes the address. However | |
70 it would be nice to improve the handling here in order to produce more | |
71 precise results. */ | |
72 | |
73 /* A "template" for memory address, used to determine whether the address is | |
74 valid for mode. */ | |
75 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
76 typedef struct GTY (()) mem_addr_template { |
0 | 77 rtx ref; /* The template. */ |
78 rtx * GTY ((skip)) step_p; /* The point in template where the step should be | |
79 filled in. */ | |
80 rtx * GTY ((skip)) off_p; /* The point in template where the offset should | |
81 be filled in. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
82 } mem_addr_template; |
0 | 83 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
84 DEF_VEC_O (mem_addr_template); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
85 DEF_VEC_ALLOC_O (mem_addr_template, gc); |
0 | 86 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
87 /* The templates. Each of the low five bits of the index corresponds to one |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
88 component of TARGET_MEM_REF being present, while the high bits identify |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
89 the address space. See TEMPL_IDX. */ |
0 | 90 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
91 static GTY(()) VEC (mem_addr_template, gc) *mem_addr_template_list; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
92 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
93 #define TEMPL_IDX(AS, SYMBOL, BASE, INDEX, STEP, OFFSET) \ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
94 (((int) (AS) << 5) \ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
95 | ((SYMBOL != 0) << 4) \ |
0 | 96 | ((BASE != 0) << 3) \ |
97 | ((INDEX != 0) << 2) \ | |
98 | ((STEP != 0) << 1) \ | |
99 | (OFFSET != 0)) | |
100 | |
101 /* Stores address for memory reference with parameters SYMBOL, BASE, INDEX, | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
102 STEP and OFFSET to *ADDR using address mode ADDRESS_MODE. Stores pointers |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
103 to where step is placed to *STEP_P and offset to *OFFSET_P. */ |
0 | 104 |
105 static void | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
106 gen_addr_rtx (enum machine_mode address_mode, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
107 rtx symbol, rtx base, rtx index, rtx step, rtx offset, |
0 | 108 rtx *addr, rtx **step_p, rtx **offset_p) |
109 { | |
110 rtx act_elem; | |
111 | |
112 *addr = NULL_RTX; | |
113 if (step_p) | |
114 *step_p = NULL; | |
115 if (offset_p) | |
116 *offset_p = NULL; | |
117 | |
118 if (index) | |
119 { | |
120 act_elem = index; | |
121 if (step) | |
122 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
123 act_elem = gen_rtx_MULT (address_mode, act_elem, step); |
0 | 124 |
125 if (step_p) | |
126 *step_p = &XEXP (act_elem, 1); | |
127 } | |
128 | |
129 *addr = act_elem; | |
130 } | |
131 | |
132 if (base) | |
133 { | |
134 if (*addr) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
135 *addr = simplify_gen_binary (PLUS, address_mode, base, *addr); |
0 | 136 else |
137 *addr = base; | |
138 } | |
139 | |
140 if (symbol) | |
141 { | |
142 act_elem = symbol; | |
143 if (offset) | |
144 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
145 act_elem = gen_rtx_PLUS (address_mode, act_elem, offset); |
0 | 146 |
147 if (offset_p) | |
148 *offset_p = &XEXP (act_elem, 1); | |
149 | |
150 if (GET_CODE (symbol) == SYMBOL_REF | |
151 || GET_CODE (symbol) == LABEL_REF | |
152 || GET_CODE (symbol) == CONST) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
153 act_elem = gen_rtx_CONST (address_mode, act_elem); |
0 | 154 } |
155 | |
156 if (*addr) | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
157 *addr = gen_rtx_PLUS (address_mode, *addr, act_elem); |
0 | 158 else |
159 *addr = act_elem; | |
160 } | |
161 else if (offset) | |
162 { | |
163 if (*addr) | |
164 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
165 *addr = gen_rtx_PLUS (address_mode, *addr, offset); |
0 | 166 if (offset_p) |
167 *offset_p = &XEXP (*addr, 1); | |
168 } | |
169 else | |
170 { | |
171 *addr = offset; | |
172 if (offset_p) | |
173 *offset_p = addr; | |
174 } | |
175 } | |
176 | |
177 if (!*addr) | |
178 *addr = const0_rtx; | |
179 } | |
180 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
181 /* Returns address for TARGET_MEM_REF with parameters given by ADDR |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
182 in address space AS. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
183 If REALLY_EXPAND is false, just make fake registers instead |
0 | 184 of really expanding the operands, and perform the expansion in-place |
185 by using one of the "templates". */ | |
186 | |
187 rtx | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
188 addr_for_mem_ref (struct mem_address *addr, addr_space_t as, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
189 bool really_expand) |
0 | 190 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
191 enum machine_mode address_mode = targetm.addr_space.address_mode (as); |
0 | 192 rtx address, sym, bse, idx, st, off; |
193 struct mem_addr_template *templ; | |
194 | |
195 if (addr->step && !integer_onep (addr->step)) | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
196 st = immed_double_int_const (tree_to_double_int (addr->step), address_mode); |
0 | 197 else |
198 st = NULL_RTX; | |
199 | |
200 if (addr->offset && !integer_zerop (addr->offset)) | |
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
|
201 off = immed_double_int_const |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
202 (double_int_sext (tree_to_double_int (addr->offset), |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
203 TYPE_PRECISION (TREE_TYPE (addr->offset))), |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
204 address_mode); |
0 | 205 else |
206 off = NULL_RTX; | |
207 | |
208 if (!really_expand) | |
209 { | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
210 unsigned int templ_index |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
211 = TEMPL_IDX (as, addr->symbol, addr->base, addr->index, st, off); |
0 | 212 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
213 if (templ_index |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
214 >= VEC_length (mem_addr_template, mem_addr_template_list)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
215 VEC_safe_grow_cleared (mem_addr_template, gc, mem_addr_template_list, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
216 templ_index + 1); |
0 | 217 |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
218 /* Reuse the templates for addresses, so that we do not waste memory. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
219 templ = VEC_index (mem_addr_template, mem_addr_template_list, templ_index); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
220 if (!templ->ref) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
221 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
222 sym = (addr->symbol ? |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
223 gen_rtx_SYMBOL_REF (address_mode, ggc_strdup ("test_symbol")) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
224 : NULL_RTX); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
225 bse = (addr->base ? |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
226 gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
227 : NULL_RTX); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
228 idx = (addr->index ? |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
229 gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
230 : NULL_RTX); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
231 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
232 gen_addr_rtx (address_mode, sym, bse, idx, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
233 st? const0_rtx : NULL_RTX, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
234 off? const0_rtx : NULL_RTX, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
235 &templ->ref, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
236 &templ->step_p, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
237 &templ->off_p); |
0 | 238 } |
239 | |
240 if (st) | |
241 *templ->step_p = st; | |
242 if (off) | |
243 *templ->off_p = off; | |
244 | |
245 return templ->ref; | |
246 } | |
247 | |
248 /* Otherwise really expand the expressions. */ | |
249 sym = (addr->symbol | |
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
|
250 ? expand_expr (addr->symbol, NULL_RTX, address_mode, EXPAND_NORMAL) |
0 | 251 : NULL_RTX); |
252 bse = (addr->base | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
253 ? expand_expr (addr->base, NULL_RTX, address_mode, EXPAND_NORMAL) |
0 | 254 : NULL_RTX); |
255 idx = (addr->index | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
256 ? expand_expr (addr->index, NULL_RTX, address_mode, EXPAND_NORMAL) |
0 | 257 : NULL_RTX); |
258 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
259 gen_addr_rtx (address_mode, sym, bse, idx, st, off, &address, NULL, NULL); |
0 | 260 return address; |
261 } | |
262 | |
263 /* Returns address of MEM_REF in TYPE. */ | |
264 | |
265 tree | |
266 tree_mem_ref_addr (tree type, tree mem_ref) | |
267 { | |
268 tree addr; | |
269 tree act_elem; | |
270 tree step = TMR_STEP (mem_ref), offset = TMR_OFFSET (mem_ref); | |
271 tree addr_base = NULL_TREE, addr_off = NULL_TREE; | |
272 | |
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
|
273 addr_base = fold_convert (type, TMR_BASE (mem_ref)); |
0 | 274 |
275 act_elem = TMR_INDEX (mem_ref); | |
276 if (act_elem) | |
277 { | |
278 if (step) | |
279 act_elem = fold_build2 (MULT_EXPR, sizetype, act_elem, step); | |
280 addr_off = act_elem; | |
281 } | |
282 | |
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
|
283 act_elem = TMR_INDEX2 (mem_ref); |
0 | 284 if (act_elem) |
285 { | |
286 if (addr_off) | |
287 addr_off = fold_build2 (PLUS_EXPR, sizetype, addr_off, act_elem); | |
288 else | |
289 addr_off = act_elem; | |
290 } | |
291 | |
292 if (offset && !integer_zerop (offset)) | |
293 { | |
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
|
294 offset = fold_convert (sizetype, offset); |
0 | 295 if (addr_off) |
296 addr_off = fold_build2 (PLUS_EXPR, sizetype, addr_off, offset); | |
297 else | |
298 addr_off = offset; | |
299 } | |
300 | |
301 if (addr_off) | |
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
|
302 addr = fold_build2 (POINTER_PLUS_EXPR, type, addr_base, addr_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
|
303 else |
0 | 304 addr = addr_base; |
305 | |
306 return addr; | |
307 } | |
308 | |
309 /* Returns true if a memory reference in MODE and with parameters given by | |
310 ADDR is valid on the current target. */ | |
311 | |
312 static bool | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
313 valid_mem_ref_p (enum machine_mode mode, addr_space_t as, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
314 struct mem_address *addr) |
0 | 315 { |
316 rtx address; | |
317 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
318 address = addr_for_mem_ref (addr, as, false); |
0 | 319 if (!address) |
320 return false; | |
321 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
322 return memory_address_addr_space_p (mode, address, as); |
0 | 323 } |
324 | |
325 /* Checks whether a TARGET_MEM_REF with type TYPE and parameters given by ADDR | |
326 is valid on the current target and if so, creates and returns the | |
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
|
327 TARGET_MEM_REF. If VERIFY is false omit the verification step. */ |
0 | 328 |
329 static tree | |
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
|
330 create_mem_ref_raw (tree type, tree alias_ptr_type, struct mem_address *addr, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
331 bool verify) |
0 | 332 { |
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
|
333 tree base, index2; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
334 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
335 if (verify |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
336 && !valid_mem_ref_p (TYPE_MODE (type), TYPE_ADDR_SPACE (type), addr)) |
0 | 337 return NULL_TREE; |
338 | |
339 if (addr->step && integer_onep (addr->step)) | |
340 addr->step = NULL_TREE; | |
341 | |
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
|
342 if (addr->offset) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
343 addr->offset = fold_convert (alias_ptr_type, addr->offset); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
344 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
|
345 addr->offset = build_int_cst (alias_ptr_type, 0); |
0 | 346 |
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
|
347 if (addr->symbol) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
348 { |
f6334be47118
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 base = addr->symbol; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
350 index2 = addr->base; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
351 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
352 else if (addr->base |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
353 && POINTER_TYPE_P (TREE_TYPE (addr->base))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
354 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
355 base = addr->base; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
356 index2 = NULL_TREE; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
357 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
358 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
|
359 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
360 base = build_int_cst (ptr_type_node, 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
|
361 index2 = addr->base; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
362 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
363 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
364 /* If possible use a plain MEM_REF instead of a TARGET_MEM_REF. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
365 if (alias_ptr_type |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
366 && (!index2 || integer_zerop (index2)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
367 && (!addr->index || integer_zerop (addr->index))) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
368 return fold_build2 (MEM_REF, type, base, addr->offset); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
369 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
370 return build5 (TARGET_MEM_REF, type, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
371 base, addr->offset, addr->index, addr->step, index2); |
0 | 372 } |
373 | |
374 /* Returns true if OBJ is an object whose address is a link time constant. */ | |
375 | |
376 static bool | |
377 fixed_address_object_p (tree obj) | |
378 { | |
379 return (TREE_CODE (obj) == VAR_DECL | |
380 && (TREE_STATIC (obj) | |
381 || DECL_EXTERNAL (obj)) | |
382 && ! DECL_DLLIMPORT_P (obj)); | |
383 } | |
384 | |
385 /* If ADDR contains an address of object that is a link time constant, | |
386 move it to PARTS->symbol. */ | |
387 | |
388 static void | |
389 move_fixed_address_to_symbol (struct mem_address *parts, aff_tree *addr) | |
390 { | |
391 unsigned i; | |
392 tree val = NULL_TREE; | |
393 | |
394 for (i = 0; i < addr->n; i++) | |
395 { | |
396 if (!double_int_one_p (addr->elts[i].coef)) | |
397 continue; | |
398 | |
399 val = addr->elts[i].val; | |
400 if (TREE_CODE (val) == ADDR_EXPR | |
401 && fixed_address_object_p (TREE_OPERAND (val, 0))) | |
402 break; | |
403 } | |
404 | |
405 if (i == addr->n) | |
406 return; | |
407 | |
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
|
408 parts->symbol = val; |
0 | 409 aff_combination_remove_elt (addr, i); |
410 } | |
411 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
412 /* If ADDR contains an instance of BASE_HINT, move it to PARTS->base. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
413 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
414 static void |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
415 move_hint_to_base (tree type, struct mem_address *parts, tree base_hint, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
416 aff_tree *addr) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
417 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
418 unsigned i; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
419 tree val = NULL_TREE; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
420 int qual; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
421 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
422 for (i = 0; i < addr->n; i++) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
423 { |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
424 if (!double_int_one_p (addr->elts[i].coef)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
425 continue; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
426 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
427 val = addr->elts[i].val; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
428 if (operand_equal_p (val, base_hint, 0)) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
429 break; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
430 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
431 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
432 if (i == addr->n) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
433 return; |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
434 |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
435 /* Cast value to appropriate pointer type. We cannot use a pointer |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
436 to TYPE directly, as the back-end will assume registers of pointer |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
437 type are aligned, and just the base itself may not actually be. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
438 We use void pointer to the type's address space instead. */ |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
439 qual = ENCODE_QUAL_ADDR_SPACE (TYPE_ADDR_SPACE (type)); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
440 type = build_qualified_type (void_type_node, qual); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
441 parts->base = fold_convert (build_pointer_type (type), val); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
442 aff_combination_remove_elt (addr, i); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
443 } |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
444 |
0 | 445 /* If ADDR contains an address of a dereferenced pointer, move it to |
446 PARTS->base. */ | |
447 | |
448 static void | |
449 move_pointer_to_base (struct mem_address *parts, aff_tree *addr) | |
450 { | |
451 unsigned i; | |
452 tree val = NULL_TREE; | |
453 | |
454 for (i = 0; i < addr->n; i++) | |
455 { | |
456 if (!double_int_one_p (addr->elts[i].coef)) | |
457 continue; | |
458 | |
459 val = addr->elts[i].val; | |
460 if (POINTER_TYPE_P (TREE_TYPE (val))) | |
461 break; | |
462 } | |
463 | |
464 if (i == addr->n) | |
465 return; | |
466 | |
467 parts->base = val; | |
468 aff_combination_remove_elt (addr, i); | |
469 } | |
470 | |
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
|
471 /* Moves the loop variant part V in linear address ADDR to be the index |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
472 of PARTS. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
473 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
474 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
|
475 move_variant_to_index (struct mem_address *parts, aff_tree *addr, tree 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
|
476 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
477 unsigned 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
|
478 tree val = NULL_TREE; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
479 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
480 gcc_assert (!parts->index); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
481 for (i = 0; i < addr->n; 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
|
482 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
483 val = addr->elts[i].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
|
484 if (operand_equal_p (val, v, 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
|
485 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
|
486 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
487 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
488 if (i == addr->n) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
489 return; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
490 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
491 parts->index = fold_convert (sizetype, 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
|
492 parts->step = double_int_to_tree (sizetype, addr->elts[i].coef); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
493 aff_combination_remove_elt (addr, 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
|
494 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
495 |
0 | 496 /* Adds ELT to PARTS. */ |
497 | |
498 static void | |
499 add_to_parts (struct mem_address *parts, tree elt) | |
500 { | |
501 tree type; | |
502 | |
503 if (!parts->index) | |
504 { | |
505 parts->index = fold_convert (sizetype, elt); | |
506 return; | |
507 } | |
508 | |
509 if (!parts->base) | |
510 { | |
511 parts->base = elt; | |
512 return; | |
513 } | |
514 | |
515 /* Add ELT to base. */ | |
516 type = TREE_TYPE (parts->base); | |
517 if (POINTER_TYPE_P (type)) | |
518 parts->base = fold_build2 (POINTER_PLUS_EXPR, type, | |
519 parts->base, | |
520 fold_convert (sizetype, elt)); | |
521 else | |
522 parts->base = fold_build2 (PLUS_EXPR, type, | |
523 parts->base, elt); | |
524 } | |
525 | |
526 /* Finds the most expensive multiplication in ADDR that can be | |
527 expressed in an addressing mode and move the corresponding | |
528 element(s) to PARTS. */ | |
529 | |
530 static void | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
531 most_expensive_mult_to_index (tree type, struct mem_address *parts, |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
532 aff_tree *addr, bool speed) |
0 | 533 { |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
534 addr_space_t as = TYPE_ADDR_SPACE (type); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
535 enum machine_mode address_mode = targetm.addr_space.address_mode (as); |
0 | 536 HOST_WIDE_INT coef; |
537 double_int best_mult, amult, amult_neg; | |
538 unsigned best_mult_cost = 0, acost; | |
539 tree mult_elt = NULL_TREE, elt; | |
540 unsigned i, j; | |
541 enum tree_code op_code; | |
542 | |
543 best_mult = double_int_zero; | |
544 for (i = 0; i < addr->n; i++) | |
545 { | |
546 if (!double_int_fits_in_shwi_p (addr->elts[i].coef)) | |
547 continue; | |
548 | |
549 coef = double_int_to_shwi (addr->elts[i].coef); | |
550 if (coef == 1 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
551 || !multiplier_allowed_in_address_p (coef, TYPE_MODE (type), as)) |
0 | 552 continue; |
553 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
554 acost = multiply_by_cost (coef, address_mode, speed); |
0 | 555 |
556 if (acost > best_mult_cost) | |
557 { | |
558 best_mult_cost = acost; | |
559 best_mult = addr->elts[i].coef; | |
560 } | |
561 } | |
562 | |
563 if (!best_mult_cost) | |
564 return; | |
565 | |
566 /* Collect elements multiplied by best_mult. */ | |
567 for (i = j = 0; i < addr->n; i++) | |
568 { | |
569 amult = addr->elts[i].coef; | |
570 amult_neg = double_int_ext_for_comb (double_int_neg (amult), addr); | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
571 |
0 | 572 if (double_int_equal_p (amult, best_mult)) |
573 op_code = PLUS_EXPR; | |
574 else if (double_int_equal_p (amult_neg, best_mult)) | |
575 op_code = MINUS_EXPR; | |
576 else | |
577 { | |
578 addr->elts[j] = addr->elts[i]; | |
579 j++; | |
580 continue; | |
581 } | |
582 | |
583 elt = fold_convert (sizetype, addr->elts[i].val); | |
584 if (mult_elt) | |
585 mult_elt = fold_build2 (op_code, sizetype, mult_elt, elt); | |
586 else if (op_code == PLUS_EXPR) | |
587 mult_elt = elt; | |
588 else | |
589 mult_elt = fold_build1 (NEGATE_EXPR, sizetype, elt); | |
590 } | |
591 addr->n = j; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
592 |
0 | 593 parts->index = mult_elt; |
594 parts->step = double_int_to_tree (sizetype, best_mult); | |
595 } | |
596 | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
597 /* Splits address ADDR for a memory access of type TYPE into PARTS. |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
598 If BASE_HINT is non-NULL, it specifies an SSA name to be used |
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
|
599 preferentially as base of the reference, and IV_CAND is the selected |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
600 iv candidate used in ADDR. |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
601 |
0 | 602 TODO -- be more clever about the distribution of the elements of ADDR |
603 to PARTS. Some architectures do not support anything but single | |
604 register in address, possibly with a small integer offset; while | |
605 create_mem_ref will simplify the address to an acceptable shape | |
606 later, it would be more efficient to know that asking for complicated | |
607 addressing modes is useless. */ | |
608 | |
609 static 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
|
610 addr_to_parts (tree type, aff_tree *addr, tree iv_cand, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
611 tree base_hint, struct mem_address *parts, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
612 bool speed) |
0 | 613 { |
614 tree part; | |
615 unsigned i; | |
616 | |
617 parts->symbol = NULL_TREE; | |
618 parts->base = NULL_TREE; | |
619 parts->index = NULL_TREE; | |
620 parts->step = NULL_TREE; | |
621 | |
622 if (!double_int_zero_p (addr->offset)) | |
623 parts->offset = double_int_to_tree (sizetype, addr->offset); | |
624 else | |
625 parts->offset = NULL_TREE; | |
626 | |
627 /* Try to find a symbol. */ | |
628 move_fixed_address_to_symbol (parts, addr); | |
629 | |
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
|
630 /* No need to do address parts reassociation if the number of parts |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
631 is <= 2 -- in that case, no loop invariant code motion can be |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
632 exposed. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
633 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
634 if (!base_hint && (addr->n > 2)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
635 move_variant_to_index (parts, addr, iv_cand); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
636 |
0 | 637 /* First move the most expensive feasible multiplication |
638 to index. */ | |
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
|
639 if (!parts->index) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
640 most_expensive_mult_to_index (type, parts, addr, speed); |
0 | 641 |
642 /* Try to find a base of the reference. Since at the moment | |
643 there is no reliable way how to distinguish between pointer and its | |
644 offset, this is just a guess. */ | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
645 if (!parts->symbol && base_hint) |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
646 move_hint_to_base (type, parts, base_hint, addr); |
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
647 if (!parts->symbol && !parts->base) |
0 | 648 move_pointer_to_base (parts, addr); |
649 | |
650 /* Then try to process the remaining elements. */ | |
651 for (i = 0; i < addr->n; i++) | |
652 { | |
653 part = fold_convert (sizetype, addr->elts[i].val); | |
654 if (!double_int_one_p (addr->elts[i].coef)) | |
655 part = fold_build2 (MULT_EXPR, sizetype, part, | |
656 double_int_to_tree (sizetype, addr->elts[i].coef)); | |
657 add_to_parts (parts, part); | |
658 } | |
659 if (addr->rest) | |
660 add_to_parts (parts, fold_convert (sizetype, addr->rest)); | |
661 } | |
662 | |
663 /* Force the PARTS to register. */ | |
664 | |
665 static void | |
666 gimplify_mem_ref_parts (gimple_stmt_iterator *gsi, struct mem_address *parts) | |
667 { | |
668 if (parts->base) | |
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
|
669 parts->base = force_gimple_operand_gsi_1 (gsi, parts->base, |
f6334be47118
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 is_gimple_mem_ref_addr, NULL_TREE, |
0 | 671 true, GSI_SAME_STMT); |
672 if (parts->index) | |
673 parts->index = force_gimple_operand_gsi (gsi, parts->index, | |
674 true, NULL_TREE, | |
675 true, GSI_SAME_STMT); | |
676 } | |
677 | |
678 /* Creates and returns a TARGET_MEM_REF for address ADDR. If necessary | |
679 computations are emitted in front of GSI. TYPE is the 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
|
680 of created memory reference. IV_CAND is the selected iv candidate in ADDR, |
f6334be47118
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 and BASE_HINT is non NULL if IV_CAND comes from a base address |
f6334be47118
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 object. */ |
0 | 683 |
684 tree | |
685 create_mem_ref (gimple_stmt_iterator *gsi, tree type, aff_tree *addr, | |
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
|
686 tree alias_ptr_type, tree iv_cand, tree base_hint, bool speed) |
0 | 687 { |
688 tree mem_ref, tmp; | |
689 tree atype; | |
690 struct mem_address parts; | |
691 | |
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
|
692 addr_to_parts (type, addr, iv_cand, base_hint, &parts, speed); |
0 | 693 gimplify_mem_ref_parts (gsi, &parts); |
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
|
694 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); |
0 | 695 if (mem_ref) |
696 return mem_ref; | |
697 | |
698 /* The expression is too complicated. Try making it simpler. */ | |
699 | |
700 if (parts.step && !integer_onep (parts.step)) | |
701 { | |
702 /* Move the multiplication to index. */ | |
703 gcc_assert (parts.index); | |
704 parts.index = force_gimple_operand_gsi (gsi, | |
705 fold_build2 (MULT_EXPR, sizetype, | |
706 parts.index, parts.step), | |
707 true, NULL_TREE, true, GSI_SAME_STMT); | |
708 parts.step = NULL_TREE; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
709 |
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
|
710 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); |
0 | 711 if (mem_ref) |
712 return mem_ref; | |
713 } | |
714 | |
715 if (parts.symbol) | |
716 { | |
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
|
717 tmp = parts.symbol; |
0 | 718 gcc_assert (is_gimple_val (tmp)); |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
719 |
0 | 720 /* Add the symbol to base, eventually forcing it to register. */ |
721 if (parts.base) | |
722 { | |
723 gcc_assert (useless_type_conversion_p | |
724 (sizetype, TREE_TYPE (parts.base))); | |
725 | |
726 if (parts.index) | |
727 { | |
728 atype = TREE_TYPE (tmp); | |
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
|
729 parts.base = force_gimple_operand_gsi_1 (gsi, |
0 | 730 fold_build2 (POINTER_PLUS_EXPR, atype, |
731 tmp, | |
732 fold_convert (sizetype, parts.base)), | |
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
|
733 is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT); |
0 | 734 } |
735 else | |
736 { | |
737 parts.index = parts.base; | |
738 parts.base = tmp; | |
739 } | |
740 } | |
741 else | |
742 parts.base = tmp; | |
743 parts.symbol = NULL_TREE; | |
744 | |
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 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); |
0 | 746 if (mem_ref) |
747 return mem_ref; | |
748 } | |
749 | |
750 if (parts.index) | |
751 { | |
752 /* Add index to base. */ | |
753 if (parts.base) | |
754 { | |
755 atype = TREE_TYPE (parts.base); | |
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
|
756 parts.base = force_gimple_operand_gsi_1 (gsi, |
0 | 757 fold_build2 (POINTER_PLUS_EXPR, atype, |
758 parts.base, | |
759 parts.index), | |
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
|
760 is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT); |
0 | 761 } |
762 else | |
763 parts.base = parts.index; | |
764 parts.index = NULL_TREE; | |
765 | |
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
|
766 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); |
0 | 767 if (mem_ref) |
768 return mem_ref; | |
769 } | |
770 | |
771 if (parts.offset && !integer_zerop (parts.offset)) | |
772 { | |
773 /* Try adding offset to base. */ | |
774 if (parts.base) | |
775 { | |
776 atype = TREE_TYPE (parts.base); | |
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
|
777 parts.base = force_gimple_operand_gsi_1 (gsi, |
0 | 778 fold_build2 (POINTER_PLUS_EXPR, atype, |
779 parts.base, | |
780 fold_convert (sizetype, parts.offset)), | |
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
|
781 is_gimple_mem_ref_addr, NULL_TREE, true, GSI_SAME_STMT); |
0 | 782 } |
783 else | |
784 parts.base = parts.offset; | |
785 | |
786 parts.offset = NULL_TREE; | |
787 | |
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
|
788 mem_ref = create_mem_ref_raw (type, alias_ptr_type, &parts, true); |
0 | 789 if (mem_ref) |
790 return mem_ref; | |
791 } | |
792 | |
793 /* Verify that the address is in the simplest possible shape | |
794 (only a register). If we cannot create such a memory reference, | |
795 something is really wrong. */ | |
796 gcc_assert (parts.symbol == NULL_TREE); | |
797 gcc_assert (parts.index == NULL_TREE); | |
798 gcc_assert (!parts.step || integer_onep (parts.step)); | |
799 gcc_assert (!parts.offset || integer_zerop (parts.offset)); | |
800 gcc_unreachable (); | |
801 } | |
802 | |
803 /* Copies components of the address from OP to ADDR. */ | |
804 | |
805 void | |
806 get_address_description (tree op, struct mem_address *addr) | |
807 { | |
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
|
808 if (TREE_CODE (TMR_BASE (op)) == ADDR_EXPR) |
f6334be47118
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 { |
f6334be47118
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 addr->symbol = TMR_BASE (op); |
f6334be47118
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 addr->base = TMR_INDEX2 (op); |
f6334be47118
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 } |
f6334be47118
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 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
|
814 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
815 addr->symbol = NULL_TREE; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
816 if (TMR_INDEX2 (op)) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
817 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
818 gcc_assert (integer_zerop (TMR_BASE (op))); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
819 addr->base = TMR_INDEX2 (op); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
820 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
821 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
|
822 addr->base = TMR_BASE (op); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
823 } |
0 | 824 addr->index = TMR_INDEX (op); |
825 addr->step = TMR_STEP (op); | |
826 addr->offset = TMR_OFFSET (op); | |
827 } | |
828 | |
829 /* Copies the additional information attached to target_mem_ref FROM to TO. */ | |
830 | |
831 void | |
832 copy_mem_ref_info (tree to, tree from) | |
833 { | |
834 /* And the info about the original reference. */ | |
63
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
835 TREE_SIDE_EFFECTS (to) = TREE_SIDE_EFFECTS (from); |
b7f97abdc517
update gcc from gcc-4.5.0 to gcc-4.6
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
55
diff
changeset
|
836 TREE_THIS_VOLATILE (to) = TREE_THIS_VOLATILE (from); |
0 | 837 } |
838 | |
839 /* Move constants in target_mem_ref REF to offset. Returns the new target | |
840 mem ref if anything changes, NULL_TREE otherwise. */ | |
841 | |
842 tree | |
843 maybe_fold_tmr (tree ref) | |
844 { | |
845 struct mem_address addr; | |
846 bool changed = false; | |
847 tree ret, off; | |
848 | |
849 get_address_description (ref, &addr); | |
850 | |
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
|
851 if (addr.base |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
852 && TREE_CODE (addr.base) == INTEGER_CST |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
853 && !integer_zerop (addr.base)) |
f6334be47118
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 { |
f6334be47118
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 addr.offset = fold_binary_to_constant (PLUS_EXPR, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
856 TREE_TYPE (addr.offset), |
f6334be47118
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 addr.offset, addr.base); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
858 addr.base = NULL_TREE; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
859 changed = true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
860 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
861 |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
862 if (addr.symbol |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
863 && TREE_CODE (TREE_OPERAND (addr.symbol, 0)) == MEM_REF) |
0 | 864 { |
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
|
865 addr.offset = fold_binary_to_constant |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
866 (PLUS_EXPR, TREE_TYPE (addr.offset), |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
867 addr.offset, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
868 TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 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
|
869 addr.symbol = TREE_OPERAND (TREE_OPERAND (addr.symbol, 0), 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
|
870 changed = true; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
871 } |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
872 else if (addr.symbol |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
873 && handled_component_p (TREE_OPERAND (addr.symbol, 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
|
874 { |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
875 HOST_WIDE_INT offset; |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
876 addr.symbol = build_fold_addr_expr |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
877 (get_addr_base_and_unit_offset |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
878 (TREE_OPERAND (addr.symbol, 0), &offset)); |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
879 addr.offset = int_const_binop (PLUS_EXPR, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
880 addr.offset, size_int (offset), 0); |
0 | 881 changed = true; |
882 } | |
883 | |
884 if (addr.index && TREE_CODE (addr.index) == INTEGER_CST) | |
885 { | |
886 off = addr.index; | |
887 if (addr.step) | |
888 { | |
889 off = fold_binary_to_constant (MULT_EXPR, sizetype, | |
890 off, addr.step); | |
891 addr.step = NULL_TREE; | |
892 } | |
893 | |
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
|
894 addr.offset = fold_binary_to_constant (PLUS_EXPR, |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
895 TREE_TYPE (addr.offset), |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
896 addr.offset, off); |
0 | 897 addr.index = NULL_TREE; |
898 changed = true; | |
899 } | |
900 | |
901 if (!changed) | |
902 return NULL_TREE; | |
55
77e2b8dfacca
update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
903 |
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
|
904 /* If we have propagated something into this TARGET_MEM_REF and thus |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
905 ended up folding it, always create a new TARGET_MEM_REF regardless |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
906 if it is valid in this for on the target - the propagation result |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
907 wouldn't be anyway. */ |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
63
diff
changeset
|
908 ret = create_mem_ref_raw (TREE_TYPE (ref), |
f6334be47118
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 TREE_TYPE (addr.offset), &addr, false); |
0 | 910 copy_mem_ref_info (ret, ref); |
911 return ret; | |
912 } | |
913 | |
914 /* Dump PARTS to FILE. */ | |
915 | |
916 extern void dump_mem_address (FILE *, struct mem_address *); | |
917 void | |
918 dump_mem_address (FILE *file, struct mem_address *parts) | |
919 { | |
920 if (parts->symbol) | |
921 { | |
922 fprintf (file, "symbol: "); | |
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
|
923 print_generic_expr (file, TREE_OPERAND (parts->symbol, 0), TDF_SLIM); |
0 | 924 fprintf (file, "\n"); |
925 } | |
926 if (parts->base) | |
927 { | |
928 fprintf (file, "base: "); | |
929 print_generic_expr (file, parts->base, TDF_SLIM); | |
930 fprintf (file, "\n"); | |
931 } | |
932 if (parts->index) | |
933 { | |
934 fprintf (file, "index: "); | |
935 print_generic_expr (file, parts->index, TDF_SLIM); | |
936 fprintf (file, "\n"); | |
937 } | |
938 if (parts->step) | |
939 { | |
940 fprintf (file, "step: "); | |
941 print_generic_expr (file, parts->step, TDF_SLIM); | |
942 fprintf (file, "\n"); | |
943 } | |
944 if (parts->offset) | |
945 { | |
946 fprintf (file, "offset: "); | |
947 print_generic_expr (file, parts->offset, TDF_SLIM); | |
948 fprintf (file, "\n"); | |
949 } | |
950 } | |
951 | |
952 #include "gt-tree-ssa-address.h" |