OSDN Git Service

2007-10-15 Gary Dismukes <dismukes@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / sched-ebb.c
1 /* Instruction scheduling pass.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
4    Free Software Foundation, Inc.
5    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
6    and currently maintained by, Jim Wilson (wilson@cygnus.com)
7
8 This file is part of GCC.
9
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
13 version.
14
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3.  If not see
22 <http://www.gnu.org/licenses/>.  */
23 \f
24 #include "config.h"
25 #include "system.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "toplev.h"
29 #include "rtl.h"
30 #include "tm_p.h"
31 #include "hard-reg-set.h"
32 #include "regs.h"
33 #include "function.h"
34 #include "flags.h"
35 #include "insn-config.h"
36 #include "insn-attr.h"
37 #include "except.h"
38 #include "toplev.h"
39 #include "recog.h"
40 #include "cfglayout.h"
41 #include "params.h"
42 #include "sched-int.h"
43 #include "target.h"
44 #include "output.h"
45
46 \f
47 /* The number of insns scheduled so far.  */
48 static int sched_n_insns;
49
50 /* The number of insns to be scheduled in total.  */
51 static int n_insns;
52
53 /* Set of blocks, that already have their dependencies calculated.  */
54 static bitmap_head dont_calc_deps;
55
56 /* Last basic block in current ebb.  */
57 static basic_block last_bb;
58
59 /* Implementations of the sched_info functions for region scheduling.  */
60 static void init_ready_list (void);
61 static void begin_schedule_ready (rtx, rtx);
62 static int schedule_more_p (void);
63 static const char *ebb_print_insn (rtx, int);
64 static int rank (rtx, rtx);
65 static int contributes_to_priority (rtx, rtx);
66 static void compute_jump_reg_dependencies (rtx, regset, regset, regset);
67 static basic_block earliest_block_with_similiar_load (basic_block, rtx);
68 static void add_deps_for_risky_insns (rtx, rtx);
69 static basic_block schedule_ebb (rtx, rtx);
70
71 static void add_remove_insn (rtx, int);
72 static void add_block1 (basic_block, basic_block);
73 static basic_block advance_target_bb (basic_block, rtx);
74 static void fix_recovery_cfg (int, int, int);
75
76 /* Return nonzero if there are more insns that should be scheduled.  */
77
78 static int
79 schedule_more_p (void)
80 {
81   return sched_n_insns < n_insns;
82 }
83
84 /* Print dependency information about ebb between HEAD and TAIL.  */
85 static void
86 debug_ebb_dependencies (rtx head, rtx tail)
87 {
88   fprintf (sched_dump,
89            ";;   --------------- forward dependences: ------------ \n");
90
91   fprintf (sched_dump, "\n;;   --- EBB Dependences --- from bb%d to bb%d \n",
92            BLOCK_NUM (head), BLOCK_NUM (tail));
93
94   debug_dependencies (head, tail);
95 }
96
97 /* Add all insns that are initially ready to the ready list READY.  Called
98    once before scheduling a set of insns.  */
99
100 static void
101 init_ready_list (void)
102 {
103   int n = 0;
104   rtx prev_head = current_sched_info->prev_head;
105   rtx next_tail = current_sched_info->next_tail;
106   rtx insn;
107
108   sched_n_insns = 0;
109
110   /* Print debugging information.  */
111   if (sched_verbose >= 5)
112     debug_ebb_dependencies (NEXT_INSN (prev_head), PREV_INSN (next_tail));
113
114   /* Initialize ready list with all 'ready' insns in target block.
115      Count number of insns in the target block being scheduled.  */
116   for (insn = NEXT_INSN (prev_head); insn != next_tail; insn = NEXT_INSN (insn))
117     {
118       try_ready (insn);
119       n++;
120     }
121
122   gcc_assert (n == n_insns);
123 }
124
125 /* INSN is being scheduled after LAST.  Update counters.  */
126 static void
127 begin_schedule_ready (rtx insn, rtx last)
128 {
129   sched_n_insns++;
130
131   if (BLOCK_FOR_INSN (insn) == last_bb
132       /* INSN is a jump in the last block, ...  */
133       && control_flow_insn_p (insn)
134       /* that is going to be moved over some instructions.  */
135       && last != PREV_INSN (insn))
136     {
137       edge e;
138       edge_iterator ei;
139       basic_block bb;
140
141       /* An obscure special case, where we do have partially dead
142          instruction scheduled after last control flow instruction.
143          In this case we can create new basic block.  It is
144          always exactly one basic block last in the sequence.  */
145       
146       FOR_EACH_EDGE (e, ei, last_bb->succs)
147         if (e->flags & EDGE_FALLTHRU)
148           break;
149
150 #ifdef ENABLE_CHECKING
151       gcc_assert (!e || !(e->flags & EDGE_COMPLEX));        
152
153       gcc_assert (BLOCK_FOR_INSN (insn) == last_bb
154                   && !IS_SPECULATION_CHECK_P (insn)
155                   && BB_HEAD (last_bb) != insn
156                   && BB_END (last_bb) == insn);
157
158       {
159         rtx x;
160
161         x = NEXT_INSN (insn);
162         if (e)
163           gcc_assert (NOTE_P (x) || LABEL_P (x));
164         else
165           gcc_assert (BARRIER_P (x));
166       }
167 #endif
168
169       if (e)
170         {
171           bb = split_edge (e);
172           gcc_assert (NOTE_INSN_BASIC_BLOCK_P (BB_END (bb)));
173         }
174       else
175         /* Create an empty unreachable block after the INSN.  */
176         bb = create_basic_block (NEXT_INSN (insn), NULL_RTX, last_bb);
177       
178       /* split_edge () creates BB before E->DEST.  Keep in mind, that
179          this operation extends scheduling region till the end of BB.
180          Hence, we need to shift NEXT_TAIL, so haifa-sched.c won't go out
181          of the scheduling region.  */
182       current_sched_info->next_tail = NEXT_INSN (BB_END (bb));
183       gcc_assert (current_sched_info->next_tail);
184
185       add_block (bb, last_bb);
186       gcc_assert (last_bb == bb);
187     }
188 }
189
190 /* Return a string that contains the insn uid and optionally anything else
191    necessary to identify this insn in an output.  It's valid to use a
192    static buffer for this.  The ALIGNED parameter should cause the string
193    to be formatted so that multiple output lines will line up nicely.  */
194
195 static const char *
196 ebb_print_insn (rtx insn, int aligned ATTRIBUTE_UNUSED)
197 {
198   static char tmp[80];
199
200   sprintf (tmp, "%4d", INSN_UID (insn));
201   return tmp;
202 }
203
204 /* Compare priority of two insns.  Return a positive number if the second
205    insn is to be preferred for scheduling, and a negative one if the first
206    is to be preferred.  Zero if they are equally good.  */
207
208 static int
209 rank (rtx insn1, rtx insn2)
210 {
211   basic_block bb1 = BLOCK_FOR_INSN (insn1);
212   basic_block bb2 = BLOCK_FOR_INSN (insn2);
213
214   if (bb1->count > bb2->count
215       || bb1->frequency > bb2->frequency)
216     return -1;
217   if (bb1->count < bb2->count
218       || bb1->frequency < bb2->frequency)
219     return 1;
220   return 0;
221 }
222
223 /* NEXT is an instruction that depends on INSN (a backward dependence);
224    return nonzero if we should include this dependence in priority
225    calculations.  */
226
227 static int
228 contributes_to_priority (rtx next ATTRIBUTE_UNUSED,
229                          rtx insn ATTRIBUTE_UNUSED)
230 {
231   return 1;
232 }
233
234  /* INSN is a JUMP_INSN, COND_SET is the set of registers that are
235     conditionally set before INSN.  Store the set of registers that
236     must be considered as used by this jump in USED and that of
237     registers that must be considered as set in SET.  */
238
239 static void
240 compute_jump_reg_dependencies (rtx insn, regset cond_set, regset used,
241                                regset set)
242 {
243   basic_block b = BLOCK_FOR_INSN (insn);
244   edge e;
245   edge_iterator ei;
246
247   FOR_EACH_EDGE (e, ei, b->succs)
248     if (e->flags & EDGE_FALLTHRU)
249       /* The jump may be a by-product of a branch that has been merged
250          in the main codepath after being conditionalized.  Therefore
251          it may guard the fallthrough block from using a value that has
252          conditionally overwritten that of the main codepath.  So we
253          consider that it restores the value of the main codepath.  */
254       bitmap_and (set, df_get_live_in (e->dest), cond_set);
255     else
256       bitmap_ior_into (used, df_get_live_in (e->dest));
257 }
258
259 /* Used in schedule_insns to initialize current_sched_info for scheduling
260    regions (or single basic blocks).  */
261
262 static struct sched_info ebb_sched_info =
263 {
264   init_ready_list,
265   NULL,
266   schedule_more_p,
267   NULL,
268   rank,
269   ebb_print_insn,
270   contributes_to_priority,
271   compute_jump_reg_dependencies,
272
273   NULL, NULL,
274   NULL, NULL,
275   0, 1, 0,
276
277   add_remove_insn,
278   begin_schedule_ready,
279   add_block1,
280   advance_target_bb,
281   fix_recovery_cfg,
282   SCHED_EBB
283   /* We can create new blocks in begin_schedule_ready ().  */
284   | NEW_BBS
285 };
286 \f
287 /* Returns the earliest block in EBB currently being processed where a
288    "similar load" 'insn2' is found, and hence LOAD_INSN can move
289    speculatively into the found block.  All the following must hold:
290
291    (1) both loads have 1 base register (PFREE_CANDIDATEs).
292    (2) load_insn and load2 have a def-use dependence upon
293    the same insn 'insn1'.
294
295    From all these we can conclude that the two loads access memory
296    addresses that differ at most by a constant, and hence if moving
297    load_insn would cause an exception, it would have been caused by
298    load2 anyhow.
299
300    The function uses list (given by LAST_BLOCK) of already processed
301    blocks in EBB.  The list is formed in `add_deps_for_risky_insns'.  */
302
303 static basic_block
304 earliest_block_with_similiar_load (basic_block last_block, rtx load_insn)
305 {
306   sd_iterator_def back_sd_it;
307   dep_t back_dep;
308   basic_block bb, earliest_block = NULL;
309
310   FOR_EACH_DEP (load_insn, SD_LIST_BACK, back_sd_it, back_dep)
311     {
312       rtx insn1 = DEP_PRO (back_dep);
313
314       if (DEP_TYPE (back_dep) == REG_DEP_TRUE)  
315         /* Found a DEF-USE dependence (insn1, load_insn).  */
316         {
317           sd_iterator_def fore_sd_it;
318           dep_t fore_dep;
319
320           FOR_EACH_DEP (insn1, SD_LIST_FORW, fore_sd_it, fore_dep)
321             {
322               rtx insn2 = DEP_CON (fore_dep);
323               basic_block insn2_block = BLOCK_FOR_INSN (insn2);
324
325               if (DEP_TYPE (fore_dep) == REG_DEP_TRUE)
326                 {
327                   if (earliest_block != NULL
328                       && earliest_block->index < insn2_block->index)
329                     continue;
330
331                   /* Found a DEF-USE dependence (insn1, insn2).  */
332                   if (haifa_classify_insn (insn2) != PFREE_CANDIDATE)
333                     /* insn2 not guaranteed to be a 1 base reg load.  */
334                     continue;
335
336                   for (bb = last_block; bb; bb = bb->aux)
337                     if (insn2_block == bb)
338                       break;
339
340                   if (!bb)
341                     /* insn2 is the similar load.  */
342                     earliest_block = insn2_block;
343                 }
344             }
345         }
346     }
347
348   return earliest_block;
349 }
350
351 /* The following function adds dependencies between jumps and risky
352    insns in given ebb.  */
353
354 static void
355 add_deps_for_risky_insns (rtx head, rtx tail)
356 {
357   rtx insn, prev;
358   int class;
359   rtx last_jump = NULL_RTX;
360   rtx next_tail = NEXT_INSN (tail);
361   basic_block last_block = NULL, bb;
362
363   for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
364     if (control_flow_insn_p (insn))
365       {
366         bb = BLOCK_FOR_INSN (insn);
367         bb->aux = last_block;
368         last_block = bb;
369         last_jump = insn;
370       }
371     else if (INSN_P (insn) && last_jump != NULL_RTX)
372       {
373         class = haifa_classify_insn (insn);
374         prev = last_jump;
375         switch (class)
376           {
377           case PFREE_CANDIDATE:
378             if (flag_schedule_speculative_load)
379               {
380                 bb = earliest_block_with_similiar_load (last_block, insn);
381                 if (bb)
382                   {
383                     bb = bb->aux;
384                     if (!bb)
385                       break;
386                     prev = BB_END (bb);
387                   }
388               }
389             /* Fall through.  */
390           case TRAP_RISKY:
391           case IRISKY:
392           case PRISKY_CANDIDATE:
393             /* ??? We could implement better checking PRISKY_CANDIDATEs
394                analogous to sched-rgn.c.  */
395             /* We can not change the mode of the backward
396                dependency because REG_DEP_ANTI has the lowest
397                rank.  */
398             if (! sched_insns_conditions_mutex_p (insn, prev))
399               {
400                 dep_def _dep, *dep = &_dep;
401
402                 init_dep (dep, prev, insn, REG_DEP_ANTI);
403
404                 if (!(current_sched_info->flags & USE_DEPS_LIST))
405                   {
406                     enum DEPS_ADJUST_RESULT res;
407
408                     res = sd_add_or_update_dep (dep, false);
409
410                     /* We can't change an existing dependency with
411                        DEP_ANTI.  */
412                     gcc_assert (res != DEP_CHANGED);
413                   }
414                 else
415                   {
416                     if ((current_sched_info->flags & DO_SPECULATION)
417                         && (spec_info->mask & BEGIN_CONTROL))
418                       DEP_STATUS (dep) = set_dep_weak (DEP_ANTI, BEGIN_CONTROL,
419                                                        MAX_DEP_WEAK);
420
421                     sd_add_or_update_dep (dep, false);
422
423                     /* Dep_status could have been changed.
424                        No assertion here.  */
425                   }
426               }
427
428             break;
429
430           default:
431             break;
432           }
433       }
434   /* Maintain the invariant that bb->aux is clear after use.  */
435   while (last_block)
436     {
437       bb = last_block->aux;
438       last_block->aux = NULL;
439       last_block = bb;
440     }
441 }
442
443 /* Schedule a single extended basic block, defined by the boundaries HEAD
444    and TAIL.  */
445
446 static basic_block
447 schedule_ebb (rtx head, rtx tail)
448 {
449   basic_block first_bb, target_bb;
450   struct deps tmp_deps;
451   
452   first_bb = BLOCK_FOR_INSN (head);
453   last_bb = BLOCK_FOR_INSN (tail);
454
455   if (no_real_insns_p (head, tail))
456     return BLOCK_FOR_INSN (tail);
457
458   gcc_assert (INSN_P (head) && INSN_P (tail));
459
460   if (!bitmap_bit_p (&dont_calc_deps, first_bb->index))
461     {
462       init_deps_global ();
463
464       /* Compute dependencies.  */
465       init_deps (&tmp_deps);
466       sched_analyze (&tmp_deps, head, tail);
467       free_deps (&tmp_deps);
468
469       add_deps_for_risky_insns (head, tail);
470
471       if (targetm.sched.dependencies_evaluation_hook)
472         targetm.sched.dependencies_evaluation_hook (head, tail);
473
474       finish_deps_global ();
475     }
476   else
477     /* Only recovery blocks can have their dependencies already calculated,
478        and they always are single block ebbs.  */       
479     gcc_assert (first_bb == last_bb);
480
481   /* Set priorities.  */
482   current_sched_info->sched_max_insns_priority = 0;
483   n_insns = set_priorities (head, tail);
484   current_sched_info->sched_max_insns_priority++;
485
486   current_sched_info->prev_head = PREV_INSN (head);
487   current_sched_info->next_tail = NEXT_INSN (tail);
488
489   /* rm_other_notes only removes notes which are _inside_ the
490      block---that is, it won't remove notes before the first real insn
491      or after the last real insn of the block.  So if the first insn
492      has a REG_SAVE_NOTE which would otherwise be emitted before the
493      insn, it is redundant with the note before the start of the
494      block, and so we have to take it out.  */
495   if (INSN_P (head))
496     {
497       rtx note;
498
499       for (note = REG_NOTES (head); note; note = XEXP (note, 1))
500         if (REG_NOTE_KIND (note) == REG_SAVE_NOTE)
501           remove_note (head, note);
502     }
503
504   /* Remove remaining note insns from the block, save them in
505      note_list.  These notes are restored at the end of
506      schedule_block ().  */
507   rm_other_notes (head, tail);
508
509   unlink_bb_notes (first_bb, last_bb);
510
511   current_sched_info->queue_must_finish_empty = 1;
512
513   target_bb = first_bb;
514   schedule_block (&target_bb, n_insns);
515
516   /* We might pack all instructions into fewer blocks,
517      so we may made some of them empty.  Can't assert (b == last_bb).  */
518   
519   /* Sanity check: verify that all region insns were scheduled.  */
520   gcc_assert (sched_n_insns == n_insns);
521
522   /* Free dependencies.  */
523   sched_free_deps (current_sched_info->head, current_sched_info->tail, true);
524
525   gcc_assert (haifa_recovery_bb_ever_added_p
526               || deps_pools_are_empty_p ());
527
528   if (EDGE_COUNT (last_bb->preds) == 0)
529     /* LAST_BB is unreachable.  */
530     {
531       gcc_assert (first_bb != last_bb
532                   && EDGE_COUNT (last_bb->succs) == 0);
533       last_bb = last_bb->prev_bb;
534       delete_basic_block (last_bb->next_bb);
535     }
536
537   return last_bb;
538 }
539
540 /* The one entry point in this file.  */
541
542 void
543 schedule_ebbs (void)
544 {
545   basic_block bb;
546   int probability_cutoff;
547   rtx tail;
548
549   if (profile_info && flag_branch_probabilities)
550     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY_FEEDBACK);
551   else
552     probability_cutoff = PARAM_VALUE (TRACER_MIN_BRANCH_PROBABILITY);
553   probability_cutoff = REG_BR_PROB_BASE / 100 * probability_cutoff;
554
555   /* Taking care of this degenerate case makes the rest of
556      this code simpler.  */
557   if (n_basic_blocks == NUM_FIXED_BLOCKS)
558     return;
559
560   /* We need current_sched_info in init_dependency_caches, which is
561      invoked via sched_init.  */
562   current_sched_info = &ebb_sched_info;
563
564   df_set_flags (DF_LR_RUN_DCE);
565   df_note_add_problem ();
566   df_analyze ();
567   df_clear_flags (DF_LR_RUN_DCE);
568   regstat_compute_calls_crossed ();
569   sched_init ();
570
571   compute_bb_for_insn ();
572
573   /* Initialize DONT_CALC_DEPS and ebb-{start, end} markers.  */
574   bitmap_initialize (&dont_calc_deps, 0);
575   bitmap_clear (&dont_calc_deps);
576
577   /* Schedule every region in the subroutine.  */
578   FOR_EACH_BB (bb)
579     {
580       rtx head = BB_HEAD (bb);
581
582       for (;;)
583         {
584           edge e;
585           edge_iterator ei;
586           tail = BB_END (bb);
587           if (bb->next_bb == EXIT_BLOCK_PTR
588               || LABEL_P (BB_HEAD (bb->next_bb)))
589             break;
590           FOR_EACH_EDGE (e, ei, bb->succs)
591             if ((e->flags & EDGE_FALLTHRU) != 0)
592               break;
593           if (! e)
594             break;
595           if (e->probability <= probability_cutoff)
596             break;
597           bb = bb->next_bb;
598         }
599
600       /* Blah.  We should fix the rest of the code not to get confused by
601          a note or two.  */
602       while (head != tail)
603         {
604           if (NOTE_P (head))
605             head = NEXT_INSN (head);
606           else if (NOTE_P (tail))
607             tail = PREV_INSN (tail);
608           else if (LABEL_P (head))
609             head = NEXT_INSN (head);
610           else
611             break;
612         }
613
614       bb = schedule_ebb (head, tail);
615     }
616   bitmap_clear (&dont_calc_deps);
617
618   /* Reposition the prologue and epilogue notes in case we moved the
619      prologue/epilogue insns.  */
620   if (reload_completed)
621     reposition_prologue_and_epilogue_notes ();
622
623   sched_finish ();
624   regstat_free_calls_crossed ();
625 }
626
627 /* INSN has been added to/removed from current ebb.  */
628 static void
629 add_remove_insn (rtx insn ATTRIBUTE_UNUSED, int remove_p)
630 {
631   if (!remove_p)
632     n_insns++;
633   else
634     n_insns--;
635 }
636
637 /* BB was added to ebb after AFTER.  */
638 static void
639 add_block1 (basic_block bb, basic_block after)
640 {
641   /* Recovery blocks are always bounded by BARRIERS, 
642      therefore, they always form single block EBB,
643      therefore, we can use rec->index to identify such EBBs.  */
644   if (after == EXIT_BLOCK_PTR)
645     bitmap_set_bit (&dont_calc_deps, bb->index);
646   else if (after == last_bb)
647     last_bb = bb;
648 }
649
650 /* Return next block in ebb chain.  For parameter meaning please refer to
651    sched-int.h: struct sched_info: advance_target_bb.  */
652 static basic_block
653 advance_target_bb (basic_block bb, rtx insn)
654 {
655   if (insn)
656     {
657       if (BLOCK_FOR_INSN (insn) != bb
658           && control_flow_insn_p (insn)
659           /* We handle interblock movement of the speculation check
660              or over a speculation check in
661              haifa-sched.c: move_block_after_check ().  */
662           && !IS_SPECULATION_BRANCHY_CHECK_P (insn)
663           && !IS_SPECULATION_BRANCHY_CHECK_P (BB_END (bb)))
664         {
665           /* Assert that we don't move jumps across blocks.  */
666           gcc_assert (!control_flow_insn_p (BB_END (bb))
667                       && NOTE_INSN_BASIC_BLOCK_P (BB_HEAD (bb->next_bb)));
668           return bb;
669         }
670       else
671         return 0;
672     }
673   else
674     /* Return next non empty block.  */
675     {
676       do
677         {
678           gcc_assert (bb != last_bb);
679
680           bb = bb->next_bb;
681         }
682       while (bb_note (bb) == BB_END (bb));
683
684       return bb;
685     }
686 }
687
688 /* Fix internal data after interblock movement of jump instruction.
689    For parameter meaning please refer to
690    sched-int.h: struct sched_info: fix_recovery_cfg.  */
691 static void
692 fix_recovery_cfg (int bbi ATTRIBUTE_UNUSED, int jump_bbi, int jump_bb_nexti)
693 {
694   gcc_assert (last_bb->index != bbi);
695
696   if (jump_bb_nexti == last_bb->index)
697     last_bb = BASIC_BLOCK (jump_bbi);
698 }