summaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-devtools
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2012-03-06 17:21:34 +0000
committerKhem Raj <raj.khem@gmail.com>2012-03-08 18:57:24 -0800
commitf256ccfb85b8b14b9b72991d5be1d3ec02f828a8 (patch)
tree543109c7ccfc9b40e76662d1fccef5e257ff360c /meta-oe/recipes-devtools
parent8a728abad7307e968a03b333811fc1f816ba18b4 (diff)
downloadmeta-openembedded-f256ccfb85b8b14b9b72991d5be1d3ec02f828a8.tar.gz
gcc-4.6: Adjust to match gcc 4.6.3 from OE-Core
Update linaro patches Signed-off-by: Khem Raj <raj.khem@gmail.com>
Diffstat (limited to 'meta-oe/recipes-devtools')
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/fix_linaro_106872.patch45
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106740.patch294
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106741.patch50
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106827.patch132
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106842.patch59
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106854.patch354
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106860.patch104
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106861.patch76
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106862.patch45
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106863.patch47
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106864.patch63
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106865.patch25
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch2389
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106870.patch28
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106872.patch126
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106873.patch80
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106874.patch46
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4_6-branch-linaro-backports.inc14
18 files changed, 3197 insertions, 780 deletions
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/fix_linaro_106872.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/fix_linaro_106872.patch
new file mode 100644
index 000000000..ef33afff7
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/fix_linaro_106872.patch
@@ -0,0 +1,45 @@
1Index: gcc-4_6-branch/gcc/config/arm/arm.c
2===================================================================
3--- gcc-4_6-branch.orig/gcc/config/arm/arm.c 2012-03-05 17:14:09.901129286 -0800
4+++ gcc-4_6-branch/gcc/config/arm/arm.c 2012-03-05 17:18:23.061141606 -0800
5@@ -17525,6 +17525,13 @@
6 }
7 return;
8
9+ case 'v':
10+ {
11+ gcc_assert (GET_CODE (x) == CONST_DOUBLE);
12+ fprintf (stream, "#%d", vfp3_const_double_for_fract_bits (x));
13+ return;
14+ }
15+
16 /* Register specifier for vld1.16/vst1.16. Translate the S register
17 number into a D register number and element index. */
18 case 'z':
19@@ -24925,4 +24932,26 @@
20 return 4;
21 }
22
23+int
24+vfp3_const_double_for_fract_bits (rtx operand)
25+{
26+ REAL_VALUE_TYPE r0;
27+
28+ if (GET_CODE (operand) != CONST_DOUBLE)
29+ return 0;
30+
31+ REAL_VALUE_FROM_CONST_DOUBLE (r0, operand);
32+ if (exact_real_inverse (DFmode, &r0))
33+ {
34+ if (exact_real_truncate (DFmode, &r0))
35+ {
36+ HOST_WIDE_INT value = real_to_integer (&r0);
37+ value = value & 0xffffffff;
38+ if ((value != 0) && ( (value & (value - 1)) == 0))
39+ return int_log2 (value);
40+ }
41+ }
42+ return 0;
43+}
44+
45 #include "gt-arm.h"
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106740.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106740.patch
deleted file mode 100644
index 11a1da670..000000000
--- a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106740.patch
+++ /dev/null
@@ -1,294 +0,0 @@
12011-05-04 Richard Sandiford <richard.sandiford@linaro.org>
2
3 Backport from mainline:
4
5 2011-03-29 Richard Sandiford <richard.sandiford@linaro.org>
6
7 PR debug/48190
8 * dwarf2out.c (dw_loc_list_node): Add resolved_addr and replaced.
9 (cached_dw_loc_list_def): New structure.
10 (cached_dw_loc_list): New typedef.
11 (cached_dw_loc_list_table): New variable.
12 (cached_dw_loc_list_table_hash): New function.
13 (cached_dw_loc_list_table_eq): Likewise.
14 (add_location_or_const_value_attribute): Take a bool cache_p.
15 Cache the list when the parameter is true.
16 (gen_formal_parameter_die): Update caller.
17 (gen_variable_die): Likewise.
18 (dwarf2out_finish): Likewise.
19 (dwarf2out_abstract_function): Nullify cached_dw_loc_list_table
20 while generating debug info for the decl.
21 (dwarf2out_function_decl): Clear cached_dw_loc_list_table.
22 (dwarf2out_init): Initialize cached_dw_loc_list_table.
23 (resolve_addr): Cache the result of resolving a chain of
24 location lists.
25
26=== modified file 'gcc/dwarf2out.c'
27--- old/gcc/dwarf2out.c 2011-03-29 22:47:59 +0000
28+++ new/gcc/dwarf2out.c 2011-05-04 13:20:12 +0000
29@@ -4427,6 +4427,11 @@
30 const char *section; /* Section this loclist is relative to */
31 dw_loc_descr_ref expr;
32 hashval_t hash;
33+ /* True if all addresses in this and subsequent lists are known to be
34+ resolved. */
35+ bool resolved_addr;
36+ /* True if this list has been replaced by dw_loc_next. */
37+ bool replaced;
38 bool emitted;
39 } dw_loc_list_node;
40
41@@ -6087,6 +6092,19 @@
42 /* Table of decl location linked lists. */
43 static GTY ((param_is (var_loc_list))) htab_t decl_loc_table;
44
45+/* A cached location list. */
46+struct GTY (()) cached_dw_loc_list_def {
47+ /* The DECL_UID of the decl that this entry describes. */
48+ unsigned int decl_id;
49+
50+ /* The cached location list. */
51+ dw_loc_list_ref loc_list;
52+};
53+typedef struct cached_dw_loc_list_def cached_dw_loc_list;
54+
55+/* Table of cached location lists. */
56+static GTY ((param_is (cached_dw_loc_list))) htab_t cached_dw_loc_list_table;
57+
58 /* A pointer to the base of a list of references to DIE's that
59 are uniquely identified by their tag, presence/absence of
60 children DIE's, and list of attribute/value pairs. */
61@@ -6434,7 +6452,7 @@
62 static void insert_double (double_int, unsigned char *);
63 static void insert_float (const_rtx, unsigned char *);
64 static rtx rtl_for_decl_location (tree);
65-static bool add_location_or_const_value_attribute (dw_die_ref, tree,
66+static bool add_location_or_const_value_attribute (dw_die_ref, tree, bool,
67 enum dwarf_attribute);
68 static bool tree_add_const_value_attribute (dw_die_ref, tree);
69 static bool tree_add_const_value_attribute_for_decl (dw_die_ref, tree);
70@@ -8168,6 +8186,24 @@
71 htab_find_with_hash (decl_loc_table, decl, DECL_UID (decl));
72 }
73
74+/* Returns a hash value for X (which really is a cached_dw_loc_list_list). */
75+
76+static hashval_t
77+cached_dw_loc_list_table_hash (const void *x)
78+{
79+ return (hashval_t) ((const cached_dw_loc_list *) x)->decl_id;
80+}
81+
82+/* Return nonzero if decl_id of cached_dw_loc_list X is the same as
83+ UID of decl *Y. */
84+
85+static int
86+cached_dw_loc_list_table_eq (const void *x, const void *y)
87+{
88+ return (((const cached_dw_loc_list *) x)->decl_id
89+ == DECL_UID ((const_tree) y));
90+}
91+
92 /* Equate a DIE to a particular declaration. */
93
94 static void
95@@ -16965,15 +17001,22 @@
96 these things can crop up in other ways also.) Note that one type of
97 constant value which can be passed into an inlined function is a constant
98 pointer. This can happen for example if an actual argument in an inlined
99- function call evaluates to a compile-time constant address. */
100+ function call evaluates to a compile-time constant address.
101+
102+ CACHE_P is true if it is worth caching the location list for DECL,
103+ so that future calls can reuse it rather than regenerate it from scratch.
104+ This is true for BLOCK_NONLOCALIZED_VARS in inlined subroutines,
105+ since we will need to refer to them each time the function is inlined. */
106
107 static bool
108-add_location_or_const_value_attribute (dw_die_ref die, tree decl,
109+add_location_or_const_value_attribute (dw_die_ref die, tree decl, bool cache_p,
110 enum dwarf_attribute attr)
111 {
112 rtx rtl;
113 dw_loc_list_ref list;
114 var_loc_list *loc_list;
115+ cached_dw_loc_list *cache;
116+ void **slot;
117
118 if (TREE_CODE (decl) == ERROR_MARK)
119 return false;
120@@ -17010,7 +17053,33 @@
121 && add_const_value_attribute (die, rtl))
122 return true;
123 }
124- list = loc_list_from_tree (decl, decl_by_reference_p (decl) ? 0 : 2);
125+ /* If this decl is from BLOCK_NONLOCALIZED_VARS, we might need its
126+ list several times. See if we've already cached the contents. */
127+ list = NULL;
128+ if (loc_list == NULL || cached_dw_loc_list_table == NULL)
129+ cache_p = false;
130+ if (cache_p)
131+ {
132+ cache = (cached_dw_loc_list *)
133+ htab_find_with_hash (cached_dw_loc_list_table, decl, DECL_UID (decl));
134+ if (cache)
135+ list = cache->loc_list;
136+ }
137+ if (list == NULL)
138+ {
139+ list = loc_list_from_tree (decl, decl_by_reference_p (decl) ? 0 : 2);
140+ /* It is usually worth caching this result if the decl is from
141+ BLOCK_NONLOCALIZED_VARS and if the list has at least two elements. */
142+ if (cache_p && list && list->dw_loc_next)
143+ {
144+ slot = htab_find_slot_with_hash (cached_dw_loc_list_table, decl,
145+ DECL_UID (decl), INSERT);
146+ cache = ggc_alloc_cleared_cached_dw_loc_list ();
147+ cache->decl_id = DECL_UID (decl);
148+ cache->loc_list = list;
149+ *slot = cache;
150+ }
151+ }
152 if (list)
153 {
154 add_AT_location_description (die, attr, list);
155@@ -18702,7 +18771,7 @@
156 equate_decl_number_to_die (node, parm_die);
157 if (! DECL_ABSTRACT (node_or_origin))
158 add_location_or_const_value_attribute (parm_die, node_or_origin,
159- DW_AT_location);
160+ node == NULL, DW_AT_location);
161
162 break;
163
164@@ -18887,6 +18956,7 @@
165 tree context;
166 int was_abstract;
167 htab_t old_decl_loc_table;
168+ htab_t old_cached_dw_loc_list_table;
169
170 /* Make sure we have the actual abstract inline, not a clone. */
171 decl = DECL_ORIGIN (decl);
172@@ -18901,6 +18971,8 @@
173 get locations in abstract instantces. */
174 old_decl_loc_table = decl_loc_table;
175 decl_loc_table = NULL;
176+ old_cached_dw_loc_list_table = cached_dw_loc_list_table;
177+ cached_dw_loc_list_table = NULL;
178
179 /* Be sure we've emitted the in-class declaration DIE (if any) first, so
180 we don't get confused by DECL_ABSTRACT. */
181@@ -18925,6 +18997,7 @@
182
183 current_function_decl = save_fn;
184 decl_loc_table = old_decl_loc_table;
185+ cached_dw_loc_list_table = old_cached_dw_loc_list_table;
186 pop_cfun ();
187 }
188
189@@ -19709,9 +19782,8 @@
190 && !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl_or_origin)))
191 defer_location (decl_or_origin, var_die);
192 else
193- add_location_or_const_value_attribute (var_die,
194- decl_or_origin,
195- DW_AT_location);
196+ add_location_or_const_value_attribute (var_die, decl_or_origin,
197+ decl == NULL, DW_AT_location);
198 add_pubname (decl_or_origin, var_die);
199 }
200 else
201@@ -21498,6 +21570,7 @@
202 dwarf2out_decl (decl);
203
204 htab_empty (decl_loc_table);
205+ htab_empty (cached_dw_loc_list_table);
206 }
207
208 /* Output a marker (i.e. a label) for the beginning of the generated code for
209@@ -22230,6 +22303,11 @@
210 decl_loc_table = htab_create_ggc (10, decl_loc_table_hash,
211 decl_loc_table_eq, NULL);
212
213+ /* Allocate the cached_dw_loc_list_table. */
214+ cached_dw_loc_list_table
215+ = htab_create_ggc (10, cached_dw_loc_list_table_hash,
216+ cached_dw_loc_list_table_eq, NULL);
217+
218 /* Allocate the initial hunk of the decl_scope_table. */
219 decl_scope_table = VEC_alloc (tree, gc, 256);
220
221@@ -22870,30 +22948,53 @@
222 {
223 dw_die_ref c;
224 dw_attr_ref a;
225- dw_loc_list_ref *curr;
226+ dw_loc_list_ref *curr, *start, loc;
227 unsigned ix;
228
229 FOR_EACH_VEC_ELT (dw_attr_node, die->die_attr, ix, a)
230 switch (AT_class (a))
231 {
232 case dw_val_class_loc_list:
233- curr = AT_loc_list_ptr (a);
234- while (*curr)
235+ start = curr = AT_loc_list_ptr (a);
236+ loc = *curr;
237+ gcc_assert (loc);
238+ /* The same list can be referenced more than once. See if we have
239+ already recorded the result from a previous pass. */
240+ if (loc->replaced)
241+ *curr = loc->dw_loc_next;
242+ else if (!loc->resolved_addr)
243 {
244- if (!resolve_addr_in_expr ((*curr)->expr))
245+ /* As things stand, we do not expect or allow one die to
246+ reference a suffix of another die's location list chain.
247+ References must be identical or completely separate.
248+ There is therefore no need to cache the result of this
249+ pass on any list other than the first; doing so
250+ would lead to unnecessary writes. */
251+ while (*curr)
252 {
253- dw_loc_list_ref next = (*curr)->dw_loc_next;
254- if (next && (*curr)->ll_symbol)
255+ gcc_assert (!(*curr)->replaced && !(*curr)->resolved_addr);
256+ if (!resolve_addr_in_expr ((*curr)->expr))
257 {
258- gcc_assert (!next->ll_symbol);
259- next->ll_symbol = (*curr)->ll_symbol;
260+ dw_loc_list_ref next = (*curr)->dw_loc_next;
261+ if (next && (*curr)->ll_symbol)
262+ {
263+ gcc_assert (!next->ll_symbol);
264+ next->ll_symbol = (*curr)->ll_symbol;
265+ }
266+ *curr = next;
267 }
268- *curr = next;
269+ else
270+ curr = &(*curr)->dw_loc_next;
271 }
272+ if (loc == *start)
273+ loc->resolved_addr = 1;
274 else
275- curr = &(*curr)->dw_loc_next;
276+ {
277+ loc->replaced = 1;
278+ loc->dw_loc_next = *start;
279+ }
280 }
281- if (!AT_loc_list (a))
282+ if (!*start)
283 {
284 remove_AT (die, a->dw_attr);
285 ix--;
286@@ -23322,6 +23423,7 @@
287 add_location_or_const_value_attribute (
288 VEC_index (deferred_locations, deferred_locations_list, i)->die,
289 VEC_index (deferred_locations, deferred_locations_list, i)->variable,
290+ false,
291 DW_AT_location);
292 }
293
294
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106741.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106741.patch
index f53b26a88..6e76c2127 100644
--- a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106741.patch
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106741.patch
@@ -19,8 +19,8 @@
19=== modified file 'gcc/combine.c' 19=== modified file 'gcc/combine.c'
20Index: gcc-4_6-branch/gcc/combine.c 20Index: gcc-4_6-branch/gcc/combine.c
21=================================================================== 21===================================================================
22--- gcc-4_6-branch.orig/gcc/combine.c 2011-09-16 19:58:21.000000000 -0700 22--- gcc-4_6-branch.orig/gcc/combine.c 2012-03-05 00:16:20.000000000 -0800
23+++ gcc-4_6-branch/gcc/combine.c 2011-09-16 20:05:36.626650681 -0700 23+++ gcc-4_6-branch/gcc/combine.c 2012-03-05 16:05:01.212928507 -0800
24@@ -391,8 +391,8 @@ 24@@ -391,8 +391,8 @@
25 static void undo_all (void); 25 static void undo_all (void);
26 static void undo_commit (void); 26 static void undo_commit (void);
@@ -32,7 +32,7 @@ Index: gcc-4_6-branch/gcc/combine.c
32 static rtx simplify_if_then_else (rtx); 32 static rtx simplify_if_then_else (rtx);
33 static rtx simplify_set (rtx); 33 static rtx simplify_set (rtx);
34 static rtx simplify_logical (rtx); 34 static rtx simplify_logical (rtx);
35@@ -3112,12 +3112,12 @@ 35@@ -3119,12 +3119,12 @@
36 if (i1) 36 if (i1)
37 { 37 {
38 subst_low_luid = DF_INSN_LUID (i1); 38 subst_low_luid = DF_INSN_LUID (i1);
@@ -47,7 +47,7 @@ Index: gcc-4_6-branch/gcc/combine.c
47 } 47 }
48 } 48 }
49 49
50@@ -3129,7 +3129,7 @@ 50@@ -3136,7 +3136,7 @@
51 self-referential RTL when we will be substituting I1SRC for I1DEST 51 self-referential RTL when we will be substituting I1SRC for I1DEST
52 later. Likewise if I0 feeds into I2, either directly or indirectly 52 later. Likewise if I0 feeds into I2, either directly or indirectly
53 through I1, and I0DEST is in I0SRC. */ 53 through I1, and I0DEST is in I0SRC. */
@@ -56,7 +56,7 @@ Index: gcc-4_6-branch/gcc/combine.c
56 (i1_feeds_i2_n && i1dest_in_i1src) 56 (i1_feeds_i2_n && i1dest_in_i1src)
57 || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n)) 57 || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n))
58 && i0dest_in_i0src)); 58 && i0dest_in_i0src));
59@@ -3168,7 +3168,7 @@ 59@@ -3180,7 +3180,7 @@
60 copy of I1SRC each time we substitute it, in order to avoid creating 60 copy of I1SRC each time we substitute it, in order to avoid creating
61 self-referential RTL when we will be substituting I0SRC for I0DEST 61 self-referential RTL when we will be substituting I0SRC for I0DEST
62 later. */ 62 later. */
@@ -65,7 +65,7 @@ Index: gcc-4_6-branch/gcc/combine.c
65 i0_feeds_i1_n && i0dest_in_i0src); 65 i0_feeds_i1_n && i0dest_in_i0src);
66 substed_i1 = 1; 66 substed_i1 = 1;
67 67
68@@ -3198,7 +3198,7 @@ 68@@ -3214,7 +3214,7 @@
69 69
70 n_occurrences = 0; 70 n_occurrences = 0;
71 subst_low_luid = DF_INSN_LUID (i0); 71 subst_low_luid = DF_INSN_LUID (i0);
@@ -74,16 +74,16 @@ Index: gcc-4_6-branch/gcc/combine.c
74 substed_i0 = 1; 74 substed_i0 = 1;
75 } 75 }
76 76
77@@ -3260,7 +3260,7 @@ 77@@ -3276,7 +3276,7 @@
78 { 78 {
79 rtx t = i1pat; 79 rtx t = i1pat;
80 if (i0_feeds_i1_n) 80 if (i0_feeds_i1_n)
81- t = subst (t, i0dest, i0src, 0, 0); 81- t = subst (t, i0dest, i0src_copy ? i0src_copy : i0src, 0, 0);
82+ t = subst (t, i0dest, i0src, 0, 0, 0); 82+ t = subst (t, i0dest, i0src_copy ? i0src_copy : i0src, 0, 0, 0);
83 83
84 XVECEXP (newpat, 0, --total_sets) = t; 84 XVECEXP (newpat, 0, --total_sets) = t;
85 } 85 }
86@@ -3268,10 +3268,10 @@ 86@@ -3284,10 +3284,10 @@
87 { 87 {
88 rtx t = i2pat; 88 rtx t = i2pat;
89 if (i1_feeds_i2_n) 89 if (i1_feeds_i2_n)
@@ -91,12 +91,12 @@ Index: gcc-4_6-branch/gcc/combine.c
91+ t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, 0, 0, 91+ t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, 0, 0,
92 i0_feeds_i1_n && i0dest_in_i0src); 92 i0_feeds_i1_n && i0dest_in_i0src);
93 if ((i0_feeds_i1_n && i1_feeds_i2_n) || i0_feeds_i2_n) 93 if ((i0_feeds_i1_n && i1_feeds_i2_n) || i0_feeds_i2_n)
94- t = subst (t, i0dest, i0src, 0, 0); 94- t = subst (t, i0dest, i0src_copy2 ? i0src_copy2 : i0src, 0, 0);
95+ t = subst (t, i0dest, i0src, 0, 0, 0); 95+ t = subst (t, i0dest, i0src_copy2 ? i0src_copy2 : i0src, 0, 0, 0);
96 96
97 XVECEXP (newpat, 0, --total_sets) = t; 97 XVECEXP (newpat, 0, --total_sets) = t;
98 } 98 }
99@@ -4943,11 +4943,13 @@ 99@@ -4959,11 +4959,13 @@
100 100
101 IN_DEST is nonzero if we are processing the SET_DEST of a SET. 101 IN_DEST is nonzero if we are processing the SET_DEST of a SET.
102 102
@@ -111,7 +111,7 @@ Index: gcc-4_6-branch/gcc/combine.c
111 { 111 {
112 enum rtx_code code = GET_CODE (x); 112 enum rtx_code code = GET_CODE (x);
113 enum machine_mode op0_mode = VOIDmode; 113 enum machine_mode op0_mode = VOIDmode;
114@@ -5008,7 +5010,7 @@ 114@@ -5024,7 +5026,7 @@
115 && GET_CODE (XVECEXP (x, 0, 0)) == SET 115 && GET_CODE (XVECEXP (x, 0, 0)) == SET
116 && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS) 116 && GET_CODE (SET_SRC (XVECEXP (x, 0, 0))) == ASM_OPERANDS)
117 { 117 {
@@ -120,7 +120,7 @@ Index: gcc-4_6-branch/gcc/combine.c
120 120
121 /* If this substitution failed, this whole thing fails. */ 121 /* If this substitution failed, this whole thing fails. */
122 if (GET_CODE (new_rtx) == CLOBBER 122 if (GET_CODE (new_rtx) == CLOBBER
123@@ -5025,7 +5027,7 @@ 123@@ -5041,7 +5043,7 @@
124 && GET_CODE (dest) != CC0 124 && GET_CODE (dest) != CC0
125 && GET_CODE (dest) != PC) 125 && GET_CODE (dest) != PC)
126 { 126 {
@@ -129,7 +129,7 @@ Index: gcc-4_6-branch/gcc/combine.c
129 129
130 /* If this substitution failed, this whole thing fails. */ 130 /* If this substitution failed, this whole thing fails. */
131 if (GET_CODE (new_rtx) == CLOBBER 131 if (GET_CODE (new_rtx) == CLOBBER
132@@ -5071,8 +5073,8 @@ 132@@ -5087,8 +5089,8 @@
133 } 133 }
134 else 134 else
135 { 135 {
@@ -140,7 +140,7 @@ Index: gcc-4_6-branch/gcc/combine.c
140 140
141 /* If this substitution failed, this whole thing 141 /* If this substitution failed, this whole thing
142 fails. */ 142 fails. */
143@@ -5149,7 +5151,9 @@ 143@@ -5165,7 +5167,9 @@
144 && (code == SUBREG || code == STRICT_LOW_PART 144 && (code == SUBREG || code == STRICT_LOW_PART
145 || code == ZERO_EXTRACT)) 145 || code == ZERO_EXTRACT))
146 || code == SET) 146 || code == SET)
@@ -151,7 +151,7 @@ Index: gcc-4_6-branch/gcc/combine.c
151 151
152 /* If we found that we will have to reject this combination, 152 /* If we found that we will have to reject this combination,
153 indicate that by returning the CLOBBER ourselves, rather than 153 indicate that by returning the CLOBBER ourselves, rather than
154@@ -5206,7 +5210,7 @@ 154@@ -5222,7 +5226,7 @@
155 /* If X is sufficiently simple, don't bother trying to do anything 155 /* If X is sufficiently simple, don't bother trying to do anything
156 with it. */ 156 with it. */
157 if (code != CONST_INT && code != REG && code != CLOBBER) 157 if (code != CONST_INT && code != REG && code != CLOBBER)
@@ -160,7 +160,7 @@ Index: gcc-4_6-branch/gcc/combine.c
160 160
161 if (GET_CODE (x) == code) 161 if (GET_CODE (x) == code)
162 break; 162 break;
163@@ -5226,10 +5230,12 @@ 163@@ -5242,10 +5246,12 @@
164 expression. 164 expression.
165 165
166 OP0_MODE is the original mode of XEXP (x, 0). IN_DEST is nonzero 166 OP0_MODE is the original mode of XEXP (x, 0). IN_DEST is nonzero
@@ -175,7 +175,7 @@ Index: gcc-4_6-branch/gcc/combine.c
175 { 175 {
176 enum rtx_code code = GET_CODE (x); 176 enum rtx_code code = GET_CODE (x);
177 enum machine_mode mode = GET_MODE (x); 177 enum machine_mode mode = GET_MODE (x);
178@@ -5284,8 +5290,8 @@ 178@@ -5300,8 +5306,8 @@
179 false arms to store-flag values. Be careful to use copy_rtx 179 false arms to store-flag values. Be careful to use copy_rtx
180 here since true_rtx or false_rtx might share RTL with x as a 180 here since true_rtx or false_rtx might share RTL with x as a
181 result of the if_then_else_cond call above. */ 181 result of the if_then_else_cond call above. */
@@ -186,7 +186,7 @@ Index: gcc-4_6-branch/gcc/combine.c
186 186
187 /* If true_rtx and false_rtx are not general_operands, an if_then_else 187 /* If true_rtx and false_rtx are not general_operands, an if_then_else
188 is unlikely to be simpler. */ 188 is unlikely to be simpler. */
189@@ -5629,7 +5635,7 @@ 189@@ -5645,7 +5651,7 @@
190 { 190 {
191 /* Try to simplify the expression further. */ 191 /* Try to simplify the expression further. */
192 rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1)); 192 rtx tor = simplify_gen_binary (IOR, mode, XEXP (x, 0), XEXP (x, 1));
@@ -195,7 +195,7 @@ Index: gcc-4_6-branch/gcc/combine.c
195 195
196 /* If we could, great. If not, do not go ahead with the IOR 196 /* If we could, great. If not, do not go ahead with the IOR
197 replacement, since PLUS appears in many special purpose 197 replacement, since PLUS appears in many special purpose
198@@ -5722,7 +5728,16 @@ 198@@ -5738,7 +5744,16 @@
199 ZERO_EXTRACT is indeed appropriate, it will be placed back by 199 ZERO_EXTRACT is indeed appropriate, it will be placed back by
200 the call to make_compound_operation in the SET case. */ 200 the call to make_compound_operation in the SET case. */
201 201
@@ -213,7 +213,7 @@ Index: gcc-4_6-branch/gcc/combine.c
213 && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 213 && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
214 && op1 == const0_rtx 214 && op1 == const0_rtx
215 && mode == GET_MODE (op0) 215 && mode == GET_MODE (op0)
216@@ -5768,7 +5783,10 @@ 216@@ -5784,7 +5799,10 @@
217 217
218 /* If STORE_FLAG_VALUE is -1, we have cases similar to 218 /* If STORE_FLAG_VALUE is -1, we have cases similar to
219 those above. */ 219 those above. */
@@ -225,7 +225,7 @@ Index: gcc-4_6-branch/gcc/combine.c
225 && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT 225 && new_code == NE && GET_MODE_CLASS (mode) == MODE_INT
226 && op1 == const0_rtx 226 && op1 == const0_rtx
227 && (num_sign_bit_copies (op0, mode) 227 && (num_sign_bit_copies (op0, mode)
228@@ -5966,11 +5984,11 @@ 228@@ -5982,11 +6000,11 @@
229 if (reg_mentioned_p (from, true_rtx)) 229 if (reg_mentioned_p (from, true_rtx))
230 true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code, 230 true_rtx = subst (known_cond (copy_rtx (true_rtx), true_code,
231 from, true_val), 231 from, true_val),
@@ -239,7 +239,7 @@ Index: gcc-4_6-branch/gcc/combine.c
239 239
240 SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx); 240 SUBST (XEXP (x, 1), swapped ? false_rtx : true_rtx);
241 SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx); 241 SUBST (XEXP (x, 2), swapped ? true_rtx : false_rtx);
242@@ -6187,11 +6205,11 @@ 242@@ -6203,11 +6221,11 @@
243 { 243 {
244 temp = subst (simplify_gen_relational (true_code, m, VOIDmode, 244 temp = subst (simplify_gen_relational (true_code, m, VOIDmode,
245 cond_op0, cond_op1), 245 cond_op0, cond_op1),
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106827.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106827.patch
index d49ebab60..28caa4007 100644
--- a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106827.patch
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106827.patch
@@ -37,8 +37,10 @@
37 * config/arm/arm.md (*arm_movqi_insn): Compute attr "length". 37 * config/arm/arm.md (*arm_movqi_insn): Compute attr "length".
38 38
39=== modified file 'gcc/config/arm/arm-protos.h' 39=== modified file 'gcc/config/arm/arm-protos.h'
40--- old/gcc/config/arm/arm-protos.h 2011-10-03 09:46:40 +0000 40Index: gcc-4_6-branch/gcc/config/arm/arm-protos.h
41+++ new/gcc/config/arm/arm-protos.h 2011-10-11 01:56:19 +0000 41===================================================================
42--- gcc-4_6-branch.orig/gcc/config/arm/arm-protos.h 2012-03-05 16:07:15.000000000 -0800
43+++ gcc-4_6-branch/gcc/config/arm/arm-protos.h 2012-03-05 16:07:50.392936694 -0800
42@@ -59,6 +59,7 @@ 44@@ -59,6 +59,7 @@
43 int); 45 int);
44 extern rtx thumb_legitimize_reload_address (rtx *, enum machine_mode, int, int, 46 extern rtx thumb_legitimize_reload_address (rtx *, enum machine_mode, int, int,
@@ -47,10 +49,10 @@
47 extern int arm_const_double_rtx (rtx); 49 extern int arm_const_double_rtx (rtx);
48 extern int neg_const_double_rtx_ok_for_fpa (rtx); 50 extern int neg_const_double_rtx_ok_for_fpa (rtx);
49 extern int vfp3_const_double_rtx (rtx); 51 extern int vfp3_const_double_rtx (rtx);
50 52Index: gcc-4_6-branch/gcc/config/arm/arm.c
51=== modified file 'gcc/config/arm/arm.c' 53===================================================================
52--- old/gcc/config/arm/arm.c 2011-10-03 09:46:40 +0000 54--- gcc-4_6-branch.orig/gcc/config/arm/arm.c 2012-03-05 16:07:15.000000000 -0800
53+++ new/gcc/config/arm/arm.c 2011-10-11 02:31:01 +0000 55+++ gcc-4_6-branch/gcc/config/arm/arm.c 2012-03-05 16:07:50.400936694 -0800
54@@ -2065,6 +2065,28 @@ 56@@ -2065,6 +2065,28 @@
55 fix_cm3_ldrd = 0; 57 fix_cm3_ldrd = 0;
56 } 58 }
@@ -80,7 +82,7 @@
80 if (TARGET_THUMB1 && flag_schedule_insns) 82 if (TARGET_THUMB1 && flag_schedule_insns)
81 { 83 {
82 /* Don't warn since it's on by default in -O2. */ 84 /* Don't warn since it's on by default in -O2. */
83@@ -6106,7 +6128,7 @@ 85@@ -6123,7 +6145,7 @@
84 addresses based on the frame pointer or arg pointer until the 86 addresses based on the frame pointer or arg pointer until the
85 reload pass starts. This is so that eliminating such addresses 87 reload pass starts. This is so that eliminating such addresses
86 into stack based ones won't produce impossible code. */ 88 into stack based ones won't produce impossible code. */
@@ -89,7 +91,7 @@
89 thumb1_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p) 91 thumb1_legitimate_address_p (enum machine_mode mode, rtx x, int strict_p)
90 { 92 {
91 /* ??? Not clear if this is right. Experiment. */ 93 /* ??? Not clear if this is right. Experiment. */
92@@ -22226,6 +22248,10 @@ 94@@ -22251,6 +22273,10 @@
93 val = 6; 95 val = 6;
94 asm_fprintf (asm_out_file, "\t.eabi_attribute 30, %d\n", val); 96 asm_fprintf (asm_out_file, "\t.eabi_attribute 30, %d\n", val);
95 97
@@ -100,22 +102,22 @@
100 /* Tag_ABI_FP_16bit_format. */ 102 /* Tag_ABI_FP_16bit_format. */
101 if (arm_fp16_format) 103 if (arm_fp16_format)
102 asm_fprintf (asm_out_file, "\t.eabi_attribute 38, %d\n", 104 asm_fprintf (asm_out_file, "\t.eabi_attribute 38, %d\n",
103 105Index: gcc-4_6-branch/gcc/config/arm/arm.md
104=== modified file 'gcc/config/arm/arm.md' 106===================================================================
105--- old/gcc/config/arm/arm.md 2011-10-03 09:47:33 +0000 107--- gcc-4_6-branch.orig/gcc/config/arm/arm.md 2012-03-05 16:07:15.000000000 -0800
106+++ new/gcc/config/arm/arm.md 2011-10-11 02:31:01 +0000 108+++ gcc-4_6-branch/gcc/config/arm/arm.md 2012-03-05 16:09:26.284941314 -0800
107@@ -113,6 +113,10 @@ 109@@ -114,6 +114,10 @@
108 (UNSPEC_SYMBOL_OFFSET 27) ; The offset of the start of the symbol from
109 ; another symbolic address. 110 ; another symbolic address.
110 (UNSPEC_MEMORY_BARRIER 28) ; Represent a memory barrier. 111 (UNSPEC_MEMORY_BARRIER 28) ; Represent a memory barrier.
111+ (UNSPEC_UNALIGNED_LOAD 29) ; Used to represent ldr/ldrh instructions that access 112 (UNSPEC_PIC_UNIFIED 29) ; Create a common pic addressing form.
113+ (UNSPEC_UNALIGNED_LOAD 30) ; Used to represent ldr/ldrh instructions that access
112+ ; unaligned locations, on architectures which support 114+ ; unaligned locations, on architectures which support
113+ ; that. 115+ ; that.
114+ (UNSPEC_UNALIGNED_STORE 30) ; Same for str/strh. 116+ (UNSPEC_UNALIGNED_STORE 31) ; Same for str/strh.
115 ] 117 ]
116 ) 118 )
117 119
118@@ -2463,10 +2467,10 @@ 120@@ -2461,10 +2465,10 @@
119 ;;; this insv pattern, so this pattern needs to be reevalutated. 121 ;;; this insv pattern, so this pattern needs to be reevalutated.
120 122
121 (define_expand "insv" 123 (define_expand "insv"
@@ -130,51 +132,59 @@
130 "TARGET_ARM || arm_arch_thumb2" 132 "TARGET_ARM || arm_arch_thumb2"
131 " 133 "
132 { 134 {
133@@ -2477,35 +2481,70 @@ 135@@ -2475,35 +2479,70 @@
134 136
135 if (arm_arch_thumb2) 137 if (arm_arch_thumb2)
136 { 138 {
137- bool use_bfi = TRUE; 139- bool use_bfi = TRUE;
138- 140-
139- if (GET_CODE (operands[3]) == CONST_INT) 141- if (GET_CODE (operands[3]) == CONST_INT)
140- {
141- HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
142-
143- if (val == 0)
144- {
145- emit_insn (gen_insv_zero (operands[0], operands[1],
146- operands[2]));
147+ if (unaligned_access && MEM_P (operands[0]) 142+ if (unaligned_access && MEM_P (operands[0])
148+ && s_register_operand (operands[3], GET_MODE (operands[3])) 143+ && s_register_operand (operands[3], GET_MODE (operands[3]))
149+ && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0) 144+ && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0)
150+ { 145 {
146- HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
151+ rtx base_addr; 147+ rtx base_addr;
152+ 148+
153+ if (BYTES_BIG_ENDIAN) 149+ if (BYTES_BIG_ENDIAN)
154+ start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width 150+ start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width
155+ - start_bit; 151+ - start_bit;
156+ 152
153- if (val == 0)
157+ if (width == 32) 154+ if (width == 32)
158+ { 155 {
156- emit_insn (gen_insv_zero (operands[0], operands[1],
157- operands[2]));
158- DONE;
159+ base_addr = adjust_address (operands[0], SImode, 159+ base_addr = adjust_address (operands[0], SImode,
160+ start_bit / BITS_PER_UNIT); 160+ start_bit / BITS_PER_UNIT);
161+ emit_insn (gen_unaligned_storesi (base_addr, operands[3])); 161+ emit_insn (gen_unaligned_storesi (base_addr, operands[3]));
162+ } 162 }
163+ else 163+ else
164+ { 164+ {
165+ rtx tmp = gen_reg_rtx (HImode); 165+ rtx tmp = gen_reg_rtx (HImode);
166+ 166
167- /* See if the set can be done with a single orr instruction. */
168- if (val == mask && const_ok_for_arm (val << start_bit))
169- use_bfi = FALSE;
167+ base_addr = adjust_address (operands[0], HImode, 170+ base_addr = adjust_address (operands[0], HImode,
168+ start_bit / BITS_PER_UNIT); 171+ start_bit / BITS_PER_UNIT);
169+ emit_move_insn (tmp, gen_lowpart (HImode, operands[3])); 172+ emit_move_insn (tmp, gen_lowpart (HImode, operands[3]));
170+ emit_insn (gen_unaligned_storehi (base_addr, tmp)); 173+ emit_insn (gen_unaligned_storehi (base_addr, tmp));
171+ } 174+ }
172+ DONE; 175+ DONE;
173+ } 176 }
177-
178- if (use_bfi)
174+ else if (s_register_operand (operands[0], GET_MODE (operands[0]))) 179+ else if (s_register_operand (operands[0], GET_MODE (operands[0])))
175+ { 180 {
181- if (GET_CODE (operands[3]) != REG)
182- operands[3] = force_reg (SImode, operands[3]);
176+ bool use_bfi = TRUE; 183+ bool use_bfi = TRUE;
177+ 184
185- emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
186- operands[3]));
187- DONE;
178+ if (GET_CODE (operands[3]) == CONST_INT) 188+ if (GET_CODE (operands[3]) == CONST_INT)
179+ { 189+ {
180+ HOST_WIDE_INT val = INTVAL (operands[3]) & mask; 190+ HOST_WIDE_INT val = INTVAL (operands[3]) & mask;
@@ -198,24 +208,9 @@
198+ 208+
199+ emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2], 209+ emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
200+ operands[3])); 210+ operands[3]));
201 DONE; 211+ DONE;
202 } 212+ }
203- 213 }
204- /* See if the set can be done with a single orr instruction. */
205- if (val == mask && const_ok_for_arm (val << start_bit))
206- use_bfi = FALSE;
207- }
208-
209- if (use_bfi)
210- {
211- if (GET_CODE (operands[3]) != REG)
212- operands[3] = force_reg (SImode, operands[3]);
213-
214- emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2],
215- operands[3]));
216- DONE;
217- }
218+ }
219+ else 214+ else
220+ FAIL; 215+ FAIL;
221 } 216 }
@@ -226,7 +221,7 @@
226 target = copy_rtx (operands[0]); 221 target = copy_rtx (operands[0]);
227 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 222 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical
228 subreg as the final target. */ 223 subreg as the final target. */
229@@ -3697,12 +3736,10 @@ 224@@ -3695,12 +3734,10 @@
230 ;; to reduce register pressure later on. 225 ;; to reduce register pressure later on.
231 226
232 (define_expand "extzv" 227 (define_expand "extzv"
@@ -243,7 +238,7 @@
243 "TARGET_THUMB1 || arm_arch_thumb2" 238 "TARGET_THUMB1 || arm_arch_thumb2"
244 " 239 "
245 { 240 {
246@@ -3711,10 +3748,57 @@ 241@@ -3709,10 +3746,57 @@
247 242
248 if (arm_arch_thumb2) 243 if (arm_arch_thumb2)
249 { 244 {
@@ -304,7 +299,7 @@
304 299
305 operands[3] = GEN_INT (rshift); 300 operands[3] = GEN_INT (rshift);
306 301
307@@ -3724,12 +3808,154 @@ 302@@ -3722,12 +3806,154 @@
308 DONE; 303 DONE;
309 } 304 }
310 305
@@ -462,7 +457,7 @@
462 [(set (match_operand:SI 0 "s_register_operand" "=r") 457 [(set (match_operand:SI 0 "s_register_operand" "=r")
463 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 458 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r")
464 (match_operand:SI 2 "const_int_operand" "M") 459 (match_operand:SI 2 "const_int_operand" "M")
465@@ -6038,8 +6264,8 @@ 460@@ -6069,8 +6295,8 @@
466 461
467 462
468 (define_insn "*arm_movqi_insn" 463 (define_insn "*arm_movqi_insn"
@@ -473,7 +468,7 @@
473 "TARGET_32BIT 468 "TARGET_32BIT
474 && ( register_operand (operands[0], QImode) 469 && ( register_operand (operands[0], QImode)
475 || register_operand (operands[1], QImode))" 470 || register_operand (operands[1], QImode))"
476@@ -6047,10 +6273,14 @@ 471@@ -6078,10 +6304,14 @@
477 mov%?\\t%0, %1 472 mov%?\\t%0, %1
478 mvn%?\\t%0, #%B1 473 mvn%?\\t%0, #%B1
479 ldr%(b%)\\t%0, %1 474 ldr%(b%)\\t%0, %1
@@ -491,10 +486,10 @@
491 ) 486 )
492 487
493 (define_insn "*thumb1_movqi_insn" 488 (define_insn "*thumb1_movqi_insn"
494 489Index: gcc-4_6-branch/gcc/config/arm/arm.opt
495=== modified file 'gcc/config/arm/arm.opt' 490===================================================================
496--- old/gcc/config/arm/arm.opt 2011-09-19 07:44:24 +0000 491--- gcc-4_6-branch.orig/gcc/config/arm/arm.opt 2012-03-05 16:07:14.000000000 -0800
497+++ new/gcc/config/arm/arm.opt 2011-10-11 02:31:01 +0000 492+++ gcc-4_6-branch/gcc/config/arm/arm.opt 2012-03-05 16:07:50.404936697 -0800
498@@ -173,3 +173,7 @@ 493@@ -173,3 +173,7 @@
499 Target Report Var(fix_cm3_ldrd) Init(2) 494 Target Report Var(fix_cm3_ldrd) Init(2)
500 Avoid overlapping destination and address registers on LDRD instructions 495 Avoid overlapping destination and address registers on LDRD instructions
@@ -503,10 +498,10 @@
503+munaligned-access 498+munaligned-access
504+Target Report Var(unaligned_access) Init(2) 499+Target Report Var(unaligned_access) Init(2)
505+Enable unaligned word and halfword accesses to packed data. 500+Enable unaligned word and halfword accesses to packed data.
506 501Index: gcc-4_6-branch/gcc/config/arm/constraints.md
507=== modified file 'gcc/config/arm/constraints.md' 502===================================================================
508--- old/gcc/config/arm/constraints.md 2011-09-12 14:14:00 +0000 503--- gcc-4_6-branch.orig/gcc/config/arm/constraints.md 2012-03-05 16:07:14.000000000 -0800
509+++ new/gcc/config/arm/constraints.md 2011-10-11 02:31:01 +0000 504+++ gcc-4_6-branch/gcc/config/arm/constraints.md 2012-03-05 16:07:50.404936697 -0800
510@@ -36,6 +36,7 @@ 505@@ -36,6 +36,7 @@
511 ;; The following memory constraints have been used: 506 ;; The following memory constraints have been used:
512 ;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us 507 ;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us
@@ -543,10 +538,10 @@
543 ;; We used to have constraint letters for S and R in ARM state, but 538 ;; We used to have constraint letters for S and R in ARM state, but
544 ;; all uses of these now appear to have been removed. 539 ;; all uses of these now appear to have been removed.
545 540
546 541Index: gcc-4_6-branch/gcc/expmed.c
547=== modified file 'gcc/expmed.c' 542===================================================================
548--- old/gcc/expmed.c 2011-05-22 19:02:59 +0000 543--- gcc-4_6-branch.orig/gcc/expmed.c 2012-01-04 15:37:51.000000000 -0800
549+++ new/gcc/expmed.c 2011-10-11 02:31:01 +0000 544+++ gcc-4_6-branch/gcc/expmed.c 2012-03-05 16:07:50.404936697 -0800
550@@ -657,6 +657,10 @@ 545@@ -657,6 +657,10 @@
551 && GET_MODE (value) != BLKmode 546 && GET_MODE (value) != BLKmode
552 && bitsize > 0 547 && bitsize > 0
@@ -625,4 +620,3 @@
625 if (xtarget == 0) 620 if (xtarget == 0)
626 xtarget = xspec_target = gen_reg_rtx (tmode); 621 xtarget = xspec_target = gen_reg_rtx (tmode);
627 622
628
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106842.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106842.patch
index 74f139d33..2cf2741ba 100644
--- a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106842.patch
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106842.patch
@@ -48,8 +48,10 @@
48 Return true for NEON. 48 Return true for NEON.
49 49
50=== modified file 'gcc/testsuite/gcc.dg/vect/pr30858.c' 50=== modified file 'gcc/testsuite/gcc.dg/vect/pr30858.c'
51--- old/gcc/testsuite/gcc.dg/vect/pr30858.c 2007-02-22 08:16:18 +0000 51Index: gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/pr30858.c
52+++ new/gcc/testsuite/gcc.dg/vect/pr30858.c 2011-11-20 09:11:09 +0000 52===================================================================
53--- gcc-4_6-branch.orig/gcc/testsuite/gcc.dg/vect/pr30858.c 2012-01-04 15:33:52.000000000 -0800
54+++ gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/pr30858.c 2012-03-05 16:23:47.748983031 -0800
53@@ -11,5 +11,6 @@ 55@@ -11,5 +11,6 @@
54 } 56 }
55 57
@@ -58,10 +60,10 @@
58+/* { dg-final { scan-tree-dump-times "Unknown def-use cycle pattern." 1 "vect" { xfail vect_multiple_sizes } } } */ 60+/* { dg-final { scan-tree-dump-times "Unknown def-use cycle pattern." 1 "vect" { xfail vect_multiple_sizes } } } */
59+/* { dg-final { scan-tree-dump-times "Unknown def-use cycle pattern." 2 "vect" { target vect_multiple_sizes } } } */ 61+/* { dg-final { scan-tree-dump-times "Unknown def-use cycle pattern." 2 "vect" { target vect_multiple_sizes } } } */
60 /* { dg-final { cleanup-tree-dump "vect" } } */ 62 /* { dg-final { cleanup-tree-dump "vect" } } */
61 63Index: gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/vect-cond-8a.c
62=== added file 'gcc/testsuite/gcc.dg/vect/vect-cond-8a.c' 64===================================================================
63--- old/gcc/testsuite/gcc.dg/vect/vect-cond-8a.c 1970-01-01 00:00:00 +0000 65--- /dev/null 1970-01-01 00:00:00.000000000 +0000
64+++ new/gcc/testsuite/gcc.dg/vect/vect-cond-8a.c 2011-11-20 09:11:09 +0000 66+++ gcc-4_6-branch/gcc/testsuite/gcc.dg/vect/vect-cond-8a.c 2012-03-05 16:23:47.748983031 -0800
65@@ -0,0 +1,75 @@ 67@@ -0,0 +1,75 @@
66+/* { dg-require-effective-target vect_condition } */ 68+/* { dg-require-effective-target vect_condition } */
67+ 69+
@@ -138,24 +140,10 @@
138+ 140+
139+/* { dg-final { scan-tree-dump-times "note: vectorized 1 loops" 3 "vect" } } */ 141+/* { dg-final { scan-tree-dump-times "note: vectorized 1 loops" 3 "vect" } } */
140+/* { dg-final { cleanup-tree-dump "vect" } } */ 142+/* { dg-final { cleanup-tree-dump "vect" } } */
141 143Index: gcc-4_6-branch/gcc/tree-vect-patterns.c
142=== modified file 'gcc/testsuite/lib/target-supports.exp' 144===================================================================
143--- old/gcc/testsuite/lib/target-supports.exp 2011-11-21 01:45:54 +0000 145--- gcc-4_6-branch.orig/gcc/tree-vect-patterns.c 2012-03-05 16:23:10.000000000 -0800
144+++ new/gcc/testsuite/lib/target-supports.exp 2011-11-22 16:52:23 +0000 146+++ gcc-4_6-branch/gcc/tree-vect-patterns.c 2012-03-05 16:23:47.748983031 -0800
145@@ -3150,7 +3150,8 @@
146 || [istarget ia64-*-*]
147 || [istarget i?86-*-*]
148 || [istarget spu-*-*]
149- || [istarget x86_64-*-*] } {
150+ || [istarget x86_64-*-*]
151+ || ([istarget arm*-*-*] && [check_effective_target_arm_neon_ok]) } {
152 set et_vect_cond_saved 1
153 }
154 }
155
156=== modified file 'gcc/tree-vect-patterns.c'
157--- old/gcc/tree-vect-patterns.c 2011-10-23 13:33:07 +0000
158+++ new/gcc/tree-vect-patterns.c 2011-11-20 09:11:09 +0000
159@@ -50,13 +50,16 @@ 147@@ -50,13 +50,16 @@
160 tree *); 148 tree *);
161 static gimple vect_recog_widen_shift_pattern (VEC (gimple, heap) **, 149 static gimple vect_recog_widen_shift_pattern (VEC (gimple, heap) **,
@@ -299,14 +287,14 @@
299 def_stmt = STMT_VINFO_PATTERN_DEF_STMT (pattern_stmt_info); 287 def_stmt = STMT_VINFO_PATTERN_DEF_STMT (pattern_stmt_info);
300- set_vinfo_for_stmt (def_stmt, 288- set_vinfo_for_stmt (def_stmt,
301- new_stmt_vec_info (def_stmt, loop_vinfo, NULL)); 289- new_stmt_vec_info (def_stmt, loop_vinfo, NULL));
302+ def_stmt_info = vinfo_for_stmt (def_stmt); 290- gimple_set_bb (def_stmt, gimple_bb (orig_stmt));
291 def_stmt_info = vinfo_for_stmt (def_stmt);
303+ if (def_stmt_info == NULL) 292+ if (def_stmt_info == NULL)
304+ { 293+ {
305+ def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo, NULL); 294+ def_stmt_info = new_stmt_vec_info (def_stmt, loop_vinfo, NULL);
306+ set_vinfo_for_stmt (def_stmt, def_stmt_info); 295+ set_vinfo_for_stmt (def_stmt, def_stmt_info);
307+ } 296+ }
308 gimple_set_bb (def_stmt, gimple_bb (orig_stmt)); 297+ gimple_set_bb (def_stmt, gimple_bb (orig_stmt));
309- def_stmt_info = vinfo_for_stmt (def_stmt);
310 STMT_VINFO_RELATED_STMT (def_stmt_info) = orig_stmt; 298 STMT_VINFO_RELATED_STMT (def_stmt_info) = orig_stmt;
311 STMT_VINFO_DEF_TYPE (def_stmt_info) 299 STMT_VINFO_DEF_TYPE (def_stmt_info)
312 = STMT_VINFO_DEF_TYPE (orig_stmt_info); 300 = STMT_VINFO_DEF_TYPE (orig_stmt_info);
@@ -316,10 +304,10 @@
316 } 304 }
317 } 305 }
318 306
319 307Index: gcc-4_6-branch/gcc/tree-vect-stmts.c
320=== modified file 'gcc/tree-vect-stmts.c' 308===================================================================
321--- old/gcc/tree-vect-stmts.c 2011-11-14 11:38:08 +0000 309--- gcc-4_6-branch.orig/gcc/tree-vect-stmts.c 2012-03-05 16:23:11.000000000 -0800
322+++ new/gcc/tree-vect-stmts.c 2011-11-22 16:52:23 +0000 310+++ gcc-4_6-branch/gcc/tree-vect-stmts.c 2012-03-05 16:23:47.748983031 -0800
323@@ -655,20 +655,40 @@ 311@@ -655,20 +655,40 @@
324 tree rhs = gimple_assign_rhs1 (stmt); 312 tree rhs = gimple_assign_rhs1 (stmt);
325 unsigned int op_num; 313 unsigned int op_num;
@@ -372,10 +360,10 @@
372 break; 360 break;
373 361
374 case GIMPLE_BINARY_RHS: 362 case GIMPLE_BINARY_RHS:
375 363Index: gcc-4_6-branch/gcc/tree-vectorizer.h
376=== modified file 'gcc/tree-vectorizer.h' 364===================================================================
377--- old/gcc/tree-vectorizer.h 2011-11-14 11:38:08 +0000 365--- gcc-4_6-branch.orig/gcc/tree-vectorizer.h 2012-03-05 16:23:11.000000000 -0800
378+++ new/gcc/tree-vectorizer.h 2011-11-22 16:52:23 +0000 366+++ gcc-4_6-branch/gcc/tree-vectorizer.h 2012-03-05 16:23:47.748983031 -0800
379@@ -917,7 +917,7 @@ 367@@ -917,7 +917,7 @@
380 Additional pattern recognition functions can (and will) be added 368 Additional pattern recognition functions can (and will) be added
381 in the future. */ 369 in the future. */
@@ -385,4 +373,3 @@
385 void vect_pattern_recog (loop_vec_info); 373 void vect_pattern_recog (loop_vec_info);
386 374
387 /* In tree-vectorizer.c. */ 375 /* In tree-vectorizer.c. */
388
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106854.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106854.patch
deleted file mode 100644
index 208ba0e78..000000000
--- a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106854.patch
+++ /dev/null
@@ -1,354 +0,0 @@
12011-12-30 Richard Sandiford <richard.sandiford@linaro.org>
2
3 gcc/
4 Backport from mainline:
5
6 2011-10-12 Richard Sandiford <richard.sandiford@linaro.org>
7
8 * expr.h (copy_blkmode_to_reg): Declare.
9 * expr.c (copy_blkmode_to_reg): New function.
10 (expand_assignment): Don't expand register RESULT_DECLs before
11 the lhs. Use copy_blkmode_to_reg to copy BLKmode values into a
12 RESULT_DECL register.
13 (expand_expr_real_1): Handle BLKmode decls when looking for promotion.
14 * stmt.c (expand_return): Move BLKmode-to-register code into
15 copy_blkmode_to_reg.
16
17=== modified file 'gcc/expr.c'
18--- old/gcc/expr.c 2011-10-23 13:33:07 +0000
19+++ new/gcc/expr.c 2011-12-30 09:41:30 +0000
20@@ -2180,6 +2180,111 @@
21 return tgtblk;
22 }
23
24+/* Copy BLKmode value SRC into a register of mode MODE. Return the
25+ register if it contains any data, otherwise return null.
26+
27+ This is used on targets that return BLKmode values in registers. */
28+
29+rtx
30+copy_blkmode_to_reg (enum machine_mode mode, tree src)
31+{
32+ int i, n_regs;
33+ unsigned HOST_WIDE_INT bitpos, xbitpos, padding_correction = 0, bytes;
34+ unsigned int bitsize;
35+ rtx *dst_words, dst, x, src_word = NULL_RTX, dst_word = NULL_RTX;
36+ enum machine_mode dst_mode;
37+
38+ gcc_assert (TYPE_MODE (TREE_TYPE (src)) == BLKmode);
39+
40+ x = expand_normal (src);
41+
42+ bytes = int_size_in_bytes (TREE_TYPE (src));
43+ if (bytes == 0)
44+ return NULL_RTX;
45+
46+ /* If the structure doesn't take up a whole number of words, see
47+ whether the register value should be padded on the left or on
48+ the right. Set PADDING_CORRECTION to the number of padding
49+ bits needed on the left side.
50+
51+ In most ABIs, the structure will be returned at the least end of
52+ the register, which translates to right padding on little-endian
53+ targets and left padding on big-endian targets. The opposite
54+ holds if the structure is returned at the most significant
55+ end of the register. */
56+ if (bytes % UNITS_PER_WORD != 0
57+ && (targetm.calls.return_in_msb (TREE_TYPE (src))
58+ ? !BYTES_BIG_ENDIAN
59+ : BYTES_BIG_ENDIAN))
60+ padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
61+ * BITS_PER_UNIT));
62+
63+ n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
64+ dst_words = XALLOCAVEC (rtx, n_regs);
65+ bitsize = MIN (TYPE_ALIGN (TREE_TYPE (src)), BITS_PER_WORD);
66+
67+ /* Copy the structure BITSIZE bits at a time. */
68+ for (bitpos = 0, xbitpos = padding_correction;
69+ bitpos < bytes * BITS_PER_UNIT;
70+ bitpos += bitsize, xbitpos += bitsize)
71+ {
72+ /* We need a new destination pseudo each time xbitpos is
73+ on a word boundary and when xbitpos == padding_correction
74+ (the first time through). */
75+ if (xbitpos % BITS_PER_WORD == 0
76+ || xbitpos == padding_correction)
77+ {
78+ /* Generate an appropriate register. */
79+ dst_word = gen_reg_rtx (word_mode);
80+ dst_words[xbitpos / BITS_PER_WORD] = dst_word;
81+
82+ /* Clear the destination before we move anything into it. */
83+ emit_move_insn (dst_word, CONST0_RTX (word_mode));
84+ }
85+
86+ /* We need a new source operand each time bitpos is on a word
87+ boundary. */
88+ if (bitpos % BITS_PER_WORD == 0)
89+ src_word = operand_subword_force (x, bitpos / BITS_PER_WORD, BLKmode);
90+
91+ /* Use bitpos for the source extraction (left justified) and
92+ xbitpos for the destination store (right justified). */
93+ store_bit_field (dst_word, bitsize, xbitpos % BITS_PER_WORD, word_mode,
94+ extract_bit_field (src_word, bitsize,
95+ bitpos % BITS_PER_WORD, 1, false,
96+ NULL_RTX, word_mode, word_mode));
97+ }
98+
99+ if (mode == BLKmode)
100+ {
101+ /* Find the smallest integer mode large enough to hold the
102+ entire structure. */
103+ for (mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
104+ mode != VOIDmode;
105+ mode = GET_MODE_WIDER_MODE (mode))
106+ /* Have we found a large enough mode? */
107+ if (GET_MODE_SIZE (mode) >= bytes)
108+ break;
109+
110+ /* A suitable mode should have been found. */
111+ gcc_assert (mode != VOIDmode);
112+ }
113+
114+ if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (word_mode))
115+ dst_mode = word_mode;
116+ else
117+ dst_mode = mode;
118+ dst = gen_reg_rtx (dst_mode);
119+
120+ for (i = 0; i < n_regs; i++)
121+ emit_move_insn (operand_subword (dst, i, 0, dst_mode), dst_words[i]);
122+
123+ if (mode != dst_mode)
124+ dst = gen_lowpart (mode, dst);
125+
126+ return dst;
127+}
128+
129 /* Add a USE expression for REG to the (possibly empty) list pointed
130 to by CALL_FUSAGE. REG must denote a hard register. */
131
132@@ -4382,7 +4487,9 @@
133 if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
134 && COMPLETE_TYPE_P (TREE_TYPE (from))
135 && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
136- && ! (((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL)
137+ && ! (((TREE_CODE (to) == VAR_DECL
138+ || TREE_CODE (to) == PARM_DECL
139+ || TREE_CODE (to) == RESULT_DECL)
140 && REG_P (DECL_RTL (to)))
141 || TREE_CODE (to) == SSA_NAME))
142 {
143@@ -4428,12 +4535,15 @@
144 rtx temp;
145
146 push_temp_slots ();
147- temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);
148+ if (REG_P (to_rtx) && TYPE_MODE (TREE_TYPE (from)) == BLKmode)
149+ temp = copy_blkmode_to_reg (GET_MODE (to_rtx), from);
150+ else
151+ temp = expand_expr (from, NULL_RTX, GET_MODE (to_rtx), EXPAND_NORMAL);
152
153 if (GET_CODE (to_rtx) == PARALLEL)
154 emit_group_load (to_rtx, temp, TREE_TYPE (from),
155 int_size_in_bytes (TREE_TYPE (from)));
156- else
157+ else if (temp)
158 emit_move_insn (to_rtx, temp);
159
160 preserve_temp_slots (to_rtx);
161@@ -8567,10 +8677,15 @@
162 return temp;
163 }
164
165- /* If the mode of DECL_RTL does not match that of the decl, it
166- must be a promoted value. We return a SUBREG of the wanted mode,
167- but mark it so that we know that it was already extended. */
168- if (REG_P (decl_rtl) && GET_MODE (decl_rtl) != DECL_MODE (exp))
169+ /* If the mode of DECL_RTL does not match that of the decl,
170+ there are two cases: we are dealing with a BLKmode value
171+ that is returned in a register, or we are dealing with
172+ a promoted value. In the latter case, return a SUBREG
173+ of the wanted mode, but mark it so that we know that it
174+ was already extended. */
175+ if (REG_P (decl_rtl)
176+ && DECL_MODE (exp) != BLKmode
177+ && GET_MODE (decl_rtl) != DECL_MODE (exp))
178 {
179 enum machine_mode pmode;
180
181
182=== modified file 'gcc/expr.h'
183--- old/gcc/expr.h 2011-03-03 21:56:58 +0000
184+++ new/gcc/expr.h 2011-10-12 08:01:43 +0000
185@@ -324,6 +324,8 @@
186 /* Copy BLKmode object from a set of registers. */
187 extern rtx copy_blkmode_from_reg (rtx, rtx, tree);
188
189+extern rtx copy_blkmode_to_reg (enum machine_mode, tree);
190+
191 /* Mark REG as holding a parameter for the next CALL_INSN. */
192 extern void use_reg (rtx *, rtx);
193
194
195=== modified file 'gcc/stmt.c'
196--- old/gcc/stmt.c 2011-03-03 21:56:58 +0000
197+++ new/gcc/stmt.c 2011-10-12 08:01:43 +0000
198@@ -1684,119 +1684,21 @@
199 expand_value_return (result_rtl);
200
201 /* If the result is an aggregate that is being returned in one (or more)
202- registers, load the registers here. The compiler currently can't handle
203- copying a BLKmode value into registers. We could put this code in a
204- more general area (for use by everyone instead of just function
205- call/return), but until this feature is generally usable it is kept here
206- (and in expand_call). */
207+ registers, load the registers here. */
208
209 else if (retval_rhs != 0
210 && TYPE_MODE (TREE_TYPE (retval_rhs)) == BLKmode
211 && REG_P (result_rtl))
212 {
213- int i;
214- unsigned HOST_WIDE_INT bitpos, xbitpos;
215- unsigned HOST_WIDE_INT padding_correction = 0;
216- unsigned HOST_WIDE_INT bytes
217- = int_size_in_bytes (TREE_TYPE (retval_rhs));
218- int n_regs = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
219- unsigned int bitsize
220- = MIN (TYPE_ALIGN (TREE_TYPE (retval_rhs)), BITS_PER_WORD);
221- rtx *result_pseudos = XALLOCAVEC (rtx, n_regs);
222- rtx result_reg, src = NULL_RTX, dst = NULL_RTX;
223- rtx result_val = expand_normal (retval_rhs);
224- enum machine_mode tmpmode, result_reg_mode;
225-
226- if (bytes == 0)
227- {
228- expand_null_return ();
229- return;
230- }
231-
232- /* If the structure doesn't take up a whole number of words, see
233- whether the register value should be padded on the left or on
234- the right. Set PADDING_CORRECTION to the number of padding
235- bits needed on the left side.
236-
237- In most ABIs, the structure will be returned at the least end of
238- the register, which translates to right padding on little-endian
239- targets and left padding on big-endian targets. The opposite
240- holds if the structure is returned at the most significant
241- end of the register. */
242- if (bytes % UNITS_PER_WORD != 0
243- && (targetm.calls.return_in_msb (TREE_TYPE (retval_rhs))
244- ? !BYTES_BIG_ENDIAN
245- : BYTES_BIG_ENDIAN))
246- padding_correction = (BITS_PER_WORD - ((bytes % UNITS_PER_WORD)
247- * BITS_PER_UNIT));
248-
249- /* Copy the structure BITSIZE bits at a time. */
250- for (bitpos = 0, xbitpos = padding_correction;
251- bitpos < bytes * BITS_PER_UNIT;
252- bitpos += bitsize, xbitpos += bitsize)
253- {
254- /* We need a new destination pseudo each time xbitpos is
255- on a word boundary and when xbitpos == padding_correction
256- (the first time through). */
257- if (xbitpos % BITS_PER_WORD == 0
258- || xbitpos == padding_correction)
259- {
260- /* Generate an appropriate register. */
261- dst = gen_reg_rtx (word_mode);
262- result_pseudos[xbitpos / BITS_PER_WORD] = dst;
263-
264- /* Clear the destination before we move anything into it. */
265- emit_move_insn (dst, CONST0_RTX (GET_MODE (dst)));
266- }
267-
268- /* We need a new source operand each time bitpos is on a word
269- boundary. */
270- if (bitpos % BITS_PER_WORD == 0)
271- src = operand_subword_force (result_val,
272- bitpos / BITS_PER_WORD,
273- BLKmode);
274-
275- /* Use bitpos for the source extraction (left justified) and
276- xbitpos for the destination store (right justified). */
277- store_bit_field (dst, bitsize, xbitpos % BITS_PER_WORD, word_mode,
278- extract_bit_field (src, bitsize,
279- bitpos % BITS_PER_WORD, 1, false,
280- NULL_RTX, word_mode, word_mode));
281- }
282-
283- tmpmode = GET_MODE (result_rtl);
284- if (tmpmode == BLKmode)
285- {
286- /* Find the smallest integer mode large enough to hold the
287- entire structure and use that mode instead of BLKmode
288- on the USE insn for the return register. */
289- for (tmpmode = GET_CLASS_NARROWEST_MODE (MODE_INT);
290- tmpmode != VOIDmode;
291- tmpmode = GET_MODE_WIDER_MODE (tmpmode))
292- /* Have we found a large enough mode? */
293- if (GET_MODE_SIZE (tmpmode) >= bytes)
294- break;
295-
296- /* A suitable mode should have been found. */
297- gcc_assert (tmpmode != VOIDmode);
298-
299- PUT_MODE (result_rtl, tmpmode);
300- }
301-
302- if (GET_MODE_SIZE (tmpmode) < GET_MODE_SIZE (word_mode))
303- result_reg_mode = word_mode;
304+ val = copy_blkmode_to_reg (GET_MODE (result_rtl), retval_rhs);
305+ if (val)
306+ {
307+ /* Use the mode of the result value on the return register. */
308+ PUT_MODE (result_rtl, GET_MODE (val));
309+ expand_value_return (val);
310+ }
311 else
312- result_reg_mode = tmpmode;
313- result_reg = gen_reg_rtx (result_reg_mode);
314-
315- for (i = 0; i < n_regs; i++)
316- emit_move_insn (operand_subword (result_reg, i, 0, result_reg_mode),
317- result_pseudos[i]);
318-
319- if (tmpmode != result_reg_mode)
320- result_reg = gen_lowpart (tmpmode, result_reg);
321-
322- expand_value_return (result_reg);
323+ expand_null_return ();
324 }
325 else if (retval_rhs != 0
326 && !VOID_TYPE_P (TREE_TYPE (retval_rhs))
327
328=== added file 'gcc/testsuite/g++.dg/pr48660.C'
329--- old/gcc/testsuite/g++.dg/pr48660.C 1970-01-01 00:00:00 +0000
330+++ new/gcc/testsuite/g++.dg/pr48660.C 2011-10-12 08:01:43 +0000
331@@ -0,0 +1,22 @@
332+template<int N> struct val { char a[N]; };
333+
334+class Base
335+{
336+public:
337+ virtual val<1> get1() const = 0;
338+ virtual val<2> get2() const = 0;
339+ virtual val<3> get3() const = 0;
340+ virtual val<4> get4() const = 0;
341+};
342+
343+class Derived : public virtual Base
344+{
345+public:
346+ virtual val<1> get1() const { return foo->get1(); }
347+ virtual val<2> get2() const { return foo->get2(); }
348+ virtual val<3> get3() const { return foo->get3(); }
349+ virtual val<4> get4() const { return foo->get4(); }
350+ Base *foo;
351+};
352+
353+Base* make() { return new Derived; }
354
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106860.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106860.patch
new file mode 100644
index 000000000..895d6a6cf
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106860.patch
@@ -0,0 +1,104 @@
12012-01-12 Ulrich Weigand <ulrich.weigand@linaro.org>
2
3 LP 879725
4 Backport from mainline:
5
6 2012-01-02 Revital Eres <revital.eres@linaro.org>
7
8 gcc/
9 * ddg.c (def_has_ccmode_p): New function.
10 (add_cross_iteration_register_deps,
11 create_ddg_dep_from_intra_loop_link): Call it.
12
13 gcc/testsuite/
14 * gcc.dg/sms-11.c: New file.
15
16=== modified file 'gcc/ddg.c'
17--- old/gcc/ddg.c 2011-10-02 06:56:53 +0000
18+++ new/gcc/ddg.c 2012-01-10 16:05:14 +0000
19@@ -166,6 +166,24 @@
20 return false;
21 }
22
23+/* Return true if one of the definitions in INSN has MODE_CC. Otherwise
24+ return false. */
25+static bool
26+def_has_ccmode_p (rtx insn)
27+{
28+ df_ref *def;
29+
30+ for (def = DF_INSN_DEFS (insn); *def; def++)
31+ {
32+ enum machine_mode mode = GET_MODE (DF_REF_REG (*def));
33+
34+ if (GET_MODE_CLASS (mode) == MODE_CC)
35+ return true;
36+ }
37+
38+ return false;
39+}
40+
41 /* Computes the dependence parameters (latency, distance etc.), creates
42 a ddg_edge and adds it to the given DDG. */
43 static void
44@@ -202,6 +220,7 @@
45 whose register has multiple defs in the loop. */
46 if (flag_modulo_sched_allow_regmoves
47 && (t == ANTI_DEP && dt == REG_DEP)
48+ && !def_has_ccmode_p (dest_node->insn)
49 && !autoinc_var_is_used_p (dest_node->insn, src_node->insn))
50 {
51 rtx set;
52@@ -335,7 +354,8 @@
53 if (DF_REF_ID (last_def) != DF_REF_ID (first_def)
54 || !flag_modulo_sched_allow_regmoves
55 || JUMP_P (use_node->insn)
56- || autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn))
57+ || autoinc_var_is_used_p (DF_REF_INSN (last_def), use_insn)
58+ || def_has_ccmode_p (DF_REF_INSN (last_def)))
59 create_ddg_dep_no_link (g, use_node, first_def_node, ANTI_DEP,
60 REG_DEP, 1);
61
62
63=== added file 'gcc/testsuite/gcc.dg/sms-11.c'
64--- old/gcc/testsuite/gcc.dg/sms-11.c 1970-01-01 00:00:00 +0000
65+++ new/gcc/testsuite/gcc.dg/sms-11.c 2012-01-10 16:05:14 +0000
66@@ -0,0 +1,37 @@
67+/* { dg-do run } */
68+/* { dg-options "-O2 -fmodulo-sched -fmodulo-sched-allow-regmoves -fdump-rtl-sms" } */
69+
70+extern void abort (void);
71+
72+float out[4][4] = { 6, 6, 7, 5, 6, 7, 5, 5, 6, 4, 4, 4, 6, 2, 3, 4 };
73+
74+void
75+invert (void)
76+{
77+ int i, j, k = 0, swap;
78+ float tmp[4][4] = { 5, 6, 7, 5, 6, 7, 5, 5, 4, 4, 4, 4, 3, 2, 3, 4 };
79+
80+ for (i = 0; i < 4; i++)
81+ {
82+ for (j = i + 1; j < 4; j++)
83+ if (tmp[j][i] > tmp[i][i])
84+ swap = j;
85+
86+ if (swap != i)
87+ tmp[i][k] = tmp[swap][k];
88+ }
89+
90+ for (i = 0; i < 4; i++)
91+ for (j = 0; j < 4; j++)
92+ if (tmp[i][j] != out[i][j])
93+ abort ();
94+}
95+
96+int
97+main ()
98+{
99+ invert ();
100+ return 0;
101+}
102+
103+/* { dg-final { cleanup-rtl-dump "sms" } } */
104
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106861.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106861.patch
new file mode 100644
index 000000000..0199f7b89
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106861.patch
@@ -0,0 +1,76 @@
12012-01-18 Michael Hope <michael.hope@linaro.org>
2
3 Backport from mainline r183126:
4
5 2012-01-12 Ira Rosen <irar@il.ibm.com>
6
7 gcc/
8 PR tree-optimization/51799
9 * tree-vect-patterns.c (vect_recog_over_widening_pattern): Check
10 that the last operation is a type demotion.
11
12 gcc/testsuite/
13 * gcc.dg/vect/pr51799.c: New test.
14 * gcc.dg/vect/vect-widen-shift-u8.c: Expect two widening shift
15 patterns.
16
17=== added file 'gcc/testsuite/gcc.dg/vect/pr51799.c'
18--- old/gcc/testsuite/gcc.dg/vect/pr51799.c 1970-01-01 00:00:00 +0000
19+++ new/gcc/testsuite/gcc.dg/vect/pr51799.c 2012-01-18 01:53:19 +0000
20@@ -0,0 +1,18 @@
21+/* { dg-do compile } */
22+
23+typedef signed char int8_t;
24+typedef unsigned char uint8_t;
25+typedef signed short int16_t;
26+typedef unsigned long uint32_t;
27+void
28+f0a (uint32_t * __restrict__ result, int8_t * __restrict__ arg1,
29+ uint32_t * __restrict__ arg4, int8_t temp_6)
30+{
31+ int idx;
32+ for (idx = 0; idx < 416; idx += 1)
33+ {
34+ result[idx] = (uint8_t)(((arg1[idx] << 7) + arg4[idx]) * temp_6);
35+ }
36+}
37+
38+/* { dg-final { cleanup-tree-dump "vect" } } */
39
40=== modified file 'gcc/testsuite/gcc.dg/vect/vect-widen-shift-u8.c'
41--- old/gcc/testsuite/gcc.dg/vect/vect-widen-shift-u8.c 2011-10-23 13:33:07 +0000
42+++ new/gcc/testsuite/gcc.dg/vect/vect-widen-shift-u8.c 2012-01-18 01:53:19 +0000
43@@ -59,7 +59,6 @@
44 return 0;
45 }
46
47-/* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: detected" 1 "vect" { target vect_widen_shift } } } */
48+/* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: detected" 2 "vect" { target vect_widen_shift } } } */
49 /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
50 /* { dg-final { cleanup-tree-dump "vect" } } */
51-
52
53=== modified file 'gcc/tree-vect-patterns.c'
54--- old/gcc/tree-vect-patterns.c 2011-12-20 07:47:44 +0000
55+++ new/gcc/tree-vect-patterns.c 2012-01-18 01:53:19 +0000
56@@ -1224,13 +1224,15 @@
57 {
58 use_lhs = gimple_assign_lhs (use_stmt);
59 use_type = TREE_TYPE (use_lhs);
60- /* Support only type promotion or signedess change. Check that USE_TYPE
61- is not bigger than the original type. */
62+ /* Support only type demotion or signedess change. */
63 if (!INTEGRAL_TYPE_P (use_type)
64- || TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type)
65- || TYPE_PRECISION (type) < TYPE_PRECISION (use_type))
66+ || TYPE_PRECISION (type) <= TYPE_PRECISION (use_type))
67 return NULL;
68
69+ /* Check that NEW_TYPE is not bigger than the conversion result. */
70+ if (TYPE_PRECISION (new_type) > TYPE_PRECISION (use_type))
71+ return NULL;
72+
73 if (TYPE_UNSIGNED (new_type) != TYPE_UNSIGNED (use_type)
74 || TYPE_PRECISION (new_type) != TYPE_PRECISION (use_type))
75 {
76
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106862.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106862.patch
new file mode 100644
index 000000000..a20d889a5
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106862.patch
@@ -0,0 +1,45 @@
12012-01-16 Michael Hope <michael.hope@linaro.org>
2
3 Backport from mainline r183011:
4
5 2012-01-09 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
6
7 * config/arm/arm-cores.def (cortex-a15): Use cortex_a15_tune for
8 tuning parameters.
9 * config/arm/arm.c (arm_cortex_a15_tune): New static variable.
10
11=== modified file 'gcc/config/arm/arm-cores.def'
12--- old/gcc/config/arm/arm-cores.def 2011-10-19 16:46:51 +0000
13+++ new/gcc/config/arm/arm-cores.def 2012-01-15 22:02:31 +0000
14@@ -128,7 +128,7 @@
15 ARM_CORE("cortex-a5", cortexa5, 7A, FL_LDSCHED, cortex_a5)
16 ARM_CORE("cortex-a8", cortexa8, 7A, FL_LDSCHED, cortex)
17 ARM_CORE("cortex-a9", cortexa9, 7A, FL_LDSCHED, cortex_a9)
18-ARM_CORE("cortex-a15", cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex)
19+ARM_CORE("cortex-a15", cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15)
20 ARM_CORE("cortex-r4", cortexr4, 7R, FL_LDSCHED, cortex)
21 ARM_CORE("cortex-r4f", cortexr4f, 7R, FL_LDSCHED, cortex)
22 ARM_CORE("cortex-r5", cortexr5, 7R, FL_LDSCHED | FL_ARM_DIV, cortex)
23
24=== modified file 'gcc/config/arm/arm.c'
25--- old/gcc/config/arm/arm.c 2012-01-05 15:35:39 +0000
26+++ new/gcc/config/arm/arm.c 2012-01-15 22:02:31 +0000
27@@ -983,6 +983,17 @@
28 arm_default_branch_cost
29 };
30
31+const struct tune_params arm_cortex_a15_tune =
32+{
33+ arm_9e_rtx_costs,
34+ NULL,
35+ 1, /* Constant limit. */
36+ 1, /* Max cond insns. */
37+ ARM_PREFETCH_NOT_BENEFICIAL, /* TODO: Calculate correct values. */
38+ false, /* Prefer constant pool. */
39+ arm_cortex_a5_branch_cost
40+};
41+
42 const struct tune_params arm_fa726te_tune =
43 {
44 arm_9e_rtx_costs,
45
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106863.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106863.patch
new file mode 100644
index 000000000..e93493f17
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106863.patch
@@ -0,0 +1,47 @@
1 2012-01-16 Michael Hope <michael.hope@linaro.org>
2
3 Backport from mainline r182561:
4
5 2011-12-20 Richard Henderson <rth@redhat.com>
6
7 gcc/
8 * config/arm/arm.md (*arm_cmpdi_unsigned): Enable for thumb2.
9 * config/arm/arm.c (arm_select_cc_mode): Use it.
10
11=== modified file 'gcc/config/arm/arm.c'
12--- old/gcc/config/arm/arm.c 2012-01-15 22:02:31 +0000
13+++ new/gcc/config/arm/arm.c 2012-01-23 00:06:27 +0000
14@@ -11602,7 +11602,7 @@
15 return CC_Zmode;
16
17 /* We can do an equality test in three Thumb instructions. */
18- if (!TARGET_ARM)
19+ if (!TARGET_32BIT)
20 return CC_Zmode;
21
22 /* FALLTHROUGH */
23@@ -11614,7 +11614,7 @@
24 /* DImode unsigned comparisons can be implemented by cmp +
25 cmpeq without a scratch register. Not worth doing in
26 Thumb-2. */
27- if (TARGET_ARM)
28+ if (TARGET_32BIT)
29 return CC_CZmode;
30
31 /* FALLTHROUGH */
32
33=== modified file 'gcc/config/arm/arm.md'
34--- old/gcc/config/arm/arm.md 2012-01-05 15:35:39 +0000
35+++ new/gcc/config/arm/arm.md 2012-01-15 21:02:00 +0000
36@@ -7515,8 +7515,8 @@
37 [(set (reg:CC_CZ CC_REGNUM)
38 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "r")
39 (match_operand:DI 1 "arm_di_operand" "rDi")))]
40- "TARGET_ARM"
41- "cmp%?\\t%R0, %R1\;cmpeq\\t%Q0, %Q1"
42+ "TARGET_32BIT"
43+ "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1"
44 [(set_attr "conds" "set")
45 (set_attr "length" "8")]
46 )
47
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106864.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106864.patch
new file mode 100644
index 000000000..f15f37a58
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106864.patch
@@ -0,0 +1,63 @@
1 2012-01-16 Michael Hope <michael.hope@linaro.org>
2
3 Backport from mainline r181210:
4
5 gcc/
6 2011-11-07 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
7
8 * config/arm/arm-cores.def: Add -mcpu=cortex-a7.
9 * config/arm/arm-tables.opt: Regenerate.
10 * config/arm/arm-tune.md: Likewise.
11 * config/arm/bpabi.h (BE8_LINK_SPEC): Add Cortex A-7.
12 * doc/invoke.texi: Document -mcpu=cortex-a7.
13
14=== modified file 'gcc/config/arm/arm-cores.def'
15--- old/gcc/config/arm/arm-cores.def 2012-01-15 22:02:31 +0000
16+++ new/gcc/config/arm/arm-cores.def 2012-01-23 00:36:02 +0000
17@@ -126,6 +126,7 @@
18 ARM_CORE("arm1156t2f-s", arm1156t2fs, 6T2, FL_LDSCHED | FL_VFPV2, v6t2)
19 ARM_CORE("generic-armv7-a", genericv7a, 7A, FL_LDSCHED, cortex)
20 ARM_CORE("cortex-a5", cortexa5, 7A, FL_LDSCHED, cortex_a5)
21+ARM_CORE("cortex-a7", cortexa7, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex)
22 ARM_CORE("cortex-a8", cortexa8, 7A, FL_LDSCHED, cortex)
23 ARM_CORE("cortex-a9", cortexa9, 7A, FL_LDSCHED, cortex_a9)
24 ARM_CORE("cortex-a15", cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15)
25
26=== modified file 'gcc/config/arm/arm-tune.md'
27--- old/gcc/config/arm/arm-tune.md 2011-10-19 16:46:51 +0000
28+++ new/gcc/config/arm/arm-tune.md 2012-01-15 22:43:29 +0000
29@@ -1,5 +1,5 @@
30 ;; -*- buffer-read-only: t -*-
31 ;; Generated automatically by gentune.sh from arm-cores.def
32 (define_attr "tune"
33- "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,fa526,fa626,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,arm1156t2fs,genericv7a,cortexa5,cortexa8,cortexa9,cortexa15,cortexr4,cortexr4f,cortexr5,cortexm4,cortexm3,cortexm1,cortexm0"
34+ "arm2,arm250,arm3,arm6,arm60,arm600,arm610,arm620,arm7,arm7d,arm7di,arm70,arm700,arm700i,arm710,arm720,arm710c,arm7100,arm7500,arm7500fe,arm7m,arm7dm,arm7dmi,arm8,arm810,strongarm,strongarm110,strongarm1100,strongarm1110,fa526,fa626,arm7tdmi,arm7tdmis,arm710t,arm720t,arm740t,arm9,arm9tdmi,arm920,arm920t,arm922t,arm940t,ep9312,arm10tdmi,arm1020t,arm9e,arm946es,arm966es,arm968es,arm10e,arm1020e,arm1022e,xscale,iwmmxt,iwmmxt2,fa606te,fa626te,fmp626,fa726te,arm926ejs,arm1026ejs,arm1136js,arm1136jfs,arm1176jzs,arm1176jzfs,mpcorenovfp,mpcore,arm1156t2s,arm1156t2fs,genericv7a,cortexa5,cortexa7,cortexa8,cortexa9,cortexa15,cortexr4,cortexr4f,cortexr5,cortexm4,cortexm3,cortexm1,cortexm0"
35 (const (symbol_ref "((enum attr_tune) arm_tune)")))
36
37=== modified file 'gcc/config/arm/bpabi.h'
38--- old/gcc/config/arm/bpabi.h 2011-11-02 21:02:53 +0000
39+++ new/gcc/config/arm/bpabi.h 2012-01-15 22:43:29 +0000
40@@ -56,6 +56,7 @@
41 "|march=armv4|mcpu=fa526|mcpu=fa626:--fix-v4bx}"
42
43 #define BE8_LINK_SPEC " %{mbig-endian:%{march=armv7-a|mcpu=cortex-a5"\
44+ "|mcpu=cortex-a7"\
45 "|mcpu=cortex-a8|mcpu=cortex-a9|mcpu=cortex-a15|mcpu=generic-armv7-a"\
46 ":%{!r:--be8}}}"
47
48
49=== modified file 'gcc/doc/invoke.texi'
50--- old/gcc/doc/invoke.texi 2012-01-05 15:35:39 +0000
51+++ new/gcc/doc/invoke.texi 2012-01-15 22:43:29 +0000
52@@ -10202,8 +10202,8 @@
53 @samp{arm10e}, @samp{arm1020e}, @samp{arm1022e},
54 @samp{arm1136j-s}, @samp{arm1136jf-s}, @samp{mpcore}, @samp{mpcorenovfp},
55 @samp{arm1156t2-s}, @samp{arm1156t2f-s}, @samp{arm1176jz-s}, @samp{arm1176jzf-s},
56-@samp{cortex-a5}, @samp{cortex-a8}, @samp{cortex-a9}, @samp{cortex-a15},
57-@samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-r5},
58+@samp{cortex-a5}, @samp{cortex-a7}, @samp{cortex-a8}, @samp{cortex-a9},
59+@samp{cortex-a15}, @samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-r5},
60 @samp{cortex-m4}, @samp{cortex-m3},
61 @samp{cortex-m1},
62 @samp{cortex-m0},
63
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106865.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106865.patch
new file mode 100644
index 000000000..5b0735b00
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106865.patch
@@ -0,0 +1,25 @@
12012-01-20 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
2
3 Backport from mainline
4 2012-01-20 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
5
6 PR target/51819
7 * config/arm/arm.c (arm_print_operand): Correct output of alignment
8 hints for neon loads and stores.
9
10=== modified file 'gcc/config/arm/arm.c'
11--- old/gcc/config/arm/arm.c 2012-01-23 00:06:27 +0000
12+++ new/gcc/config/arm/arm.c 2012-01-23 18:54:21 +0000
13@@ -17463,9 +17463,9 @@
14 /* Only certain alignment specifiers are supported by the hardware. */
15 if (memsize == 16 && (align % 32) == 0)
16 align_bits = 256;
17- else if ((memsize == 8 || memsize == 16) && (align % 16) == 0)
18+ else if (memsize == 16 && (align % 16) == 0)
19 align_bits = 128;
20- else if ((align % 8) == 0)
21+ else if (memsize >= 8 && (align % 8) == 0)
22 align_bits = 64;
23 else
24 align_bits = 0;
25
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch
new file mode 100644
index 000000000..de3d2ff4c
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch
@@ -0,0 +1,2389 @@
12012-02-08 Ulrich Weigand <ulrich.weigand@linaro.org>
2
3 gcc/
4 * config/arm/arm.c (arm_option_optimization_table): Enable
5 -fsched-pressure using -fsched-pressure-algorithm=model by
6 default when optimizing.
7
82012-02-08 Richard Sandiford <richard.sandiford@linaro.org>
9
10 gcc/
11 * sched-deps.c (fixup_sched_groups): Rename to...
12 (chain_to_prev_insn): ...this.
13 (chain_to_prev_insn_p): New function.
14 (deps_analyze_insn): Use it instead of SCHED_GROUP_P.
15
162012-02-08 Richard Sandiford <richard.sandiford@linaro.org>
17
18 gcc/
19 * sched-int.h (_haifa_insn_data): Move priority_status.
20 Add model_index.
21 (INSN_MODEL_INDEX): New macro.
22 * haifa-sched.c (insn_delay): New function.
23 (sched_regno_pressure_class): Update commentary.
24 (mark_regno_birth_or_death): Pass the liveness bitmap and
25 pressure array as arguments, instead of using curr_reg_live and
26 curr_reg_pressure. Only update the pressure if the bit in the
27 liveness set has changed.
28 (initiate_reg_pressure_info): Always trust the live-in set for
29 SCHED_PRESSURE_MODEL.
30 (initiate_bb_reg_pressure_info): Update call to
31 mark_regno_birth_or_death.
32 (dep_list_size): Take the list as argument.
33 (calculate_reg_deaths): New function, extracted from...
34 (setup_insn_reg_pressure_info): ...here.
35 (MODEL_BAR): New macro.
36 (model_pressure_data, model_insn_info, model_pressure_limit)
37 (model_pressure_group): New structures.
38 (model_schedule, model_worklist, model_insns, model_num_insns)
39 (model_curr_point, model_before_pressure, model_next_priority):
40 New variables.
41 (MODEL_PRESSURE_DATA, MODEL_MAX_PRESSURE, MODEL_REF_PRESSURE)
42 (MODEL_INSN_INFO, MODEL_INSN): New macros.
43 (model_index, model_update_limit_points_in_group): New functions.
44 (model_update_limit_points, model_last_use_except): Likewise.
45 (model_start_update_pressure, model_update_pressure): Likewise.
46 (model_recompute, model_spill_cost, model_excess_group_cost): Likewise.
47 (model_excess_cost, model_dump_pressure_points): Likewise.
48 (model_set_excess_costs): Likewise.
49 (rank_for_schedule): Extend SCHED_PRIORITY_WEIGHTED ordering to
50 SCHED_PRIORITY_MODEL. Use insn_delay. Use the order in the model
51 schedule as an alternative tie-breaker. Update the call to
52 dep_list_size.
53 (ready_sort): Call model_set_excess_costs.
54 (update_register_pressure): Update call to mark_regno_birth_or_death.
55 Rely on that function to check liveness rather than doing it here.
56 (model_classify_pressure, model_order_p, model_add_to_worklist_at)
57 (model_remove_from_worklist, model_add_to_worklist, model_promote_insn)
58 (model_add_to_schedule, model_analyze_insns, model_init_pressure_group)
59 (model_record_pressure, model_record_pressures): New functions.
60 (model_record_final_pressures, model_add_successors_to_worklist)
61 (model_promote_predecessors, model_choose_insn): Likewise.
62 (model_reset_queue_indices, model_dump_pressure_summary): Likewise.
63 (model_start_schedule, model_finalize_pressure_group): Likewise.
64 (model_end_schedule): Likewise.
65 (schedule_insn): Say when we're scheduling the next instruction
66 in the model schedule.
67 (schedule_insn): Handle SCHED_PRESSURE_MODEL.
68 (queue_to_ready): Do not add instructions that are
69 MAX_SCHED_READY_INSNS beyond the current point of the model schedule.
70 Always allow the next instruction in the model schedule to be added.
71 (debug_ready_list): Print the INSN_REG_PRESSURE_EXCESS_COST_CHANGE
72 and delay for SCHED_PRESSURE_MODEL too.
73 (prune_ready_list): Extend SCHED_PRIORITY_WEIGHTED handling to
74 SCHED_PRIORITY_MODEL, but also take the DFA into account.
75 (schedule_block): Call model_start_schedule and model_end_schedule.
76 Extend SCHED_PRIORITY_WEIGHTED stall handling to SCHED_PRIORITY_MODEL.
77 (sched_init): Extend INSN_REG_PRESSURE_EXCESS_COST_CHANGE handling
78 to SCHED_PRESSURE_MODEL, but don't allocate saved_reg_live or
79 region_ref_regs.
80 (sched_finish): Update accordingly.
81 (fix_tick_ready): Extend INSN_REG_PRESSURE_EXCESS_COST_CHANGE handling
82 to SCHED_PRESSURE_MODEL.
83 (add_jump_dependencies): Update call to dep_list_size.
84 (haifa_finish_h_i_d): Fix leak of max_reg_pressure.
85 (haifa_init_insn): Extend INSN_REG_PRESSURE_EXCESS_COST_CHANGE handling
86 to SCHED_PRESSURE_MODEL.
87 * sched-deps.c (init_insn_reg_pressure_info): Likewise, but don't
88 allocate INSN_MAX_REG_PRESSURE for SCHED_PRESSURE_MODEL.
89 (sched_analyze_insn): Extend INSN_REG_PRESSURE_EXCESS_COST_CHANGE
90 handling to SCHED_PRESSURE_MODEL.
91
922012-02-08 Richard Sandiford <richard.sandiford@linaro.org>
93
94 gcc/
95 * common.opt (fsched-pressure-algorithm=): New option.
96 * flag-types.h (sched_pressure_algorithm): New enum.
97 * sched-int.h (sched_pressure_p): Replace with...
98 (sched_pressure): ...this new variable.
99 * haifa-sched.c (sched_pressure_p): Replace with...
100 (sched_pressure): ...this new variable.
101 (sched_regno_pressure_class, rank_for_schedule, ready_sort)
102 (update_reg_and_insn_max_reg_pressure, schedule_insn)
103 (debug_ready_list, schedule_block, sched_init, sched_finish)
104 (fix_tick_ready, haifa_init_insn): Update accordingly.
105 * sched-deps.c (init_insn_reg_pressure_info): Likewise.
106 * sched-rgn.c (schedule_region): Likewise.
107
1082012-02-08 Richard Sandiford <richard.sandiford@linaro.org>
109
110 gcc/
111 Backport from mainline:
112
113 2011-04-01 Bernd Schmidt <bernds@codesourcery.com>
114
115 * haifa-sched.c (prune_ready_list): New function, broken out of
116 schedule_block.
117 (schedule_block): Use it.
118
119=== modified file 'gcc/common.opt'
120--- old/gcc/common.opt 2011-04-11 15:26:47 +0000
121+++ new/gcc/common.opt 2012-02-08 23:38:13 +0000
122@@ -1614,6 +1614,19 @@
123 Common Report Var(flag_sched_pressure) Init(0) Optimization
124 Enable register pressure sensitive insn scheduling
125
126+fsched-pressure-algorithm=
127+Common Joined RejectNegative Enum(sched_pressure_algorithm) Var(flag_sched_pressure_algorithm) Init(SCHED_PRESSURE_WEIGHTED)
128+-fira-algorithm=[CB|priority] Set the used IRA algorithm
129+
130+Enum
131+Name(sched_pressure_algorithm) Type(enum sched_pressure_algorithm) UnknownError(unknown %<fsched-pressure%> algorithm %qs)
132+
133+EnumValue
134+Enum(sched_pressure_algorithm) String(weighted) Value(SCHED_PRESSURE_WEIGHTED)
135+
136+EnumValue
137+Enum(sched_pressure_algorithm) String(model) Value(SCHED_PRESSURE_MODEL)
138+
139 fsched-spec
140 Common Report Var(flag_schedule_speculative) Init(1) Optimization
141 Allow speculative motion of non-loads
142
143=== modified file 'gcc/config/arm/arm.c'
144--- old/gcc/config/arm/arm.c 2012-02-01 14:13:07 +0000
145+++ new/gcc/config/arm/arm.c 2012-02-09 00:47:59 +0000
146@@ -311,6 +311,11 @@
147 /* Set default optimization options. */
148 static const struct default_options arm_option_optimization_table[] =
149 {
150+ /* Enable -fsched-pressure using -fsched-pressure-algorithm=model
151+ by default when optimizing. */
152+ { OPT_LEVELS_1_PLUS, OPT_fsched_pressure, NULL, 1 },
153+ { OPT_LEVELS_1_PLUS, OPT_fsched_pressure_algorithm_,
154+ NULL, SCHED_PRESSURE_MODEL },
155 /* Enable section anchors by default at -O1 or higher. */
156 { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
157 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
158
159=== modified file 'gcc/flag-types.h'
160--- old/gcc/flag-types.h 2010-11-24 13:28:38 +0000
161+++ new/gcc/flag-types.h 2012-02-08 23:38:13 +0000
162@@ -106,6 +106,14 @@
163 };
164 #endif
165
166+/* The algorithm used to implement -fsched-pressure. */
167+enum sched_pressure_algorithm
168+{
169+ SCHED_PRESSURE_NONE,
170+ SCHED_PRESSURE_WEIGHTED,
171+ SCHED_PRESSURE_MODEL
172+};
173+
174 /* The algorithm used for the integrated register allocator (IRA). */
175 enum ira_algorithm
176 {
177
178=== modified file 'gcc/haifa-sched.c'
179--- old/gcc/haifa-sched.c 2011-02-19 20:59:23 +0000
180+++ new/gcc/haifa-sched.c 2012-02-08 23:39:02 +0000
181@@ -348,6 +348,14 @@
182 /* Create empty basic block after the specified block. */
183 basic_block (* sched_create_empty_bb) (basic_block);
184
185+/* Return the number of cycles until INSN is expected to be ready.
186+ Return zero if it already is. */
187+static int
188+insn_delay (rtx insn)
189+{
190+ return MAX (INSN_TICK (insn) - clock_var, 0);
191+}
192+
193 static int
194 may_trap_exp (const_rtx x, int is_store)
195 {
196@@ -571,10 +579,10 @@
197
198 /* Do register pressure sensitive insn scheduling if the flag is set
199 up. */
200-bool sched_pressure_p;
201+enum sched_pressure_algorithm sched_pressure;
202
203 /* Map regno -> its cover class. The map defined only when
204- SCHED_PRESSURE_P is true. */
205+ SCHED_PRESSURE != SCHED_PRESSURE_NONE. */
206 enum reg_class *sched_regno_cover_class;
207
208 /* The current register pressure. Only elements corresponding cover
209@@ -602,10 +610,12 @@
210 bitmap_clear (region_ref_regs);
211 }
212
213-/* Update current register pressure related info after birth (if
214- BIRTH_P) or death of register REGNO. */
215-static void
216-mark_regno_birth_or_death (int regno, bool birth_p)
217+/* PRESSURE[CL] describes the pressure on register class CL. Update it
218+ for the birth (if BIRTH_P) or death (if !BIRTH_P) of register REGNO.
219+ LIVE tracks the set of live registers; if it is null, assume that
220+ every birth or death is genuine. */
221+static inline void
222+mark_regno_birth_or_death (bitmap live, int *pressure, int regno, bool birth_p)
223 {
224 enum reg_class cover_class;
225
226@@ -616,15 +626,17 @@
227 {
228 if (birth_p)
229 {
230- bitmap_set_bit (curr_reg_live, regno);
231- curr_reg_pressure[cover_class]
232- += ira_reg_class_nregs[cover_class][PSEUDO_REGNO_MODE (regno)];
233+ if (!live || bitmap_set_bit (live, regno))
234+ pressure[cover_class]
235+ += (ira_reg_class_nregs
236+ [cover_class][PSEUDO_REGNO_MODE (regno)]);
237 }
238 else
239 {
240- bitmap_clear_bit (curr_reg_live, regno);
241- curr_reg_pressure[cover_class]
242- -= ira_reg_class_nregs[cover_class][PSEUDO_REGNO_MODE (regno)];
243+ if (!live || bitmap_clear_bit (live, regno))
244+ pressure[cover_class]
245+ -= (ira_reg_class_nregs
246+ [cover_class][PSEUDO_REGNO_MODE (regno)]);
247 }
248 }
249 }
250@@ -633,13 +645,13 @@
251 {
252 if (birth_p)
253 {
254- bitmap_set_bit (curr_reg_live, regno);
255- curr_reg_pressure[cover_class]++;
256+ if (!live || bitmap_set_bit (live, regno))
257+ pressure[cover_class]++;
258 }
259 else
260 {
261- bitmap_clear_bit (curr_reg_live, regno);
262- curr_reg_pressure[cover_class]--;
263+ if (!live || bitmap_clear_bit (live, regno))
264+ pressure[cover_class]--;
265 }
266 }
267 }
268@@ -657,8 +669,10 @@
269 curr_reg_pressure[ira_reg_class_cover[i]] = 0;
270 bitmap_clear (curr_reg_live);
271 EXECUTE_IF_SET_IN_BITMAP (live, 0, j, bi)
272- if (current_nr_blocks == 1 || bitmap_bit_p (region_ref_regs, j))
273- mark_regno_birth_or_death (j, true);
274+ if (sched_pressure == SCHED_PRESSURE_MODEL
275+ || current_nr_blocks == 1
276+ || bitmap_bit_p (region_ref_regs, j))
277+ mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure, j, true);
278 }
279
280 /* Mark registers in X as mentioned in the current region. */
281@@ -712,7 +726,8 @@
282 if (regno == INVALID_REGNUM)
283 break;
284 if (! bitmap_bit_p (df_get_live_in (bb), regno))
285- mark_regno_birth_or_death (regno, true);
286+ mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
287+ regno, true);
288 }
289 #endif
290 }
291@@ -956,19 +971,19 @@
292 return true;
293 }
294
295-/* Compute the number of nondebug forward deps of an insn. */
296+/* Compute the number of nondebug deps in list LIST for INSN. */
297
298 static int
299-dep_list_size (rtx insn)
300+dep_list_size (rtx insn, sd_list_types_def list)
301 {
302 sd_iterator_def sd_it;
303 dep_t dep;
304 int dbgcount = 0, nodbgcount = 0;
305
306 if (!MAY_HAVE_DEBUG_INSNS)
307- return sd_lists_size (insn, SD_LIST_FORW);
308+ return sd_lists_size (insn, list);
309
310- FOR_EACH_DEP (insn, SD_LIST_FORW, sd_it, dep)
311+ FOR_EACH_DEP (insn, list, sd_it, dep)
312 {
313 if (DEBUG_INSN_P (DEP_CON (dep)))
314 dbgcount++;
315@@ -976,7 +991,7 @@
316 nodbgcount++;
317 }
318
319- gcc_assert (dbgcount + nodbgcount == sd_lists_size (insn, SD_LIST_FORW));
320+ gcc_assert (dbgcount + nodbgcount == sd_lists_size (insn, list));
321
322 return nodbgcount;
323 }
324@@ -995,7 +1010,7 @@
325 {
326 int this_priority = -1;
327
328- if (dep_list_size (insn) == 0)
329+ if (dep_list_size (insn, SD_LIST_FORW) == 0)
330 /* ??? We should set INSN_PRIORITY to insn_cost when and insn has
331 some forward deps but all of them are ignored by
332 contributes_to_priority hook. At the moment we set priority of
333@@ -1091,6 +1106,22 @@
334 qsort (READY, N_READY, sizeof (rtx), rank_for_schedule); } \
335 while (0)
336
337+/* For each cover class CL, set DEATH[CL] to the number of registers
338+ in that class that die in INSN. */
339+
340+static void
341+calculate_reg_deaths (rtx insn, int *death)
342+{
343+ int i;
344+ struct reg_use_data *use;
345+
346+ for (i = 0; i < ira_reg_class_cover_size; i++)
347+ death[ira_reg_class_cover[i]] = 0;
348+ for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
349+ if (dying_use_p (use))
350+ mark_regno_birth_or_death (0, death, use->regno, true);
351+}
352+
353 /* Setup info about the current register pressure impact of scheduling
354 INSN at the current scheduling point. */
355 static void
356@@ -1102,23 +1133,12 @@
357 enum reg_class cl;
358 struct reg_pressure_data *pressure_info;
359 int *max_reg_pressure;
360- struct reg_use_data *use;
361 static int death[N_REG_CLASSES];
362
363 gcc_checking_assert (!DEBUG_INSN_P (insn));
364
365 excess_cost_change = 0;
366- for (i = 0; i < ira_reg_class_cover_size; i++)
367- death[ira_reg_class_cover[i]] = 0;
368- for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
369- if (dying_use_p (use))
370- {
371- cl = sched_regno_cover_class[use->regno];
372- if (use->regno < FIRST_PSEUDO_REGISTER)
373- death[cl]++;
374- else
375- death[cl] += ira_reg_class_nregs[cl][PSEUDO_REGNO_MODE (use->regno)];
376- }
377+ calculate_reg_deaths (insn, death);
378 pressure_info = INSN_REG_PRESSURE (insn);
379 max_reg_pressure = INSN_MAX_REG_PRESSURE (insn);
380 gcc_assert (pressure_info != NULL && max_reg_pressure != NULL);
381@@ -1139,7 +1159,765 @@
382 }
383 INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insn) = excess_cost_change;
384 }
385-
386+
387+/* This is the first page of code related to SCHED_PRESSURE_MODEL.
388+ It tries to make the scheduler take register pressure into account
389+ without introducing too many unnecessary stalls. It hooks into the
390+ main scheduling algorithm at several points:
391+
392+ - Before scheduling starts, model_start_schedule constructs a
393+ "model schedule" for the current block. This model schedule is
394+ chosen solely to keep register pressure down. It does not take the
395+ target's pipeline or the original instruction order into account,
396+ except as a tie-breaker. It also doesn't work to a particular
397+ pressure limit.
398+
399+ This model schedule gives us an idea of what pressure can be
400+ achieved for the block gives us an example of a schedule that
401+ keeps to that pressure. It also makes the final schedule less
402+ dependent on the original instruction order. This is important
403+ because the original order can either be "wide" (many values live
404+ at once, such as in user-scheduled code) or "narrow" (few values
405+ live at once, such as after loop unrolling, where several
406+ iterations are executed sequentially).
407+
408+ We do not apply this model schedule to the rtx stream. We simply
409+ record it in model_schedule. We also compute the maximum pressure,
410+ MP, that was seen during this schedule.
411+
412+ - Instructions are added to the ready queue even if they require
413+ a stall. The length of the stall is instead computed as:
414+
415+ MAX (INSN_TICK (INSN) - clock_var, 0)
416+
417+ (= insn_delay). This allows rank_for_schedule to choose between
418+ introducing a deliberate stall or increasing pressure.
419+
420+ - Before sorting the ready queue, model_set_excess_costs assigns
421+ a pressure-based cost to each ready instruction in the queue.
422+ This is the instruction's INSN_REG_PRESSURE_EXCESS_COST_CHANGE
423+ (ECC for short) and is effectively measured in cycles.
424+
425+ - rank_for_schedule ranks instructions based on:
426+
427+ ECC (insn) + insn_delay (insn)
428+
429+ then as:
430+
431+ insn_delay (insn)
432+
433+ So, for example, an instruction X1 with an ECC of 1 that can issue
434+ now will win over an instruction X0 with an ECC of zero that would
435+ introduce a stall of one cycle. However, an instruction X2 with an
436+ ECC of 2 that can issue now will lose to X0.
437+
438+ - When an instruction is scheduled, model_recompute updates the model
439+ schedule with the new pressures (some of which might now exceed the
440+ original maximum pressure MP). model_update_limit_points then searches
441+ for the new point of maximum pressure, if not already known. */
442+
443+/* Used to separate high-verbosity debug information for SCHED_PRESSURE_MODEL
444+ from surrounding debug information. */
445+#define MODEL_BAR \
446+ ";;\t\t+------------------------------------------------------\n"
447+
448+/* Information about the pressure on a particular register class at a
449+ particular point of the model schedule. */
450+struct model_pressure_data {
451+ /* The pressure at this point of the model schedule, or -1 if the
452+ point is associated with an instruction that has already been
453+ scheduled. */
454+ int ref_pressure;
455+
456+ /* The maximum pressure during or after this point of the model schedule. */
457+ int max_pressure;
458+};
459+
460+/* Per-instruction information that is used while building the model
461+ schedule. Here, "schedule" refers to the model schedule rather
462+ than the main schedule. */
463+struct model_insn_info {
464+ /* The instruction itself. */
465+ rtx insn;
466+
467+ /* If this instruction is in model_worklist, these fields link to the
468+ previous (higher-priority) and next (lower-priority) instructions
469+ in the list. */
470+ struct model_insn_info *prev;
471+ struct model_insn_info *next;
472+
473+ /* While constructing the schedule, QUEUE_INDEX describes whether an
474+ instruction has already been added to the schedule (QUEUE_SCHEDULED),
475+ is in model_worklist (QUEUE_READY), or neither (QUEUE_NOWHERE).
476+ old_queue records the value that QUEUE_INDEX had before scheduling
477+ started, so that we can restore it once the schedule is complete. */
478+ int old_queue;
479+
480+ /* The relative importance of an unscheduled instruction. Higher
481+ values indicate greater importance. */
482+ unsigned int model_priority;
483+
484+ /* The length of the longest path of satisfied true dependencies
485+ that leads to this instruction. */
486+ unsigned int depth;
487+
488+ /* The length of the longest path of dependencies of any kind
489+ that leads from this instruction. */
490+ unsigned int alap;
491+
492+ /* The number of predecessor nodes that must still be scheduled. */
493+ int unscheduled_preds;
494+};
495+
496+/* Information about the pressure limit for a particular register class.
497+ This structure is used when applying a model schedule to the main
498+ schedule. */
499+struct model_pressure_limit {
500+ /* The maximum register pressure seen in the original model schedule. */
501+ int orig_pressure;
502+
503+ /* The maximum register pressure seen in the current model schedule
504+ (which excludes instructions that have already been scheduled). */
505+ int pressure;
506+
507+ /* The point of the current model schedule at which PRESSURE is first
508+ reached. It is set to -1 if the value needs to be recomputed. */
509+ int point;
510+};
511+
512+/* Describes a particular way of measuring register pressure. */
513+struct model_pressure_group {
514+ /* Index CCI describes the maximum pressure on ira_reg_class_cover[CCI]. */
515+ struct model_pressure_limit limits[N_REG_CLASSES];
516+
517+ /* Index (POINT * ira_num_pressure_classes + CCI) describes the pressure
518+ on register class ira_reg_class_cover[CCI] at point POINT of the
519+ current model schedule. A POINT of model_num_insns describes the
520+ pressure at the end of the schedule. */
521+ struct model_pressure_data *model;
522+};
523+
524+/* Index POINT gives the instruction at point POINT of the model schedule.
525+ This array doesn't change during main scheduling. */
526+static VEC (rtx, heap) *model_schedule;
527+
528+/* The list of instructions in the model worklist, sorted in order of
529+ decreasing priority. */
530+static struct model_insn_info *model_worklist;
531+
532+/* Index I describes the instruction with INSN_LUID I. */
533+static struct model_insn_info *model_insns;
534+
535+/* The number of instructions in the model schedule. */
536+static int model_num_insns;
537+
538+/* The index of the first instruction in model_schedule that hasn't yet been
539+ added to the main schedule, or model_num_insns if all of them have. */
540+static int model_curr_point;
541+
542+/* Describes the pressure before each instruction in the model schedule. */
543+static struct model_pressure_group model_before_pressure;
544+
545+/* The first unused model_priority value (as used in model_insn_info). */
546+static unsigned int model_next_priority;
547+
548+
549+/* The model_pressure_data for ira_reg_class_cover[CCI] in GROUP
550+ at point POINT of the model schedule. */
551+#define MODEL_PRESSURE_DATA(GROUP, POINT, CCI) \
552+ (&(GROUP)->model[(POINT) * ira_reg_class_cover_size + (CCI)])
553+
554+/* The maximum pressure on ira_reg_class_cover[CCI] in GROUP at or
555+ after point POINT of the model schedule. */
556+#define MODEL_MAX_PRESSURE(GROUP, POINT, CCI) \
557+ (MODEL_PRESSURE_DATA (GROUP, POINT, CCI)->max_pressure)
558+
559+/* The pressure on ira_reg_class_cover[CCI] in GROUP at point POINT
560+ of the model schedule. */
561+#define MODEL_REF_PRESSURE(GROUP, POINT, CCI) \
562+ (MODEL_PRESSURE_DATA (GROUP, POINT, CCI)->ref_pressure)
563+
564+/* Information about INSN that is used when creating the model schedule. */
565+#define MODEL_INSN_INFO(INSN) \
566+ (&model_insns[INSN_LUID (INSN)])
567+
568+/* The instruction at point POINT of the model schedule. */
569+#define MODEL_INSN(POINT) \
570+ (VEC_index (rtx, model_schedule, POINT))
571+
572+
573+/* Return INSN's index in the model schedule, or model_num_insns if it
574+ doesn't belong to that schedule. */
575+
576+static int
577+model_index (rtx insn)
578+{
579+ if (INSN_MODEL_INDEX (insn) == 0)
580+ return model_num_insns;
581+ return INSN_MODEL_INDEX (insn) - 1;
582+}
583+
584+/* Make sure that GROUP->limits is up-to-date for the current point
585+ of the model schedule. */
586+
587+static void
588+model_update_limit_points_in_group (struct model_pressure_group *group)
589+{
590+ int cci, max_pressure, point;
591+
592+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
593+ {
594+ /* We may have passed the final point at which the pressure in
595+ group->limits[cci].pressure was reached. Update the limit if so. */
596+ max_pressure = MODEL_MAX_PRESSURE (group, model_curr_point, cci);
597+ group->limits[cci].pressure = max_pressure;
598+
599+ /* Find the point at which MAX_PRESSURE is first reached. We need
600+ to search in three cases:
601+
602+ - We've already moved past the previous pressure point.
603+ In this case we search forward from model_curr_point.
604+
605+ - We scheduled the previous point of maximum pressure ahead of
606+ its position in the model schedule, but doing so didn't bring
607+ the pressure point earlier. In this case we search forward
608+ from that previous pressure point.
609+
610+ - Scheduling an instruction early caused the maximum pressure
611+ to decrease. In this case we will have set the pressure
612+ point to -1, and we search forward from model_curr_point. */
613+ point = MAX (group->limits[cci].point, model_curr_point);
614+ while (point < model_num_insns
615+ && MODEL_REF_PRESSURE (group, point, cci) < max_pressure)
616+ point++;
617+ group->limits[cci].point = point;
618+
619+ gcc_assert (MODEL_REF_PRESSURE (group, point, cci) == max_pressure);
620+ gcc_assert (MODEL_MAX_PRESSURE (group, point, cci) == max_pressure);
621+ }
622+}
623+
624+/* Make sure that all register-pressure limits are up-to-date for the
625+ current position in the model schedule. */
626+
627+static void
628+model_update_limit_points (void)
629+{
630+ model_update_limit_points_in_group (&model_before_pressure);
631+}
632+
633+/* Return the model_index of the last unscheduled use in chain USE
634+ outside of USE's instruction. Return -1 if there are no other uses,
635+ or model_num_insns if the register is live at the end of the block. */
636+
637+static int
638+model_last_use_except (struct reg_use_data *use)
639+{
640+ struct reg_use_data *next;
641+ int last, index;
642+
643+ last = -1;
644+ for (next = use->next_regno_use; next != use; next = next->next_regno_use)
645+ if (NONDEBUG_INSN_P (next->insn)
646+ && QUEUE_INDEX (next->insn) != QUEUE_SCHEDULED)
647+ {
648+ index = model_index (next->insn);
649+ if (index == model_num_insns)
650+ return model_num_insns;
651+ if (last < index)
652+ last = index;
653+ }
654+ return last;
655+}
656+
657+/* An instruction with model_index POINT has just been scheduled, and it
658+ adds DELTA to the pressure on ira_reg_class_cover[CCI] after POINT - 1.
659+ Update MODEL_REF_PRESSURE (GROUP, POINT, CCI) and
660+ MODEL_MAX_PRESSURE (GROUP, POINT, CCI) accordingly. */
661+
662+static void
663+model_start_update_pressure (struct model_pressure_group *group,
664+ int point, int cci, int delta)
665+{
666+ int next_max_pressure;
667+
668+ if (point == model_num_insns)
669+ {
670+ /* The instruction wasn't part of the model schedule; it was moved
671+ from a different block. Update the pressure for the end of
672+ the model schedule. */
673+ MODEL_REF_PRESSURE (group, point, cci) += delta;
674+ MODEL_MAX_PRESSURE (group, point, cci) += delta;
675+ }
676+ else
677+ {
678+ /* Record that this instruction has been scheduled. Nothing now
679+ changes between POINT and POINT + 1, so get the maximum pressure
680+ from the latter. If the maximum pressure decreases, the new
681+ pressure point may be before POINT. */
682+ MODEL_REF_PRESSURE (group, point, cci) = -1;
683+ next_max_pressure = MODEL_MAX_PRESSURE (group, point + 1, cci);
684+ if (MODEL_MAX_PRESSURE (group, point, cci) > next_max_pressure)
685+ {
686+ MODEL_MAX_PRESSURE (group, point, cci) = next_max_pressure;
687+ if (group->limits[cci].point == point)
688+ group->limits[cci].point = -1;
689+ }
690+ }
691+}
692+
693+/* Record that scheduling a later instruction has changed the pressure
694+ at point POINT of the model schedule by DELTA (which might be 0).
695+ Update GROUP accordingly. Return nonzero if these changes might
696+ trigger changes to previous points as well. */
697+
698+static int
699+model_update_pressure (struct model_pressure_group *group,
700+ int point, int cci, int delta)
701+{
702+ int ref_pressure, max_pressure, next_max_pressure;
703+
704+ /* If POINT hasn't yet been scheduled, update its pressure. */
705+ ref_pressure = MODEL_REF_PRESSURE (group, point, cci);
706+ if (ref_pressure >= 0 && delta != 0)
707+ {
708+ ref_pressure += delta;
709+ MODEL_REF_PRESSURE (group, point, cci) = ref_pressure;
710+
711+ /* Check whether the maximum pressure in the overall schedule
712+ has increased. (This means that the MODEL_MAX_PRESSURE of
713+ every point <= POINT will need to increae too; see below.) */
714+ if (group->limits[cci].pressure < ref_pressure)
715+ group->limits[cci].pressure = ref_pressure;
716+
717+ /* If we are at maximum pressure, and the maximum pressure
718+ point was previously unknown or later than POINT,
719+ bring it forward. */
720+ if (group->limits[cci].pressure == ref_pressure
721+ && !IN_RANGE (group->limits[cci].point, 0, point))
722+ group->limits[cci].point = point;
723+
724+ /* If POINT used to be the point of maximum pressure, but isn't
725+ any longer, we need to recalculate it using a forward walk. */
726+ if (group->limits[cci].pressure > ref_pressure
727+ && group->limits[cci].point == point)
728+ group->limits[cci].point = -1;
729+ }
730+
731+ /* Update the maximum pressure at POINT. Changes here might also
732+ affect the maximum pressure at POINT - 1. */
733+ next_max_pressure = MODEL_MAX_PRESSURE (group, point + 1, cci);
734+ max_pressure = MAX (ref_pressure, next_max_pressure);
735+ if (MODEL_MAX_PRESSURE (group, point, cci) != max_pressure)
736+ {
737+ MODEL_MAX_PRESSURE (group, point, cci) = max_pressure;
738+ return 1;
739+ }
740+ return 0;
741+}
742+
743+/* INSN has just been scheduled. Update the model schedule accordingly. */
744+
745+static void
746+model_recompute (rtx insn)
747+{
748+ struct {
749+ int last_use;
750+ int regno;
751+ } uses[FIRST_PSEUDO_REGISTER + MAX_RECOG_OPERANDS];
752+ struct reg_use_data *use;
753+ struct reg_pressure_data *reg_pressure;
754+ int delta[N_REG_CLASSES];
755+ int cci, point, mix, new_last, cl, ref_pressure, queue;
756+ unsigned int i, num_uses, num_pending_births;
757+ bool print_p;
758+
759+ /* The destinations of INSN were previously live from POINT onwards, but are
760+ now live from model_curr_point onwards. Set up DELTA accordingly. */
761+ point = model_index (insn);
762+ reg_pressure = INSN_REG_PRESSURE (insn);
763+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
764+ {
765+ cl = ira_reg_class_cover[cci];
766+ delta[cl] = reg_pressure[cci].set_increase;
767+ }
768+
769+ /* Record which registers previously died at POINT, but which now die
770+ before POINT. Adjust DELTA so that it represents the effect of
771+ this change after POINT - 1. Set NUM_PENDING_BIRTHS to the number of
772+ registers that will be born in the range [model_curr_point, POINT). */
773+ num_uses = 0;
774+ num_pending_births = 0;
775+ for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
776+ {
777+ new_last = model_last_use_except (use);
778+ if (new_last < point)
779+ {
780+ gcc_assert (num_uses < ARRAY_SIZE (uses));
781+ uses[num_uses].last_use = new_last;
782+ uses[num_uses].regno = use->regno;
783+ /* This register is no longer live after POINT - 1. */
784+ mark_regno_birth_or_death (NULL, delta, use->regno, false);
785+ num_uses++;
786+ if (new_last >= 0)
787+ num_pending_births++;
788+ }
789+ }
790+
791+ /* Update the MODEL_REF_PRESSURE and MODEL_MAX_PRESSURE for POINT.
792+ Also set each group pressure limit for POINT. */
793+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
794+ {
795+ cl = ira_reg_class_cover[cci];
796+ model_start_update_pressure (&model_before_pressure,
797+ point, cci, delta[cl]);
798+ }
799+
800+ /* Walk the model schedule backwards, starting immediately before POINT. */
801+ print_p = false;
802+ if (point != model_curr_point)
803+ do
804+ {
805+ point--;
806+ insn = MODEL_INSN (point);
807+ queue = QUEUE_INDEX (insn);
808+
809+ if (queue != QUEUE_SCHEDULED)
810+ {
811+ /* DELTA describes the effect of the move on the register pressure
812+ after POINT. Make it describe the effect on the pressure
813+ before POINT. */
814+ i = 0;
815+ while (i < num_uses)
816+ {
817+ if (uses[i].last_use == point)
818+ {
819+ /* This register is now live again. */
820+ mark_regno_birth_or_death (NULL, delta,
821+ uses[i].regno, true);
822+
823+ /* Remove this use from the array. */
824+ uses[i] = uses[num_uses - 1];
825+ num_uses--;
826+ num_pending_births--;
827+ }
828+ else
829+ i++;
830+ }
831+
832+ if (sched_verbose >= 5)
833+ {
834+ char buf[2048];
835+
836+ if (!print_p)
837+ {
838+ fprintf (sched_dump, MODEL_BAR);
839+ fprintf (sched_dump, ";;\t\t| New pressure for model"
840+ " schedule\n");
841+ fprintf (sched_dump, MODEL_BAR);
842+ print_p = true;
843+ }
844+
845+ print_pattern (buf, PATTERN (insn), 0);
846+ fprintf (sched_dump, ";;\t\t| %3d %4d %-30s ",
847+ point, INSN_UID (insn), buf);
848+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
849+ {
850+ cl = ira_reg_class_cover[cci];
851+ ref_pressure = MODEL_REF_PRESSURE (&model_before_pressure,
852+ point, cci);
853+ fprintf (sched_dump, " %s:[%d->%d]",
854+ reg_class_names[ira_reg_class_cover[cci]],
855+ ref_pressure, ref_pressure + delta[cl]);
856+ }
857+ fprintf (sched_dump, "\n");
858+ }
859+ }
860+
861+ /* Adjust the pressure at POINT. Set MIX to nonzero if POINT - 1
862+ might have changed as well. */
863+ mix = num_pending_births;
864+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
865+ {
866+ cl = ira_reg_class_cover[cci];
867+ mix |= delta[cl];
868+ mix |= model_update_pressure (&model_before_pressure,
869+ point, cci, delta[cl]);
870+ }
871+ }
872+ while (mix && point > model_curr_point);
873+
874+ if (print_p)
875+ fprintf (sched_dump, MODEL_BAR);
876+}
877+
878+/* model_spill_cost (CL, P, P') returns the cost of increasing the
879+ pressure on CL from P to P'. We use this to calculate a "base ECC",
880+ baseECC (CL, X), for each cover class CL and each instruction X.
881+ Supposing X changes the pressure on CL from P to P', and that the
882+ maximum pressure on CL in the current model schedule is MP', then:
883+
884+ * if X occurs before or at the next point of maximum pressure in
885+ the model schedule and P' > MP', then:
886+
887+ baseECC (CL, X) = model_spill_cost (CL, MP, P')
888+
889+ The idea is that the pressure after scheduling a fixed set of
890+ instructions -- in this case, the set up to and including the
891+ next maximum pressure point -- is going to be the same regardless
892+ of the order; we simply want to keep the intermediate pressure
893+ under control. Thus X has a cost of zero unless scheduling it
894+ now would exceed MP'.
895+
896+ If all increases in the set are by the same amount, no zero-cost
897+ instruction will ever cause the pressure to exceed MP'. However,
898+ if X is instead moved past an instruction X' with pressure in the
899+ range (MP' - (P' - P), MP'), the pressure at X' will increase
900+ beyond MP'. Since baseECC is very much a heuristic anyway,
901+ it doesn't seem worth the overhead of tracking cases like these.
902+
903+ The cost of exceeding MP' is always based on the original maximum
904+ pressure MP. This is so that going 2 registers over the original
905+ limit has the same cost regardless of whether it comes from two
906+ separate +1 deltas or from a single +2 delta.
907+
908+ * if X occurs after the next point of maximum pressure in the model
909+ schedule and P' > P, then:
910+
911+ baseECC (CL, X) = model_spill_cost (CL, MP, MP' + (P' - P))
912+
913+ That is, if we move X forward across a point of maximum pressure,
914+ and if X increases the pressure by P' - P, then we conservatively
915+ assume that scheduling X next would increase the maximum pressure
916+ by P' - P. Again, the cost of doing this is based on the original
917+ maximum pressure MP, for the same reason as above.
918+
919+ * if P' < P, P > MP, and X occurs at or after the next point of
920+ maximum pressure, then:
921+
922+ baseECC (CL, X) = -model_spill_cost (CL, MAX (MP, P'), P)
923+
924+ That is, if we have already exceeded the original maximum pressure MP,
925+ and if X might reduce the maximum pressure again -- or at least push
926+ it further back, and thus allow more scheduling freedom -- it is given
927+ a negative cost to reflect the improvement.
928+
929+ * otherwise,
930+
931+ baseECC (CL, X) = 0
932+
933+ In this case, X is not expected to affect the maximum pressure MP',
934+ so it has zero cost.
935+
936+ We then create a combined value baseECC (X) that is the sum of
937+ baseECC (CL, X) for each cover class CL.
938+
939+ baseECC (X) could itself be used as the ECC value described above.
940+ However, this is often too conservative, in the sense that it
941+ tends to make high-priority instructions that increase pressure
942+ wait too long in cases where introducing a spill would be better.
943+ For this reason the final ECC is a priority-adjusted form of
944+ baseECC (X). Specifically, we calculate:
945+
946+ P (X) = INSN_PRIORITY (X) - insn_delay (X) - baseECC (X)
947+ baseP = MAX { P (X) | baseECC (X) <= 0 }
948+
949+ Then:
950+
951+ ECC (X) = MAX (MIN (baseP - P (X), baseECC (X)), 0)
952+
953+ Thus an instruction's effect on pressure is ignored if it has a high
954+ enough priority relative to the ones that don't increase pressure.
955+ Negative values of baseECC (X) do not increase the priority of X
956+ itself, but they do make it harder for other instructions to
957+ increase the pressure further.
958+
959+ This pressure cost is deliberately timid. The intention has been
960+ to choose a heuristic that rarely interferes with the normal list
961+ scheduler in cases where that scheduler would produce good code.
962+ We simply want to curb some of its worst excesses. */
963+
964+/* Return the cost of increasing the pressure in class CL from FROM to TO.
965+
966+ Here we use the very simplistic cost model that every register above
967+ ira_available_class_regs[CL] has a spill cost of 1. We could use other
968+ measures instead, such as one based on MEMORY_MOVE_COST. However:
969+
970+ (1) In order for an instruction to be scheduled, the higher cost
971+ would need to be justified in a single saving of that many stalls.
972+ This is overly pessimistic, because the benefit of spilling is
973+ often to avoid a sequence of several short stalls rather than
974+ a single long one.
975+
976+ (2) The cost is still arbitrary. Because we are not allocating
977+ registers during scheduling, we have no way of knowing for
978+ sure how many memory accesses will be required by each spill,
979+ where the spills will be placed within the block, or even
980+ which block(s) will contain the spills.
981+
982+ So a higher cost than 1 is often too conservative in practice,
983+ forcing blocks to contain unnecessary stalls instead of spill code.
984+ The simple cost below seems to be the best compromise. It reduces
985+ the interference with the normal list scheduler, which helps make
986+ it more suitable for a default-on option. */
987+
988+static int
989+model_spill_cost (int cl, int from, int to)
990+{
991+ from = MAX (from, ira_available_class_regs[cl]);
992+ return MAX (to, from) - from;
993+}
994+
995+/* Return baseECC (ira_reg_class_cover[CCI], POINT), given that
996+ P = curr_reg_pressure[ira_reg_class_cover[CCI]] and that
997+ P' = P + DELTA. */
998+
999+static int
1000+model_excess_group_cost (struct model_pressure_group *group,
1001+ int point, int cci, int delta)
1002+{
1003+ int pressure, cl;
1004+
1005+ cl = ira_reg_class_cover[cci];
1006+ if (delta < 0 && point >= group->limits[cci].point)
1007+ {
1008+ pressure = MAX (group->limits[cci].orig_pressure,
1009+ curr_reg_pressure[cl] + delta);
1010+ return -model_spill_cost (cl, pressure, curr_reg_pressure[cl]);
1011+ }
1012+
1013+ if (delta > 0)
1014+ {
1015+ if (point > group->limits[cci].point)
1016+ pressure = group->limits[cci].pressure + delta;
1017+ else
1018+ pressure = curr_reg_pressure[cl] + delta;
1019+
1020+ if (pressure > group->limits[cci].pressure)
1021+ return model_spill_cost (cl, group->limits[cci].orig_pressure,
1022+ pressure);
1023+ }
1024+
1025+ return 0;
1026+}
1027+
1028+/* Return baseECC (MODEL_INSN (INSN)). Dump the costs to sched_dump
1029+ if PRINT_P. */
1030+
1031+static int
1032+model_excess_cost (rtx insn, bool print_p)
1033+{
1034+ int point, cci, cl, cost, this_cost, delta;
1035+ struct reg_pressure_data *insn_reg_pressure;
1036+ int insn_death[N_REG_CLASSES];
1037+
1038+ calculate_reg_deaths (insn, insn_death);
1039+ point = model_index (insn);
1040+ insn_reg_pressure = INSN_REG_PRESSURE (insn);
1041+ cost = 0;
1042+
1043+ if (print_p)
1044+ fprintf (sched_dump, ";;\t\t| %3d %4d | %4d %+3d |", point,
1045+ INSN_UID (insn), INSN_PRIORITY (insn), insn_delay (insn));
1046+
1047+ /* Sum up the individual costs for each register class. */
1048+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
1049+ {
1050+ cl = ira_reg_class_cover[cci];
1051+ delta = insn_reg_pressure[cci].set_increase - insn_death[cl];
1052+ this_cost = model_excess_group_cost (&model_before_pressure,
1053+ point, cci, delta);
1054+ cost += this_cost;
1055+ if (print_p)
1056+ fprintf (sched_dump, " %s:[%d base cost %d]",
1057+ reg_class_names[cl], delta, this_cost);
1058+ }
1059+
1060+ if (print_p)
1061+ fprintf (sched_dump, "\n");
1062+
1063+ return cost;
1064+}
1065+
1066+/* Dump the next points of maximum pressure for GROUP. */
1067+
1068+static void
1069+model_dump_pressure_points (struct model_pressure_group *group)
1070+{
1071+ int cci, cl;
1072+
1073+ fprintf (sched_dump, ";;\t\t| pressure points");
1074+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
1075+ {
1076+ cl = ira_reg_class_cover[cci];
1077+ fprintf (sched_dump, " %s:[%d->%d at ", reg_class_names[cl],
1078+ curr_reg_pressure[cl], group->limits[cci].pressure);
1079+ if (group->limits[cci].point < model_num_insns)
1080+ fprintf (sched_dump, "%d:%d]", group->limits[cci].point,
1081+ INSN_UID (MODEL_INSN (group->limits[cci].point)));
1082+ else
1083+ fprintf (sched_dump, "end]");
1084+ }
1085+ fprintf (sched_dump, "\n");
1086+}
1087+
1088+/* Set INSN_REG_PRESSURE_EXCESS_COST_CHANGE for INSNS[0...COUNT-1]. */
1089+
1090+static void
1091+model_set_excess_costs (rtx *insns, int count)
1092+{
1093+ int i, cost, priority_base, priority;
1094+ bool print_p;
1095+
1096+ /* Record the baseECC value for each instruction in the model schedule,
1097+ except that negative costs are converted to zero ones now rather thatn
1098+ later. Do not assign a cost to debug instructions, since they must
1099+ not change code-generation decisions. Experiments suggest we also
1100+ get better results by not assigning a cost to instructions from
1101+ a different block.
1102+
1103+ Set PRIORITY_BASE to baseP in the block comment above. This is the
1104+ maximum priority of the "cheap" instructions, which should always
1105+ include the next model instruction. */
1106+ priority_base = 0;
1107+ print_p = false;
1108+ for (i = 0; i < count; i++)
1109+ if (INSN_MODEL_INDEX (insns[i]))
1110+ {
1111+ if (sched_verbose >= 6 && !print_p)
1112+ {
1113+ fprintf (sched_dump, MODEL_BAR);
1114+ fprintf (sched_dump, ";;\t\t| Pressure costs for ready queue\n");
1115+ model_dump_pressure_points (&model_before_pressure);
1116+ fprintf (sched_dump, MODEL_BAR);
1117+ print_p = true;
1118+ }
1119+ cost = model_excess_cost (insns[i], print_p);
1120+ if (cost <= 0)
1121+ {
1122+ priority = INSN_PRIORITY (insns[i]) - insn_delay (insns[i]) - cost;
1123+ priority_base = MAX (priority_base, priority);
1124+ cost = 0;
1125+ }
1126+ INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]) = cost;
1127+ }
1128+ if (print_p)
1129+ fprintf (sched_dump, MODEL_BAR);
1130+
1131+ /* Use MAX (baseECC, 0) and baseP to calculcate ECC for each
1132+ instruction. */
1133+ for (i = 0; i < count; i++)
1134+ {
1135+ cost = INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]);
1136+ priority = INSN_PRIORITY (insns[i]) - insn_delay (insns[i]);
1137+ if (cost > 0 && priority > priority_base)
1138+ {
1139+ cost += priority_base - priority;
1140+ INSN_REG_PRESSURE_EXCESS_COST_CHANGE (insns[i]) = MAX (cost, 0);
1141+ }
1142+ }
1143+}
1144+
1145 /* Returns a positive value if x is preferred; returns a negative value if
1146 y is preferred. Should never return 0, since that will make the sort
1147 unstable. */
1148@@ -1170,23 +1948,20 @@
1149 /* Make sure that priority of TMP and TMP2 are initialized. */
1150 gcc_assert (INSN_PRIORITY_KNOWN (tmp) && INSN_PRIORITY_KNOWN (tmp2));
1151
1152- if (sched_pressure_p)
1153+ if (sched_pressure != SCHED_PRESSURE_NONE)
1154 {
1155 int diff;
1156
1157 /* Prefer insn whose scheduling results in the smallest register
1158 pressure excess. */
1159 if ((diff = (INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp)
1160- + (INSN_TICK (tmp) > clock_var
1161- ? INSN_TICK (tmp) - clock_var : 0)
1162+ + insn_delay (tmp)
1163 - INSN_REG_PRESSURE_EXCESS_COST_CHANGE (tmp2)
1164- - (INSN_TICK (tmp2) > clock_var
1165- ? INSN_TICK (tmp2) - clock_var : 0))) != 0)
1166+ - insn_delay (tmp2))))
1167 return diff;
1168 }
1169
1170-
1171- if (sched_pressure_p
1172+ if (sched_pressure != SCHED_PRESSURE_NONE
1173 && (INSN_TICK (tmp2) > clock_var || INSN_TICK (tmp) > clock_var))
1174 {
1175 if (INSN_TICK (tmp) <= clock_var)
1176@@ -1277,11 +2052,22 @@
1177 return val;
1178 }
1179
1180+ /* Prefer instructions that occur earlier in the model schedule. */
1181+ if (sched_pressure == SCHED_PRESSURE_MODEL)
1182+ {
1183+ int diff;
1184+
1185+ diff = model_index (tmp) - model_index (tmp2);
1186+ if (diff != 0)
1187+ return diff;
1188+ }
1189+
1190 /* Prefer the insn which has more later insns that depend on it.
1191 This gives the scheduler more freedom when scheduling later
1192 instructions at the expense of added register pressure. */
1193
1194- val = (dep_list_size (tmp2) - dep_list_size (tmp));
1195+ val = (dep_list_size (tmp2, SD_LIST_FORW)
1196+ - dep_list_size (tmp, SD_LIST_FORW));
1197
1198 if (flag_sched_dep_count_heuristic && val != 0)
1199 return val;
1200@@ -1480,12 +2266,15 @@
1201 int i;
1202 rtx *first = ready_lastpos (ready);
1203
1204- if (sched_pressure_p)
1205+ if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
1206 {
1207 for (i = 0; i < ready->n_ready; i++)
1208 if (!DEBUG_INSN_P (first[i]))
1209 setup_insn_reg_pressure_info (first[i]);
1210 }
1211+ if (sched_pressure == SCHED_PRESSURE_MODEL
1212+ && model_curr_point < model_num_insns)
1213+ model_set_excess_costs (first, ready->n_ready);
1214 SCHED_SORT (first, ready->n_ready);
1215 }
1216
1217@@ -1551,10 +2340,12 @@
1218 gcc_checking_assert (!DEBUG_INSN_P (insn));
1219
1220 for (use = INSN_REG_USE_LIST (insn); use != NULL; use = use->next_insn_use)
1221- if (dying_use_p (use) && bitmap_bit_p (curr_reg_live, use->regno))
1222- mark_regno_birth_or_death (use->regno, false);
1223+ if (dying_use_p (use))
1224+ mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
1225+ use->regno, false);
1226 for (set = INSN_REG_SET_LIST (insn); set != NULL; set = set->next_insn_set)
1227- mark_regno_birth_or_death (set->regno, true);
1228+ mark_regno_birth_or_death (curr_reg_live, curr_reg_pressure,
1229+ set->regno, true);
1230 }
1231
1232 /* Set up or update (if UPDATE_P) max register pressure (see its
1233@@ -1626,11 +2417,618 @@
1234 void
1235 sched_setup_bb_reg_pressure_info (basic_block bb, rtx after)
1236 {
1237- gcc_assert (sched_pressure_p);
1238+ gcc_assert (sched_pressure == SCHED_PRESSURE_WEIGHTED);
1239 initiate_bb_reg_pressure_info (bb);
1240 setup_insn_max_reg_pressure (after, false);
1241 }
1242-
1243+
1244+/* Return (in order):
1245+
1246+ - positive if INSN adversely affects the pressure on one
1247+ register class
1248+
1249+ - negative if INSN reduces the pressure on one register class
1250+
1251+ - 0 if INSN doesn't affect the pressure on any register class. */
1252+
1253+static int
1254+model_classify_pressure (struct model_insn_info *insn)
1255+{
1256+ struct reg_pressure_data *reg_pressure;
1257+ int death[N_REG_CLASSES];
1258+ int cci, cl, sum;
1259+
1260+ calculate_reg_deaths (insn->insn, death);
1261+ reg_pressure = INSN_REG_PRESSURE (insn->insn);
1262+ sum = 0;
1263+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
1264+ {
1265+ cl = ira_reg_class_cover[cci];
1266+ if (death[cl] < reg_pressure[cci].set_increase)
1267+ return 1;
1268+ sum += reg_pressure[cci].set_increase - death[cl];
1269+ }
1270+ return sum;
1271+}
1272+
1273+/* Return true if INSN1 should come before INSN2 in the model schedule. */
1274+
1275+static int
1276+model_order_p (struct model_insn_info *insn1, struct model_insn_info *insn2)
1277+{
1278+ unsigned int height1, height2;
1279+ unsigned int priority1, priority2;
1280+
1281+ /* Prefer instructions with a higher model priority. */
1282+ if (insn1->model_priority != insn2->model_priority)
1283+ return insn1->model_priority > insn2->model_priority;
1284+
1285+ /* Combine the length of the longest path of satisfied true dependencies
1286+ that leads to each instruction (depth) with the length of the longest
1287+ path of any dependencies that leads from the instruction (alap).
1288+ Prefer instructions with the greatest combined length. If the combined
1289+ lengths are equal, prefer instructions with the greatest depth.
1290+
1291+ The idea is that, if we have a set S of "equal" instructions that each
1292+ have ALAP value X, and we pick one such instruction I, any true-dependent
1293+ successors of I that have ALAP value X - 1 should be preferred over S.
1294+ This encourages the schedule to be "narrow" rather than "wide".
1295+ However, if I is a low-priority instruction that we decided to
1296+ schedule because of its model_classify_pressure, and if there
1297+ is a set of higher-priority instructions T, the aforementioned
1298+ successors of I should not have the edge over T. */
1299+ height1 = insn1->depth + insn1->alap;
1300+ height2 = insn2->depth + insn2->alap;
1301+ if (height1 != height2)
1302+ return height1 > height2;
1303+ if (insn1->depth != insn2->depth)
1304+ return insn1->depth > insn2->depth;
1305+
1306+ /* We have no real preference between INSN1 an INSN2 as far as attempts
1307+ to reduce pressure go. Prefer instructions with higher priorities. */
1308+ priority1 = INSN_PRIORITY (insn1->insn);
1309+ priority2 = INSN_PRIORITY (insn2->insn);
1310+ if (priority1 != priority2)
1311+ return priority1 > priority2;
1312+
1313+ /* Use the original rtl sequence as a tie-breaker. */
1314+ return insn1 < insn2;
1315+}
1316+
1317+/* Add INSN to the model worklist immediately after PREV. Add it to the
1318+ beginning of the list if PREV is null. */
1319+
1320+static void
1321+model_add_to_worklist_at (struct model_insn_info *insn,
1322+ struct model_insn_info *prev)
1323+{
1324+ gcc_assert (QUEUE_INDEX (insn->insn) == QUEUE_NOWHERE);
1325+ QUEUE_INDEX (insn->insn) = QUEUE_READY;
1326+
1327+ insn->prev = prev;
1328+ if (prev)
1329+ {
1330+ insn->next = prev->next;
1331+ prev->next = insn;
1332+ }
1333+ else
1334+ {
1335+ insn->next = model_worklist;
1336+ model_worklist = insn;
1337+ }
1338+ if (insn->next)
1339+ insn->next->prev = insn;
1340+}
1341+
1342+/* Remove INSN from the model worklist. */
1343+
1344+static void
1345+model_remove_from_worklist (struct model_insn_info *insn)
1346+{
1347+ gcc_assert (QUEUE_INDEX (insn->insn) == QUEUE_READY);
1348+ QUEUE_INDEX (insn->insn) = QUEUE_NOWHERE;
1349+
1350+ if (insn->prev)
1351+ insn->prev->next = insn->next;
1352+ else
1353+ model_worklist = insn->next;
1354+ if (insn->next)
1355+ insn->next->prev = insn->prev;
1356+}
1357+
1358+/* Add INSN to the model worklist. Start looking for a suitable position
1359+ between neighbors PREV and NEXT, testing at most MAX_SCHED_READY_INSNS
1360+ insns either side. A null PREV indicates the beginning of the list and
1361+ a null NEXT indicates the end. */
1362+
1363+static void
1364+model_add_to_worklist (struct model_insn_info *insn,
1365+ struct model_insn_info *prev,
1366+ struct model_insn_info *next)
1367+{
1368+ int count;
1369+
1370+ count = MAX_SCHED_READY_INSNS;
1371+ if (count > 0 && prev && model_order_p (insn, prev))
1372+ do
1373+ {
1374+ count--;
1375+ prev = prev->prev;
1376+ }
1377+ while (count > 0 && prev && model_order_p (insn, prev));
1378+ else
1379+ while (count > 0 && next && model_order_p (next, insn))
1380+ {
1381+ count--;
1382+ prev = next;
1383+ next = next->next;
1384+ }
1385+ model_add_to_worklist_at (insn, prev);
1386+}
1387+
1388+/* INSN may now have a higher priority (in the model_order_p sense)
1389+ than before. Move it up the worklist if necessary. */
1390+
1391+static void
1392+model_promote_insn (struct model_insn_info *insn)
1393+{
1394+ struct model_insn_info *prev;
1395+ int count;
1396+
1397+ prev = insn->prev;
1398+ count = MAX_SCHED_READY_INSNS;
1399+ while (count > 0 && prev && model_order_p (insn, prev))
1400+ {
1401+ count--;
1402+ prev = prev->prev;
1403+ }
1404+ if (prev != insn->prev)
1405+ {
1406+ model_remove_from_worklist (insn);
1407+ model_add_to_worklist_at (insn, prev);
1408+ }
1409+}
1410+
1411+/* Add INSN to the end of the model schedule. */
1412+
1413+static void
1414+model_add_to_schedule (rtx insn)
1415+{
1416+ unsigned int point;
1417+
1418+ gcc_assert (QUEUE_INDEX (insn) == QUEUE_NOWHERE);
1419+ QUEUE_INDEX (insn) = QUEUE_SCHEDULED;
1420+
1421+ point = VEC_length (rtx, model_schedule);
1422+ VEC_quick_push (rtx, model_schedule, insn);
1423+ INSN_MODEL_INDEX (insn) = point + 1;
1424+}
1425+
1426+/* Analyze the instructions that are to be scheduled, setting up
1427+ MODEL_INSN_INFO (...) and model_num_insns accordingly. Add ready
1428+ instructions to model_worklist. */
1429+
1430+static void
1431+model_analyze_insns (void)
1432+{
1433+ rtx start, end, iter;
1434+ sd_iterator_def sd_it;
1435+ dep_t dep;
1436+ struct model_insn_info *insn, *con;
1437+
1438+ model_num_insns = 0;
1439+ start = PREV_INSN (current_sched_info->next_tail);
1440+ end = current_sched_info->prev_head;
1441+ for (iter = start; iter != end; iter = PREV_INSN (iter))
1442+ if (NONDEBUG_INSN_P (iter))
1443+ {
1444+ insn = MODEL_INSN_INFO (iter);
1445+ insn->insn = iter;
1446+ FOR_EACH_DEP (iter, SD_LIST_FORW, sd_it, dep)
1447+ {
1448+ con = MODEL_INSN_INFO (DEP_CON (dep));
1449+ if (con->insn && insn->alap < con->alap + 1)
1450+ insn->alap = con->alap + 1;
1451+ }
1452+
1453+ insn->old_queue = QUEUE_INDEX (iter);
1454+ QUEUE_INDEX (iter) = QUEUE_NOWHERE;
1455+
1456+ insn->unscheduled_preds = dep_list_size (iter, SD_LIST_HARD_BACK);
1457+ if (insn->unscheduled_preds == 0)
1458+ model_add_to_worklist (insn, NULL, model_worklist);
1459+
1460+ model_num_insns++;
1461+ }
1462+}
1463+
1464+/* The global state describes the register pressure at the start of the
1465+ model schedule. Initialize GROUP accordingly. */
1466+
1467+static void
1468+model_init_pressure_group (struct model_pressure_group *group)
1469+{
1470+ int cci, cl;
1471+
1472+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
1473+ {
1474+ cl = ira_reg_class_cover[cci];
1475+ group->limits[cci].pressure = curr_reg_pressure[cl];
1476+ group->limits[cci].point = 0;
1477+ }
1478+ /* Use index model_num_insns to record the state after the last
1479+ instruction in the model schedule. */
1480+ group->model = XNEWVEC (struct model_pressure_data,
1481+ (model_num_insns + 1) * ira_reg_class_cover_size);
1482+}
1483+
1484+/* Record that MODEL_REF_PRESSURE (GROUP, POINT, CCI) is PRESSURE.
1485+ Update the maximum pressure for the whole schedule. */
1486+
1487+static void
1488+model_record_pressure (struct model_pressure_group *group,
1489+ int point, int cci, int pressure)
1490+{
1491+ MODEL_REF_PRESSURE (group, point, cci) = pressure;
1492+ if (group->limits[cci].pressure < pressure)
1493+ {
1494+ group->limits[cci].pressure = pressure;
1495+ group->limits[cci].point = point;
1496+ }
1497+}
1498+
1499+/* INSN has just been added to the end of the model schedule. Record its
1500+ register-pressure information. */
1501+
1502+static void
1503+model_record_pressures (struct model_insn_info *insn)
1504+{
1505+ struct reg_pressure_data *reg_pressure;
1506+ int point, cci, cl, delta;
1507+ int death[N_REG_CLASSES];
1508+
1509+ point = model_index (insn->insn);
1510+ if (sched_verbose >= 2)
1511+ {
1512+ char buf[2048];
1513+
1514+ if (point == 0)
1515+ {
1516+ fprintf (sched_dump, "\n;;\tModel schedule:\n;;\n");
1517+ fprintf (sched_dump, ";;\t| idx insn | mpri hght dpth prio |\n");
1518+ }
1519+ print_pattern (buf, PATTERN (insn->insn), 0);
1520+ fprintf (sched_dump, ";;\t| %3d %4d | %4d %4d %4d %4d | %-30s ",
1521+ point, INSN_UID (insn->insn), insn->model_priority,
1522+ insn->depth + insn->alap, insn->depth,
1523+ INSN_PRIORITY (insn->insn), buf);
1524+ }
1525+ calculate_reg_deaths (insn->insn, death);
1526+ reg_pressure = INSN_REG_PRESSURE (insn->insn);
1527+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
1528+ {
1529+ cl = ira_reg_class_cover[cci];
1530+ delta = reg_pressure[cci].set_increase - death[cl];
1531+ if (sched_verbose >= 2)
1532+ fprintf (sched_dump, " %s:[%d,%+d]", reg_class_names[cl],
1533+ curr_reg_pressure[cl], delta);
1534+ model_record_pressure (&model_before_pressure, point, cci,
1535+ curr_reg_pressure[cl]);
1536+ }
1537+ if (sched_verbose >= 2)
1538+ fprintf (sched_dump, "\n");
1539+}
1540+
1541+/* All instructions have been added to the model schedule. Record the
1542+ final register pressure in GROUP and set up all MODEL_MAX_PRESSUREs. */
1543+
1544+static void
1545+model_record_final_pressures (struct model_pressure_group *group)
1546+{
1547+ int point, cci, max_pressure, ref_pressure, cl;
1548+
1549+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
1550+ {
1551+ /* Record the final pressure for this class. */
1552+ cl = ira_reg_class_cover[cci];
1553+ point = model_num_insns;
1554+ ref_pressure = curr_reg_pressure[cl];
1555+ model_record_pressure (group, point, cci, ref_pressure);
1556+
1557+ /* Record the original maximum pressure. */
1558+ group->limits[cci].orig_pressure = group->limits[cci].pressure;
1559+
1560+ /* Update the MODEL_MAX_PRESSURE for every point of the schedule. */
1561+ max_pressure = ref_pressure;
1562+ MODEL_MAX_PRESSURE (group, point, cci) = max_pressure;
1563+ while (point > 0)
1564+ {
1565+ point--;
1566+ ref_pressure = MODEL_REF_PRESSURE (group, point, cci);
1567+ max_pressure = MAX (max_pressure, ref_pressure);
1568+ MODEL_MAX_PRESSURE (group, point, cci) = max_pressure;
1569+ }
1570+ }
1571+}
1572+
1573+/* Update all successors of INSN, given that INSN has just been scheduled. */
1574+
1575+static void
1576+model_add_successors_to_worklist (struct model_insn_info *insn)
1577+{
1578+ sd_iterator_def sd_it;
1579+ struct model_insn_info *con;
1580+ dep_t dep;
1581+
1582+ FOR_EACH_DEP (insn->insn, SD_LIST_FORW, sd_it, dep)
1583+ {
1584+ con = MODEL_INSN_INFO (DEP_CON (dep));
1585+ /* Ignore debug instructions, and instructions from other blocks. */
1586+ if (con->insn)
1587+ {
1588+ con->unscheduled_preds--;
1589+
1590+ /* Update the depth field of each true-dependent successor.
1591+ Increasing the depth gives them a higher priority than
1592+ before. */
1593+ if (DEP_TYPE (dep) == REG_DEP_TRUE && con->depth < insn->depth + 1)
1594+ {
1595+ con->depth = insn->depth + 1;
1596+ if (QUEUE_INDEX (con->insn) == QUEUE_READY)
1597+ model_promote_insn (con);
1598+ }
1599+
1600+ /* If this is a true dependency, or if there are no remaining
1601+ dependencies for CON (meaning that CON only had non-true
1602+ dependencies), make sure that CON is on the worklist.
1603+ We don't bother otherwise because it would tend to fill the
1604+ worklist with a lot of low-priority instructions that are not
1605+ yet ready to issue. */
1606+ if ((con->depth > 0 || con->unscheduled_preds == 0)
1607+ && QUEUE_INDEX (con->insn) == QUEUE_NOWHERE)
1608+ model_add_to_worklist (con, insn, insn->next);
1609+ }
1610+ }
1611+}
1612+
1613+/* Give INSN a higher priority than any current instruction, then give
1614+ unscheduled predecessors of INSN a higher priority still. If any of
1615+ those predecessors are not on the model worklist, do the same for its
1616+ predecessors, and so on. */
1617+
1618+static void
1619+model_promote_predecessors (struct model_insn_info *insn)
1620+{
1621+ struct model_insn_info *pro, *first;
1622+ sd_iterator_def sd_it;
1623+ dep_t dep;
1624+
1625+ if (sched_verbose >= 7)
1626+ fprintf (sched_dump, ";;\t+--- priority of %d = %d, priority of",
1627+ INSN_UID (insn->insn), model_next_priority);
1628+ insn->model_priority = model_next_priority++;
1629+ model_remove_from_worklist (insn);
1630+ model_add_to_worklist_at (insn, NULL);
1631+
1632+ first = NULL;
1633+ for (;;)
1634+ {
1635+ FOR_EACH_DEP (insn->insn, SD_LIST_HARD_BACK, sd_it, dep)
1636+ {
1637+ pro = MODEL_INSN_INFO (DEP_PRO (dep));
1638+ /* The first test is to ignore debug instructions, and instructions
1639+ from other blocks. */
1640+ if (pro->insn
1641+ && pro->model_priority != model_next_priority
1642+ && QUEUE_INDEX (pro->insn) != QUEUE_SCHEDULED)
1643+ {
1644+ pro->model_priority = model_next_priority;
1645+ if (sched_verbose >= 7)
1646+ fprintf (sched_dump, " %d", INSN_UID (pro->insn));
1647+ if (QUEUE_INDEX (pro->insn) == QUEUE_READY)
1648+ {
1649+ /* PRO is already in the worklist, but it now has
1650+ a higher priority than before. Move it at the
1651+ appropriate place. */
1652+ model_remove_from_worklist (pro);
1653+ model_add_to_worklist (pro, NULL, model_worklist);
1654+ }
1655+ else
1656+ {
1657+ /* PRO isn't in the worklist. Recursively process
1658+ its predecessors until we find one that is. */
1659+ pro->next = first;
1660+ first = pro;
1661+ }
1662+ }
1663+ }
1664+ if (!first)
1665+ break;
1666+ insn = first;
1667+ first = insn->next;
1668+ }
1669+ if (sched_verbose >= 7)
1670+ fprintf (sched_dump, " = %d\n", model_next_priority);
1671+ model_next_priority++;
1672+}
1673+
1674+/* Pick one instruction from model_worklist and process it. */
1675+
1676+static void
1677+model_choose_insn (void)
1678+{
1679+ struct model_insn_info *insn, *fallback;
1680+ int count;
1681+
1682+ if (sched_verbose >= 7)
1683+ {
1684+ fprintf (sched_dump, ";;\t+--- worklist:\n");
1685+ insn = model_worklist;
1686+ count = MAX_SCHED_READY_INSNS;
1687+ while (count > 0 && insn)
1688+ {
1689+ fprintf (sched_dump, ";;\t+--- %d [%d, %d, %d, %d]\n",
1690+ INSN_UID (insn->insn), insn->model_priority,
1691+ insn->depth + insn->alap, insn->depth,
1692+ INSN_PRIORITY (insn->insn));
1693+ count--;
1694+ insn = insn->next;
1695+ }
1696+ }
1697+
1698+ /* Look for a ready instruction whose model_classify_priority is zero
1699+ or negative, picking the highest-priority one. Adding such an
1700+ instruction to the schedule now should do no harm, and may actually
1701+ do some good.
1702+
1703+ Failing that, see whether there is an instruction with the highest
1704+ extant model_priority that is not yet ready, but which would reduce
1705+ pressure if it became ready. This is designed to catch cases like:
1706+
1707+ (set (mem (reg R1)) (reg R2))
1708+
1709+ where the instruction is the last remaining use of R1 and where the
1710+ value of R2 is not yet available (or vice versa). The death of R1
1711+ means that this instruction already reduces pressure. It is of
1712+ course possible that the computation of R2 involves other registers
1713+ that are hard to kill, but such cases are rare enough for this
1714+ heuristic to be a win in general.
1715+
1716+ Failing that, just pick the highest-priority instruction in the
1717+ worklist. */
1718+ count = MAX_SCHED_READY_INSNS;
1719+ insn = model_worklist;
1720+ fallback = 0;
1721+ for (;;)
1722+ {
1723+ if (count == 0 || !insn)
1724+ {
1725+ insn = fallback ? fallback : model_worklist;
1726+ break;
1727+ }
1728+ if (insn->unscheduled_preds)
1729+ {
1730+ if (model_worklist->model_priority == insn->model_priority
1731+ && !fallback
1732+ && model_classify_pressure (insn) < 0)
1733+ fallback = insn;
1734+ }
1735+ else
1736+ {
1737+ if (model_classify_pressure (insn) <= 0)
1738+ break;
1739+ }
1740+ count--;
1741+ insn = insn->next;
1742+ }
1743+
1744+ if (sched_verbose >= 7 && insn != model_worklist)
1745+ {
1746+ if (insn->unscheduled_preds)
1747+ fprintf (sched_dump, ";;\t+--- promoting insn %d, with dependencies\n",
1748+ INSN_UID (insn->insn));
1749+ else
1750+ fprintf (sched_dump, ";;\t+--- promoting insn %d, which is ready\n",
1751+ INSN_UID (insn->insn));
1752+ }
1753+ if (insn->unscheduled_preds)
1754+ /* INSN isn't yet ready to issue. Give all its predecessors the
1755+ highest priority. */
1756+ model_promote_predecessors (insn);
1757+ else
1758+ {
1759+ /* INSN is ready. Add it to the end of model_schedule and
1760+ process its successors. */
1761+ model_add_successors_to_worklist (insn);
1762+ model_remove_from_worklist (insn);
1763+ model_add_to_schedule (insn->insn);
1764+ model_record_pressures (insn);
1765+ update_register_pressure (insn->insn);
1766+ }
1767+}
1768+
1769+/* Restore all QUEUE_INDEXs to the values that they had before
1770+ model_start_schedule was called. */
1771+
1772+static void
1773+model_reset_queue_indices (void)
1774+{
1775+ unsigned int i;
1776+ rtx insn;
1777+
1778+ FOR_EACH_VEC_ELT (rtx, model_schedule, i, insn)
1779+ QUEUE_INDEX (insn) = MODEL_INSN_INFO (insn)->old_queue;
1780+}
1781+
1782+/* We have calculated the model schedule and spill costs. Print a summary
1783+ to sched_dump. */
1784+
1785+static void
1786+model_dump_pressure_summary (void)
1787+{
1788+ int cci, cl;
1789+
1790+ fprintf (sched_dump, ";; Pressure summary:");
1791+ for (cci = 0; cci < ira_reg_class_cover_size; cci++)
1792+ {
1793+ cl = ira_reg_class_cover[cci];
1794+ fprintf (sched_dump, " %s:%d", reg_class_names[cl],
1795+ model_before_pressure.limits[cci].pressure);
1796+ }
1797+ fprintf (sched_dump, "\n\n");
1798+}
1799+
1800+/* Initialize the SCHED_PRESSURE_MODEL information for the current
1801+ scheduling region. */
1802+
1803+static void
1804+model_start_schedule (void)
1805+{
1806+ basic_block bb;
1807+
1808+ model_next_priority = 1;
1809+ model_schedule = VEC_alloc (rtx, heap, sched_max_luid);
1810+ model_insns = XCNEWVEC (struct model_insn_info, sched_max_luid);
1811+
1812+ bb = BLOCK_FOR_INSN (NEXT_INSN (current_sched_info->prev_head));
1813+ initiate_reg_pressure_info (df_get_live_in (bb));
1814+
1815+ model_analyze_insns ();
1816+ model_init_pressure_group (&model_before_pressure);
1817+ while (model_worklist)
1818+ model_choose_insn ();
1819+ gcc_assert (model_num_insns == (int) VEC_length (rtx, model_schedule));
1820+ if (sched_verbose >= 2)
1821+ fprintf (sched_dump, "\n");
1822+
1823+ model_record_final_pressures (&model_before_pressure);
1824+ model_reset_queue_indices ();
1825+
1826+ XDELETEVEC (model_insns);
1827+
1828+ model_curr_point = 0;
1829+ initiate_reg_pressure_info (df_get_live_in (bb));
1830+ if (sched_verbose >= 1)
1831+ model_dump_pressure_summary ();
1832+}
1833+
1834+/* Free the information associated with GROUP. */
1835+
1836+static void
1837+model_finalize_pressure_group (struct model_pressure_group *group)
1838+{
1839+ XDELETEVEC (group->model);
1840+}
1841+
1842+/* Free the information created by model_start_schedule. */
1843+
1844+static void
1845+model_end_schedule (void)
1846+{
1847+ model_finalize_pressure_group (&model_before_pressure);
1848+ VEC_free (rtx, heap, model_schedule);
1849+}
1850+
1851 /* INSN is the "currently executing insn". Launch each insn which was
1852 waiting on INSN. READY is the ready list which contains the insns
1853 that are ready to fire. CLOCK is the current cycle. The function
1854@@ -1667,10 +3065,14 @@
1855 reg_class_names[ira_reg_class_cover[i]],
1856 pressure_info[i].set_increase, pressure_info[i].change);
1857 }
1858+ if (sched_pressure == SCHED_PRESSURE_MODEL
1859+ && model_curr_point < model_num_insns
1860+ && model_index (insn) == model_curr_point)
1861+ fprintf (sched_dump, ":model %d", model_curr_point);
1862 fputc ('\n', sched_dump);
1863 }
1864
1865- if (sched_pressure_p && !DEBUG_INSN_P (insn))
1866+ if (sched_pressure == SCHED_PRESSURE_WEIGHTED && !DEBUG_INSN_P (insn))
1867 update_reg_and_insn_max_reg_pressure (insn);
1868
1869 /* Scheduling instruction should have all its dependencies resolved and
1870@@ -1728,6 +3130,24 @@
1871 gcc_assert (QUEUE_INDEX (insn) == QUEUE_NOWHERE);
1872 QUEUE_INDEX (insn) = QUEUE_SCHEDULED;
1873
1874+ if (sched_pressure == SCHED_PRESSURE_MODEL
1875+ && model_curr_point < model_num_insns
1876+ && NONDEBUG_INSN_P (insn))
1877+ {
1878+ if (model_index (insn) == model_curr_point)
1879+ do
1880+ model_curr_point++;
1881+ while (model_curr_point < model_num_insns
1882+ && (QUEUE_INDEX (MODEL_INSN (model_curr_point))
1883+ == QUEUE_SCHEDULED));
1884+ else
1885+ model_recompute (insn);
1886+ model_update_limit_points ();
1887+ update_register_pressure (insn);
1888+ if (sched_verbose >= 2)
1889+ print_curr_reg_pressure ();
1890+ }
1891+
1892 gcc_assert (INSN_TICK (insn) >= MIN_TICK);
1893 if (INSN_TICK (insn) > clock_var)
1894 /* INSN has been prematurely moved from the queue to the ready list.
1895@@ -2056,7 +3476,16 @@
1896 /* If the ready list is full, delay the insn for 1 cycle.
1897 See the comment in schedule_block for the rationale. */
1898 if (!reload_completed
1899- && ready->n_ready - ready->n_debug > MAX_SCHED_READY_INSNS
1900+ && (ready->n_ready - ready->n_debug > MAX_SCHED_READY_INSNS
1901+ || (sched_pressure == SCHED_PRESSURE_MODEL
1902+ /* Limit pressure recalculations to MAX_SCHED_READY_INSNS
1903+ instructions too. */
1904+ && model_index (insn) > (model_curr_point
1905+ + MAX_SCHED_READY_INSNS)))
1906+ && !(sched_pressure == SCHED_PRESSURE_MODEL
1907+ && model_curr_point < model_num_insns
1908+ /* Always allow the next model instruction to issue. */
1909+ && model_index (insn) == model_curr_point)
1910 && !SCHED_GROUP_P (insn)
1911 && insn != skip_insn)
1912 {
1913@@ -2293,12 +3722,12 @@
1914 fprintf (sched_dump, " %s:%d",
1915 (*current_sched_info->print_insn) (p[i], 0),
1916 INSN_LUID (p[i]));
1917- if (sched_pressure_p)
1918+ if (sched_pressure != SCHED_PRESSURE_NONE)
1919 fprintf (sched_dump, "(cost=%d",
1920 INSN_REG_PRESSURE_EXCESS_COST_CHANGE (p[i]));
1921 if (INSN_TICK (p[i]) > clock_var)
1922 fprintf (sched_dump, ":delay=%d", INSN_TICK (p[i]) - clock_var);
1923- if (sched_pressure_p)
1924+ if (sched_pressure != SCHED_PRESSURE_NONE)
1925 fprintf (sched_dump, ")");
1926 }
1927 fprintf (sched_dump, "\n");
1928@@ -2609,8 +4038,8 @@
1929 {
1930 if (state_dead_lock_p (state)
1931 || insn_finishes_cycle_p (insn))
1932- /* We won't issue any more instructions in the next
1933- choice_state. */
1934+ /* We won't issue any more instructions in the next
1935+ choice_state. */
1936 top->rest = 0;
1937 else
1938 top->rest--;
1939@@ -2813,6 +4242,59 @@
1940 }
1941 }
1942
1943+/* Examine all insns on the ready list and queue those which can't be
1944+ issued in this cycle. TEMP_STATE is temporary scheduler state we
1945+ can use as scratch space. If FIRST_CYCLE_INSN_P is true, no insns
1946+ have been issued for the current cycle, which means it is valid to
1947+ issue an asm statement. */
1948+
1949+static void
1950+prune_ready_list (state_t temp_state, bool first_cycle_insn_p)
1951+{
1952+ int i;
1953+
1954+ restart:
1955+ for (i = 0; i < ready.n_ready; i++)
1956+ {
1957+ rtx insn = ready_element (&ready, i);
1958+ int cost = 0;
1959+
1960+ if (recog_memoized (insn) < 0)
1961+ {
1962+ if (!first_cycle_insn_p
1963+ && (GET_CODE (PATTERN (insn)) == ASM_INPUT
1964+ || asm_noperands (PATTERN (insn)) >= 0))
1965+ cost = 1;
1966+ }
1967+ else if (sched_pressure != SCHED_PRESSURE_NONE)
1968+ {
1969+ if (sched_pressure == SCHED_PRESSURE_MODEL
1970+ && INSN_TICK (insn) <= clock_var)
1971+ {
1972+ memcpy (temp_state, curr_state, dfa_state_size);
1973+ if (state_transition (temp_state, insn) >= 0)
1974+ INSN_TICK (insn) = clock_var + 1;
1975+ }
1976+ cost = 0;
1977+ }
1978+ else
1979+ {
1980+ memcpy (temp_state, curr_state, dfa_state_size);
1981+ cost = state_transition (temp_state, insn);
1982+ if (cost < 0)
1983+ cost = 0;
1984+ else if (cost == 0)
1985+ cost = 1;
1986+ }
1987+ if (cost >= 1)
1988+ {
1989+ ready_remove (&ready, i);
1990+ queue_insn (insn, cost);
1991+ goto restart;
1992+ }
1993+ }
1994+}
1995+
1996 /* Use forward list scheduling to rearrange insns of block pointed to by
1997 TARGET_BB, possibly bringing insns from subsequent blocks in the same
1998 region. */
1999@@ -2882,6 +4364,9 @@
2000 in try_ready () (which is called through init_ready_list ()). */
2001 (*current_sched_info->init_ready_list) ();
2002
2003+ if (sched_pressure == SCHED_PRESSURE_MODEL)
2004+ model_start_schedule ();
2005+
2006 /* The algorithm is O(n^2) in the number of ready insns at any given
2007 time in the worst case. Before reload we are more likely to have
2008 big lists so truncate them to a reasonable size. */
2009@@ -2963,6 +4448,10 @@
2010 }
2011 while (advance > 0);
2012
2013+ prune_ready_list (temp_state, true);
2014+ if (ready.n_ready == 0)
2015+ continue;
2016+
2017 if (sort_p)
2018 {
2019 /* Sort the ready list based on priority. */
2020@@ -3040,7 +4529,7 @@
2021 fprintf (sched_dump, ";;\tReady list (t = %3d): ",
2022 clock_var);
2023 debug_ready_list (&ready);
2024- if (sched_pressure_p)
2025+ if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
2026 print_curr_reg_pressure ();
2027 }
2028
2029@@ -3084,7 +4573,8 @@
2030 else
2031 insn = ready_remove_first (&ready);
2032
2033- if (sched_pressure_p && INSN_TICK (insn) > clock_var)
2034+ if (sched_pressure != SCHED_PRESSURE_NONE
2035+ && INSN_TICK (insn) > clock_var)
2036 {
2037 ready_add (&ready, insn, true);
2038 advance = 1;
2039@@ -3112,44 +4602,6 @@
2040 }
2041
2042 sort_p = TRUE;
2043- memcpy (temp_state, curr_state, dfa_state_size);
2044- if (recog_memoized (insn) < 0)
2045- {
2046- asm_p = (GET_CODE (PATTERN (insn)) == ASM_INPUT
2047- || asm_noperands (PATTERN (insn)) >= 0);
2048- if (!first_cycle_insn_p && asm_p)
2049- /* This is asm insn which is tried to be issued on the
2050- cycle not first. Issue it on the next cycle. */
2051- cost = 1;
2052- else
2053- /* A USE insn, or something else we don't need to
2054- understand. We can't pass these directly to
2055- state_transition because it will trigger a
2056- fatal error for unrecognizable insns. */
2057- cost = 0;
2058- }
2059- else if (sched_pressure_p)
2060- cost = 0;
2061- else
2062- {
2063- cost = state_transition (temp_state, insn);
2064- if (cost < 0)
2065- cost = 0;
2066- else if (cost == 0)
2067- cost = 1;
2068- }
2069-
2070- if (cost >= 1)
2071- {
2072- queue_insn (insn, cost);
2073- if (SCHED_GROUP_P (insn))
2074- {
2075- advance = cost;
2076- break;
2077- }
2078-
2079- continue;
2080- }
2081
2082 if (current_sched_info->can_schedule_ready_p
2083 && ! (*current_sched_info->can_schedule_ready_p) (insn))
2084@@ -3200,11 +4652,17 @@
2085 reemit_notes (insn);
2086 last_scheduled_insn = insn;
2087
2088- if (memcmp (curr_state, temp_state, dfa_state_size) != 0)
2089- {
2090- cycle_issued_insns++;
2091- memcpy (curr_state, temp_state, dfa_state_size);
2092- }
2093+ if (recog_memoized (insn) >= 0)
2094+ {
2095+ cost = state_transition (curr_state, insn);
2096+ if (sched_pressure != SCHED_PRESSURE_WEIGHTED)
2097+ gcc_assert (cost < 0);
2098+ cycle_issued_insns++;
2099+ asm_p = false;
2100+ }
2101+ else
2102+ asm_p = (GET_CODE (PATTERN (insn)) == ASM_INPUT
2103+ || asm_noperands (PATTERN (insn)) >= 0);
2104
2105 if (targetm.sched.variable_issue)
2106 can_issue_more =
2107@@ -3225,6 +4683,9 @@
2108
2109 first_cycle_insn_p = false;
2110
2111+ if (ready.n_ready > 0)
2112+ prune_ready_list (temp_state, false);
2113+
2114 /* Sort the ready list based on priority. This must be
2115 redone here, as schedule_insn may have readied additional
2116 insns that will not be sorted correctly. */
2117@@ -3321,6 +4782,9 @@
2118 }
2119 }
2120
2121+ if (sched_pressure == SCHED_PRESSURE_MODEL)
2122+ model_end_schedule ();
2123+
2124 if (sched_verbose)
2125 fprintf (sched_dump, ";; total time = %d\n", clock_var);
2126
2127@@ -3424,10 +4888,14 @@
2128 if (targetm.sched.dispatch (NULL_RTX, IS_DISPATCH_ON))
2129 targetm.sched.dispatch_do (NULL_RTX, DISPATCH_INIT);
2130
2131- sched_pressure_p = (flag_sched_pressure && ! reload_completed
2132- && common_sched_info->sched_pass_id == SCHED_RGN_PASS);
2133+ if (flag_sched_pressure
2134+ && !reload_completed
2135+ && common_sched_info->sched_pass_id == SCHED_RGN_PASS)
2136+ sched_pressure = flag_sched_pressure_algorithm;
2137+ else
2138+ sched_pressure = SCHED_PRESSURE_NONE;
2139
2140- if (sched_pressure_p)
2141+ if (sched_pressure != SCHED_PRESSURE_NONE)
2142 ira_setup_eliminable_regset ();
2143
2144 /* Initialize SPEC_INFO. */
2145@@ -3504,7 +4972,7 @@
2146 if (targetm.sched.init_global)
2147 targetm.sched.init_global (sched_dump, sched_verbose, get_max_uid () + 1);
2148
2149- if (sched_pressure_p)
2150+ if (sched_pressure != SCHED_PRESSURE_NONE)
2151 {
2152 int i, max_regno = max_reg_num ();
2153
2154@@ -3517,8 +4985,11 @@
2155 ? ira_class_translate[REGNO_REG_CLASS (i)]
2156 : reg_cover_class (i));
2157 curr_reg_live = BITMAP_ALLOC (NULL);
2158- saved_reg_live = BITMAP_ALLOC (NULL);
2159- region_ref_regs = BITMAP_ALLOC (NULL);
2160+ if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
2161+ {
2162+ saved_reg_live = BITMAP_ALLOC (NULL);
2163+ region_ref_regs = BITMAP_ALLOC (NULL);
2164+ }
2165 }
2166
2167 curr_state = xmalloc (dfa_state_size);
2168@@ -3618,12 +5089,15 @@
2169 sched_finish (void)
2170 {
2171 haifa_finish_h_i_d ();
2172- if (sched_pressure_p)
2173+ if (sched_pressure != SCHED_PRESSURE_NONE)
2174 {
2175+ if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
2176+ {
2177+ BITMAP_FREE (region_ref_regs);
2178+ BITMAP_FREE (saved_reg_live);
2179+ }
2180+ BITMAP_FREE (curr_reg_live);
2181 free (sched_regno_cover_class);
2182- BITMAP_FREE (region_ref_regs);
2183- BITMAP_FREE (saved_reg_live);
2184- BITMAP_FREE (curr_reg_live);
2185 }
2186 free (curr_state);
2187
2188@@ -3936,7 +5410,7 @@
2189 INSN_TICK (next) = tick;
2190
2191 delay = tick - clock_var;
2192- if (delay <= 0 || sched_pressure_p)
2193+ if (delay <= 0 || sched_pressure != SCHED_PRESSURE_NONE)
2194 delay = QUEUE_READY;
2195
2196 change_queue_index (next, delay);
2197@@ -5185,7 +6659,7 @@
2198 if (insn == jump)
2199 break;
2200
2201- if (dep_list_size (insn) == 0)
2202+ if (dep_list_size (insn, SD_LIST_FORW) == 0)
2203 {
2204 dep_def _new_dep, *new_dep = &_new_dep;
2205
2206@@ -5556,6 +7030,7 @@
2207
2208 FOR_EACH_VEC_ELT (haifa_insn_data_def, h_i_d, i, data)
2209 {
2210+ free (data->max_reg_pressure);
2211 if (data->reg_pressure != NULL)
2212 free (data->reg_pressure);
2213 for (use = data->reg_use_list; use != NULL; use = next)
2214
2215=== modified file 'gcc/sched-deps.c'
2216--- old/gcc/sched-deps.c 2011-12-08 13:33:58 +0000
2217+++ new/gcc/sched-deps.c 2012-02-08 23:39:45 +0000
2218@@ -450,7 +450,7 @@
2219 static void add_dependence_list_and_free (struct deps_desc *, rtx,
2220 rtx *, int, enum reg_note);
2221 static void delete_all_dependences (rtx);
2222-static void fixup_sched_groups (rtx);
2223+static void chain_to_prev_insn (rtx);
2224
2225 static void flush_pending_lists (struct deps_desc *, rtx, int, int);
2226 static void sched_analyze_1 (struct deps_desc *, rtx, rtx);
2227@@ -1490,7 +1490,7 @@
2228 the previous nonnote insn. */
2229
2230 static void
2231-fixup_sched_groups (rtx insn)
2232+chain_to_prev_insn (rtx insn)
2233 {
2234 sd_iterator_def sd_it;
2235 dep_t dep;
2236@@ -1999,7 +1999,7 @@
2237 static struct reg_pressure_data *pressure_info;
2238 rtx link;
2239
2240- gcc_assert (sched_pressure_p);
2241+ gcc_assert (sched_pressure != SCHED_PRESSURE_NONE);
2242
2243 if (! INSN_P (insn))
2244 return;
2245@@ -2030,8 +2030,9 @@
2246 len = sizeof (struct reg_pressure_data) * ira_reg_class_cover_size;
2247 pressure_info
2248 = INSN_REG_PRESSURE (insn) = (struct reg_pressure_data *) xmalloc (len);
2249- INSN_MAX_REG_PRESSURE (insn) = (int *) xcalloc (ira_reg_class_cover_size
2250- * sizeof (int), 1);
2251+ if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
2252+ INSN_MAX_REG_PRESSURE (insn) = (int *) xcalloc (ira_reg_class_cover_size
2253+ * sizeof (int), 1);
2254 for (i = 0; i < ira_reg_class_cover_size; i++)
2255 {
2256 cl = ira_reg_class_cover[i];
2257@@ -2775,7 +2776,7 @@
2258 || (NONJUMP_INSN_P (insn) && control_flow_insn_p (insn)))
2259 reg_pending_barrier = MOVE_BARRIER;
2260
2261- if (sched_pressure_p)
2262+ if (sched_pressure != SCHED_PRESSURE_NONE)
2263 {
2264 setup_insn_reg_uses (deps, insn);
2265 setup_insn_reg_pressure_info (insn);
2266@@ -3076,7 +3077,7 @@
2267 instructions that follow seem like they should be part
2268 of the call group.
2269
2270- Also, if we did, fixup_sched_groups() would move the
2271+ Also, if we did, chain_to_prev_insn would move the
2272 deps of the debug insn to the call insn, modifying
2273 non-debug post-dependency counts of the debug insn
2274 dependencies and otherwise messing with the scheduling
2275@@ -3222,6 +3223,37 @@
2276 return true;
2277 }
2278
2279+/* Return true if INSN should be made dependent on the previous instruction
2280+ group, and if all INSN's dependencies should be moved to the first
2281+ instruction of that group. */
2282+
2283+static bool
2284+chain_to_prev_insn_p (rtx insn)
2285+{
2286+ rtx prev, x;
2287+
2288+ /* INSN forms a group with the previous instruction. */
2289+ if (SCHED_GROUP_P (insn))
2290+ return true;
2291+
2292+ /* If the previous instruction clobbers a register R and this one sets
2293+ part of R, the clobber was added specifically to help us track the
2294+ liveness of R. There's no point scheduling the clobber and leaving
2295+ INSN behind, especially if we move the clobber to another block. */
2296+ prev = prev_nonnote_nondebug_insn (insn);
2297+ if (prev
2298+ && INSN_P (prev)
2299+ && BLOCK_FOR_INSN (prev) == BLOCK_FOR_INSN (insn)
2300+ && GET_CODE (PATTERN (prev)) == CLOBBER)
2301+ {
2302+ x = XEXP (PATTERN (prev), 0);
2303+ if (set_of (x, insn))
2304+ return true;
2305+ }
2306+
2307+ return false;
2308+}
2309+
2310 /* Analyze INSN with DEPS as a context. */
2311 void
2312 deps_analyze_insn (struct deps_desc *deps, rtx insn)
2313@@ -3358,8 +3390,9 @@
2314
2315 /* Fixup the dependencies in the sched group. */
2316 if ((NONJUMP_INSN_P (insn) || JUMP_P (insn))
2317- && SCHED_GROUP_P (insn) && !sel_sched_p ())
2318- fixup_sched_groups (insn);
2319+ && chain_to_prev_insn_p (insn)
2320+ && !sel_sched_p ())
2321+ chain_to_prev_insn (insn);
2322 }
2323
2324 /* Initialize DEPS for the new block beginning with HEAD. */
2325
2326=== modified file 'gcc/sched-int.h'
2327--- old/gcc/sched-int.h 2011-02-02 04:31:35 +0000
2328+++ new/gcc/sched-int.h 2012-02-08 23:39:02 +0000
2329@@ -651,7 +651,7 @@
2330
2331 /* Do register pressure sensitive insn scheduling if the flag is set
2332 up. */
2333-extern bool sched_pressure_p;
2334+extern enum sched_pressure_algorithm sched_pressure;
2335
2336 /* Map regno -> its cover class. The map defined only when
2337 SCHED_PRESSURE_P is true. */
2338@@ -773,16 +773,16 @@
2339
2340 short cost;
2341
2342+ /* '> 0' if priority is valid,
2343+ '== 0' if priority was not yet computed,
2344+ '< 0' if priority in invalid and should be recomputed. */
2345+ signed char priority_status;
2346+
2347 /* Set if there's DEF-USE dependence between some speculatively
2348 moved load insn and this one. */
2349 unsigned int fed_by_spec_load : 1;
2350 unsigned int is_load_insn : 1;
2351
2352- /* '> 0' if priority is valid,
2353- '== 0' if priority was not yet computed,
2354- '< 0' if priority in invalid and should be recomputed. */
2355- signed char priority_status;
2356-
2357 /* What speculations are necessary to apply to schedule the instruction. */
2358 ds_t todo_spec;
2359
2360@@ -817,6 +817,7 @@
2361 /* Info about how scheduling the insn changes cost of register
2362 pressure excess (between source and target). */
2363 int reg_pressure_excess_cost_change;
2364+ int model_index;
2365 };
2366
2367 typedef struct _haifa_insn_data haifa_insn_data_def;
2368@@ -839,6 +840,7 @@
2369 #define INSN_REG_PRESSURE_EXCESS_COST_CHANGE(INSN) \
2370 (HID (INSN)->reg_pressure_excess_cost_change)
2371 #define INSN_PRIORITY_STATUS(INSN) (HID (INSN)->priority_status)
2372+#define INSN_MODEL_INDEX(INSN) (HID (INSN)->model_index)
2373
2374 typedef struct _haifa_deps_insn_data haifa_deps_insn_data_def;
2375 typedef haifa_deps_insn_data_def *haifa_deps_insn_data_t;
2376
2377=== modified file 'gcc/sched-rgn.c'
2378--- old/gcc/sched-rgn.c 2011-06-04 10:15:48 +0000
2379+++ new/gcc/sched-rgn.c 2012-02-08 23:38:13 +0000
2380@@ -2943,7 +2943,7 @@
2381
2382 sched_extend_ready_list (rgn_n_insns);
2383
2384- if (sched_pressure_p)
2385+ if (sched_pressure == SCHED_PRESSURE_WEIGHTED)
2386 {
2387 sched_init_region_reg_pressure_info ();
2388 for (bb = 0; bb < current_nr_blocks; bb++)
2389
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106870.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106870.patch
new file mode 100644
index 000000000..1a5448403
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106870.patch
@@ -0,0 +1,28 @@
12012-02-20 Andrew Stubbs <ams@codesourcery.com>
2
3 gcc/
4 * config/arm/arm.c (arm_print_operand): Avoid null-pointer
5 dereference from MEM_SIZE.
6
7=== modified file 'gcc/config/arm/arm.c'
8--- old/gcc/config/arm/arm.c 2012-02-09 00:47:59 +0000
9+++ new/gcc/config/arm/arm.c 2012-02-20 15:32:26 +0000
10@@ -17446,6 +17446,7 @@
11 rtx addr;
12 bool postinc = FALSE;
13 unsigned align, memsize, align_bits;
14+ rtx memsize_rtx;
15
16 gcc_assert (GET_CODE (x) == MEM);
17 addr = XEXP (x, 0);
18@@ -17460,7 +17461,8 @@
19 instruction (for some alignments) as an aid to the memory subsystem
20 of the target. */
21 align = MEM_ALIGN (x) >> 3;
22- memsize = INTVAL (MEM_SIZE (x));
23+ memsize_rtx = MEM_SIZE (x);
24+ memsize = memsize_rtx ? INTVAL (memsize_rtx) : 0;
25
26 /* Only certain alignment specifiers are supported by the hardware. */
27 if (memsize == 16 && (align % 32) == 0)
28
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106872.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106872.patch
new file mode 100644
index 000000000..9bfd969df
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106872.patch
@@ -0,0 +1,126 @@
12012-02-24 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
2
3 Backport from mainline.
4 2011-12-05 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
5
6 gcc/
7 * config/arm/arm.c (vfp3_const_double_for_fract_bits): Define.
8 * config/arm/arm-protos.h (vfp3_const_double_for_fract_bits): Declare.
9 * config/arm/constraints.md ("Dt"): New constraint.
10 * config/arm/predicates.md (const_double_vcvt_power_of_two_reciprocal):
11 New.
12 * config/arm/vfp.md (*arm_combine_vcvt_f32_s32): New.
13 (*arm_combine_vcvt_f32_u32): New.
14
15 LP:#900426
16
17 2011-12-06 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
18 * config/arm/vfp.md (*combine_vcvt_f64_<FCVTI32typename>): Fix
19 formatting character for vmov.f64 case.
20
212012-02-24 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
22
23 gcc/
24 * config/arm/arm.c (arm_print_operand): Remove wrongly merged code.
25 (vfp3_const_double_for_fract_bits): Likewise.
26
27=== modified file 'gcc/config/arm/arm-protos.h'
28--- old/gcc/config/arm/arm-protos.h 2011-12-06 10:42:29 +0000
29+++ new/gcc/config/arm/arm-protos.h 2012-02-22 13:31:54 +0000
30@@ -238,6 +238,7 @@
31 };
32
33 extern const struct tune_params *current_tune;
34+extern int vfp3_const_double_for_fract_bits (rtx);
35 #endif /* RTX_CODE */
36
37 #endif /* ! GCC_ARM_PROTOS_H */
38
39=== modified file 'gcc/config/arm/constraints.md'
40--- old/gcc/config/arm/constraints.md 2011-12-06 10:42:29 +0000
41+++ new/gcc/config/arm/constraints.md 2012-02-22 13:31:54 +0000
42@@ -29,7 +29,7 @@
43 ;; in Thumb-1 state: I, J, K, L, M, N, O
44
45 ;; The following multi-letter normal constraints have been used:
46-;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di, Dz
47+;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di, Dt, Dz
48 ;; in Thumb-1 state: Pa, Pb, Pc, Pd
49 ;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py
50
51@@ -291,6 +291,12 @@
52 (and (match_code "const_double")
53 (match_test "TARGET_32BIT && TARGET_VFP_DOUBLE && vfp3_const_double_rtx (op)")))
54
55+(define_constraint "Dt"
56+ "@internal
57+ In ARM/ Thumb2 a const_double which can be used with a vcvt.f32.s32 with fract bits operation"
58+ (and (match_code "const_double")
59+ (match_test "TARGET_32BIT && TARGET_VFP && vfp3_const_double_for_fract_bits (op)")))
60+
61 (define_memory_constraint "Ut"
62 "@internal
63 In ARM/Thumb-2 state an address valid for loading/storing opaque structure
64
65=== modified file 'gcc/config/arm/predicates.md'
66--- old/gcc/config/arm/predicates.md 2011-12-06 10:42:29 +0000
67+++ new/gcc/config/arm/predicates.md 2012-02-22 13:31:54 +0000
68@@ -725,6 +725,11 @@
69 return true;
70 })
71
72+(define_predicate "const_double_vcvt_power_of_two_reciprocal"
73+ (and (match_code "const_double")
74+ (match_test "TARGET_32BIT && TARGET_VFP
75+ && vfp3_const_double_for_fract_bits (op)")))
76+
77 (define_special_predicate "neon_struct_operand"
78 (and (match_code "mem")
79 (match_test "TARGET_32BIT && neon_vector_mem_operand (op, 2)")))
80
81=== modified file 'gcc/config/arm/vfp.md'
82--- old/gcc/config/arm/vfp.md 2011-12-06 10:42:29 +0000
83+++ new/gcc/config/arm/vfp.md 2012-02-22 13:31:54 +0000
84@@ -1131,9 +1131,40 @@
85 (set_attr "type" "fcmpd")]
86 )
87
88+;; Fixed point to floating point conversions.
89+(define_code_iterator FCVT [unsigned_float float])
90+(define_code_attr FCVTI32typename [(unsigned_float "u32") (float "s32")])
91+
92+(define_insn "*combine_vcvt_f32_<FCVTI32typename>"
93+ [(set (match_operand:SF 0 "s_register_operand" "=t")
94+ (mult:SF (FCVT:SF (match_operand:SI 1 "s_register_operand" "0"))
95+ (match_operand 2
96+ "const_double_vcvt_power_of_two_reciprocal" "Dt")))]
97+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math"
98+ "vcvt.f32.<FCVTI32typename>\\t%0, %1, %v2"
99+ [(set_attr "predicable" "no")
100+ (set_attr "type" "f_cvt")]
101+)
102+
103+;; Not the ideal way of implementing this. Ideally we would be able to split
104+;; this into a move to a DP register and then a vcvt.f64.i32
105+(define_insn "*combine_vcvt_f64_<FCVTI32typename>"
106+ [(set (match_operand:DF 0 "s_register_operand" "=x,x,w")
107+ (mult:DF (FCVT:DF (match_operand:SI 1 "s_register_operand" "r,t,r"))
108+ (match_operand 2
109+ "const_double_vcvt_power_of_two_reciprocal" "Dt,Dt,Dt")))]
110+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math
111+ && !TARGET_VFP_SINGLE"
112+ "@
113+ vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2
114+ vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2
115+ vmov.f64\\t%P0, %1, %1\; vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2"
116+ [(set_attr "predicable" "no")
117+ (set_attr "type" "f_cvt")
118+ (set_attr "length" "8")]
119+)
120
121 ;; Store multiple insn used in function prologue.
122-
123 (define_insn "*push_multi_vfp"
124 [(match_parallel 2 "multi_register_push"
125 [(set (match_operand:BLK 0 "memory_operand" "=m")
126
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106873.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106873.patch
new file mode 100644
index 000000000..5ce71a513
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106873.patch
@@ -0,0 +1,80 @@
1 2012-02-24 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
2
3 LP:#922474
4 gcc/
5 * config/arm/sync.md (sync_lock_releasedi): Define.
6 (arm_sync_lock_releasedi): Likewise.
7 gcc/testsuite
8 Backport from mainline.
9 2012-01-30 Greta Yorsh <Greta.Yorsh@arm.com>
10 * gcc.target/arm/di-longlong64-sync-withldrexd.c: Accept
11 new code generated for __sync_lock_release.
12
13=== modified file 'gcc/config/arm/arm.md'
14--- old/gcc/config/arm/arm.md 2012-02-01 14:13:07 +0000
15+++ new/gcc/config/arm/arm.md 2012-02-22 18:37:56 +0000
16@@ -157,6 +157,7 @@
17 (VUNSPEC_SYNC_OP 23) ; Represent a sync_<op>
18 (VUNSPEC_SYNC_NEW_OP 24) ; Represent a sync_new_<op>
19 (VUNSPEC_SYNC_OLD_OP 25) ; Represent a sync_old_<op>
20+ (VUNSPEC_SYNC_RELEASE 26) ; Represent a sync_lock_release.
21 ]
22 )
23
24
25=== modified file 'gcc/config/arm/sync.md'
26--- old/gcc/config/arm/sync.md 2011-10-14 15:47:15 +0000
27+++ new/gcc/config/arm/sync.md 2012-02-22 18:37:56 +0000
28@@ -494,3 +494,36 @@
29 (set_attr "conds" "unconditional")
30 (set_attr "predicable" "no")])
31
32+(define_expand "sync_lock_releasedi"
33+ [(match_operand:DI 0 "memory_operand")
34+ (match_operand:DI 1 "s_register_operand")]
35+ "TARGET_HAVE_LDREXD && ARM_DOUBLEWORD_ALIGN && TARGET_HAVE_MEMORY_BARRIER"
36+ {
37+ struct arm_sync_generator generator;
38+ rtx tmp1 = gen_reg_rtx (DImode);
39+ generator.op = arm_sync_generator_omn;
40+ generator.u.omn = gen_arm_sync_lock_releasedi;
41+ arm_expand_sync (DImode, &generator, operands[1], operands[0], NULL, tmp1);
42+ DONE;
43+ }
44+)
45+
46+(define_insn "arm_sync_lock_releasedi"
47+ [(set (match_operand:DI 2 "s_register_operand" "=&r")
48+ (unspec_volatile:DI [(match_operand:DI 1 "arm_sync_memory_operand" "+Q")
49+ (match_operand:DI 0 "s_register_operand" "r")]
50+ VUNSPEC_SYNC_RELEASE))
51+ (clobber (reg:CC CC_REGNUM))
52+ (clobber (match_scratch:SI 3 "=&r"))]
53+ "TARGET_HAVE_LDREXD && ARM_DOUBLEWORD_ALIGN && TARGET_HAVE_MEMORY_BARRIER"
54+ {
55+ return arm_output_sync_insn (insn, operands);
56+ }
57+ [(set_attr "sync_memory" "1")
58+ (set_attr "sync_result" "2")
59+ (set_attr "sync_t1" "2")
60+ (set_attr "sync_t2" "3")
61+ (set_attr "sync_new_value" "0")
62+ (set_attr "conds" "clob")
63+ (set_attr "predicable" "no")]
64+)
65
66=== modified file 'gcc/testsuite/gcc.target/arm/di-longlong64-sync-withldrexd.c'
67--- old/gcc/testsuite/gcc.target/arm/di-longlong64-sync-withldrexd.c 2011-10-14 15:56:32 +0000
68+++ new/gcc/testsuite/gcc.target/arm/di-longlong64-sync-withldrexd.c 2012-02-22 18:37:56 +0000
69@@ -10,8 +10,8 @@
70 #include "../../gcc.dg/di-longlong64-sync-1.c"
71
72 /* We should be using ldrexd, strexd and no helpers or shorter ldrex. */
73-/* { dg-final { scan-assembler-times "\tldrexd" 46 } } */
74-/* { dg-final { scan-assembler-times "\tstrexd" 46 } } */
75+/* { dg-final { scan-assembler-times "\tldrexd" 48 } } */
76+/* { dg-final { scan-assembler-times "\tstrexd" 48 } } */
77 /* { dg-final { scan-assembler-not "__sync_" } } */
78 /* { dg-final { scan-assembler-not "ldrex\t" } } */
79 /* { dg-final { scan-assembler-not "strex\t" } } */
80
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106874.patch b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106874.patch
new file mode 100644
index 000000000..092650dc9
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106874.patch
@@ -0,0 +1,46 @@
1 2012-02-24 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org>
2
3 Backport from mainline.
4 gcc/
5 2012-02-21 Matthew Gretton-Dann <matthew.gretton-dann@arm.com>
6
7 Revert r183011
8 * config/arm/arm-cores.def (cortex-a15): Use generic Cortex tuning
9 parameters.
10 * config/arm/arm.c (arm_cortex_a15_tune): Remove.
11
12=== modified file 'gcc/config/arm/arm-cores.def'
13--- old/gcc/config/arm/arm-cores.def 2012-01-23 00:36:02 +0000
14+++ new/gcc/config/arm/arm-cores.def 2012-02-22 15:53:56 +0000
15@@ -129,7 +129,7 @@
16 ARM_CORE("cortex-a7", cortexa7, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex)
17 ARM_CORE("cortex-a8", cortexa8, 7A, FL_LDSCHED, cortex)
18 ARM_CORE("cortex-a9", cortexa9, 7A, FL_LDSCHED, cortex_a9)
19-ARM_CORE("cortex-a15", cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex_a15)
20+ARM_CORE("cortex-a15", cortexa15, 7A, FL_LDSCHED | FL_THUMB_DIV | FL_ARM_DIV, cortex)
21 ARM_CORE("cortex-r4", cortexr4, 7R, FL_LDSCHED, cortex)
22 ARM_CORE("cortex-r4f", cortexr4f, 7R, FL_LDSCHED, cortex)
23 ARM_CORE("cortex-r5", cortexr5, 7R, FL_LDSCHED | FL_ARM_DIV, cortex)
24
25=== modified file 'gcc/config/arm/arm.c'
26--- old/gcc/config/arm/arm.c 2012-02-24 16:20:29 +0000
27+++ new/gcc/config/arm/arm.c 2012-02-24 17:33:58 +0000
28@@ -988,17 +988,6 @@
29 arm_default_branch_cost
30 };
31
32-const struct tune_params arm_cortex_a15_tune =
33-{
34- arm_9e_rtx_costs,
35- NULL,
36- 1, /* Constant limit. */
37- 1, /* Max cond insns. */
38- ARM_PREFETCH_NOT_BENEFICIAL, /* TODO: Calculate correct values. */
39- false, /* Prefer constant pool. */
40- arm_cortex_a5_branch_cost
41-};
42-
43 const struct tune_params arm_fa726te_tune =
44 {
45 arm_9e_rtx_costs,
46
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4_6-branch-linaro-backports.inc b/meta-oe/recipes-devtools/gcc/gcc-4_6-branch-linaro-backports.inc
index e42aeeaad..90a857d9a 100644
--- a/meta-oe/recipes-devtools/gcc/gcc-4_6-branch-linaro-backports.inc
+++ b/meta-oe/recipes-devtools/gcc/gcc-4_6-branch-linaro-backports.inc
@@ -4,7 +4,6 @@ file://linaro/gcc-4.6-linaro-r106733.patch \
4file://linaro/gcc-4.6-linaro-r106737.patch \ 4file://linaro/gcc-4.6-linaro-r106737.patch \
5file://linaro/gcc-4.6-linaro-r106738.patch \ 5file://linaro/gcc-4.6-linaro-r106738.patch \
6file://linaro/gcc-4.6-linaro-r106739.patch \ 6file://linaro/gcc-4.6-linaro-r106739.patch \
7file://linaro/gcc-4.6-linaro-r106740.patch \
8file://linaro/gcc-4.6-linaro-r106741.patch \ 7file://linaro/gcc-4.6-linaro-r106741.patch \
9file://linaro/gcc-4.6-linaro-r106742.patch \ 8file://linaro/gcc-4.6-linaro-r106742.patch \
10file://linaro/gcc-4.6-linaro-r106744.patch \ 9file://linaro/gcc-4.6-linaro-r106744.patch \
@@ -81,6 +80,17 @@ file://linaro/gcc-4.6-linaro-r106845.patch \
81file://linaro/gcc-4.6-linaro-r106846.patch \ 80file://linaro/gcc-4.6-linaro-r106846.patch \
82file://linaro/gcc-4.6-linaro-r106848.patch \ 81file://linaro/gcc-4.6-linaro-r106848.patch \
83file://linaro/gcc-4.6-linaro-r106853.patch \ 82file://linaro/gcc-4.6-linaro-r106853.patch \
84file://linaro/gcc-4.6-linaro-r106854.patch \
85file://linaro/gcc-4.6-linaro-r106855.patch \ 83file://linaro/gcc-4.6-linaro-r106855.patch \
84file://linaro/gcc-4.6-linaro-r106860.patch \
85file://linaro/gcc-4.6-linaro-r106861.patch \
86file://linaro/gcc-4.6-linaro-r106862.patch \
87file://linaro/gcc-4.6-linaro-r106863.patch \
88file://linaro/gcc-4.6-linaro-r106864.patch \
89file://linaro/gcc-4.6-linaro-r106865.patch \
90file://linaro/gcc-4.6-linaro-r106869.patch \
91file://linaro/gcc-4.6-linaro-r106870.patch \
92file://linaro/gcc-4.6-linaro-r106872.patch \
93file://linaro/gcc-4.6-linaro-r106873.patch \
94file://linaro/gcc-4.6-linaro-r106874.patch \
95file://linaro/fix_linaro_106872.patch \
86" 96"