summaryrefslogtreecommitdiffstats
path: root/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch
diff options
context:
space:
mode:
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch')
-rw-r--r--toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch2389
1 files changed, 0 insertions, 2389 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch
deleted file mode 100644
index de3d2ff4c..000000000
--- a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106869.patch
+++ /dev/null
@@ -1,2389 +0,0 @@
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