Mercurial > hg > CbC > CbC_gcc
comparison gcc/df-byte-scan.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children | 77e2b8dfacca |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* Scanning of rtl byte level scanning for dataflow analysis. | |
2 Copyright (C) 2008 Free Software Foundation, Inc. | |
3 Contributed by Kenneth Zadeck (zadeck@naturalbridge.com). | |
4 | |
5 This file is part of GCC. | |
6 | |
7 GCC is free software; you can redistribute it and/or modify it under | |
8 the terms of the GNU General Public License as published by the Free | |
9 Software Foundation; either version 3, or (at your option) any later | |
10 version. | |
11 | |
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 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. | |
16 | |
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 #include "config.h" | |
22 #include "system.h" | |
23 #include "coretypes.h" | |
24 #include "tm.h" | |
25 #include "rtl.h" | |
26 #include "tm_p.h" | |
27 #include "df.h" | |
28 #include "output.h" | |
29 #include "dbgcnt.h" | |
30 | |
31 /* The following suite of functions provides bytewise modeling of REFs | |
32 which are struct df_ref. START_BYTE and LAST_BYTE are returned. | |
33 These can be used as indexes into bitmaps. The indexes are | |
34 normalized so that 0 is the lowest numbered byte, of the inner | |
35 register according to the natural ordering of the machine. | |
36 | |
37 This code is designed to be used in backwards scans (which is, of | |
38 course, the way all dataflow scanning should really be done). It | |
39 would require a lot of reworking of the api to make it work in a | |
40 forwards scanning world. */ | |
41 | |
42 | |
43 /* Helper for df_compute_accessed_bytes. Ref is some sort of extract. | |
44 Return true if this effects the entire reg in REF. Return false if | |
45 otherwise and set START_BYTE and LAST_BYTE. See the description of | |
46 df_compute_accessed_bytes for a description of MM. */ | |
47 | |
48 static bool | |
49 df_compute_accessed_bytes_extract (df_ref ref, | |
50 enum df_mm mm , | |
51 unsigned int *start_byte, | |
52 unsigned int *last_byte) | |
53 { | |
54 int start; | |
55 int last; | |
56 rtx reg = DF_REF_REG (ref); | |
57 enum machine_mode m1; | |
58 int m1_size; | |
59 enum machine_mode m2; | |
60 int m2_size; | |
61 | |
62 /* (*_extract:M1 (reg:M2 X) WIDTH POS) | |
63 (*_extract:M1 (subreg:M1 (reg:M2 X N) WIDTH POS) | |
64 | |
65 This is a bitfield extraction. The assignment clobbers/extracts | |
66 exactly the bits named by WIDTH and POS and does not affect the | |
67 other bits in register X. It is also technically possible that | |
68 the bits asked for are longer than units per word. */ | |
69 | |
70 int offset = DF_REF_EXTRACT_OFFSET (ref); | |
71 int width = DF_REF_EXTRACT_WIDTH (ref); | |
72 | |
73 if (width == -1 || offset == -1) | |
74 return true; | |
75 | |
76 m1 = DF_REF_EXTRACT_MODE (ref); | |
77 m1_size = GET_MODE_SIZE (m1); | |
78 | |
79 gcc_assert (m1_size <= UNITS_PER_WORD); | |
80 | |
81 /* There is nothing to do if this is a pure big or small endian | |
82 machine, but if the machine is a pastiche, we have to convert the | |
83 bit offsets into byte offsets. This is only possible because we | |
84 do not care about individual bits because this conversion may | |
85 make the bits non-contiguous. */ | |
86 if (BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN) | |
87 offset = GET_MODE_BITSIZE (m1_size) - (offset + width); | |
88 | |
89 /* The offset is now in the same order as the subreg_byte. */ | |
90 if (GET_CODE (reg) == SUBREG) | |
91 { | |
92 m2 = GET_MODE (SUBREG_REG (reg)); | |
93 m2_size = GET_MODE_SIZE (m2); | |
94 if (m1_size > m2_size) | |
95 /* If it is paradoxical, subreg_byte will be zero. */ | |
96 offset -= subreg_lowpart_offset (m2, m1) * BITS_PER_UNIT; | |
97 else | |
98 offset += SUBREG_BYTE (reg) * BITS_PER_UNIT; | |
99 } | |
100 else | |
101 { | |
102 m2 = GET_MODE (reg); | |
103 m2_size = GET_MODE_SIZE (m2); | |
104 } | |
105 | |
106 if (mm == DF_MM_MUST) | |
107 { | |
108 /* For defs (generally), count the byte only if the whole byte | |
109 is touched. */ | |
110 start = (offset + BITS_PER_UNIT - 1) / BITS_PER_UNIT; | |
111 last = (width + offset) / BITS_PER_UNIT; | |
112 | |
113 /* In the case where there is nothing, start may be one larger | |
114 than last, we canonize this to return zeros. This keeps | |
115 computations of length from being negative. */ | |
116 if (start >= last) | |
117 { | |
118 start = 0; | |
119 last = 0; | |
120 } | |
121 } | |
122 else | |
123 { | |
124 /* For uses (generally), count the byte if any part of the byte | |
125 is touched. */ | |
126 start = offset / BITS_PER_UNIT; | |
127 last = (width + offset + BITS_PER_UNIT - 1) / BITS_PER_UNIT; | |
128 } | |
129 | |
130 /* Paradoxical truncation. */ | |
131 if (start < 0) | |
132 start = 0; | |
133 if (last > m2_size) | |
134 last = m2_size; | |
135 | |
136 if (dump_file) | |
137 fprintf (dump_file, " cpb extract regno=%d start=%d last=%d\n", | |
138 DF_REF_REGNO (ref), start, last); | |
139 | |
140 *start_byte = start; | |
141 *last_byte = last; | |
142 return false; | |
143 } | |
144 | |
145 | |
146 /* Helper for df_compute_accessed_bytes. Ref is a strict_low_part. | |
147 Return true if this effects the entire reg in REF. Return false if | |
148 otherwise and set START_BYTE and LAST_BYTE. */ | |
149 | |
150 static bool | |
151 df_compute_accessed_bytes_strict_low_part (df_ref ref, | |
152 unsigned int *start_byte, | |
153 unsigned int *last_byte) | |
154 { | |
155 int start; | |
156 int last; | |
157 rtx reg = DF_REF_REG (ref); | |
158 enum machine_mode m1; | |
159 int m1_size; | |
160 enum machine_mode m2; | |
161 int m2_size; | |
162 int offset; | |
163 | |
164 /* In order to accommodate multiword subregs of a hardreg, df_scan | |
165 eats the subreg and it can only be found from the loc. */ | |
166 if (REG_P (reg)) | |
167 reg = *(DF_REF_LOC (ref)); | |
168 | |
169 m1 = GET_MODE (reg); | |
170 m1_size = GET_MODE_SIZE (m1); | |
171 m2 = GET_MODE (SUBREG_REG (reg)); | |
172 m2_size = GET_MODE_SIZE (m2); | |
173 offset = SUBREG_BYTE (reg); | |
174 | |
175 /* It does not seem to be meaningful to apply a strict_low_part of a | |
176 paradoxical register. */ | |
177 gcc_assert (m1_size <= m2_size); | |
178 | |
179 /* (set (strict_low_part (subreg:M1 (reg:M2 X) N)) ...) | |
180 | |
181 This is a bitfield insertion. The assignment clobbers exactly the | |
182 bits named by the subreg--the M1 bits at position N. It is also | |
183 technically possible that the bits asked for are longer than units | |
184 per word. */ | |
185 | |
186 start = offset; | |
187 last = offset + m1_size; | |
188 | |
189 if (dump_file) | |
190 fprintf (dump_file, " cpb strict low part regno=%d start=%d last=%d\n", | |
191 DF_REF_REGNO (ref), start, last); | |
192 | |
193 *start_byte = start; | |
194 *last_byte = last; | |
195 return false; | |
196 } | |
197 | |
198 /* Helper for df_compute_accessed_bytes. Ref is a naked subreg. | |
199 Return true if this effects the entire reg in REF. Return false if | |
200 otherwise and set START_BYTE and LAST_BYTE. */ | |
201 | |
202 static bool | |
203 df_compute_accessed_bytes_subreg (df_ref ref, unsigned int *start_byte, | |
204 unsigned int *last_byte) | |
205 | |
206 { | |
207 /* (subreg:M1 (reg:M2 X) N) */ | |
208 int start; | |
209 int last; | |
210 rtx reg = DF_REF_REG (ref); | |
211 | |
212 enum machine_mode m1; | |
213 int m1_size; | |
214 enum machine_mode m2; | |
215 int m2_size; | |
216 | |
217 /* In order to accommodate multiword subregs of a hardreg, df_scan | |
218 eats the subreg and it can only be found from the loc. */ | |
219 if (REG_P (reg)) | |
220 reg = *(DF_REF_LOC (ref)); | |
221 | |
222 m1 = GET_MODE (reg); | |
223 m1_size = GET_MODE_SIZE (m1); | |
224 m2 = GET_MODE (SUBREG_REG (reg)); | |
225 m2_size = GET_MODE_SIZE (m2); | |
226 | |
227 /* A simple paradoxical subreg just accesses the entire inner reg. */ | |
228 if (m1_size >= m2_size) | |
229 return true; | |
230 | |
231 /* Defs and uses are different in the amount of the reg that touch. */ | |
232 if (DF_REF_REG_DEF_P (ref)) | |
233 { | |
234 /* This is an lvalue. */ | |
235 | |
236 if (m2_size > UNITS_PER_WORD) | |
237 { | |
238 /* The assignment clobbers UNITS_PER_WORD segments of X. | |
239 Look at the bytes named by the subreg, and expand it to | |
240 cover a UNITS_PER_WORD part of register X. That part of | |
241 register X is clobbered, the rest is not. | |
242 | |
243 E.g., (subreg:SI (reg:DI X) 0), where UNITS_PER_WORD is the | |
244 size of SImode, clobbers the first SImode part of X, and does | |
245 not affect the second SImode part. | |
246 | |
247 E.g., (subreg:QI (reg:DI X) 0), where UNITS_PER_WORD is the | |
248 size of SImode, clobbers the first SImode part of X, and does | |
249 not affect the second SImode part. Here the QImode byte is | |
250 expanded to a UNITS_PER_WORD portion of the register for | |
251 purposes of determining what is clobbered. | |
252 | |
253 If this is an rvalue, then it touches just the bytes that it | |
254 talks about. */ | |
255 int offset = SUBREG_BYTE (reg); | |
256 | |
257 start = offset & ~(UNITS_PER_WORD - 1); | |
258 last = (offset + m1_size + UNITS_PER_WORD - 1) | |
259 & ~(UNITS_PER_WORD - 1); | |
260 } | |
261 else | |
262 /* Whole register size M2 equal to or smaller than | |
263 UNITS_PER_WORD The assignment clobbers the entire register | |
264 X. */ | |
265 return true; | |
266 } | |
267 else | |
268 { | |
269 /* This is an rvalue. It touches just the bytes they explicitly | |
270 mentioned. */ | |
271 int offset = SUBREG_BYTE (reg); | |
272 start = offset; | |
273 last = start + m1_size; | |
274 } | |
275 | |
276 if (dump_file) | |
277 fprintf (dump_file, " cpb subreg regno=%d start=%d last=%d\n", | |
278 DF_REF_REGNO (ref), start, last); | |
279 | |
280 *start_byte = start; | |
281 *last_byte = last; | |
282 return false; | |
283 } | |
284 | |
285 | |
286 /* Compute the set of affected bytes by a store to a pseudo to REF. | |
287 MM is either DF_MM_MAY or DF_MM_MUST. This is only relevant for | |
288 the extracts which are not aligned to byte boundaries. The | |
289 DF_MM_MAY returns all of the bytes that any bit is set in and the | |
290 DF_MM_MUST returns only the bytes that are completely covered. In | |
291 general DF_MM_MAY is used for uses and DF_MM_MUST is used for defs, | |
292 but there are exceptions such as the inner loop of the byte level | |
293 dead code eliminator which needs DF_MM_MAY for the defs to see if | |
294 it any possible bit could be used. | |
295 | |
296 If the store is to the whole register, just return TRUE, if it is | |
297 to part of the register, return FALSE and set START_BYTE and | |
298 LAST_BYTE properly. In the case where fabricated uses are passed | |
299 in, START_BYTE and LAST_BYTE are set to 0 and false is returned. | |
300 This means that this use can be ignored. */ | |
301 | |
302 bool | |
303 df_compute_accessed_bytes (df_ref ref, enum df_mm mm, | |
304 unsigned int *start_byte, | |
305 unsigned int *last_byte) | |
306 { | |
307 if (!dbg_cnt (df_byte_scan)) | |
308 return true; | |
309 | |
310 if (!DF_REF_REG_DEF_P (ref) | |
311 && DF_REF_FLAGS_IS_SET (ref, DF_REF_READ_WRITE)) | |
312 { | |
313 if (DF_REF_FLAGS_IS_SET (ref, DF_REF_PRE_POST_MODIFY)) | |
314 /* Pre/post modify/inc/dec always read and write the entire | |
315 reg. */ | |
316 return true; | |
317 else | |
318 { | |
319 /* DF_REF_READ_WRITE on a use (except for the | |
320 DF_REF_PRE_POST_MODIFY) means that this use is fabricated | |
321 from a def that is a partial set to a multiword reg. | |
322 Here, we only model those cases precisely so the only one | |
323 to consider is the use put on a auto inc and dec | |
324 insns. */ | |
325 *start_byte = 0; | |
326 *last_byte = 0; | |
327 return false; | |
328 } | |
329 } | |
330 | |
331 if (DF_REF_FLAGS_IS_SET (ref, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT)) | |
332 return df_compute_accessed_bytes_extract (ref, mm, start_byte, last_byte); | |
333 else if (DF_REF_FLAGS_IS_SET (ref, DF_REF_STRICT_LOW_PART)) | |
334 return df_compute_accessed_bytes_strict_low_part (ref, | |
335 start_byte, last_byte); | |
336 else if (GET_CODE (DF_REF_REG (ref)) == SUBREG) | |
337 return df_compute_accessed_bytes_subreg (ref, start_byte, last_byte); | |
338 return true; | |
339 } | |
340 |