OSDN Git Service

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