]>
Commit | Line | Data |
---|---|---|
6d9d0028 KZ |
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 | |
b8698a0f | 46 | df_compute_accessed_bytes for a description of MM. */ |
6d9d0028 | 47 | |
b8698a0f | 48 | static bool |
57512f53 | 49 | df_compute_accessed_bytes_extract (df_ref ref, |
6d9d0028 | 50 | enum df_mm mm , |
b8698a0f | 51 | unsigned int *start_byte, |
6d9d0028 KZ |
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) | |
b8698a0f | 64 | |
6d9d0028 KZ |
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. */ | |
b8698a0f | 69 | |
6d9d0028 KZ |
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) | |
b8698a0f | 137 | fprintf (dump_file, " cpb extract regno=%d start=%d last=%d\n", |
6d9d0028 | 138 | DF_REF_REGNO (ref), start, last); |
b8698a0f | 139 | |
6d9d0028 KZ |
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 | |
b8698a0f | 148 | otherwise and set START_BYTE and LAST_BYTE. */ |
6d9d0028 | 149 | |
b8698a0f L |
150 | static bool |
151 | df_compute_accessed_bytes_strict_low_part (df_ref ref, | |
152 | unsigned int *start_byte, | |
6d9d0028 KZ |
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 | ||
fa10beec | 164 | /* In order to accommodate multiword subregs of a hardreg, df_scan |
6d9d0028 KZ |
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)) ...) | |
b8698a0f | 180 | |
6d9d0028 KZ |
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. */ | |
b8698a0f | 185 | |
6d9d0028 KZ |
186 | start = offset; |
187 | last = offset + m1_size; | |
188 | ||
189 | if (dump_file) | |
b8698a0f | 190 | fprintf (dump_file, " cpb strict low part regno=%d start=%d last=%d\n", |
6d9d0028 KZ |
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 | |
b8698a0f | 200 | otherwise and set START_BYTE and LAST_BYTE. */ |
6d9d0028 | 201 | |
b8698a0f L |
202 | static bool |
203 | df_compute_accessed_bytes_subreg (df_ref ref, unsigned int *start_byte, | |
6d9d0028 KZ |
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 | ||
fa10beec | 217 | /* In order to accommodate multiword subregs of a hardreg, df_scan |
6d9d0028 KZ |
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. */ | |
57512f53 | 232 | if (DF_REF_REG_DEF_P (ref)) |
6d9d0028 | 233 | { |
b8698a0f | 234 | /* This is an lvalue. */ |
6d9d0028 KZ |
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. | |
b8698a0f | 242 | |
6d9d0028 KZ |
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. | |
b8698a0f | 246 | |
6d9d0028 KZ |
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. | |
b8698a0f | 252 | |
6d9d0028 KZ |
253 | If this is an rvalue, then it touches just the bytes that it |
254 | talks about. */ | |
255 | int offset = SUBREG_BYTE (reg); | |
b8698a0f | 256 | |
6d9d0028 | 257 | start = offset & ~(UNITS_PER_WORD - 1); |
b8698a0f | 258 | last = (offset + m1_size + UNITS_PER_WORD - 1) |
6d9d0028 KZ |
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 | } | |
b8698a0f | 267 | else |
6d9d0028 KZ |
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 | } | |
b8698a0f | 275 | |
6d9d0028 | 276 | if (dump_file) |
b8698a0f | 277 | fprintf (dump_file, " cpb subreg regno=%d start=%d last=%d\n", |
6d9d0028 KZ |
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 | ||
b8698a0f L |
302 | bool |
303 | df_compute_accessed_bytes (df_ref ref, enum df_mm mm, | |
304 | unsigned int *start_byte, | |
6d9d0028 KZ |
305 | unsigned int *last_byte) |
306 | { | |
307 | if (!dbg_cnt (df_byte_scan)) | |
308 | return true; | |
309 | ||
b8698a0f | 310 | if (!DF_REF_REG_DEF_P (ref) |
6d9d0028 KZ |
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)) | |
b8698a0f | 334 | return df_compute_accessed_bytes_strict_low_part (ref, |
6d9d0028 KZ |
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 |