diff options
Diffstat (limited to 'meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106781.patch')
-rw-r--r-- | meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106781.patch | 741 |
1 files changed, 741 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106781.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106781.patch new file mode 100644 index 000000000..a86ddfdec --- /dev/null +++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106781.patch | |||
@@ -0,0 +1,741 @@ | |||
1 | 2011-07-21 Richard Sandiford <richard.sandiford@linaro.org> | ||
2 | |||
3 | gcc/ | ||
4 | PR middle-end/49736 | ||
5 | * expr.c (all_zeros_p): Undo bogus part of last change. | ||
6 | |||
7 | 2011-07-21 Richard Sandiford <richard.sandiford@linaro.org> | ||
8 | |||
9 | Backport from mainline: | ||
10 | gcc/cp/ | ||
11 | 2011-07-13 Richard Sandiford <richard.sandiford@linaro.org> | ||
12 | |||
13 | * typeck2.c (split_nonconstant_init_1): Pass the initializer directly, | ||
14 | rather than a pointer to it. Return true if the whole of the value | ||
15 | was initialized by the generated statements. Use | ||
16 | complete_ctor_at_level_p instead of count_type_elements. | ||
17 | |||
18 | gcc/ | ||
19 | 2011-07-13 Richard Sandiford <richard.sandiford@linaro.org> | ||
20 | |||
21 | * tree.h (categorize_ctor_elements): Remove comment. Fix long line. | ||
22 | (count_type_elements): Delete. | ||
23 | (complete_ctor_at_level_p): Declare. | ||
24 | * expr.c (flexible_array_member_p): New function, split out from... | ||
25 | (count_type_elements): ...here. Make static. Replace allow_flexarr | ||
26 | parameter with for_ctor_p. When for_ctor_p is true, return the | ||
27 | number of elements that should appear in the top-level constructor, | ||
28 | otherwise return an estimate of the number of scalars. | ||
29 | (categorize_ctor_elements): Replace p_must_clear with p_complete. | ||
30 | (categorize_ctor_elements_1): Likewise. Use complete_ctor_at_level_p. | ||
31 | (complete_ctor_at_level_p): New function, borrowing union logic | ||
32 | from old categorize_ctor_elements_1. | ||
33 | (mostly_zeros_p): Return true if the constructor is not complete. | ||
34 | (all_zeros_p): Update call to categorize_ctor_elements. | ||
35 | * gimplify.c (gimplify_init_constructor): Update call to | ||
36 | categorize_ctor_elements. Don't call count_type_elements. | ||
37 | Unconditionally prevent clearing for variable-sized types, | ||
38 | otherwise rely on categorize_ctor_elements to detect | ||
39 | incomplete initializers. | ||
40 | |||
41 | gcc/testsuite/ | ||
42 | 2011-07-13 Chung-Lin Tang <cltang@codesourcery.com> | ||
43 | |||
44 | * gcc.target/arm/pr48183.c: New test. | ||
45 | |||
46 | === modified file 'gcc/cp/typeck2.c' | ||
47 | --- old/gcc/cp/typeck2.c 2011-05-20 21:29:14 +0000 | ||
48 | +++ new/gcc/cp/typeck2.c 2011-07-13 13:17:31 +0000 | ||
49 | @@ -473,18 +473,20 @@ | ||
50 | |||
51 | |||
52 | /* The recursive part of split_nonconstant_init. DEST is an lvalue | ||
53 | - expression to which INIT should be assigned. INIT is a CONSTRUCTOR. */ | ||
54 | + expression to which INIT should be assigned. INIT is a CONSTRUCTOR. | ||
55 | + Return true if the whole of the value was initialized by the | ||
56 | + generated statements. */ | ||
57 | |||
58 | -static void | ||
59 | -split_nonconstant_init_1 (tree dest, tree *initp) | ||
60 | +static bool | ||
61 | +split_nonconstant_init_1 (tree dest, tree init) | ||
62 | { | ||
63 | unsigned HOST_WIDE_INT idx; | ||
64 | - tree init = *initp; | ||
65 | tree field_index, value; | ||
66 | tree type = TREE_TYPE (dest); | ||
67 | tree inner_type = NULL; | ||
68 | bool array_type_p = false; | ||
69 | - HOST_WIDE_INT num_type_elements, num_initialized_elements; | ||
70 | + bool complete_p = true; | ||
71 | + HOST_WIDE_INT num_split_elts = 0; | ||
72 | |||
73 | switch (TREE_CODE (type)) | ||
74 | { | ||
75 | @@ -496,7 +498,6 @@ | ||
76 | case RECORD_TYPE: | ||
77 | case UNION_TYPE: | ||
78 | case QUAL_UNION_TYPE: | ||
79 | - num_initialized_elements = 0; | ||
80 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, | ||
81 | field_index, value) | ||
82 | { | ||
83 | @@ -519,13 +520,14 @@ | ||
84 | sub = build3 (COMPONENT_REF, inner_type, dest, field_index, | ||
85 | NULL_TREE); | ||
86 | |||
87 | - split_nonconstant_init_1 (sub, &value); | ||
88 | + if (!split_nonconstant_init_1 (sub, value)) | ||
89 | + complete_p = false; | ||
90 | + num_split_elts++; | ||
91 | } | ||
92 | else if (!initializer_constant_valid_p (value, inner_type)) | ||
93 | { | ||
94 | tree code; | ||
95 | tree sub; | ||
96 | - HOST_WIDE_INT inner_elements; | ||
97 | |||
98 | /* FIXME: Ordered removal is O(1) so the whole function is | ||
99 | worst-case quadratic. This could be fixed using an aside | ||
100 | @@ -549,21 +551,9 @@ | ||
101 | code = build_stmt (input_location, EXPR_STMT, code); | ||
102 | add_stmt (code); | ||
103 | |||
104 | - inner_elements = count_type_elements (inner_type, true); | ||
105 | - if (inner_elements < 0) | ||
106 | - num_initialized_elements = -1; | ||
107 | - else if (num_initialized_elements >= 0) | ||
108 | - num_initialized_elements += inner_elements; | ||
109 | - continue; | ||
110 | + num_split_elts++; | ||
111 | } | ||
112 | } | ||
113 | - | ||
114 | - num_type_elements = count_type_elements (type, true); | ||
115 | - /* If all elements of the initializer are non-constant and | ||
116 | - have been split out, we don't need the empty CONSTRUCTOR. */ | ||
117 | - if (num_type_elements > 0 | ||
118 | - && num_type_elements == num_initialized_elements) | ||
119 | - *initp = NULL; | ||
120 | break; | ||
121 | |||
122 | case VECTOR_TYPE: | ||
123 | @@ -575,6 +565,7 @@ | ||
124 | code = build2 (MODIFY_EXPR, type, dest, cons); | ||
125 | code = build_stmt (input_location, EXPR_STMT, code); | ||
126 | add_stmt (code); | ||
127 | + num_split_elts += CONSTRUCTOR_NELTS (init); | ||
128 | } | ||
129 | break; | ||
130 | |||
131 | @@ -584,6 +575,8 @@ | ||
132 | |||
133 | /* The rest of the initializer is now a constant. */ | ||
134 | TREE_CONSTANT (init) = 1; | ||
135 | + return complete_p && complete_ctor_at_level_p (TREE_TYPE (init), | ||
136 | + num_split_elts, inner_type); | ||
137 | } | ||
138 | |||
139 | /* A subroutine of store_init_value. Splits non-constant static | ||
140 | @@ -599,7 +592,8 @@ | ||
141 | if (TREE_CODE (init) == CONSTRUCTOR) | ||
142 | { | ||
143 | code = push_stmt_list (); | ||
144 | - split_nonconstant_init_1 (dest, &init); | ||
145 | + if (split_nonconstant_init_1 (dest, init)) | ||
146 | + init = NULL_TREE; | ||
147 | code = pop_stmt_list (code); | ||
148 | DECL_INITIAL (dest) = init; | ||
149 | TREE_READONLY (dest) = 0; | ||
150 | |||
151 | === modified file 'gcc/expr.c' | ||
152 | --- old/gcc/expr.c 2011-06-02 12:12:00 +0000 | ||
153 | +++ new/gcc/expr.c 2011-07-14 11:52:32 +0000 | ||
154 | @@ -4866,16 +4866,136 @@ | ||
155 | return NULL_RTX; | ||
156 | } | ||
157 | |||
158 | +/* Return true if field F of structure TYPE is a flexible array. */ | ||
159 | + | ||
160 | +static bool | ||
161 | +flexible_array_member_p (const_tree f, const_tree type) | ||
162 | +{ | ||
163 | + const_tree tf; | ||
164 | + | ||
165 | + tf = TREE_TYPE (f); | ||
166 | + return (DECL_CHAIN (f) == NULL | ||
167 | + && TREE_CODE (tf) == ARRAY_TYPE | ||
168 | + && TYPE_DOMAIN (tf) | ||
169 | + && TYPE_MIN_VALUE (TYPE_DOMAIN (tf)) | ||
170 | + && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf))) | ||
171 | + && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf)) | ||
172 | + && int_size_in_bytes (type) >= 0); | ||
173 | +} | ||
174 | + | ||
175 | +/* If FOR_CTOR_P, return the number of top-level elements that a constructor | ||
176 | + must have in order for it to completely initialize a value of type TYPE. | ||
177 | + Return -1 if the number isn't known. | ||
178 | + | ||
179 | + If !FOR_CTOR_P, return an estimate of the number of scalars in TYPE. */ | ||
180 | + | ||
181 | +static HOST_WIDE_INT | ||
182 | +count_type_elements (const_tree type, bool for_ctor_p) | ||
183 | +{ | ||
184 | + switch (TREE_CODE (type)) | ||
185 | + { | ||
186 | + case ARRAY_TYPE: | ||
187 | + { | ||
188 | + tree nelts; | ||
189 | + | ||
190 | + nelts = array_type_nelts (type); | ||
191 | + if (nelts && host_integerp (nelts, 1)) | ||
192 | + { | ||
193 | + unsigned HOST_WIDE_INT n; | ||
194 | + | ||
195 | + n = tree_low_cst (nelts, 1) + 1; | ||
196 | + if (n == 0 || for_ctor_p) | ||
197 | + return n; | ||
198 | + else | ||
199 | + return n * count_type_elements (TREE_TYPE (type), false); | ||
200 | + } | ||
201 | + return for_ctor_p ? -1 : 1; | ||
202 | + } | ||
203 | + | ||
204 | + case RECORD_TYPE: | ||
205 | + { | ||
206 | + unsigned HOST_WIDE_INT n; | ||
207 | + tree f; | ||
208 | + | ||
209 | + n = 0; | ||
210 | + for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f)) | ||
211 | + if (TREE_CODE (f) == FIELD_DECL) | ||
212 | + { | ||
213 | + if (!for_ctor_p) | ||
214 | + n += count_type_elements (TREE_TYPE (f), false); | ||
215 | + else if (!flexible_array_member_p (f, type)) | ||
216 | + /* Don't count flexible arrays, which are not supposed | ||
217 | + to be initialized. */ | ||
218 | + n += 1; | ||
219 | + } | ||
220 | + | ||
221 | + return n; | ||
222 | + } | ||
223 | + | ||
224 | + case UNION_TYPE: | ||
225 | + case QUAL_UNION_TYPE: | ||
226 | + { | ||
227 | + tree f; | ||
228 | + HOST_WIDE_INT n, m; | ||
229 | + | ||
230 | + gcc_assert (!for_ctor_p); | ||
231 | + /* Estimate the number of scalars in each field and pick the | ||
232 | + maximum. Other estimates would do instead; the idea is simply | ||
233 | + to make sure that the estimate is not sensitive to the ordering | ||
234 | + of the fields. */ | ||
235 | + n = 1; | ||
236 | + for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f)) | ||
237 | + if (TREE_CODE (f) == FIELD_DECL) | ||
238 | + { | ||
239 | + m = count_type_elements (TREE_TYPE (f), false); | ||
240 | + /* If the field doesn't span the whole union, add an extra | ||
241 | + scalar for the rest. */ | ||
242 | + if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (f)), | ||
243 | + TYPE_SIZE (type)) != 1) | ||
244 | + m++; | ||
245 | + if (n < m) | ||
246 | + n = m; | ||
247 | + } | ||
248 | + return n; | ||
249 | + } | ||
250 | + | ||
251 | + case COMPLEX_TYPE: | ||
252 | + return 2; | ||
253 | + | ||
254 | + case VECTOR_TYPE: | ||
255 | + return TYPE_VECTOR_SUBPARTS (type); | ||
256 | + | ||
257 | + case INTEGER_TYPE: | ||
258 | + case REAL_TYPE: | ||
259 | + case FIXED_POINT_TYPE: | ||
260 | + case ENUMERAL_TYPE: | ||
261 | + case BOOLEAN_TYPE: | ||
262 | + case POINTER_TYPE: | ||
263 | + case OFFSET_TYPE: | ||
264 | + case REFERENCE_TYPE: | ||
265 | + return 1; | ||
266 | + | ||
267 | + case ERROR_MARK: | ||
268 | + return 0; | ||
269 | + | ||
270 | + case VOID_TYPE: | ||
271 | + case METHOD_TYPE: | ||
272 | + case FUNCTION_TYPE: | ||
273 | + case LANG_TYPE: | ||
274 | + default: | ||
275 | + gcc_unreachable (); | ||
276 | + } | ||
277 | +} | ||
278 | + | ||
279 | /* Helper for categorize_ctor_elements. Identical interface. */ | ||
280 | |||
281 | static bool | ||
282 | categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts, | ||
283 | - HOST_WIDE_INT *p_elt_count, | ||
284 | - bool *p_must_clear) | ||
285 | + HOST_WIDE_INT *p_init_elts, bool *p_complete) | ||
286 | { | ||
287 | unsigned HOST_WIDE_INT idx; | ||
288 | - HOST_WIDE_INT nz_elts, elt_count; | ||
289 | - tree value, purpose; | ||
290 | + HOST_WIDE_INT nz_elts, init_elts, num_fields; | ||
291 | + tree value, purpose, elt_type; | ||
292 | |||
293 | /* Whether CTOR is a valid constant initializer, in accordance with what | ||
294 | initializer_constant_valid_p does. If inferred from the constructor | ||
295 | @@ -4884,7 +5004,9 @@ | ||
296 | bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor); | ||
297 | |||
298 | nz_elts = 0; | ||
299 | - elt_count = 0; | ||
300 | + init_elts = 0; | ||
301 | + num_fields = 0; | ||
302 | + elt_type = NULL_TREE; | ||
303 | |||
304 | FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), idx, purpose, value) | ||
305 | { | ||
306 | @@ -4899,6 +5021,8 @@ | ||
307 | mult = (tree_low_cst (hi_index, 1) | ||
308 | - tree_low_cst (lo_index, 1) + 1); | ||
309 | } | ||
310 | + num_fields += mult; | ||
311 | + elt_type = TREE_TYPE (value); | ||
312 | |||
313 | switch (TREE_CODE (value)) | ||
314 | { | ||
315 | @@ -4906,11 +5030,11 @@ | ||
316 | { | ||
317 | HOST_WIDE_INT nz = 0, ic = 0; | ||
318 | |||
319 | - bool const_elt_p | ||
320 | - = categorize_ctor_elements_1 (value, &nz, &ic, p_must_clear); | ||
321 | + bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &ic, | ||
322 | + p_complete); | ||
323 | |||
324 | nz_elts += mult * nz; | ||
325 | - elt_count += mult * ic; | ||
326 | + init_elts += mult * ic; | ||
327 | |||
328 | if (const_from_elts_p && const_p) | ||
329 | const_p = const_elt_p; | ||
330 | @@ -4922,12 +5046,12 @@ | ||
331 | case FIXED_CST: | ||
332 | if (!initializer_zerop (value)) | ||
333 | nz_elts += mult; | ||
334 | - elt_count += mult; | ||
335 | + init_elts += mult; | ||
336 | break; | ||
337 | |||
338 | case STRING_CST: | ||
339 | nz_elts += mult * TREE_STRING_LENGTH (value); | ||
340 | - elt_count += mult * TREE_STRING_LENGTH (value); | ||
341 | + init_elts += mult * TREE_STRING_LENGTH (value); | ||
342 | break; | ||
343 | |||
344 | case COMPLEX_CST: | ||
345 | @@ -4935,7 +5059,7 @@ | ||
346 | nz_elts += mult; | ||
347 | if (!initializer_zerop (TREE_IMAGPART (value))) | ||
348 | nz_elts += mult; | ||
349 | - elt_count += mult; | ||
350 | + init_elts += mult; | ||
351 | break; | ||
352 | |||
353 | case VECTOR_CST: | ||
354 | @@ -4945,65 +5069,31 @@ | ||
355 | { | ||
356 | if (!initializer_zerop (TREE_VALUE (v))) | ||
357 | nz_elts += mult; | ||
358 | - elt_count += mult; | ||
359 | + init_elts += mult; | ||
360 | } | ||
361 | } | ||
362 | break; | ||
363 | |||
364 | default: | ||
365 | { | ||
366 | - HOST_WIDE_INT tc = count_type_elements (TREE_TYPE (value), true); | ||
367 | - if (tc < 1) | ||
368 | - tc = 1; | ||
369 | + HOST_WIDE_INT tc = count_type_elements (elt_type, false); | ||
370 | nz_elts += mult * tc; | ||
371 | - elt_count += mult * tc; | ||
372 | + init_elts += mult * tc; | ||
373 | |||
374 | if (const_from_elts_p && const_p) | ||
375 | - const_p = initializer_constant_valid_p (value, TREE_TYPE (value)) | ||
376 | + const_p = initializer_constant_valid_p (value, elt_type) | ||
377 | != NULL_TREE; | ||
378 | } | ||
379 | break; | ||
380 | } | ||
381 | } | ||
382 | |||
383 | - if (!*p_must_clear | ||
384 | - && (TREE_CODE (TREE_TYPE (ctor)) == UNION_TYPE | ||
385 | - || TREE_CODE (TREE_TYPE (ctor)) == QUAL_UNION_TYPE)) | ||
386 | - { | ||
387 | - tree init_sub_type; | ||
388 | - bool clear_this = true; | ||
389 | - | ||
390 | - if (!VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (ctor))) | ||
391 | - { | ||
392 | - /* We don't expect more than one element of the union to be | ||
393 | - initialized. Not sure what we should do otherwise... */ | ||
394 | - gcc_assert (VEC_length (constructor_elt, CONSTRUCTOR_ELTS (ctor)) | ||
395 | - == 1); | ||
396 | - | ||
397 | - init_sub_type = TREE_TYPE (VEC_index (constructor_elt, | ||
398 | - CONSTRUCTOR_ELTS (ctor), | ||
399 | - 0)->value); | ||
400 | - | ||
401 | - /* ??? We could look at each element of the union, and find the | ||
402 | - largest element. Which would avoid comparing the size of the | ||
403 | - initialized element against any tail padding in the union. | ||
404 | - Doesn't seem worth the effort... */ | ||
405 | - if (simple_cst_equal (TYPE_SIZE (TREE_TYPE (ctor)), | ||
406 | - TYPE_SIZE (init_sub_type)) == 1) | ||
407 | - { | ||
408 | - /* And now we have to find out if the element itself is fully | ||
409 | - constructed. E.g. for union { struct { int a, b; } s; } u | ||
410 | - = { .s = { .a = 1 } }. */ | ||
411 | - if (elt_count == count_type_elements (init_sub_type, false)) | ||
412 | - clear_this = false; | ||
413 | - } | ||
414 | - } | ||
415 | - | ||
416 | - *p_must_clear = clear_this; | ||
417 | - } | ||
418 | + if (*p_complete && !complete_ctor_at_level_p (TREE_TYPE (ctor), | ||
419 | + num_fields, elt_type)) | ||
420 | + *p_complete = false; | ||
421 | |||
422 | *p_nz_elts += nz_elts; | ||
423 | - *p_elt_count += elt_count; | ||
424 | + *p_init_elts += init_elts; | ||
425 | |||
426 | return const_p; | ||
427 | } | ||
428 | @@ -5013,111 +5103,50 @@ | ||
429 | and place it in *P_NZ_ELTS; | ||
430 | * how many scalar fields in total are in CTOR, | ||
431 | and place it in *P_ELT_COUNT. | ||
432 | - * if a type is a union, and the initializer from the constructor | ||
433 | - is not the largest element in the union, then set *p_must_clear. | ||
434 | + * whether the constructor is complete -- in the sense that every | ||
435 | + meaningful byte is explicitly given a value -- | ||
436 | + and place it in *P_COMPLETE. | ||
437 | |||
438 | Return whether or not CTOR is a valid static constant initializer, the same | ||
439 | as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */ | ||
440 | |||
441 | bool | ||
442 | categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts, | ||
443 | - HOST_WIDE_INT *p_elt_count, | ||
444 | - bool *p_must_clear) | ||
445 | + HOST_WIDE_INT *p_init_elts, bool *p_complete) | ||
446 | { | ||
447 | *p_nz_elts = 0; | ||
448 | - *p_elt_count = 0; | ||
449 | - *p_must_clear = false; | ||
450 | + *p_init_elts = 0; | ||
451 | + *p_complete = true; | ||
452 | |||
453 | - return | ||
454 | - categorize_ctor_elements_1 (ctor, p_nz_elts, p_elt_count, p_must_clear); | ||
455 | + return categorize_ctor_elements_1 (ctor, p_nz_elts, p_init_elts, p_complete); | ||
456 | } | ||
457 | |||
458 | -/* Count the number of scalars in TYPE. Return -1 on overflow or | ||
459 | - variable-sized. If ALLOW_FLEXARR is true, don't count flexible | ||
460 | - array member at the end of the structure. */ | ||
461 | +/* TYPE is initialized by a constructor with NUM_ELTS elements, the last | ||
462 | + of which had type LAST_TYPE. Each element was itself a complete | ||
463 | + initializer, in the sense that every meaningful byte was explicitly | ||
464 | + given a value. Return true if the same is true for the constructor | ||
465 | + as a whole. */ | ||
466 | |||
467 | -HOST_WIDE_INT | ||
468 | -count_type_elements (const_tree type, bool allow_flexarr) | ||
469 | +bool | ||
470 | +complete_ctor_at_level_p (const_tree type, HOST_WIDE_INT num_elts, | ||
471 | + const_tree last_type) | ||
472 | { | ||
473 | - const HOST_WIDE_INT max = ~((HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT-1)); | ||
474 | - switch (TREE_CODE (type)) | ||
475 | + if (TREE_CODE (type) == UNION_TYPE | ||
476 | + || TREE_CODE (type) == QUAL_UNION_TYPE) | ||
477 | { | ||
478 | - case ARRAY_TYPE: | ||
479 | - { | ||
480 | - tree telts = array_type_nelts (type); | ||
481 | - if (telts && host_integerp (telts, 1)) | ||
482 | - { | ||
483 | - HOST_WIDE_INT n = tree_low_cst (telts, 1) + 1; | ||
484 | - HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type), false); | ||
485 | - if (n == 0) | ||
486 | - return 0; | ||
487 | - else if (max / n > m) | ||
488 | - return n * m; | ||
489 | - } | ||
490 | - return -1; | ||
491 | - } | ||
492 | - | ||
493 | - case RECORD_TYPE: | ||
494 | - { | ||
495 | - HOST_WIDE_INT n = 0, t; | ||
496 | - tree f; | ||
497 | - | ||
498 | - for (f = TYPE_FIELDS (type); f ; f = DECL_CHAIN (f)) | ||
499 | - if (TREE_CODE (f) == FIELD_DECL) | ||
500 | - { | ||
501 | - t = count_type_elements (TREE_TYPE (f), false); | ||
502 | - if (t < 0) | ||
503 | - { | ||
504 | - /* Check for structures with flexible array member. */ | ||
505 | - tree tf = TREE_TYPE (f); | ||
506 | - if (allow_flexarr | ||
507 | - && DECL_CHAIN (f) == NULL | ||
508 | - && TREE_CODE (tf) == ARRAY_TYPE | ||
509 | - && TYPE_DOMAIN (tf) | ||
510 | - && TYPE_MIN_VALUE (TYPE_DOMAIN (tf)) | ||
511 | - && integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (tf))) | ||
512 | - && !TYPE_MAX_VALUE (TYPE_DOMAIN (tf)) | ||
513 | - && int_size_in_bytes (type) >= 0) | ||
514 | - break; | ||
515 | - | ||
516 | - return -1; | ||
517 | - } | ||
518 | - n += t; | ||
519 | - } | ||
520 | - | ||
521 | - return n; | ||
522 | - } | ||
523 | - | ||
524 | - case UNION_TYPE: | ||
525 | - case QUAL_UNION_TYPE: | ||
526 | - return -1; | ||
527 | - | ||
528 | - case COMPLEX_TYPE: | ||
529 | - return 2; | ||
530 | - | ||
531 | - case VECTOR_TYPE: | ||
532 | - return TYPE_VECTOR_SUBPARTS (type); | ||
533 | - | ||
534 | - case INTEGER_TYPE: | ||
535 | - case REAL_TYPE: | ||
536 | - case FIXED_POINT_TYPE: | ||
537 | - case ENUMERAL_TYPE: | ||
538 | - case BOOLEAN_TYPE: | ||
539 | - case POINTER_TYPE: | ||
540 | - case OFFSET_TYPE: | ||
541 | - case REFERENCE_TYPE: | ||
542 | - return 1; | ||
543 | - | ||
544 | - case ERROR_MARK: | ||
545 | - return 0; | ||
546 | - | ||
547 | - case VOID_TYPE: | ||
548 | - case METHOD_TYPE: | ||
549 | - case FUNCTION_TYPE: | ||
550 | - case LANG_TYPE: | ||
551 | - default: | ||
552 | - gcc_unreachable (); | ||
553 | + if (num_elts == 0) | ||
554 | + return false; | ||
555 | + | ||
556 | + gcc_assert (num_elts == 1 && last_type); | ||
557 | + | ||
558 | + /* ??? We could look at each element of the union, and find the | ||
559 | + largest element. Which would avoid comparing the size of the | ||
560 | + initialized element against any tail padding in the union. | ||
561 | + Doesn't seem worth the effort... */ | ||
562 | + return simple_cst_equal (TYPE_SIZE (type), TYPE_SIZE (last_type)) == 1; | ||
563 | } | ||
564 | + | ||
565 | + return count_type_elements (type, true) == num_elts; | ||
566 | } | ||
567 | |||
568 | /* Return 1 if EXP contains mostly (3/4) zeros. */ | ||
569 | @@ -5126,18 +5155,12 @@ | ||
570 | mostly_zeros_p (const_tree exp) | ||
571 | { | ||
572 | if (TREE_CODE (exp) == CONSTRUCTOR) | ||
573 | - | ||
574 | { | ||
575 | - HOST_WIDE_INT nz_elts, count, elts; | ||
576 | - bool must_clear; | ||
577 | - | ||
578 | - categorize_ctor_elements (exp, &nz_elts, &count, &must_clear); | ||
579 | - if (must_clear) | ||
580 | - return 1; | ||
581 | - | ||
582 | - elts = count_type_elements (TREE_TYPE (exp), false); | ||
583 | - | ||
584 | - return nz_elts < elts / 4; | ||
585 | + HOST_WIDE_INT nz_elts, init_elts; | ||
586 | + bool complete_p; | ||
587 | + | ||
588 | + categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p); | ||
589 | + return !complete_p || nz_elts < init_elts / 4; | ||
590 | } | ||
591 | |||
592 | return initializer_zerop (exp); | ||
593 | @@ -5149,12 +5172,11 @@ | ||
594 | all_zeros_p (const_tree exp) | ||
595 | { | ||
596 | if (TREE_CODE (exp) == CONSTRUCTOR) | ||
597 | - | ||
598 | { | ||
599 | - HOST_WIDE_INT nz_elts, count; | ||
600 | - bool must_clear; | ||
601 | + HOST_WIDE_INT nz_elts, init_elts; | ||
602 | + bool complete_p; | ||
603 | |||
604 | - categorize_ctor_elements (exp, &nz_elts, &count, &must_clear); | ||
605 | + categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p); | ||
606 | return nz_elts == 0; | ||
607 | } | ||
608 | |||
609 | |||
610 | === modified file 'gcc/gimplify.c' | ||
611 | --- old/gcc/gimplify.c 2011-05-26 10:27:57 +0000 | ||
612 | +++ new/gcc/gimplify.c 2011-07-13 13:17:31 +0000 | ||
613 | @@ -3693,9 +3693,8 @@ | ||
614 | case ARRAY_TYPE: | ||
615 | { | ||
616 | struct gimplify_init_ctor_preeval_data preeval_data; | ||
617 | - HOST_WIDE_INT num_type_elements, num_ctor_elements; | ||
618 | - HOST_WIDE_INT num_nonzero_elements; | ||
619 | - bool cleared, valid_const_initializer; | ||
620 | + HOST_WIDE_INT num_ctor_elements, num_nonzero_elements; | ||
621 | + bool cleared, complete_p, valid_const_initializer; | ||
622 | |||
623 | /* Aggregate types must lower constructors to initialization of | ||
624 | individual elements. The exception is that a CONSTRUCTOR node | ||
625 | @@ -3712,7 +3711,7 @@ | ||
626 | can only do so if it known to be a valid constant initializer. */ | ||
627 | valid_const_initializer | ||
628 | = categorize_ctor_elements (ctor, &num_nonzero_elements, | ||
629 | - &num_ctor_elements, &cleared); | ||
630 | + &num_ctor_elements, &complete_p); | ||
631 | |||
632 | /* If a const aggregate variable is being initialized, then it | ||
633 | should never be a lose to promote the variable to be static. */ | ||
634 | @@ -3750,26 +3749,29 @@ | ||
635 | parts in, then generate code for the non-constant parts. */ | ||
636 | /* TODO. There's code in cp/typeck.c to do this. */ | ||
637 | |||
638 | - num_type_elements = count_type_elements (type, true); | ||
639 | + if (int_size_in_bytes (TREE_TYPE (ctor)) < 0) | ||
640 | + /* store_constructor will ignore the clearing of variable-sized | ||
641 | + objects. Initializers for such objects must explicitly set | ||
642 | + every field that needs to be set. */ | ||
643 | + cleared = false; | ||
644 | + else if (!complete_p) | ||
645 | + /* If the constructor isn't complete, clear the whole object | ||
646 | + beforehand. | ||
647 | |||
648 | - /* If count_type_elements could not determine number of type elements | ||
649 | - for a constant-sized object, assume clearing is needed. | ||
650 | - Don't do this for variable-sized objects, as store_constructor | ||
651 | - will ignore the clearing of variable-sized objects. */ | ||
652 | - if (num_type_elements < 0 && int_size_in_bytes (type) >= 0) | ||
653 | + ??? This ought not to be needed. For any element not present | ||
654 | + in the initializer, we should simply set them to zero. Except | ||
655 | + we'd need to *find* the elements that are not present, and that | ||
656 | + requires trickery to avoid quadratic compile-time behavior in | ||
657 | + large cases or excessive memory use in small cases. */ | ||
658 | cleared = true; | ||
659 | - /* If there are "lots" of zeros, then block clear the object first. */ | ||
660 | - else if (num_type_elements - num_nonzero_elements | ||
661 | + else if (num_ctor_elements - num_nonzero_elements | ||
662 | > CLEAR_RATIO (optimize_function_for_speed_p (cfun)) | ||
663 | - && num_nonzero_elements < num_type_elements/4) | ||
664 | - cleared = true; | ||
665 | - /* ??? This bit ought not be needed. For any element not present | ||
666 | - in the initializer, we should simply set them to zero. Except | ||
667 | - we'd need to *find* the elements that are not present, and that | ||
668 | - requires trickery to avoid quadratic compile-time behavior in | ||
669 | - large cases or excessive memory use in small cases. */ | ||
670 | - else if (num_ctor_elements < num_type_elements) | ||
671 | - cleared = true; | ||
672 | + && num_nonzero_elements < num_ctor_elements / 4) | ||
673 | + /* If there are "lots" of zeros, it's more efficient to clear | ||
674 | + the memory and then set the nonzero elements. */ | ||
675 | + cleared = true; | ||
676 | + else | ||
677 | + cleared = false; | ||
678 | |||
679 | /* If there are "lots" of initialized elements, and all of them | ||
680 | are valid address constants, then the entire initializer can | ||
681 | |||
682 | === added file 'gcc/testsuite/gcc.target/arm/pr48183.c' | ||
683 | --- old/gcc/testsuite/gcc.target/arm/pr48183.c 1970-01-01 00:00:00 +0000 | ||
684 | +++ new/gcc/testsuite/gcc.target/arm/pr48183.c 2011-07-13 13:17:31 +0000 | ||
685 | @@ -0,0 +1,25 @@ | ||
686 | +/* testsuite/gcc.target/arm/pr48183.c */ | ||
687 | + | ||
688 | +/* { dg-do compile } */ | ||
689 | +/* { dg-require-effective-target arm_neon_ok } */ | ||
690 | +/* { dg-options "-O -g" } */ | ||
691 | +/* { dg-add-options arm_neon } */ | ||
692 | + | ||
693 | +#include <arm_neon.h> | ||
694 | + | ||
695 | +void move_16bit_to_32bit (int32_t *dst, const short *src, unsigned n) | ||
696 | +{ | ||
697 | + unsigned i; | ||
698 | + int16x4x2_t input; | ||
699 | + int32x4x2_t mid; | ||
700 | + int32x4x2_t output; | ||
701 | + | ||
702 | + for (i = 0; i < n/2; i += 8) { | ||
703 | + input = vld2_s16(src + i); | ||
704 | + mid.val[0] = vmovl_s16(input.val[0]); | ||
705 | + mid.val[1] = vmovl_s16(input.val[1]); | ||
706 | + output.val[0] = vshlq_n_s32(mid.val[0], 8); | ||
707 | + output.val[1] = vshlq_n_s32(mid.val[1], 8); | ||
708 | + vst2q_s32((int32_t *)dst + i, output); | ||
709 | + } | ||
710 | +} | ||
711 | |||
712 | === modified file 'gcc/tree.h' | ||
713 | --- old/gcc/tree.h 2011-07-01 09:19:21 +0000 | ||
714 | +++ new/gcc/tree.h 2011-07-13 13:17:31 +0000 | ||
715 | @@ -4627,21 +4627,10 @@ | ||
716 | |||
717 | extern VEC(tree,gc) *ctor_to_vec (tree); | ||
718 | |||
719 | -/* Examine CTOR to discover: | ||
720 | - * how many scalar fields are set to nonzero values, | ||
721 | - and place it in *P_NZ_ELTS; | ||
722 | - * how many scalar fields in total are in CTOR, | ||
723 | - and place it in *P_ELT_COUNT. | ||
724 | - * if a type is a union, and the initializer from the constructor | ||
725 | - is not the largest element in the union, then set *p_must_clear. | ||
726 | - | ||
727 | - Return whether or not CTOR is a valid static constant initializer, the same | ||
728 | - as "initializer_constant_valid_p (CTOR, TREE_TYPE (CTOR)) != 0". */ | ||
729 | - | ||
730 | -extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *, HOST_WIDE_INT *, | ||
731 | - bool *); | ||
732 | - | ||
733 | -extern HOST_WIDE_INT count_type_elements (const_tree, bool); | ||
734 | +extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *, | ||
735 | + HOST_WIDE_INT *, bool *); | ||
736 | + | ||
737 | +extern bool complete_ctor_at_level_p (const_tree, HOST_WIDE_INT, const_tree); | ||
738 | |||
739 | /* integer_zerop (tree x) is nonzero if X is an integer constant of value 0. */ | ||
740 | |||
741 | |||