summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106781.patch
diff options
context:
space:
mode:
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.patch741
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 @@
12011-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
72011-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