Merge branch 'vendor/GDB' into gdb7
[dragonfly.git] / contrib / gcc-4.4 / gcc / sel-sched-ir.c
1 /* Instruction scheduling pass.  Selective scheduler and pipeliner.
2    Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
3
4 This file is part of GCC.
5
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
9 version.
10
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3.  If not see
18 <http://www.gnu.org/licenses/>.  */
19
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "tm.h"
24 #include "toplev.h"
25 #include "rtl.h"
26 #include "tm_p.h"
27 #include "hard-reg-set.h"
28 #include "regs.h"
29 #include "function.h"
30 #include "flags.h"
31 #include "insn-config.h"
32 #include "insn-attr.h"
33 #include "except.h"
34 #include "toplev.h"
35 #include "recog.h"
36 #include "params.h"
37 #include "target.h"
38 #include "timevar.h"
39 #include "tree-pass.h"
40 #include "sched-int.h"
41 #include "ggc.h"
42 #include "tree.h"
43 #include "vec.h"
44 #include "langhooks.h"
45 #include "rtlhooks-def.h"
46
47 #ifdef INSN_SCHEDULING
48 #include "sel-sched-ir.h"
49 /* We don't have to use it except for sel_print_insn.  */
50 #include "sel-sched-dump.h"
51
52 /* A vector holding bb info for whole scheduling pass.  */
53 VEC(sel_global_bb_info_def, heap) *sel_global_bb_info = NULL;
54
55 /* A vector holding bb info.  */
56 VEC(sel_region_bb_info_def, heap) *sel_region_bb_info = NULL;
57
58 /* A pool for allocating all lists.  */
59 alloc_pool sched_lists_pool;
60
61 /* This contains information about successors for compute_av_set.  */
62 struct succs_info current_succs;
63
64 /* Data structure to describe interaction with the generic scheduler utils.  */
65 static struct common_sched_info_def sel_common_sched_info;
66
67 /* The loop nest being pipelined.  */
68 struct loop *current_loop_nest;
69
70 /* LOOP_NESTS is a vector containing the corresponding loop nest for
71    each region.  */
72 static VEC(loop_p, heap) *loop_nests = NULL;
73
74 /* Saves blocks already in loop regions, indexed by bb->index.  */
75 static sbitmap bbs_in_loop_rgns = NULL;
76
77 /* CFG hooks that are saved before changing create_basic_block hook.  */
78 static struct cfg_hooks orig_cfg_hooks;
79 \f
80
81 /* Array containing reverse topological index of function basic blocks,
82    indexed by BB->INDEX.  */
83 static int *rev_top_order_index = NULL;
84
85 /* Length of the above array.  */
86 static int rev_top_order_index_len = -1;
87
88 /* A regset pool structure.  */
89 static struct
90 {
91   /* The stack to which regsets are returned.  */
92   regset *v;
93
94   /* Its pointer.  */
95   int n;
96
97   /* Its size.  */
98   int s;
99
100   /* In VV we save all generated regsets so that, when destructing the
101      pool, we can compare it with V and check that every regset was returned
102      back to pool.  */
103   regset *vv;
104
105   /* The pointer of VV stack.  */
106   int nn;
107
108   /* Its size.  */
109   int ss;
110
111   /* The difference between allocated and returned regsets.  */
112   int diff;
113 } regset_pool = { NULL, 0, 0, NULL, 0, 0, 0 };
114
115 /* This represents the nop pool.  */
116 static struct
117 {
118   /* The vector which holds previously emitted nops.  */
119   insn_t *v;
120
121   /* Its pointer.  */
122   int n;
123
124   /* Its size.  */
125   int s;  
126 } nop_pool = { NULL, 0, 0 };
127
128 /* The pool for basic block notes.  */
129 static rtx_vec_t bb_note_pool;
130
131 /* A NOP pattern used to emit placeholder insns.  */
132 rtx nop_pattern = NULL_RTX;
133 /* A special instruction that resides in EXIT_BLOCK.
134    EXIT_INSN is successor of the insns that lead to EXIT_BLOCK.  */
135 rtx exit_insn = NULL_RTX;
136
137 /* TRUE if while scheduling current region, which is loop, its preheader 
138    was removed.  */
139 bool preheader_removed = false;
140 \f
141
142 /* Forward static declarations.  */
143 static void fence_clear (fence_t);
144
145 static void deps_init_id (idata_t, insn_t, bool);
146 static void init_id_from_df (idata_t, insn_t, bool);
147 static expr_t set_insn_init (expr_t, vinsn_t, int);
148
149 static void cfg_preds (basic_block, insn_t **, int *);
150 static void prepare_insn_expr (insn_t, int);
151 static void free_history_vect (VEC (expr_history_def, heap) **);
152
153 static void move_bb_info (basic_block, basic_block);
154 static void remove_empty_bb (basic_block, bool);
155 static void sel_remove_loop_preheader (void);
156
157 static bool insn_is_the_only_one_in_bb_p (insn_t);
158 static void create_initial_data_sets (basic_block);
159
160 static void invalidate_av_set (basic_block);
161 static void extend_insn_data (void);
162 static void sel_init_new_insn (insn_t, int);
163 static void finish_insns (void);
164 \f
165 /* Various list functions.  */
166
167 /* Copy an instruction list L.  */
168 ilist_t
169 ilist_copy (ilist_t l)
170 {
171   ilist_t head = NULL, *tailp = &head;
172
173   while (l)
174     {
175       ilist_add (tailp, ILIST_INSN (l));
176       tailp = &ILIST_NEXT (*tailp);
177       l = ILIST_NEXT (l);
178     }
179
180   return head;
181 }
182
183 /* Invert an instruction list L.  */
184 ilist_t
185 ilist_invert (ilist_t l)
186 {
187   ilist_t res = NULL;
188
189   while (l)
190     {
191       ilist_add (&res, ILIST_INSN (l));
192       l = ILIST_NEXT (l);
193     }
194
195   return res;
196 }
197
198 /* Add a new boundary to the LP list with parameters TO, PTR, and DC.  */
199 void
200 blist_add (blist_t *lp, insn_t to, ilist_t ptr, deps_t dc)
201 {
202   bnd_t bnd;
203
204   _list_add (lp);
205   bnd = BLIST_BND (*lp);
206
207   BND_TO (bnd) = to;
208   BND_PTR (bnd) = ptr;
209   BND_AV (bnd) = NULL;
210   BND_AV1 (bnd) = NULL;
211   BND_DC (bnd) = dc;
212 }
213
214 /* Remove the list note pointed to by LP.  */
215 void
216 blist_remove (blist_t *lp)
217 {
218   bnd_t b = BLIST_BND (*lp);
219
220   av_set_clear (&BND_AV (b));
221   av_set_clear (&BND_AV1 (b));
222   ilist_clear (&BND_PTR (b));
223
224   _list_remove (lp);
225 }
226
227 /* Init a fence tail L.  */
228 void
229 flist_tail_init (flist_tail_t l)
230 {
231   FLIST_TAIL_HEAD (l) = NULL;
232   FLIST_TAIL_TAILP (l) = &FLIST_TAIL_HEAD (l);
233 }
234
235 /* Try to find fence corresponding to INSN in L.  */
236 fence_t
237 flist_lookup (flist_t l, insn_t insn)
238 {
239   while (l)
240     {
241       if (FENCE_INSN (FLIST_FENCE (l)) == insn)
242         return FLIST_FENCE (l);
243
244       l = FLIST_NEXT (l);
245     }
246
247   return NULL;
248 }
249
250 /* Init the fields of F before running fill_insns.  */
251 static void
252 init_fence_for_scheduling (fence_t f)
253 {
254   FENCE_BNDS (f) = NULL;
255   FENCE_PROCESSED_P (f) = false;
256   FENCE_SCHEDULED_P (f) = false;
257 }
258
259 /* Add new fence consisting of INSN and STATE to the list pointed to by LP.  */
260 static void
261 flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc, 
262            insn_t last_scheduled_insn, VEC(rtx,gc) *executing_insns, 
263            int *ready_ticks, int ready_ticks_size, insn_t sched_next, 
264            int cycle, int cycle_issued_insns, 
265            bool starts_cycle_p, bool after_stall_p)
266 {
267   fence_t f;
268
269   _list_add (lp);
270   f = FLIST_FENCE (*lp);
271
272   FENCE_INSN (f) = insn;
273
274   gcc_assert (state != NULL);
275   FENCE_STATE (f) = state;
276
277   FENCE_CYCLE (f) = cycle;
278   FENCE_ISSUED_INSNS (f) = cycle_issued_insns;
279   FENCE_STARTS_CYCLE_P (f) = starts_cycle_p;
280   FENCE_AFTER_STALL_P (f) = after_stall_p;
281
282   gcc_assert (dc != NULL);
283   FENCE_DC (f) = dc;
284
285   gcc_assert (tc != NULL || targetm.sched.alloc_sched_context == NULL);
286   FENCE_TC (f) = tc;
287
288   FENCE_LAST_SCHEDULED_INSN (f) = last_scheduled_insn;
289   FENCE_EXECUTING_INSNS (f) = executing_insns;
290   FENCE_READY_TICKS (f) = ready_ticks;
291   FENCE_READY_TICKS_SIZE (f) = ready_ticks_size;
292   FENCE_SCHED_NEXT (f) = sched_next;
293
294   init_fence_for_scheduling (f);
295 }
296
297 /* Remove the head node of the list pointed to by LP.  */
298 static void
299 flist_remove (flist_t *lp)
300 {
301   if (FENCE_INSN (FLIST_FENCE (*lp)))
302     fence_clear (FLIST_FENCE (*lp));
303   _list_remove (lp);
304 }
305
306 /* Clear the fence list pointed to by LP.  */
307 void
308 flist_clear (flist_t *lp)
309 {
310   while (*lp)
311     flist_remove (lp);
312 }
313
314 /* Add ORIGINAL_INSN the def list DL honoring CROSSES_CALL.  */
315 void
316 def_list_add (def_list_t *dl, insn_t original_insn, bool crosses_call)
317 {
318   def_t d;
319   
320   _list_add (dl);
321   d = DEF_LIST_DEF (*dl);
322
323   d->orig_insn = original_insn;
324   d->crosses_call = crosses_call;
325 }
326 \f
327
328 /* Functions to work with target contexts.  */
329
330 /* Bulk target context.  It is convenient for debugging purposes to ensure 
331    that there are no uninitialized (null) target contexts.  */
332 static tc_t bulk_tc = (tc_t) 1;
333
334 /* Target hooks wrappers.  In the future we can provide some default 
335    implementations for them.  */
336
337 /* Allocate a store for the target context.  */
338 static tc_t
339 alloc_target_context (void)
340 {
341   return (targetm.sched.alloc_sched_context
342           ? targetm.sched.alloc_sched_context () : bulk_tc);
343 }
344
345 /* Init target context TC.
346    If CLEAN_P is true, then make TC as it is beginning of the scheduler.
347    Overwise, copy current backend context to TC.  */
348 static void
349 init_target_context (tc_t tc, bool clean_p)
350 {
351   if (targetm.sched.init_sched_context)
352     targetm.sched.init_sched_context (tc, clean_p);
353 }
354
355 /* Allocate and initialize a target context.  Meaning of CLEAN_P is the same as
356    int init_target_context ().  */
357 tc_t
358 create_target_context (bool clean_p)
359 {
360   tc_t tc = alloc_target_context ();
361
362   init_target_context (tc, clean_p);
363   return tc;
364 }
365
366 /* Copy TC to the current backend context.  */
367 void
368 set_target_context (tc_t tc)
369 {
370   if (targetm.sched.set_sched_context)
371     targetm.sched.set_sched_context (tc);
372 }
373
374 /* TC is about to be destroyed.  Free any internal data.  */
375 static void
376 clear_target_context (tc_t tc)
377 {
378   if (targetm.sched.clear_sched_context)
379     targetm.sched.clear_sched_context (tc);
380 }
381
382 /*  Clear and free it.  */
383 static void
384 delete_target_context (tc_t tc)
385 {
386   clear_target_context (tc);
387
388   if (targetm.sched.free_sched_context)
389     targetm.sched.free_sched_context (tc);
390 }
391
392 /* Make a copy of FROM in TO.
393    NB: May be this should be a hook.  */
394 static void
395 copy_target_context (tc_t to, tc_t from)
396 {
397   tc_t tmp = create_target_context (false);
398
399   set_target_context (from);
400   init_target_context (to, false);
401
402   set_target_context (tmp);
403   delete_target_context (tmp);
404 }
405
406 /* Create a copy of TC.  */
407 static tc_t
408 create_copy_of_target_context (tc_t tc)
409 {
410   tc_t copy = alloc_target_context ();
411
412   copy_target_context (copy, tc);
413
414   return copy;
415 }
416
417 /* Clear TC and initialize it according to CLEAN_P.  The meaning of CLEAN_P
418    is the same as in init_target_context ().  */
419 void
420 reset_target_context (tc_t tc, bool clean_p)
421 {
422   clear_target_context (tc);
423   init_target_context (tc, clean_p);
424 }
425 \f
426 /* Functions to work with dependence contexts. 
427    Dc (aka deps context, aka deps_t, aka struct deps *) is short for dependence
428    context.  It accumulates information about processed insns to decide if
429    current insn is dependent on the processed ones.  */
430
431 /* Make a copy of FROM in TO.  */
432 static void
433 copy_deps_context (deps_t to, deps_t from)
434 {
435   init_deps (to);
436   deps_join (to, from);
437 }
438
439 /* Allocate store for dep context.  */
440 static deps_t
441 alloc_deps_context (void)
442 {
443   return XNEW (struct deps);
444 }
445
446 /* Allocate and initialize dep context.  */
447 static deps_t
448 create_deps_context (void)
449 {
450   deps_t dc = alloc_deps_context ();
451
452   init_deps (dc);
453   return dc;
454 }
455
456 /* Create a copy of FROM.  */
457 static deps_t
458 create_copy_of_deps_context (deps_t from)
459 {
460   deps_t to = alloc_deps_context ();
461
462   copy_deps_context (to, from);
463   return to;
464 }
465
466 /* Clean up internal data of DC.  */
467 static void
468 clear_deps_context (deps_t dc)
469 {
470   free_deps (dc);
471 }
472
473 /* Clear and free DC.  */
474 static void
475 delete_deps_context (deps_t dc)
476 {
477   clear_deps_context (dc);
478   free (dc);
479 }
480
481 /* Clear and init DC.  */
482 static void
483 reset_deps_context (deps_t dc)
484 {
485   clear_deps_context (dc);
486   init_deps (dc);
487 }
488
489 /* This structure describes the dependence analysis hooks for advancing 
490    dependence context.  */
491 static struct sched_deps_info_def advance_deps_context_sched_deps_info =
492   {
493     NULL,
494
495     NULL, /* start_insn */
496     NULL, /* finish_insn */
497     NULL, /* start_lhs */
498     NULL, /* finish_lhs */
499     NULL, /* start_rhs */
500     NULL, /* finish_rhs */
501     haifa_note_reg_set,
502     haifa_note_reg_clobber,
503     haifa_note_reg_use,
504     NULL, /* note_mem_dep */
505     NULL, /* note_dep */
506
507     0, 0, 0
508   };
509
510 /* Process INSN and add its impact on DC.  */
511 void
512 advance_deps_context (deps_t dc, insn_t insn)
513 {
514   sched_deps_info = &advance_deps_context_sched_deps_info;
515   deps_analyze_insn (dc, insn);
516 }
517 \f
518
519 /* Functions to work with DFA states.  */
520
521 /* Allocate store for a DFA state.  */
522 static state_t
523 state_alloc (void)
524 {
525   return xmalloc (dfa_state_size);
526 }
527
528 /* Allocate and initialize DFA state.  */
529 static state_t
530 state_create (void)
531 {
532   state_t state = state_alloc ();
533
534   state_reset (state);
535   advance_state (state);
536   return state;
537 }
538
539 /* Free DFA state.  */
540 static void
541 state_free (state_t state)
542 {
543   free (state);
544 }
545
546 /* Make a copy of FROM in TO.  */
547 static void
548 state_copy (state_t to, state_t from)
549 {
550   memcpy (to, from, dfa_state_size);
551 }
552
553 /* Create a copy of FROM.  */
554 static state_t
555 state_create_copy (state_t from)
556 {
557   state_t to = state_alloc ();
558
559   state_copy (to, from);
560   return to;
561 }
562 \f
563
564 /* Functions to work with fences.  */
565
566 /* Clear the fence.  */
567 static void
568 fence_clear (fence_t f)
569 {
570   state_t s = FENCE_STATE (f);
571   deps_t dc = FENCE_DC (f);
572   void *tc = FENCE_TC (f);
573
574   ilist_clear (&FENCE_BNDS (f));
575
576   gcc_assert ((s != NULL && dc != NULL && tc != NULL)
577               || (s == NULL && dc == NULL && tc == NULL));
578
579   if (s != NULL)
580     free (s);
581
582   if (dc != NULL)
583     delete_deps_context (dc);
584
585   if (tc != NULL)
586     delete_target_context (tc);
587   VEC_free (rtx, gc, FENCE_EXECUTING_INSNS (f));
588   free (FENCE_READY_TICKS (f));
589   FENCE_READY_TICKS (f) = NULL;
590 }
591
592 /* Init a list of fences with successors of OLD_FENCE.  */
593 void
594 init_fences (insn_t old_fence)
595 {
596   insn_t succ;
597   succ_iterator si;
598   bool first = true;
599   int ready_ticks_size = get_max_uid () + 1;
600       
601   FOR_EACH_SUCC_1 (succ, si, old_fence, 
602                    SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
603     {
604       
605       if (first)
606         first = false;
607       else
608         gcc_assert (flag_sel_sched_pipelining_outer_loops);
609
610       flist_add (&fences, succ,
611                  state_create (),
612                  create_deps_context () /* dc */,
613                  create_target_context (true) /* tc */,
614                  NULL_RTX /* last_scheduled_insn */, 
615                  NULL, /* executing_insns */
616                  XCNEWVEC (int, ready_ticks_size), /* ready_ticks */
617                  ready_ticks_size,
618                  NULL_RTX /* sched_next */,
619                  1 /* cycle */, 0 /* cycle_issued_insns */, 
620                  1 /* starts_cycle_p */, 0 /* after_stall_p */);  
621     }
622 }
623
624 /* Merges two fences (filling fields of fence F with resulting values) by
625    following rules: 1) state, target context and last scheduled insn are
626    propagated from fallthrough edge if it is available; 
627    2) deps context and cycle is propagated from more probable edge;
628    3) all other fields are set to corresponding constant values.  
629
630    INSN, STATE, DC, TC, LAST_SCHEDULED_INSN, EXECUTING_INSNS, 
631    READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE and AFTER_STALL_P
632    are the corresponding fields of the second fence.  */
633 static void
634 merge_fences (fence_t f, insn_t insn,
635               state_t state, deps_t dc, void *tc, 
636               rtx last_scheduled_insn, VEC(rtx, gc) *executing_insns,
637               int *ready_ticks, int ready_ticks_size,
638               rtx sched_next, int cycle, bool after_stall_p)
639 {
640   insn_t last_scheduled_insn_old = FENCE_LAST_SCHEDULED_INSN (f);
641
642   gcc_assert (sel_bb_head_p (FENCE_INSN (f))
643               && !sched_next && !FENCE_SCHED_NEXT (f));
644
645   /* Check if we can decide which path fences came.  
646      If we can't (or don't want to) - reset all.  */
647   if (last_scheduled_insn == NULL
648       || last_scheduled_insn_old == NULL
649       /* This is a case when INSN is reachable on several paths from 
650          one insn (this can happen when pipelining of outer loops is on and 
651          there are two edges: one going around of inner loop and the other - 
652          right through it; in such case just reset everything).  */
653       || last_scheduled_insn == last_scheduled_insn_old)
654     {
655       state_reset (FENCE_STATE (f));
656       state_free (state);
657   
658       reset_deps_context (FENCE_DC (f));
659       delete_deps_context (dc);
660   
661       reset_target_context (FENCE_TC (f), true);
662       delete_target_context (tc);
663
664       if (cycle > FENCE_CYCLE (f))
665         FENCE_CYCLE (f) = cycle;
666
667       FENCE_LAST_SCHEDULED_INSN (f) = NULL;
668       VEC_free (rtx, gc, executing_insns);
669       free (ready_ticks);
670       if (FENCE_EXECUTING_INSNS (f))
671         VEC_block_remove (rtx, FENCE_EXECUTING_INSNS (f), 0, 
672                           VEC_length (rtx, FENCE_EXECUTING_INSNS (f)));
673       if (FENCE_READY_TICKS (f))
674         memset (FENCE_READY_TICKS (f), 0, FENCE_READY_TICKS_SIZE (f));
675     }
676   else
677     {
678       edge edge_old = NULL, edge_new = NULL;
679       edge candidate;
680       succ_iterator si;
681       insn_t succ;
682     
683       /* Find fallthrough edge.  */
684       gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb);
685       candidate = find_fallthru_edge (BLOCK_FOR_INSN (insn)->prev_bb);
686
687       if (!candidate
688           || (candidate->src != BLOCK_FOR_INSN (last_scheduled_insn)
689               && candidate->src != BLOCK_FOR_INSN (last_scheduled_insn_old)))
690         {
691           /* No fallthrough edge leading to basic block of INSN.  */
692           state_reset (FENCE_STATE (f));
693           state_free (state);
694   
695           reset_target_context (FENCE_TC (f), true);
696           delete_target_context (tc);
697   
698           FENCE_LAST_SCHEDULED_INSN (f) = NULL;
699         }
700       else
701         if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn))
702           {
703             /* Would be weird if same insn is successor of several fallthrough 
704                edges.  */
705             gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb
706                         != BLOCK_FOR_INSN (last_scheduled_insn_old));
707
708             state_free (FENCE_STATE (f));
709             FENCE_STATE (f) = state;
710
711             delete_target_context (FENCE_TC (f));
712             FENCE_TC (f) = tc;
713
714             FENCE_LAST_SCHEDULED_INSN (f) = last_scheduled_insn;
715           }
716         else
717           {
718             /* Leave STATE, TC and LAST_SCHEDULED_INSN fields untouched.  */
719             state_free (state);
720             delete_target_context (tc);
721
722             gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb
723                         != BLOCK_FOR_INSN (last_scheduled_insn));
724           }
725
726         /* Find edge of first predecessor (last_scheduled_insn_old->insn).  */
727         FOR_EACH_SUCC_1 (succ, si, last_scheduled_insn_old,
728                          SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
729           {
730             if (succ == insn)
731               {
732                 /* No same successor allowed from several edges.  */
733                 gcc_assert (!edge_old);
734                 edge_old = si.e1;
735               }
736           }
737         /* Find edge of second predecessor (last_scheduled_insn->insn).  */
738         FOR_EACH_SUCC_1 (succ, si, last_scheduled_insn,
739                          SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
740           {
741             if (succ == insn)
742               {
743                 /* No same successor allowed from several edges.  */
744                 gcc_assert (!edge_new);
745                 edge_new = si.e1;
746               }
747           }
748
749         /* Check if we can choose most probable predecessor.  */
750         if (edge_old == NULL || edge_new == NULL)
751           {
752             reset_deps_context (FENCE_DC (f));
753             delete_deps_context (dc);
754             VEC_free (rtx, gc, executing_insns);
755             free (ready_ticks);
756   
757             FENCE_CYCLE (f) = MAX (FENCE_CYCLE (f), cycle);
758             if (FENCE_EXECUTING_INSNS (f))
759               VEC_block_remove (rtx, FENCE_EXECUTING_INSNS (f), 0, 
760                                 VEC_length (rtx, FENCE_EXECUTING_INSNS (f)));
761             if (FENCE_READY_TICKS (f))
762               memset (FENCE_READY_TICKS (f), 0, FENCE_READY_TICKS_SIZE (f));
763           }
764         else
765           if (edge_new->probability > edge_old->probability)
766             {
767               delete_deps_context (FENCE_DC (f));
768               FENCE_DC (f) = dc;
769               VEC_free (rtx, gc, FENCE_EXECUTING_INSNS (f));
770               FENCE_EXECUTING_INSNS (f) = executing_insns;
771               free (FENCE_READY_TICKS (f));
772               FENCE_READY_TICKS (f) = ready_ticks;
773               FENCE_READY_TICKS_SIZE (f) = ready_ticks_size;
774               FENCE_CYCLE (f) = cycle;
775             }
776           else
777             {
778               /* Leave DC and CYCLE untouched.  */
779               delete_deps_context (dc);
780               VEC_free (rtx, gc, executing_insns);
781               free (ready_ticks);
782             }
783     }
784
785   /* Fill remaining invariant fields.  */
786   if (after_stall_p)
787     FENCE_AFTER_STALL_P (f) = 1;
788
789   FENCE_ISSUED_INSNS (f) = 0;
790   FENCE_STARTS_CYCLE_P (f) = 1;
791   FENCE_SCHED_NEXT (f) = NULL;
792 }
793
794 /* Add a new fence to NEW_FENCES list, initializing it from all 
795    other parameters.  */
796 static void
797 add_to_fences (flist_tail_t new_fences, insn_t insn,
798                state_t state, deps_t dc, void *tc, rtx last_scheduled_insn, 
799                VEC(rtx, gc) *executing_insns, int *ready_ticks, 
800                int ready_ticks_size, rtx sched_next, int cycle, 
801                int cycle_issued_insns, bool starts_cycle_p, bool after_stall_p)
802 {
803   fence_t f = flist_lookup (FLIST_TAIL_HEAD (new_fences), insn);
804
805   if (! f)
806     {
807       flist_add (FLIST_TAIL_TAILP (new_fences), insn, state, dc, tc,
808                  last_scheduled_insn, executing_insns, ready_ticks, 
809                  ready_ticks_size, sched_next, cycle, cycle_issued_insns,
810                  starts_cycle_p, after_stall_p);
811
812       FLIST_TAIL_TAILP (new_fences)
813         = &FLIST_NEXT (*FLIST_TAIL_TAILP (new_fences));
814     }
815   else
816     {
817       merge_fences (f, insn, state, dc, tc, last_scheduled_insn, 
818                     executing_insns, ready_ticks, ready_ticks_size, 
819                     sched_next, cycle, after_stall_p);
820     }
821 }
822
823 /* Move the first fence in the OLD_FENCES list to NEW_FENCES.  */
824 void
825 move_fence_to_fences (flist_t old_fences, flist_tail_t new_fences)
826 {
827   fence_t f, old;
828   flist_t *tailp = FLIST_TAIL_TAILP (new_fences);
829
830   old = FLIST_FENCE (old_fences);
831   f = flist_lookup (FLIST_TAIL_HEAD (new_fences), 
832                     FENCE_INSN (FLIST_FENCE (old_fences)));
833   if (f)
834     {
835       merge_fences (f, old->insn, old->state, old->dc, old->tc,
836                     old->last_scheduled_insn, old->executing_insns,
837                     old->ready_ticks, old->ready_ticks_size,
838                     old->sched_next, old->cycle, 
839                     old->after_stall_p);
840     }
841   else
842     {
843       _list_add (tailp);
844       FLIST_TAIL_TAILP (new_fences) = &FLIST_NEXT (*tailp);
845       *FLIST_FENCE (*tailp) = *old;
846       init_fence_for_scheduling (FLIST_FENCE (*tailp));
847     }
848   FENCE_INSN (old) = NULL;
849 }
850
851 /* Add a new fence to NEW_FENCES list and initialize most of its data 
852    as a clean one.  */
853 void
854 add_clean_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence)
855 {
856   int ready_ticks_size = get_max_uid () + 1;
857   
858   add_to_fences (new_fences,
859                  succ, state_create (), create_deps_context (),
860                  create_target_context (true),
861                  NULL_RTX, NULL, 
862                  XCNEWVEC (int, ready_ticks_size), ready_ticks_size,
863                  NULL_RTX, FENCE_CYCLE (fence) + 1,
864                  0, 1, FENCE_AFTER_STALL_P (fence));
865 }
866
867 /* Add a new fence to NEW_FENCES list and initialize all of its data 
868    from FENCE and SUCC.  */
869 void
870 add_dirty_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence)
871 {
872   int * new_ready_ticks 
873     = XNEWVEC (int, FENCE_READY_TICKS_SIZE (fence));
874   
875   memcpy (new_ready_ticks, FENCE_READY_TICKS (fence),
876           FENCE_READY_TICKS_SIZE (fence) * sizeof (int));
877   add_to_fences (new_fences,
878                  succ, state_create_copy (FENCE_STATE (fence)),
879                  create_copy_of_deps_context (FENCE_DC (fence)),
880                  create_copy_of_target_context (FENCE_TC (fence)),
881                  FENCE_LAST_SCHEDULED_INSN (fence), 
882                  VEC_copy (rtx, gc, FENCE_EXECUTING_INSNS (fence)),
883                  new_ready_ticks,
884                  FENCE_READY_TICKS_SIZE (fence),
885                  FENCE_SCHED_NEXT (fence),
886                  FENCE_CYCLE (fence),
887                  FENCE_ISSUED_INSNS (fence),
888                  FENCE_STARTS_CYCLE_P (fence),
889                  FENCE_AFTER_STALL_P (fence));
890 }
891 \f
892
893 /* Functions to work with regset and nop pools.  */
894
895 /* Returns the new regset from pool.  It might have some of the bits set
896    from the previous usage.  */
897 regset
898 get_regset_from_pool (void)
899 {
900   regset rs;
901
902   if (regset_pool.n != 0)
903     rs = regset_pool.v[--regset_pool.n];
904   else
905     /* We need to create the regset.  */
906     {
907       rs = ALLOC_REG_SET (&reg_obstack);
908
909       if (regset_pool.nn == regset_pool.ss)
910         regset_pool.vv = XRESIZEVEC (regset, regset_pool.vv,
911                                      (regset_pool.ss = 2 * regset_pool.ss + 1));
912       regset_pool.vv[regset_pool.nn++] = rs;
913     }
914
915   regset_pool.diff++;
916
917   return rs;
918 }
919
920 /* Same as above, but returns the empty regset.  */
921 regset
922 get_clear_regset_from_pool (void)
923 {
924   regset rs = get_regset_from_pool ();
925
926   CLEAR_REG_SET (rs);
927   return rs;
928 }
929
930 /* Return regset RS to the pool for future use.  */
931 void
932 return_regset_to_pool (regset rs)
933 {
934   regset_pool.diff--;
935
936   if (regset_pool.n == regset_pool.s)
937     regset_pool.v = XRESIZEVEC (regset, regset_pool.v,
938                                 (regset_pool.s = 2 * regset_pool.s + 1));
939   regset_pool.v[regset_pool.n++] = rs;
940 }
941
942 #ifdef ENABLE_CHECKING
943 /* This is used as a qsort callback for sorting regset pool stacks.
944    X and XX are addresses of two regsets.  They are never equal.  */
945 static int
946 cmp_v_in_regset_pool (const void *x, const void *xx)
947 {
948   return *((const regset *) x) - *((const regset *) xx);
949 }
950 #endif
951
952 /*  Free the regset pool possibly checking for memory leaks.  */
953 void
954 free_regset_pool (void)
955 {
956 #ifdef ENABLE_CHECKING
957   {
958     regset *v = regset_pool.v;
959     int i = 0;
960     int n = regset_pool.n;
961     
962     regset *vv = regset_pool.vv;
963     int ii = 0;
964     int nn = regset_pool.nn;
965     
966     int diff = 0;
967     
968     gcc_assert (n <= nn);
969     
970     /* Sort both vectors so it will be possible to compare them.  */
971     qsort (v, n, sizeof (*v), cmp_v_in_regset_pool);
972     qsort (vv, nn, sizeof (*vv), cmp_v_in_regset_pool);
973     
974     while (ii < nn)
975       {
976         if (v[i] == vv[ii])
977           i++;
978         else
979           /* VV[II] was lost.  */
980           diff++;
981         
982         ii++;
983       }
984     
985     gcc_assert (diff == regset_pool.diff);
986   }
987 #endif
988   
989   /* If not true - we have a memory leak.  */
990   gcc_assert (regset_pool.diff == 0);
991   
992   while (regset_pool.n)
993     {
994       --regset_pool.n;
995       FREE_REG_SET (regset_pool.v[regset_pool.n]);
996     }
997
998   free (regset_pool.v);
999   regset_pool.v = NULL;
1000   regset_pool.s = 0;
1001   
1002   free (regset_pool.vv);
1003   regset_pool.vv = NULL;
1004   regset_pool.nn = 0;
1005   regset_pool.ss = 0;
1006
1007   regset_pool.diff = 0;
1008 }
1009 \f
1010
1011 /* Functions to work with nop pools.  NOP insns are used as temporary 
1012    placeholders of the insns being scheduled to allow correct update of 
1013    the data sets.  When update is finished, NOPs are deleted.  */
1014
1015 /* A vinsn that is used to represent a nop.  This vinsn is shared among all
1016    nops sel-sched generates.  */
1017 static vinsn_t nop_vinsn = NULL;
1018
1019 /* Emit a nop before INSN, taking it from pool.  */
1020 insn_t
1021 get_nop_from_pool (insn_t insn)
1022 {
1023   insn_t nop;
1024   bool old_p = nop_pool.n != 0;
1025   int flags;
1026
1027   if (old_p)
1028     nop = nop_pool.v[--nop_pool.n];
1029   else
1030     nop = nop_pattern;
1031
1032   nop = emit_insn_before (nop, insn);
1033
1034   if (old_p)
1035     flags = INSN_INIT_TODO_SSID;
1036   else
1037     flags = INSN_INIT_TODO_LUID | INSN_INIT_TODO_SSID;
1038
1039   set_insn_init (INSN_EXPR (insn), nop_vinsn, INSN_SEQNO (insn));
1040   sel_init_new_insn (nop, flags);
1041
1042   return nop;
1043 }
1044
1045 /* Remove NOP from the instruction stream and return it to the pool.  */
1046 void
1047 return_nop_to_pool (insn_t nop)
1048 {
1049   gcc_assert (INSN_IN_STREAM_P (nop));
1050   sel_remove_insn (nop, false, true);
1051
1052   if (nop_pool.n == nop_pool.s)
1053     nop_pool.v = XRESIZEVEC (rtx, nop_pool.v, 
1054                              (nop_pool.s = 2 * nop_pool.s + 1));
1055   nop_pool.v[nop_pool.n++] = nop;
1056 }
1057
1058 /* Free the nop pool.  */
1059 void
1060 free_nop_pool (void)
1061 {
1062   nop_pool.n = 0;
1063   nop_pool.s = 0;
1064   free (nop_pool.v);
1065   nop_pool.v = NULL;
1066 }
1067 \f
1068
1069 /* Skip unspec to support ia64 speculation. Called from rtx_equal_p_cb.  
1070    The callback is given two rtxes XX and YY and writes the new rtxes
1071    to NX and NY in case some needs to be skipped.  */
1072 static int
1073 skip_unspecs_callback (const_rtx *xx, const_rtx *yy, rtx *nx, rtx* ny)
1074 {
1075   const_rtx x = *xx;
1076   const_rtx y = *yy;
1077   
1078   if (GET_CODE (x) == UNSPEC
1079       && (targetm.sched.skip_rtx_p == NULL
1080           || targetm.sched.skip_rtx_p (x)))
1081     {
1082       *nx = XVECEXP (x, 0, 0);
1083       *ny = CONST_CAST_RTX (y);
1084       return 1;
1085     }
1086   
1087   if (GET_CODE (y) == UNSPEC
1088       && (targetm.sched.skip_rtx_p == NULL
1089           || targetm.sched.skip_rtx_p (y)))
1090     {
1091       *nx = CONST_CAST_RTX (x);
1092       *ny = XVECEXP (y, 0, 0);
1093       return 1;
1094     }
1095   
1096   return 0;
1097 }
1098
1099 /* Callback, called from hash_rtx_cb.  Helps to hash UNSPEC rtx X in a correct way 
1100    to support ia64 speculation.  When changes are needed, new rtx X and new mode
1101    NMODE are written, and the callback returns true.  */
1102 static int
1103 hash_with_unspec_callback (const_rtx x, enum machine_mode mode ATTRIBUTE_UNUSED,
1104                            rtx *nx, enum machine_mode* nmode)
1105 {
1106   if (GET_CODE (x) == UNSPEC 
1107       && targetm.sched.skip_rtx_p
1108       && targetm.sched.skip_rtx_p (x))
1109     {
1110       *nx = XVECEXP (x, 0 ,0);
1111       *nmode = 0;
1112       return 1;
1113     }
1114   
1115   return 0;
1116 }
1117
1118 /* Returns LHS and RHS are ok to be scheduled separately.  */
1119 static bool
1120 lhs_and_rhs_separable_p (rtx lhs, rtx rhs)
1121 {
1122   if (lhs == NULL || rhs == NULL)
1123     return false;
1124
1125   /* Do not schedule CONST, CONST_INT and CONST_DOUBLE etc as rhs: no point 
1126      to use reg, if const can be used.  Moreover, scheduling const as rhs may 
1127      lead to mode mismatch cause consts don't have modes but they could be 
1128      merged from branches where the same const used in different modes.  */
1129   if (CONSTANT_P (rhs))
1130     return false;
1131
1132   /* ??? Do not rename predicate registers to avoid ICEs in bundling.  */
1133   if (COMPARISON_P (rhs))
1134       return false;
1135
1136   /* Do not allow single REG to be an rhs.  */
1137   if (REG_P (rhs))
1138     return false;
1139
1140   /* See comment at find_used_regs_1 (*1) for explanation of this 
1141      restriction.  */
1142   /* FIXME: remove this later.  */
1143   if (MEM_P (lhs))
1144     return false;
1145
1146   /* This will filter all tricky things like ZERO_EXTRACT etc.
1147      For now we don't handle it.  */
1148   if (!REG_P (lhs) && !MEM_P (lhs))
1149     return false;
1150
1151   return true;
1152 }
1153
1154 /* Initialize vinsn VI for INSN.  Only for use from vinsn_create ().  When 
1155    FORCE_UNIQUE_P is true, the resulting vinsn will not be clonable.  This is 
1156    used e.g. for insns from recovery blocks.  */
1157 static void
1158 vinsn_init (vinsn_t vi, insn_t insn, bool force_unique_p)
1159 {
1160   hash_rtx_callback_function hrcf;
1161   int insn_class;
1162
1163   VINSN_INSN_RTX (vi) = insn;
1164   VINSN_COUNT (vi) = 0;
1165   vi->cost = -1;
1166   
1167   if (DF_INSN_UID_SAFE_GET (INSN_UID (insn)) != NULL)
1168     init_id_from_df (VINSN_ID (vi), insn, force_unique_p);
1169   else
1170     deps_init_id (VINSN_ID (vi), insn, force_unique_p);
1171   
1172   /* Hash vinsn depending on whether it is separable or not.  */
1173   hrcf = targetm.sched.skip_rtx_p ? hash_with_unspec_callback : NULL;
1174   if (VINSN_SEPARABLE_P (vi))
1175     {
1176       rtx rhs = VINSN_RHS (vi);
1177
1178       VINSN_HASH (vi) = hash_rtx_cb (rhs, GET_MODE (rhs),
1179                                      NULL, NULL, false, hrcf);
1180       VINSN_HASH_RTX (vi) = hash_rtx_cb (VINSN_PATTERN (vi),
1181                                          VOIDmode, NULL, NULL,
1182                                          false, hrcf);
1183     }
1184   else
1185     {
1186       VINSN_HASH (vi) = hash_rtx_cb (VINSN_PATTERN (vi), VOIDmode,
1187                                      NULL, NULL, false, hrcf);
1188       VINSN_HASH_RTX (vi) = VINSN_HASH (vi);
1189     }
1190     
1191   insn_class = haifa_classify_insn (insn);
1192   if (insn_class >= 2
1193       && (!targetm.sched.get_insn_spec_ds
1194           || ((targetm.sched.get_insn_spec_ds (insn) & BEGIN_CONTROL)
1195               == 0)))
1196     VINSN_MAY_TRAP_P (vi) = true;
1197   else
1198     VINSN_MAY_TRAP_P (vi) = false;
1199 }
1200
1201 /* Indicate that VI has become the part of an rtx object.  */
1202 void
1203 vinsn_attach (vinsn_t vi)
1204 {
1205   /* Assert that VI is not pending for deletion.  */
1206   gcc_assert (VINSN_INSN_RTX (vi));
1207
1208   VINSN_COUNT (vi)++;
1209 }
1210
1211 /* Create and init VI from the INSN.  Use UNIQUE_P for determining the correct 
1212    VINSN_TYPE (VI).  */
1213 static vinsn_t
1214 vinsn_create (insn_t insn, bool force_unique_p)
1215 {
1216   vinsn_t vi = XCNEW (struct vinsn_def);
1217
1218   vinsn_init (vi, insn, force_unique_p);
1219   return vi;
1220 }
1221
1222 /* Return a copy of VI.  When REATTACH_P is true, detach VI and attach
1223    the copy.  */
1224 vinsn_t 
1225 vinsn_copy (vinsn_t vi, bool reattach_p)
1226 {
1227   rtx copy;
1228   bool unique = VINSN_UNIQUE_P (vi);
1229   vinsn_t new_vi;
1230   
1231   copy = create_copy_of_insn_rtx (VINSN_INSN_RTX (vi));
1232   new_vi = create_vinsn_from_insn_rtx (copy, unique);
1233   if (reattach_p)
1234     {
1235       vinsn_detach (vi);
1236       vinsn_attach (new_vi);
1237     }
1238
1239   return new_vi;
1240 }
1241
1242 /* Delete the VI vinsn and free its data.  */
1243 static void
1244 vinsn_delete (vinsn_t vi)
1245 {
1246   gcc_assert (VINSN_COUNT (vi) == 0);
1247
1248   return_regset_to_pool (VINSN_REG_SETS (vi));
1249   return_regset_to_pool (VINSN_REG_USES (vi));
1250   return_regset_to_pool (VINSN_REG_CLOBBERS (vi));
1251
1252   free (vi);
1253 }
1254
1255 /* Indicate that VI is no longer a part of some rtx object.  
1256    Remove VI if it is no longer needed.  */
1257 void
1258 vinsn_detach (vinsn_t vi)
1259 {
1260   gcc_assert (VINSN_COUNT (vi) > 0);
1261
1262   if (--VINSN_COUNT (vi) == 0)
1263     vinsn_delete (vi);
1264 }
1265
1266 /* Returns TRUE if VI is a branch.  */
1267 bool
1268 vinsn_cond_branch_p (vinsn_t vi)
1269 {
1270   insn_t insn;
1271
1272   if (!VINSN_UNIQUE_P (vi))
1273     return false;
1274
1275   insn = VINSN_INSN_RTX (vi);
1276   if (BB_END (BLOCK_FOR_INSN (insn)) != insn)
1277     return false;
1278
1279   return control_flow_insn_p (insn);
1280 }
1281
1282 /* Return latency of INSN.  */
1283 static int
1284 sel_insn_rtx_cost (rtx insn)
1285 {
1286   int cost;
1287
1288   /* A USE insn, or something else we don't need to
1289      understand.  We can't pass these directly to
1290      result_ready_cost or insn_default_latency because it will
1291      trigger a fatal error for unrecognizable insns.  */
1292   if (recog_memoized (insn) < 0)
1293     cost = 0;
1294   else
1295     {
1296       cost = insn_default_latency (insn);
1297
1298       if (cost < 0)
1299         cost = 0;
1300     }
1301
1302   return cost;
1303 }
1304
1305 /* Return the cost of the VI.
1306    !!! FIXME: Unify with haifa-sched.c: insn_cost ().  */
1307 int
1308 sel_vinsn_cost (vinsn_t vi)
1309 {
1310   int cost = vi->cost;
1311
1312   if (cost < 0)
1313     {
1314       cost = sel_insn_rtx_cost (VINSN_INSN_RTX (vi));
1315       vi->cost = cost;
1316     }
1317
1318   return cost;
1319 }
1320 \f
1321
1322 /* Functions for insn emitting.  */
1323
1324 /* Emit new insn after AFTER based on PATTERN and initialize its data from
1325    EXPR and SEQNO.  */
1326 insn_t
1327 sel_gen_insn_from_rtx_after (rtx pattern, expr_t expr, int seqno, insn_t after)
1328 {
1329   insn_t new_insn;
1330
1331   gcc_assert (EXPR_TARGET_AVAILABLE (expr) == true);
1332
1333   new_insn = emit_insn_after (pattern, after);
1334   set_insn_init (expr, NULL, seqno);
1335   sel_init_new_insn (new_insn, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SSID);
1336
1337   return new_insn;
1338 }
1339
1340 /* Force newly generated vinsns to be unique.  */
1341 static bool init_insn_force_unique_p = false;
1342
1343 /* Emit new speculation recovery insn after AFTER based on PATTERN and
1344    initialize its data from EXPR and SEQNO.  */
1345 insn_t
1346 sel_gen_recovery_insn_from_rtx_after (rtx pattern, expr_t expr, int seqno,
1347                                       insn_t after)
1348 {
1349   insn_t insn;
1350
1351   gcc_assert (!init_insn_force_unique_p);
1352
1353   init_insn_force_unique_p = true;
1354   insn = sel_gen_insn_from_rtx_after (pattern, expr, seqno, after);
1355   CANT_MOVE (insn) = 1;
1356   init_insn_force_unique_p = false;
1357
1358   return insn;
1359 }
1360
1361 /* Emit new insn after AFTER based on EXPR and SEQNO.  If VINSN is not NULL,
1362    take it as a new vinsn instead of EXPR's vinsn.  
1363    We simplify insns later, after scheduling region in 
1364    simplify_changed_insns.  */
1365 insn_t
1366 sel_gen_insn_from_expr_after (expr_t expr, vinsn_t vinsn, int seqno, 
1367                               insn_t after)
1368 {
1369   expr_t emit_expr;
1370   insn_t insn;
1371   int flags;
1372   
1373   emit_expr = set_insn_init (expr, vinsn ? vinsn : EXPR_VINSN (expr), 
1374                              seqno);
1375   insn = EXPR_INSN_RTX (emit_expr);
1376   add_insn_after (insn, after, BLOCK_FOR_INSN (insn));          
1377
1378   flags = INSN_INIT_TODO_SSID;
1379   if (INSN_LUID (insn) == 0)
1380     flags |= INSN_INIT_TODO_LUID;
1381   sel_init_new_insn (insn, flags);
1382
1383   return insn;
1384 }
1385
1386 /* Move insn from EXPR after AFTER.  */
1387 insn_t
1388 sel_move_insn (expr_t expr, int seqno, insn_t after)
1389 {
1390   insn_t insn = EXPR_INSN_RTX (expr);
1391   basic_block bb = BLOCK_FOR_INSN (after);
1392   insn_t next = NEXT_INSN (after);
1393
1394   /* Assert that in move_op we disconnected this insn properly.  */
1395   gcc_assert (EXPR_VINSN (INSN_EXPR (insn)) != NULL);
1396   PREV_INSN (insn) = after;
1397   NEXT_INSN (insn) = next;
1398
1399   NEXT_INSN (after) = insn;
1400   PREV_INSN (next) = insn;
1401
1402   /* Update links from insn to bb and vice versa.  */
1403   df_insn_change_bb (insn, bb);
1404   if (BB_END (bb) == after)
1405     BB_END (bb) = insn;
1406       
1407   prepare_insn_expr (insn, seqno);
1408   return insn;
1409 }
1410
1411 \f
1412 /* Functions to work with right-hand sides.  */
1413
1414 /* Search for a hash value determined by UID/NEW_VINSN in a sorted vector 
1415    VECT and return true when found.  Use NEW_VINSN for comparison only when
1416    COMPARE_VINSNS is true.  Write to INDP the index on which 
1417    the search has stopped, such that inserting the new element at INDP will 
1418    retain VECT's sort order.  */
1419 static bool
1420 find_in_history_vect_1 (VEC(expr_history_def, heap) *vect, 
1421                         unsigned uid, vinsn_t new_vinsn, 
1422                         bool compare_vinsns, int *indp)
1423 {
1424   expr_history_def *arr;
1425   int i, j, len = VEC_length (expr_history_def, vect);
1426
1427   if (len == 0)
1428     {
1429       *indp = 0;
1430       return false;
1431     }
1432
1433   arr = VEC_address (expr_history_def, vect);
1434   i = 0, j = len - 1;
1435
1436   while (i <= j)
1437     {
1438       unsigned auid = arr[i].uid;
1439       vinsn_t avinsn = arr[i].new_expr_vinsn; 
1440
1441       if (auid == uid
1442           /* When undoing transformation on a bookkeeping copy, the new vinsn 
1443              may not be exactly equal to the one that is saved in the vector. 
1444              This is because the insn whose copy we're checking was possibly
1445              substituted itself.  */
1446           && (! compare_vinsns 
1447               || vinsn_equal_p (avinsn, new_vinsn)))
1448         {
1449           *indp = i;
1450           return true;
1451         }
1452       else if (auid > uid)
1453         break;
1454       i++;
1455     }
1456
1457   *indp = i;
1458   return false;
1459 }
1460
1461 /* Search for a uid of INSN and NEW_VINSN in a sorted vector VECT.  Return 
1462    the position found or -1, if no such value is in vector.  
1463    Search also for UIDs of insn's originators, if ORIGINATORS_P is true.  */
1464 int
1465 find_in_history_vect (VEC(expr_history_def, heap) *vect, rtx insn, 
1466                       vinsn_t new_vinsn, bool originators_p)
1467 {
1468   int ind;
1469
1470   if (find_in_history_vect_1 (vect, INSN_UID (insn), new_vinsn, 
1471                               false, &ind))
1472     return ind;
1473
1474   if (INSN_ORIGINATORS (insn) && originators_p)
1475     {
1476       unsigned uid;
1477       bitmap_iterator bi;
1478
1479       EXECUTE_IF_SET_IN_BITMAP (INSN_ORIGINATORS (insn), 0, uid, bi)
1480         if (find_in_history_vect_1 (vect, uid, new_vinsn, false, &ind))
1481           return ind;
1482     }
1483   
1484   return -1;
1485 }
1486
1487 /* Insert new element in a sorted history vector pointed to by PVECT, 
1488    if it is not there already.  The element is searched using 
1489    UID/NEW_EXPR_VINSN pair.  TYPE, OLD_EXPR_VINSN and SPEC_DS save
1490    the history of a transformation.  */
1491 void
1492 insert_in_history_vect (VEC (expr_history_def, heap) **pvect,
1493                         unsigned uid, enum local_trans_type type,
1494                         vinsn_t old_expr_vinsn, vinsn_t new_expr_vinsn, 
1495                         ds_t spec_ds)
1496 {
1497   VEC(expr_history_def, heap) *vect = *pvect;
1498   expr_history_def temp;
1499   bool res;
1500   int ind;
1501
1502   res = find_in_history_vect_1 (vect, uid, new_expr_vinsn, true, &ind);
1503
1504   if (res)
1505     {
1506       expr_history_def *phist = VEC_index (expr_history_def, vect, ind);
1507
1508       /* When merging, either old vinsns are the *same* or, if not, both 
1509          old and new vinsns are different pointers.  In the latter case, 
1510          though, new vinsns should be equal.  */
1511       gcc_assert (phist->old_expr_vinsn == old_expr_vinsn
1512                   || (phist->new_expr_vinsn != new_expr_vinsn 
1513                       && (vinsn_equal_p 
1514                           (phist->old_expr_vinsn, old_expr_vinsn))));
1515
1516       /* It is possible that speculation types of expressions that were 
1517          propagated through different paths will be different here.  In this
1518          case, merge the status to get the correct check later.  */
1519       if (phist->spec_ds != spec_ds)
1520         phist->spec_ds = ds_max_merge (phist->spec_ds, spec_ds);
1521       return;
1522     }
1523       
1524   temp.uid = uid;
1525   temp.old_expr_vinsn = old_expr_vinsn;
1526   temp.new_expr_vinsn = new_expr_vinsn; 
1527   temp.spec_ds = spec_ds;
1528   temp.type = type;
1529
1530   vinsn_attach (old_expr_vinsn);
1531   vinsn_attach (new_expr_vinsn);
1532   VEC_safe_insert (expr_history_def, heap, vect, ind, &temp);
1533   *pvect = vect;
1534 }
1535
1536 /* Free history vector PVECT.  */
1537 static void
1538 free_history_vect (VEC (expr_history_def, heap) **pvect)
1539 {
1540   unsigned i;
1541   expr_history_def *phist;
1542
1543   if (! *pvect)
1544     return;
1545   
1546   for (i = 0; 
1547        VEC_iterate (expr_history_def, *pvect, i, phist);
1548        i++)
1549     {
1550       vinsn_detach (phist->old_expr_vinsn);
1551       vinsn_detach (phist->new_expr_vinsn);
1552     }
1553   
1554   VEC_free (expr_history_def, heap, *pvect);
1555   *pvect = NULL;
1556 }
1557
1558
1559 /* Compare two vinsns as rhses if possible and as vinsns otherwise.  */
1560 bool
1561 vinsn_equal_p (vinsn_t x, vinsn_t y)
1562 {
1563   rtx_equal_p_callback_function repcf;
1564
1565   if (x == y)
1566     return true;
1567
1568   if (VINSN_TYPE (x) != VINSN_TYPE (y))
1569     return false;
1570
1571   if (VINSN_HASH (x) != VINSN_HASH (y))
1572     return false;
1573
1574   repcf = targetm.sched.skip_rtx_p ? skip_unspecs_callback : NULL;
1575   if (VINSN_SEPARABLE_P (x)) 
1576     {
1577       /* Compare RHSes of VINSNs.  */
1578       gcc_assert (VINSN_RHS (x));
1579       gcc_assert (VINSN_RHS (y));
1580
1581       return rtx_equal_p_cb (VINSN_RHS (x), VINSN_RHS (y), repcf);
1582     }
1583
1584   return rtx_equal_p_cb (VINSN_PATTERN (x), VINSN_PATTERN (y), repcf);
1585 }
1586 \f
1587
1588 /* Functions for working with expressions.  */
1589
1590 /* Initialize EXPR.  */
1591 static void
1592 init_expr (expr_t expr, vinsn_t vi, int spec, int use, int priority,
1593            int sched_times, int orig_bb_index, ds_t spec_done_ds,
1594            ds_t spec_to_check_ds, int orig_sched_cycle,
1595            VEC(expr_history_def, heap) *history, bool target_available, 
1596            bool was_substituted, bool was_renamed, bool needs_spec_check_p,
1597            bool cant_move)
1598 {
1599   vinsn_attach (vi);
1600
1601   EXPR_VINSN (expr) = vi;
1602   EXPR_SPEC (expr) = spec;
1603   EXPR_USEFULNESS (expr) = use;
1604   EXPR_PRIORITY (expr) = priority;
1605   EXPR_PRIORITY_ADJ (expr) = 0;
1606   EXPR_SCHED_TIMES (expr) = sched_times;
1607   EXPR_ORIG_BB_INDEX (expr) = orig_bb_index;
1608   EXPR_ORIG_SCHED_CYCLE (expr) = orig_sched_cycle;
1609   EXPR_SPEC_DONE_DS (expr) = spec_done_ds;
1610   EXPR_SPEC_TO_CHECK_DS (expr) = spec_to_check_ds;
1611
1612   if (history)
1613     EXPR_HISTORY_OF_CHANGES (expr) = history;
1614   else
1615     EXPR_HISTORY_OF_CHANGES (expr) = NULL;
1616
1617   EXPR_TARGET_AVAILABLE (expr) = target_available;
1618   EXPR_WAS_SUBSTITUTED (expr) = was_substituted;
1619   EXPR_WAS_RENAMED (expr) = was_renamed;
1620   EXPR_NEEDS_SPEC_CHECK_P (expr) = needs_spec_check_p;
1621   EXPR_CANT_MOVE (expr) = cant_move;
1622 }
1623
1624 /* Make a copy of the expr FROM into the expr TO.  */
1625 void
1626 copy_expr (expr_t to, expr_t from)
1627 {
1628   VEC(expr_history_def, heap) *temp = NULL;
1629
1630   if (EXPR_HISTORY_OF_CHANGES (from))
1631     {
1632       unsigned i;
1633       expr_history_def *phist;
1634
1635       temp = VEC_copy (expr_history_def, heap, EXPR_HISTORY_OF_CHANGES (from));
1636       for (i = 0; 
1637            VEC_iterate (expr_history_def, temp, i, phist);
1638            i++)
1639         {
1640           vinsn_attach (phist->old_expr_vinsn);
1641           vinsn_attach (phist->new_expr_vinsn);
1642         }
1643     }
1644
1645   init_expr (to, EXPR_VINSN (from), EXPR_SPEC (from), 
1646              EXPR_USEFULNESS (from), EXPR_PRIORITY (from),
1647              EXPR_SCHED_TIMES (from), EXPR_ORIG_BB_INDEX (from),
1648              EXPR_SPEC_DONE_DS (from), EXPR_SPEC_TO_CHECK_DS (from), 
1649              EXPR_ORIG_SCHED_CYCLE (from), temp,
1650              EXPR_TARGET_AVAILABLE (from), EXPR_WAS_SUBSTITUTED (from), 
1651              EXPR_WAS_RENAMED (from), EXPR_NEEDS_SPEC_CHECK_P (from),
1652              EXPR_CANT_MOVE (from));
1653 }
1654
1655 /* Same, but the final expr will not ever be in av sets, so don't copy 
1656    "uninteresting" data such as bitmap cache.  */
1657 void
1658 copy_expr_onside (expr_t to, expr_t from)
1659 {
1660   init_expr (to, EXPR_VINSN (from), EXPR_SPEC (from), EXPR_USEFULNESS (from),
1661              EXPR_PRIORITY (from), EXPR_SCHED_TIMES (from), 0,
1662              EXPR_SPEC_DONE_DS (from), EXPR_SPEC_TO_CHECK_DS (from), 0, NULL,
1663              EXPR_TARGET_AVAILABLE (from), EXPR_WAS_SUBSTITUTED (from),
1664              EXPR_WAS_RENAMED (from), EXPR_NEEDS_SPEC_CHECK_P (from),
1665              EXPR_CANT_MOVE (from));
1666 }
1667
1668 /* Prepare the expr of INSN for scheduling.  Used when moving insn and when
1669    initializing new insns.  */
1670 static void
1671 prepare_insn_expr (insn_t insn, int seqno)
1672 {
1673   expr_t expr = INSN_EXPR (insn);
1674   ds_t ds;
1675   
1676   INSN_SEQNO (insn) = seqno;
1677   EXPR_ORIG_BB_INDEX (expr) = BLOCK_NUM (insn);
1678   EXPR_SPEC (expr) = 0;
1679   EXPR_ORIG_SCHED_CYCLE (expr) = 0;
1680   EXPR_WAS_SUBSTITUTED (expr) = 0;
1681   EXPR_WAS_RENAMED (expr) = 0;
1682   EXPR_TARGET_AVAILABLE (expr) = 1;
1683   INSN_LIVE_VALID_P (insn) = false;
1684
1685   /* ??? If this expression is speculative, make its dependence
1686      as weak as possible.  We can filter this expression later
1687      in process_spec_exprs, because we do not distinguish
1688      between the status we got during compute_av_set and the
1689      existing status.  To be fixed.  */
1690   ds = EXPR_SPEC_DONE_DS (expr);
1691   if (ds)
1692     EXPR_SPEC_DONE_DS (expr) = ds_get_max_dep_weak (ds);
1693
1694   free_history_vect (&EXPR_HISTORY_OF_CHANGES (expr));
1695 }
1696
1697 /* Update target_available bits when merging exprs TO and FROM.  SPLIT_POINT
1698    is non-null when expressions are merged from different successors at 
1699    a split point.  */
1700 static void
1701 update_target_availability (expr_t to, expr_t from, insn_t split_point)
1702 {
1703   if (EXPR_TARGET_AVAILABLE (to) < 0  
1704       || EXPR_TARGET_AVAILABLE (from) < 0)
1705     EXPR_TARGET_AVAILABLE (to) = -1;
1706   else
1707     {
1708       /* We try to detect the case when one of the expressions
1709          can only be reached through another one.  In this case,
1710          we can do better.  */
1711       if (split_point == NULL)
1712         {
1713           int toind, fromind;
1714
1715           toind = EXPR_ORIG_BB_INDEX (to);
1716           fromind = EXPR_ORIG_BB_INDEX (from);
1717           
1718           if (toind && toind == fromind)
1719             /* Do nothing -- everything is done in 
1720                merge_with_other_exprs.  */
1721             ;
1722           else
1723             EXPR_TARGET_AVAILABLE (to) = -1;
1724         }
1725       else
1726         EXPR_TARGET_AVAILABLE (to) &= EXPR_TARGET_AVAILABLE (from);
1727     }
1728 }
1729
1730 /* Update speculation bits when merging exprs TO and FROM.  SPLIT_POINT
1731    is non-null when expressions are merged from different successors at 
1732    a split point.  */
1733 static void
1734 update_speculative_bits (expr_t to, expr_t from, insn_t split_point)
1735 {
1736   ds_t old_to_ds, old_from_ds;
1737
1738   old_to_ds = EXPR_SPEC_DONE_DS (to);
1739   old_from_ds = EXPR_SPEC_DONE_DS (from);
1740     
1741   EXPR_SPEC_DONE_DS (to) = ds_max_merge (old_to_ds, old_from_ds);
1742   EXPR_SPEC_TO_CHECK_DS (to) |= EXPR_SPEC_TO_CHECK_DS (from);
1743   EXPR_NEEDS_SPEC_CHECK_P (to) |= EXPR_NEEDS_SPEC_CHECK_P (from);
1744
1745   /* When merging e.g. control & data speculative exprs, or a control
1746      speculative with a control&data speculative one, we really have 
1747      to change vinsn too.  Also, when speculative status is changed,
1748      we also need to record this as a transformation in expr's history.  */
1749   if ((old_to_ds & SPECULATIVE) || (old_from_ds & SPECULATIVE))
1750     {
1751       old_to_ds = ds_get_speculation_types (old_to_ds);
1752       old_from_ds = ds_get_speculation_types (old_from_ds);
1753         
1754       if (old_to_ds != old_from_ds)
1755         {
1756           ds_t record_ds;
1757             
1758           /* When both expressions are speculative, we need to change 
1759              the vinsn first.  */
1760           if ((old_to_ds & SPECULATIVE) && (old_from_ds & SPECULATIVE))
1761             {
1762               int res;
1763                 
1764               res = speculate_expr (to, EXPR_SPEC_DONE_DS (to));
1765               gcc_assert (res >= 0);
1766             }
1767
1768           if (split_point != NULL)
1769             {
1770               /* Record the change with proper status.  */
1771               record_ds = EXPR_SPEC_DONE_DS (to) & SPECULATIVE;
1772               record_ds &= ~(old_to_ds & SPECULATIVE);
1773               record_ds &= ~(old_from_ds & SPECULATIVE);
1774                 
1775               insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (to), 
1776                                       INSN_UID (split_point), TRANS_SPECULATION, 
1777                                       EXPR_VINSN (from), EXPR_VINSN (to),
1778                                       record_ds);
1779             }
1780         }
1781     }
1782 }
1783
1784
1785 /* Merge bits of FROM expr to TO expr.  When SPLIT_POINT is not NULL,
1786    this is done along different paths.  */
1787 void
1788 merge_expr_data (expr_t to, expr_t from, insn_t split_point)
1789 {
1790   int i;
1791   expr_history_def *phist;
1792   
1793   /* For now, we just set the spec of resulting expr to be minimum of the specs
1794      of merged exprs.  */
1795   if (EXPR_SPEC (to) > EXPR_SPEC (from))
1796     EXPR_SPEC (to) = EXPR_SPEC (from);
1797
1798   if (split_point)
1799     EXPR_USEFULNESS (to) += EXPR_USEFULNESS (from);
1800   else
1801     EXPR_USEFULNESS (to) = MAX (EXPR_USEFULNESS (to), 
1802                                 EXPR_USEFULNESS (from));
1803
1804   if (EXPR_PRIORITY (to) < EXPR_PRIORITY (from))
1805     EXPR_PRIORITY (to) = EXPR_PRIORITY (from);
1806
1807   if (EXPR_SCHED_TIMES (to) > EXPR_SCHED_TIMES (from))
1808     EXPR_SCHED_TIMES (to) = EXPR_SCHED_TIMES (from);
1809
1810   if (EXPR_ORIG_BB_INDEX (to) != EXPR_ORIG_BB_INDEX (from))
1811     EXPR_ORIG_BB_INDEX (to) = 0;
1812
1813   EXPR_ORIG_SCHED_CYCLE (to) = MIN (EXPR_ORIG_SCHED_CYCLE (to), 
1814                                     EXPR_ORIG_SCHED_CYCLE (from));
1815
1816   /* We keep this vector sorted.  */
1817   for (i = 0; 
1818        VEC_iterate (expr_history_def, EXPR_HISTORY_OF_CHANGES (from), 
1819                     i, phist);
1820        i++)
1821     insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (to), 
1822                             phist->uid, phist->type, 
1823                             phist->old_expr_vinsn, phist->new_expr_vinsn, 
1824                             phist->spec_ds);
1825
1826   EXPR_WAS_SUBSTITUTED (to) |= EXPR_WAS_SUBSTITUTED (from);
1827   EXPR_WAS_RENAMED (to) |= EXPR_WAS_RENAMED (from);
1828   EXPR_CANT_MOVE (to) |= EXPR_CANT_MOVE (from);
1829
1830   update_target_availability (to, from, split_point);
1831   update_speculative_bits (to, from, split_point);
1832 }
1833
1834 /* Merge bits of FROM expr to TO expr.  Vinsns in the exprs should be equal
1835    in terms of vinsn_equal_p.  SPLIT_POINT is non-null when expressions 
1836    are merged from different successors at a split point.  */
1837 void
1838 merge_expr (expr_t to, expr_t from, insn_t split_point)
1839 {
1840   vinsn_t to_vi = EXPR_VINSN (to);
1841   vinsn_t from_vi = EXPR_VINSN (from);
1842
1843   gcc_assert (vinsn_equal_p (to_vi, from_vi));
1844
1845   /* Make sure that speculative pattern is propagated into exprs that
1846      have non-speculative one.  This will provide us with consistent
1847      speculative bits and speculative patterns inside expr.  */
1848   if (EXPR_SPEC_DONE_DS (to) == 0
1849       && EXPR_SPEC_DONE_DS (from) != 0)
1850     change_vinsn_in_expr (to, EXPR_VINSN (from));
1851
1852   merge_expr_data (to, from, split_point);
1853   gcc_assert (EXPR_USEFULNESS (to) <= REG_BR_PROB_BASE);
1854 }
1855
1856 /* Clear the information of this EXPR.  */
1857 void
1858 clear_expr (expr_t expr)
1859 {
1860  
1861   vinsn_detach (EXPR_VINSN (expr));
1862   EXPR_VINSN (expr) = NULL;
1863
1864   free_history_vect (&EXPR_HISTORY_OF_CHANGES (expr));
1865 }
1866
1867 /* For a given LV_SET, mark EXPR having unavailable target register.  */
1868 static void
1869 set_unavailable_target_for_expr (expr_t expr, regset lv_set)
1870 {
1871   if (EXPR_SEPARABLE_P (expr))
1872     {
1873       if (REG_P (EXPR_LHS (expr))
1874           && bitmap_bit_p (lv_set, REGNO (EXPR_LHS (expr))))
1875         {
1876           /* If it's an insn like r1 = use (r1, ...), and it exists in 
1877              different forms in each of the av_sets being merged, we can't say 
1878              whether original destination register is available or not.  
1879              However, this still works if destination register is not used 
1880              in the original expression: if the branch at which LV_SET we're
1881              looking here is not actually 'other branch' in sense that same
1882              expression is available through it (but it can't be determined 
1883              at computation stage because of transformations on one of the
1884              branches), it still won't affect the availability.  
1885              Liveness of a register somewhere on a code motion path means 
1886              it's either read somewhere on a codemotion path, live on 
1887              'other' branch, live at the point immediately following
1888              the original operation, or is read by the original operation.
1889              The latter case is filtered out in the condition below.
1890              It still doesn't cover the case when register is defined and used
1891              somewhere within the code motion path, and in this case we could
1892              miss a unifying code motion along both branches using a renamed
1893              register, but it won't affect a code correctness since upon
1894              an actual code motion a bookkeeping code would be generated.  */
1895           if (bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)), 
1896                             REGNO (EXPR_LHS (expr))))
1897             EXPR_TARGET_AVAILABLE (expr) = -1;
1898           else
1899             EXPR_TARGET_AVAILABLE (expr) = false;
1900         }
1901     }
1902   else
1903     {
1904       unsigned regno;
1905       reg_set_iterator rsi;
1906       
1907       EXECUTE_IF_SET_IN_REG_SET (VINSN_REG_SETS (EXPR_VINSN (expr)), 
1908                                  0, regno, rsi)
1909         if (bitmap_bit_p (lv_set, regno))
1910           {
1911             EXPR_TARGET_AVAILABLE (expr) = false;
1912             break;
1913           }
1914
1915       EXECUTE_IF_SET_IN_REG_SET (VINSN_REG_CLOBBERS (EXPR_VINSN (expr)),
1916                                  0, regno, rsi)
1917         if (bitmap_bit_p (lv_set, regno))
1918           {
1919             EXPR_TARGET_AVAILABLE (expr) = false;
1920             break;
1921           }
1922     }
1923 }
1924
1925 /* Try to make EXPR speculative.  Return 1 when EXPR's pattern 
1926    or dependence status have changed, 2 when also the target register
1927    became unavailable, 0 if nothing had to be changed.  */
1928 int
1929 speculate_expr (expr_t expr, ds_t ds)
1930 {
1931   int res;
1932   rtx orig_insn_rtx;
1933   rtx spec_pat;
1934   ds_t target_ds, current_ds;
1935
1936   /* Obtain the status we need to put on EXPR.   */
1937   target_ds = (ds & SPECULATIVE);
1938   current_ds = EXPR_SPEC_DONE_DS (expr);
1939   ds = ds_full_merge (current_ds, target_ds, NULL_RTX, NULL_RTX);
1940
1941   orig_insn_rtx = EXPR_INSN_RTX (expr);
1942
1943   res = sched_speculate_insn (orig_insn_rtx, ds, &spec_pat);
1944
1945   switch (res)
1946     {
1947     case 0:
1948       EXPR_SPEC_DONE_DS (expr) = ds;
1949       return current_ds != ds ? 1 : 0;
1950       
1951     case 1:
1952       {
1953         rtx spec_insn_rtx = create_insn_rtx_from_pattern (spec_pat, NULL_RTX);
1954         vinsn_t spec_vinsn = create_vinsn_from_insn_rtx (spec_insn_rtx, false);
1955
1956         change_vinsn_in_expr (expr, spec_vinsn);
1957         EXPR_SPEC_DONE_DS (expr) = ds;
1958         EXPR_NEEDS_SPEC_CHECK_P (expr) = true;
1959
1960         /* Do not allow clobbering the address register of speculative 
1961            insns.  */
1962         if (bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)), 
1963                           expr_dest_regno (expr)))
1964           {
1965             EXPR_TARGET_AVAILABLE (expr) = false;
1966             return 2;
1967           }
1968
1969         return 1;
1970       }
1971
1972     case -1:
1973       return -1;
1974
1975     default:
1976       gcc_unreachable ();
1977       return -1;
1978     }
1979 }
1980
1981 /* Return a destination register, if any, of EXPR.  */
1982 rtx
1983 expr_dest_reg (expr_t expr)
1984 {
1985   rtx dest = VINSN_LHS (EXPR_VINSN (expr));
1986
1987   if (dest != NULL_RTX && REG_P (dest))
1988     return dest;
1989
1990   return NULL_RTX;
1991 }
1992
1993 /* Returns the REGNO of the R's destination.  */
1994 unsigned
1995 expr_dest_regno (expr_t expr)
1996 {
1997   rtx dest = expr_dest_reg (expr);
1998
1999   gcc_assert (dest != NULL_RTX);
2000   return REGNO (dest);
2001 }
2002
2003 /* For a given LV_SET, mark all expressions in JOIN_SET, but not present in 
2004    AV_SET having unavailable target register.  */
2005 void
2006 mark_unavailable_targets (av_set_t join_set, av_set_t av_set, regset lv_set)
2007 {
2008   expr_t expr;
2009   av_set_iterator avi;
2010
2011   FOR_EACH_EXPR (expr, avi, join_set)
2012     if (av_set_lookup (av_set, EXPR_VINSN (expr)) == NULL)
2013       set_unavailable_target_for_expr (expr, lv_set);
2014 }
2015 \f
2016
2017 /* Av set functions.  */
2018
2019 /* Add a new element to av set SETP.
2020    Return the element added.  */
2021 static av_set_t
2022 av_set_add_element (av_set_t *setp)
2023 {
2024   /* Insert at the beginning of the list.  */
2025   _list_add (setp);
2026   return *setp;
2027 }
2028
2029 /* Add EXPR to SETP.  */
2030 void
2031 av_set_add (av_set_t *setp, expr_t expr)
2032 {
2033   av_set_t elem;
2034   
2035   gcc_assert (!INSN_NOP_P (EXPR_INSN_RTX (expr)));
2036   elem = av_set_add_element (setp);
2037   copy_expr (_AV_SET_EXPR (elem), expr);
2038 }
2039
2040 /* Same, but do not copy EXPR.  */
2041 static void
2042 av_set_add_nocopy (av_set_t *setp, expr_t expr)
2043 {
2044   av_set_t elem;
2045
2046   elem = av_set_add_element (setp);
2047   *_AV_SET_EXPR (elem) = *expr;
2048 }
2049
2050 /* Remove expr pointed to by IP from the av_set.  */
2051 void
2052 av_set_iter_remove (av_set_iterator *ip)
2053 {
2054   clear_expr (_AV_SET_EXPR (*ip->lp));
2055   _list_iter_remove (ip);
2056 }
2057
2058 /* Search for an expr in SET, such that it's equivalent to SOUGHT_VINSN in the
2059    sense of vinsn_equal_p function. Return NULL if no such expr is
2060    in SET was found.  */
2061 expr_t
2062 av_set_lookup (av_set_t set, vinsn_t sought_vinsn)
2063 {
2064   expr_t expr;
2065   av_set_iterator i;
2066
2067   FOR_EACH_EXPR (expr, i, set)
2068     if (vinsn_equal_p (EXPR_VINSN (expr), sought_vinsn))
2069       return expr;
2070   return NULL;
2071 }
2072
2073 /* Same, but also remove the EXPR found.   */
2074 static expr_t
2075 av_set_lookup_and_remove (av_set_t *setp, vinsn_t sought_vinsn)
2076 {
2077   expr_t expr;
2078   av_set_iterator i;
2079
2080   FOR_EACH_EXPR_1 (expr, i, setp)
2081     if (vinsn_equal_p (EXPR_VINSN (expr), sought_vinsn))
2082       {
2083         _list_iter_remove_nofree (&i);
2084         return expr;
2085       }
2086   return NULL;
2087 }
2088
2089 /* Search for an expr in SET, such that it's equivalent to EXPR in the
2090    sense of vinsn_equal_p function of their vinsns, but not EXPR itself.
2091    Returns NULL if no such expr is in SET was found.  */
2092 static expr_t
2093 av_set_lookup_other_equiv_expr (av_set_t set, expr_t expr)
2094 {
2095   expr_t cur_expr;
2096   av_set_iterator i;
2097
2098   FOR_EACH_EXPR (cur_expr, i, set)
2099     {
2100       if (cur_expr == expr)
2101         continue;
2102       if (vinsn_equal_p (EXPR_VINSN (cur_expr), EXPR_VINSN (expr)))
2103         return cur_expr;
2104     }
2105
2106   return NULL;
2107 }
2108
2109 /* If other expression is already in AVP, remove one of them.  */
2110 expr_t
2111 merge_with_other_exprs (av_set_t *avp, av_set_iterator *ip, expr_t expr)
2112 {
2113   expr_t expr2;
2114
2115   expr2 = av_set_lookup_other_equiv_expr (*avp, expr);
2116   if (expr2 != NULL)
2117     {
2118       /* Reset target availability on merge, since taking it only from one
2119          of the exprs would be controversial for different code.  */
2120       EXPR_TARGET_AVAILABLE (expr2) = -1;
2121       EXPR_USEFULNESS (expr2) = 0;
2122
2123       merge_expr (expr2, expr, NULL);
2124       
2125       /* Fix usefulness as it should be now REG_BR_PROB_BASE.  */
2126       EXPR_USEFULNESS (expr2) = REG_BR_PROB_BASE;
2127       
2128       av_set_iter_remove (ip);
2129       return expr2;
2130     }
2131
2132   return expr;
2133 }
2134
2135 /* Return true if there is an expr that correlates to VI in SET.  */
2136 bool
2137 av_set_is_in_p (av_set_t set, vinsn_t vi)
2138 {
2139   return av_set_lookup (set, vi) != NULL;
2140 }
2141
2142 /* Return a copy of SET.  */
2143 av_set_t
2144 av_set_copy (av_set_t set)
2145 {
2146   expr_t expr;
2147   av_set_iterator i;
2148   av_set_t res = NULL;
2149
2150   FOR_EACH_EXPR (expr, i, set)
2151     av_set_add (&res, expr);
2152
2153   return res;
2154 }
2155
2156 /* Join two av sets that do not have common elements by attaching second set
2157    (pointed to by FROMP) to the end of first set (TO_TAILP must point to
2158    _AV_SET_NEXT of first set's last element).  */
2159 static void
2160 join_distinct_sets (av_set_t *to_tailp, av_set_t *fromp)
2161 {
2162   gcc_assert (*to_tailp == NULL);
2163   *to_tailp = *fromp;
2164   *fromp = NULL;
2165 }
2166
2167 /* Makes set pointed to by TO to be the union of TO and FROM.  Clear av_set
2168    pointed to by FROMP afterwards.  */
2169 void
2170 av_set_union_and_clear (av_set_t *top, av_set_t *fromp, insn_t insn)
2171 {
2172   expr_t expr1;
2173   av_set_iterator i;
2174
2175   /* Delete from TOP all exprs, that present in FROMP.  */
2176   FOR_EACH_EXPR_1 (expr1, i, top)
2177     {
2178       expr_t expr2 = av_set_lookup (*fromp, EXPR_VINSN (expr1));
2179
2180       if (expr2)
2181         {
2182           merge_expr (expr2, expr1, insn);
2183           av_set_iter_remove (&i);
2184         }
2185     }
2186
2187   join_distinct_sets (i.lp, fromp);
2188 }
2189
2190 /* Same as above, but also update availability of target register in 
2191    TOP judging by TO_LV_SET and FROM_LV_SET.  */
2192 void
2193 av_set_union_and_live (av_set_t *top, av_set_t *fromp, regset to_lv_set,
2194                        regset from_lv_set, insn_t insn)
2195 {
2196   expr_t expr1;
2197   av_set_iterator i;
2198   av_set_t *to_tailp, in_both_set = NULL;
2199
2200   /* Delete from TOP all expres, that present in FROMP.  */
2201   FOR_EACH_EXPR_1 (expr1, i, top)
2202     {
2203       expr_t expr2 = av_set_lookup_and_remove (fromp, EXPR_VINSN (expr1));
2204
2205       if (expr2)
2206         {
2207           /* It may be that the expressions have different destination 
2208              registers, in which case we need to check liveness here.  */
2209           if (EXPR_SEPARABLE_P (expr1))
2210             {
2211               int regno1 = (REG_P (EXPR_LHS (expr1)) 
2212                             ? (int) expr_dest_regno (expr1) : -1);
2213               int regno2 = (REG_P (EXPR_LHS (expr2)) 
2214                             ? (int) expr_dest_regno (expr2) : -1);
2215               
2216               /* ??? We don't have a way to check restrictions for 
2217                *other* register on the current path, we did it only
2218                for the current target register.  Give up.  */
2219               if (regno1 != regno2)
2220                 EXPR_TARGET_AVAILABLE (expr2) = -1;
2221             }
2222           else if (EXPR_INSN_RTX (expr1) != EXPR_INSN_RTX (expr2))
2223             EXPR_TARGET_AVAILABLE (expr2) = -1;
2224
2225           merge_expr (expr2, expr1, insn);
2226           av_set_add_nocopy (&in_both_set, expr2);
2227           av_set_iter_remove (&i);
2228         }
2229       else
2230         /* EXPR1 is present in TOP, but not in FROMP.  Check it on 
2231            FROM_LV_SET.  */
2232         set_unavailable_target_for_expr (expr1, from_lv_set);
2233     }
2234   to_tailp = i.lp;
2235
2236   /* These expressions are not present in TOP.  Check liveness
2237      restrictions on TO_LV_SET.  */
2238   FOR_EACH_EXPR (expr1, i, *fromp)
2239     set_unavailable_target_for_expr (expr1, to_lv_set);
2240
2241   join_distinct_sets (i.lp, &in_both_set);
2242   join_distinct_sets (to_tailp, fromp);
2243 }
2244
2245 /* Clear av_set pointed to by SETP.  */
2246 void
2247 av_set_clear (av_set_t *setp)
2248 {
2249   expr_t expr;
2250   av_set_iterator i;
2251
2252   FOR_EACH_EXPR_1 (expr, i, setp)
2253     av_set_iter_remove (&i);
2254
2255   gcc_assert (*setp == NULL);
2256 }
2257
2258 /* Leave only one non-speculative element in the SETP.  */
2259 void
2260 av_set_leave_one_nonspec (av_set_t *setp)
2261 {
2262   expr_t expr;
2263   av_set_iterator i;
2264   bool has_one_nonspec = false;
2265
2266   /* Keep all speculative exprs, and leave one non-speculative 
2267      (the first one).  */
2268   FOR_EACH_EXPR_1 (expr, i, setp)
2269     {
2270       if (!EXPR_SPEC_DONE_DS (expr))
2271         {
2272           if (has_one_nonspec)
2273             av_set_iter_remove (&i);
2274           else
2275             has_one_nonspec = true;
2276         }
2277     }
2278 }
2279
2280 /* Return the N'th element of the SET.  */
2281 expr_t
2282 av_set_element (av_set_t set, int n)
2283 {
2284   expr_t expr;
2285   av_set_iterator i;
2286
2287   FOR_EACH_EXPR (expr, i, set)
2288     if (n-- == 0)
2289       return expr;
2290
2291   gcc_unreachable ();
2292   return NULL;
2293 }
2294
2295 /* Deletes all expressions from AVP that are conditional branches (IFs).  */
2296 void
2297 av_set_substract_cond_branches (av_set_t *avp)
2298 {
2299   av_set_iterator i;
2300   expr_t expr;
2301
2302   FOR_EACH_EXPR_1 (expr, i, avp)
2303     if (vinsn_cond_branch_p (EXPR_VINSN (expr)))
2304       av_set_iter_remove (&i);
2305 }
2306
2307 /* Multiplies usefulness attribute of each member of av-set *AVP by 
2308    value PROB / ALL_PROB.  */
2309 void
2310 av_set_split_usefulness (av_set_t av, int prob, int all_prob)
2311 {
2312   av_set_iterator i;
2313   expr_t expr;
2314
2315   FOR_EACH_EXPR (expr, i, av)
2316     EXPR_USEFULNESS (expr) = (all_prob 
2317                               ? (EXPR_USEFULNESS (expr) * prob) / all_prob
2318                               : 0);
2319 }
2320
2321 /* Leave in AVP only those expressions, which are present in AV,
2322    and return it.  */
2323 void
2324 av_set_intersect (av_set_t *avp, av_set_t av)
2325 {
2326   av_set_iterator i;
2327   expr_t expr;
2328
2329   FOR_EACH_EXPR_1 (expr, i, avp)
2330     if (av_set_lookup (av, EXPR_VINSN (expr)) == NULL)
2331       av_set_iter_remove (&i);
2332 }
2333
2334 \f
2335
2336 /* Dependence hooks to initialize insn data.  */
2337
2338 /* This is used in hooks callable from dependence analysis when initializing
2339    instruction's data.  */
2340 static struct
2341 {
2342   /* Where the dependence was found (lhs/rhs).  */
2343   deps_where_t where;
2344
2345   /* The actual data object to initialize.  */
2346   idata_t id;
2347
2348   /* True when the insn should not be made clonable.  */
2349   bool force_unique_p;
2350
2351   /* True when insn should be treated as of type USE, i.e. never renamed.  */
2352   bool force_use_p;
2353 } deps_init_id_data;
2354
2355
2356 /* Setup ID for INSN.  FORCE_UNIQUE_P is true when INSN should not be 
2357    clonable.  */
2358 static void
2359 setup_id_for_insn (idata_t id, insn_t insn, bool force_unique_p)
2360 {
2361   int type;
2362   
2363   /* Determine whether INSN could be cloned and return appropriate vinsn type.
2364      That clonable insns which can be separated into lhs and rhs have type SET.
2365      Other clonable insns have type USE.  */
2366   type = GET_CODE (insn);
2367
2368   /* Only regular insns could be cloned.  */
2369   if (type == INSN && !force_unique_p)
2370     type = SET;
2371   else if (type == JUMP_INSN && simplejump_p (insn))
2372     type = PC;
2373   
2374   IDATA_TYPE (id) = type;
2375   IDATA_REG_SETS (id) = get_clear_regset_from_pool ();
2376   IDATA_REG_USES (id) = get_clear_regset_from_pool ();
2377   IDATA_REG_CLOBBERS (id) = get_clear_regset_from_pool ();
2378 }
2379
2380 /* Start initializing insn data.  */
2381 static void
2382 deps_init_id_start_insn (insn_t insn)
2383 {
2384   gcc_assert (deps_init_id_data.where == DEPS_IN_NOWHERE);
2385
2386   setup_id_for_insn (deps_init_id_data.id, insn,
2387                      deps_init_id_data.force_unique_p);
2388   deps_init_id_data.where = DEPS_IN_INSN;
2389 }
2390
2391 /* Start initializing lhs data.  */
2392 static void
2393 deps_init_id_start_lhs (rtx lhs)
2394 {
2395   gcc_assert (deps_init_id_data.where == DEPS_IN_INSN);
2396   gcc_assert (IDATA_LHS (deps_init_id_data.id) == NULL);
2397
2398   if (IDATA_TYPE (deps_init_id_data.id) == SET)
2399     {
2400       IDATA_LHS (deps_init_id_data.id) = lhs;
2401       deps_init_id_data.where = DEPS_IN_LHS;
2402     }
2403 }
2404
2405 /* Finish initializing lhs data.  */
2406 static void
2407 deps_init_id_finish_lhs (void)
2408 {
2409   deps_init_id_data.where = DEPS_IN_INSN;
2410 }
2411
2412 /* Note a set of REGNO.  */
2413 static void
2414 deps_init_id_note_reg_set (int regno)
2415 {
2416   haifa_note_reg_set (regno);
2417
2418   if (deps_init_id_data.where == DEPS_IN_RHS)
2419     deps_init_id_data.force_use_p = true;
2420
2421   if (IDATA_TYPE (deps_init_id_data.id) != PC)
2422     SET_REGNO_REG_SET (IDATA_REG_SETS (deps_init_id_data.id), regno);
2423
2424 #ifdef STACK_REGS
2425   /* Make instructions that set stack registers to be ineligible for 
2426      renaming to avoid issues with find_used_regs.  */
2427   if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG))
2428     deps_init_id_data.force_use_p = true;
2429 #endif
2430 }
2431
2432 /* Note a clobber of REGNO.  */
2433 static void
2434 deps_init_id_note_reg_clobber (int regno)
2435 {
2436   haifa_note_reg_clobber (regno);
2437
2438   if (deps_init_id_data.where == DEPS_IN_RHS)
2439     deps_init_id_data.force_use_p = true;
2440
2441   if (IDATA_TYPE (deps_init_id_data.id) != PC)
2442     SET_REGNO_REG_SET (IDATA_REG_CLOBBERS (deps_init_id_data.id), regno);
2443 }
2444
2445 /* Note a use of REGNO.  */
2446 static void
2447 deps_init_id_note_reg_use (int regno)
2448 {
2449   haifa_note_reg_use (regno);
2450
2451   if (IDATA_TYPE (deps_init_id_data.id) != PC)
2452     SET_REGNO_REG_SET (IDATA_REG_USES (deps_init_id_data.id), regno);
2453 }
2454
2455 /* Start initializing rhs data.  */
2456 static void
2457 deps_init_id_start_rhs (rtx rhs)
2458 {
2459   gcc_assert (deps_init_id_data.where == DEPS_IN_INSN);
2460
2461   /* And there was no sel_deps_reset_to_insn ().  */
2462   if (IDATA_LHS (deps_init_id_data.id) != NULL)
2463     {
2464       IDATA_RHS (deps_init_id_data.id) = rhs;
2465       deps_init_id_data.where = DEPS_IN_RHS;
2466     }
2467 }
2468
2469 /* Finish initializing rhs data.  */
2470 static void
2471 deps_init_id_finish_rhs (void)
2472 {
2473   gcc_assert (deps_init_id_data.where == DEPS_IN_RHS
2474               || deps_init_id_data.where == DEPS_IN_INSN);
2475   deps_init_id_data.where = DEPS_IN_INSN;
2476 }
2477
2478 /* Finish initializing insn data.  */
2479 static void
2480 deps_init_id_finish_insn (void)
2481 {
2482   gcc_assert (deps_init_id_data.where == DEPS_IN_INSN);
2483
2484   if (IDATA_TYPE (deps_init_id_data.id) == SET)
2485     {
2486       rtx lhs = IDATA_LHS (deps_init_id_data.id);
2487       rtx rhs = IDATA_RHS (deps_init_id_data.id);
2488
2489       if (lhs == NULL || rhs == NULL || !lhs_and_rhs_separable_p (lhs, rhs)
2490           || deps_init_id_data.force_use_p)
2491         {
2492           /* This should be a USE, as we don't want to schedule its RHS 
2493              separately.  However, we still want to have them recorded
2494              for the purposes of substitution.  That's why we don't 
2495              simply call downgrade_to_use () here.  */
2496           gcc_assert (IDATA_TYPE (deps_init_id_data.id) == SET);
2497           gcc_assert (!lhs == !rhs);
2498
2499           IDATA_TYPE (deps_init_id_data.id) = USE;
2500         }
2501     }
2502
2503   deps_init_id_data.where = DEPS_IN_NOWHERE;
2504 }
2505
2506 /* This is dependence info used for initializing insn's data.  */
2507 static struct sched_deps_info_def deps_init_id_sched_deps_info;
2508
2509 /* This initializes most of the static part of the above structure.  */
2510 static const struct sched_deps_info_def const_deps_init_id_sched_deps_info =
2511   {
2512     NULL,
2513
2514     deps_init_id_start_insn,
2515     deps_init_id_finish_insn,
2516     deps_init_id_start_lhs,
2517     deps_init_id_finish_lhs,
2518     deps_init_id_start_rhs,
2519     deps_init_id_finish_rhs,
2520     deps_init_id_note_reg_set,
2521     deps_init_id_note_reg_clobber,
2522     deps_init_id_note_reg_use,
2523     NULL, /* note_mem_dep */
2524     NULL, /* note_dep */
2525
2526     0, /* use_cselib */
2527     0, /* use_deps_list */
2528     0 /* generate_spec_deps */
2529   };
2530
2531 /* Initialize INSN's lhs and rhs in ID.  When FORCE_UNIQUE_P is true,
2532    we don't actually need information about lhs and rhs.  */
2533 static void
2534 setup_id_lhs_rhs (idata_t id, insn_t insn, bool force_unique_p)
2535 {
2536   rtx pat = PATTERN (insn);
2537   
2538   if (GET_CODE (insn) == INSN
2539       && GET_CODE (pat) == SET 
2540       && !force_unique_p)
2541     {
2542       IDATA_RHS (id) = SET_SRC (pat);
2543       IDATA_LHS (id) = SET_DEST (pat);
2544     }
2545   else
2546     IDATA_LHS (id) = IDATA_RHS (id) = NULL;
2547 }
2548
2549 /* Possibly downgrade INSN to USE.  */
2550 static void
2551 maybe_downgrade_id_to_use (idata_t id, insn_t insn)
2552 {
2553   bool must_be_use = false;
2554   unsigned uid = INSN_UID (insn);
2555   df_ref *rec;
2556   rtx lhs = IDATA_LHS (id);
2557   rtx rhs = IDATA_RHS (id);
2558   
2559   /* We downgrade only SETs.  */
2560   if (IDATA_TYPE (id) != SET)
2561     return;
2562
2563   if (!lhs || !lhs_and_rhs_separable_p (lhs, rhs))
2564     {
2565       IDATA_TYPE (id) = USE;
2566       return;
2567     }
2568   
2569   for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++)
2570     {
2571       df_ref def = *rec;
2572       
2573       if (DF_REF_INSN (def)
2574           && DF_REF_FLAGS_IS_SET (def, DF_REF_PRE_POST_MODIFY)
2575           && loc_mentioned_in_p (DF_REF_LOC (def), IDATA_RHS (id)))
2576         {
2577           must_be_use = true;
2578           break;
2579         }
2580
2581 #ifdef STACK_REGS
2582       /* Make instructions that set stack registers to be ineligible for 
2583          renaming to avoid issues with find_used_regs.  */
2584       if (IN_RANGE (DF_REF_REGNO (def), FIRST_STACK_REG, LAST_STACK_REG))
2585         {
2586           must_be_use = true;
2587           break;
2588         }
2589 #endif
2590     }    
2591   
2592   if (must_be_use)
2593     IDATA_TYPE (id) = USE;
2594 }
2595
2596 /* Setup register sets describing INSN in ID.  */
2597 static void
2598 setup_id_reg_sets (idata_t id, insn_t insn)
2599 {
2600   unsigned uid = INSN_UID (insn);
2601   df_ref *rec;
2602   regset tmp = get_clear_regset_from_pool ();
2603   
2604   for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++)
2605     {
2606       df_ref def = *rec;
2607       unsigned int regno = DF_REF_REGNO (def);
2608       
2609       /* Post modifies are treated like clobbers by sched-deps.c.  */
2610       if (DF_REF_FLAGS_IS_SET (def, (DF_REF_MUST_CLOBBER
2611                                      | DF_REF_PRE_POST_MODIFY)))
2612         SET_REGNO_REG_SET (IDATA_REG_CLOBBERS (id), regno);
2613       else if (! DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER))
2614         {
2615           SET_REGNO_REG_SET (IDATA_REG_SETS (id), regno);
2616
2617 #ifdef STACK_REGS
2618           /* For stack registers, treat writes to them as writes 
2619              to the first one to be consistent with sched-deps.c.  */
2620           if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG))
2621             SET_REGNO_REG_SET (IDATA_REG_SETS (id), FIRST_STACK_REG);
2622 #endif
2623         }
2624       /* Mark special refs that generate read/write def pair.  */
2625       if (DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL)
2626           || regno == STACK_POINTER_REGNUM)
2627         bitmap_set_bit (tmp, regno);
2628     }
2629       
2630   for (rec = DF_INSN_UID_USES (uid); *rec; rec++)
2631     {
2632       df_ref use = *rec;
2633       unsigned int regno = DF_REF_REGNO (use);
2634
2635       /* When these refs are met for the first time, skip them, as
2636          these uses are just counterparts of some defs.  */
2637       if (bitmap_bit_p (tmp, regno))
2638         bitmap_clear_bit (tmp, regno);
2639       else if (! DF_REF_FLAGS_IS_SET (use, DF_REF_CALL_STACK_USAGE))
2640         {
2641           SET_REGNO_REG_SET (IDATA_REG_USES (id), regno);
2642
2643 #ifdef STACK_REGS
2644           /* For stack registers, treat reads from them as reads from 
2645              the first one to be consistent with sched-deps.c.  */
2646           if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG))
2647             SET_REGNO_REG_SET (IDATA_REG_USES (id), FIRST_STACK_REG);
2648 #endif
2649         }
2650     }
2651
2652   return_regset_to_pool (tmp);
2653 }
2654
2655 /* Initialize instruction data for INSN in ID using DF's data.  */
2656 static void
2657 init_id_from_df (idata_t id, insn_t insn, bool force_unique_p)
2658 {
2659   gcc_assert (DF_INSN_UID_SAFE_GET (INSN_UID (insn)) != NULL);
2660
2661   setup_id_for_insn (id, insn, force_unique_p);
2662   setup_id_lhs_rhs (id, insn, force_unique_p);
2663
2664   if (INSN_NOP_P (insn))
2665     return;
2666
2667   maybe_downgrade_id_to_use (id, insn);
2668   setup_id_reg_sets (id, insn);
2669 }
2670
2671 /* Initialize instruction data for INSN in ID.  */
2672 static void
2673 deps_init_id (idata_t id, insn_t insn, bool force_unique_p)
2674 {
2675   struct deps _dc, *dc = &_dc;
2676
2677   deps_init_id_data.where = DEPS_IN_NOWHERE;
2678   deps_init_id_data.id = id;
2679   deps_init_id_data.force_unique_p = force_unique_p;
2680   deps_init_id_data.force_use_p = false;
2681
2682   init_deps (dc);
2683
2684   memcpy (&deps_init_id_sched_deps_info,
2685           &const_deps_init_id_sched_deps_info,
2686           sizeof (deps_init_id_sched_deps_info));
2687
2688   if (spec_info != NULL)
2689     deps_init_id_sched_deps_info.generate_spec_deps = 1;
2690
2691   sched_deps_info = &deps_init_id_sched_deps_info;
2692
2693   deps_analyze_insn (dc, insn);
2694
2695   free_deps (dc);
2696
2697   deps_init_id_data.id = NULL;
2698 }
2699
2700 \f
2701
2702 /* Implement hooks for collecting fundamental insn properties like if insn is
2703    an ASM or is within a SCHED_GROUP.  */
2704
2705 /* True when a "one-time init" data for INSN was already inited.  */
2706 static bool
2707 first_time_insn_init (insn_t insn)
2708 {
2709   return INSN_LIVE (insn) == NULL;
2710 }
2711
2712 /* Hash an entry in a transformed_insns hashtable.  */
2713 static hashval_t
2714 hash_transformed_insns (const void *p)
2715 {
2716   return VINSN_HASH_RTX (((const struct transformed_insns *) p)->vinsn_old);
2717 }
2718
2719 /* Compare the entries in a transformed_insns hashtable.  */
2720 static int
2721 eq_transformed_insns (const void *p, const void *q)
2722 {
2723   rtx i1 = VINSN_INSN_RTX (((const struct transformed_insns *) p)->vinsn_old);
2724   rtx i2 = VINSN_INSN_RTX (((const struct transformed_insns *) q)->vinsn_old);
2725
2726   if (INSN_UID (i1) == INSN_UID (i2))
2727     return 1;
2728   return rtx_equal_p (PATTERN (i1), PATTERN (i2));
2729 }
2730
2731 /* Free an entry in a transformed_insns hashtable.  */
2732 static void
2733 free_transformed_insns (void *p)
2734 {
2735   struct transformed_insns *pti = (struct transformed_insns *) p;
2736
2737   vinsn_detach (pti->vinsn_old);
2738   vinsn_detach (pti->vinsn_new);
2739   free (pti);
2740 }
2741
2742 /* Init the s_i_d data for INSN which should be inited just once, when 
2743    we first see the insn.  */
2744 static void
2745 init_first_time_insn_data (insn_t insn)
2746 {
2747   /* This should not be set if this is the first time we init data for
2748      insn.  */
2749   gcc_assert (first_time_insn_init (insn));
2750   
2751   /* These are needed for nops too.  */
2752   INSN_LIVE (insn) = get_regset_from_pool ();
2753   INSN_LIVE_VALID_P (insn) = false;
2754   
2755   if (!INSN_NOP_P (insn))
2756     {
2757       INSN_ANALYZED_DEPS (insn) = BITMAP_ALLOC (NULL);
2758       INSN_FOUND_DEPS (insn) = BITMAP_ALLOC (NULL);
2759       INSN_TRANSFORMED_INSNS (insn) 
2760         = htab_create (16, hash_transformed_insns,
2761                        eq_transformed_insns, free_transformed_insns);
2762       init_deps (&INSN_DEPS_CONTEXT (insn));
2763     }
2764 }
2765
2766 /* Free the same data as above for INSN.  */
2767 static void
2768 free_first_time_insn_data (insn_t insn)
2769 {
2770   gcc_assert (! first_time_insn_init (insn));
2771
2772   BITMAP_FREE (INSN_ANALYZED_DEPS (insn));
2773   BITMAP_FREE (INSN_FOUND_DEPS (insn));
2774   htab_delete (INSN_TRANSFORMED_INSNS (insn));
2775   return_regset_to_pool (INSN_LIVE (insn));
2776   INSN_LIVE (insn) = NULL;
2777   INSN_LIVE_VALID_P (insn) = false;
2778
2779   /* This is allocated only for bookkeeping insns.  */
2780   if (INSN_ORIGINATORS (insn))
2781     BITMAP_FREE (INSN_ORIGINATORS (insn));
2782   free_deps (&INSN_DEPS_CONTEXT (insn));
2783 }
2784
2785 /* Initialize region-scope data structures for basic blocks.  */
2786 static void
2787 init_global_and_expr_for_bb (basic_block bb)
2788 {
2789   if (sel_bb_empty_p (bb))
2790     return;
2791
2792   invalidate_av_set (bb);
2793 }
2794
2795 /* Data for global dependency analysis (to initialize CANT_MOVE and
2796    SCHED_GROUP_P).  */
2797 static struct
2798 {
2799   /* Previous insn.  */
2800   insn_t prev_insn;
2801 } init_global_data;
2802
2803 /* Determine if INSN is in the sched_group, is an asm or should not be
2804    cloned.  After that initialize its expr.  */
2805 static void
2806 init_global_and_expr_for_insn (insn_t insn)
2807 {
2808   if (LABEL_P (insn))
2809     return;
2810
2811   if (NOTE_INSN_BASIC_BLOCK_P (insn))
2812     {
2813       init_global_data.prev_insn = NULL_RTX;
2814       return;
2815     }
2816
2817   gcc_assert (INSN_P (insn));
2818
2819   if (SCHED_GROUP_P (insn))
2820     /* Setup a sched_group.  */
2821     {
2822       insn_t prev_insn = init_global_data.prev_insn;
2823
2824       if (prev_insn)
2825         INSN_SCHED_NEXT (prev_insn) = insn;
2826
2827       init_global_data.prev_insn = insn;
2828     }
2829   else
2830     init_global_data.prev_insn = NULL_RTX;
2831
2832   if (GET_CODE (PATTERN (insn)) == ASM_INPUT
2833       || asm_noperands (PATTERN (insn)) >= 0)
2834     /* Mark INSN as an asm.  */
2835     INSN_ASM_P (insn) = true;
2836
2837   {
2838     bool force_unique_p;
2839     ds_t spec_done_ds;
2840
2841     /* Certain instructions cannot be cloned.  */
2842     if (CANT_MOVE (insn)
2843         || INSN_ASM_P (insn)
2844         || SCHED_GROUP_P (insn)
2845         || prologue_epilogue_contains (insn) 
2846         /* Exception handling insns are always unique.  */
2847         || (flag_non_call_exceptions && can_throw_internal (insn))
2848         /* TRAP_IF though have an INSN code is control_flow_insn_p ().  */
2849         || control_flow_insn_p (insn))
2850       force_unique_p = true;
2851     else
2852       force_unique_p = false;
2853
2854     if (targetm.sched.get_insn_spec_ds)
2855       {
2856         spec_done_ds = targetm.sched.get_insn_spec_ds (insn);
2857         spec_done_ds = ds_get_max_dep_weak (spec_done_ds);
2858       }
2859     else
2860       spec_done_ds = 0;
2861
2862     /* Initialize INSN's expr.  */
2863     init_expr (INSN_EXPR (insn), vinsn_create (insn, force_unique_p), 0,
2864                REG_BR_PROB_BASE, INSN_PRIORITY (insn), 0, BLOCK_NUM (insn),
2865                spec_done_ds, 0, 0, NULL, true, false, false, false, 
2866                CANT_MOVE (insn));
2867   }
2868
2869   init_first_time_insn_data (insn);
2870 }
2871
2872 /* Scan the region and initialize instruction data for basic blocks BBS.  */
2873 void
2874 sel_init_global_and_expr (bb_vec_t bbs)
2875 {
2876   /* ??? It would be nice to implement push / pop scheme for sched_infos.  */
2877   const struct sched_scan_info_def ssi =
2878     {
2879       NULL, /* extend_bb */
2880       init_global_and_expr_for_bb, /* init_bb */
2881       extend_insn_data, /* extend_insn */
2882       init_global_and_expr_for_insn /* init_insn */
2883     };
2884   
2885   sched_scan (&ssi, bbs, NULL, NULL, NULL);
2886 }
2887
2888 /* Finalize region-scope data structures for basic blocks.  */
2889 static void
2890 finish_global_and_expr_for_bb (basic_block bb)
2891 {
2892   av_set_clear (&BB_AV_SET (bb));
2893   BB_AV_LEVEL (bb) = 0;
2894 }
2895
2896 /* Finalize INSN's data.  */
2897 static void
2898 finish_global_and_expr_insn (insn_t insn)
2899 {
2900   if (LABEL_P (insn) || NOTE_INSN_BASIC_BLOCK_P (insn))
2901     return;
2902
2903   gcc_assert (INSN_P (insn));
2904
2905   if (INSN_LUID (insn) > 0)
2906     {
2907       free_first_time_insn_data (insn);
2908       INSN_WS_LEVEL (insn) = 0;
2909       CANT_MOVE (insn) = 0;
2910       
2911       /* We can no longer assert this, as vinsns of this insn could be 
2912          easily live in other insn's caches.  This should be changed to 
2913          a counter-like approach among all vinsns.  */
2914       gcc_assert (true || VINSN_COUNT (INSN_VINSN (insn)) == 1);
2915       clear_expr (INSN_EXPR (insn));
2916     }
2917 }
2918
2919 /* Finalize per instruction data for the whole region.  */
2920 void
2921 sel_finish_global_and_expr (void)
2922 {
2923   {
2924     bb_vec_t bbs;
2925     int i;
2926
2927     bbs = VEC_alloc (basic_block, heap, current_nr_blocks);
2928
2929     for (i = 0; i < current_nr_blocks; i++)
2930       VEC_quick_push (basic_block, bbs, BASIC_BLOCK (BB_TO_BLOCK (i)));
2931
2932     /* Clear AV_SETs and INSN_EXPRs.  */
2933     {
2934       const struct sched_scan_info_def ssi =
2935         {
2936           NULL, /* extend_bb */
2937           finish_global_and_expr_for_bb, /* init_bb */
2938           NULL, /* extend_insn */
2939           finish_global_and_expr_insn /* init_insn */
2940         };
2941
2942       sched_scan (&ssi, bbs, NULL, NULL, NULL);
2943     }
2944
2945     VEC_free (basic_block, heap, bbs);
2946   }
2947
2948   finish_insns ();
2949 }
2950 \f
2951
2952 /* In the below hooks, we merely calculate whether or not a dependence 
2953    exists, and in what part of insn.  However, we will need more data 
2954    when we'll start caching dependence requests.  */
2955
2956 /* Container to hold information for dependency analysis.  */
2957 static struct
2958 {
2959   deps_t dc;
2960
2961   /* A variable to track which part of rtx we are scanning in
2962      sched-deps.c: sched_analyze_insn ().  */
2963   deps_where_t where;
2964
2965   /* Current producer.  */
2966   insn_t pro;
2967
2968   /* Current consumer.  */
2969   vinsn_t con;
2970
2971   /* Is SEL_DEPS_HAS_DEP_P[DEPS_IN_X] is true, then X has a dependence.
2972      X is from { INSN, LHS, RHS }.  */
2973   ds_t has_dep_p[DEPS_IN_NOWHERE];
2974 } has_dependence_data;
2975
2976 /* Start analyzing dependencies of INSN.  */
2977 static void
2978 has_dependence_start_insn (insn_t insn ATTRIBUTE_UNUSED)
2979 {
2980   gcc_assert (has_dependence_data.where == DEPS_IN_NOWHERE);
2981
2982   has_dependence_data.where = DEPS_IN_INSN;
2983 }
2984
2985 /* Finish analyzing dependencies of an insn.  */
2986 static void
2987 has_dependence_finish_insn (void)
2988 {
2989   gcc_assert (has_dependence_data.where == DEPS_IN_INSN);
2990
2991   has_dependence_data.where = DEPS_IN_NOWHERE;
2992 }
2993
2994 /* Start analyzing dependencies of LHS.  */
2995 static void
2996 has_dependence_start_lhs (rtx lhs ATTRIBUTE_UNUSED)
2997 {
2998   gcc_assert (has_dependence_data.where == DEPS_IN_INSN);
2999
3000   if (VINSN_LHS (has_dependence_data.con) != NULL)
3001     has_dependence_data.where = DEPS_IN_LHS;
3002 }
3003
3004 /* Finish analyzing dependencies of an lhs.  */
3005 static void
3006 has_dependence_finish_lhs (void)
3007 {
3008   has_dependence_data.where = DEPS_IN_INSN;
3009 }
3010
3011 /* Start analyzing dependencies of RHS.  */
3012 static void
3013 has_dependence_start_rhs (rtx rhs ATTRIBUTE_UNUSED)
3014 {
3015   gcc_assert (has_dependence_data.where == DEPS_IN_INSN);
3016
3017   if (VINSN_RHS (has_dependence_data.con) != NULL)
3018     has_dependence_data.where = DEPS_IN_RHS;
3019 }
3020
3021 /* Start analyzing dependencies of an rhs.  */
3022 static void
3023 has_dependence_finish_rhs (void)
3024 {
3025   gcc_assert (has_dependence_data.where == DEPS_IN_RHS
3026               || has_dependence_data.where == DEPS_IN_INSN);
3027
3028   has_dependence_data.where = DEPS_IN_INSN;
3029 }
3030
3031 /* Note a set of REGNO.  */
3032 static void
3033 has_dependence_note_reg_set (int regno)
3034 {
3035   struct deps_reg *reg_last = &has_dependence_data.dc->reg_last[regno];
3036
3037   if (!sched_insns_conditions_mutex_p (has_dependence_data.pro,
3038                                        VINSN_INSN_RTX
3039                                        (has_dependence_data.con)))
3040     {
3041       ds_t *dsp = &has_dependence_data.has_dep_p[has_dependence_data.where];
3042
3043       if (reg_last->sets != NULL
3044           || reg_last->clobbers != NULL)
3045         *dsp = (*dsp & ~SPECULATIVE) | DEP_OUTPUT;
3046
3047       if (reg_last->uses)
3048         *dsp = (*dsp & ~SPECULATIVE) | DEP_ANTI;
3049     }
3050 }
3051
3052 /* Note a clobber of REGNO.  */
3053 static void
3054 has_dependence_note_reg_clobber (int regno)
3055 {
3056   struct deps_reg *reg_last = &has_dependence_data.dc->reg_last[regno];
3057
3058   if (!sched_insns_conditions_mutex_p (has_dependence_data.pro,
3059                                        VINSN_INSN_RTX
3060                                        (has_dependence_data.con)))
3061     {
3062       ds_t *dsp = &has_dependence_data.has_dep_p[has_dependence_data.where];
3063
3064       if (reg_last->sets)
3065         *dsp = (*dsp & ~SPECULATIVE) | DEP_OUTPUT;
3066         
3067       if (reg_last->uses)
3068         *dsp = (*dsp & ~SPECULATIVE) | DEP_ANTI;
3069     }
3070 }
3071
3072 /* Note a use of REGNO.  */
3073 static void
3074 has_dependence_note_reg_use (int regno)
3075 {
3076   struct deps_reg *reg_last = &has_dependence_data.dc->reg_last[regno];
3077
3078   if (!sched_insns_conditions_mutex_p (has_dependence_data.pro,
3079                                        VINSN_INSN_RTX
3080                                        (has_dependence_data.con)))
3081     {
3082       ds_t *dsp = &has_dependence_data.has_dep_p[has_dependence_data.where];
3083
3084       if (reg_last->sets)
3085         *dsp = (*dsp & ~SPECULATIVE) | DEP_TRUE;
3086
3087       if (reg_last->clobbers)
3088         *dsp = (*dsp & ~SPECULATIVE) | DEP_ANTI;
3089
3090       /* Handle BE_IN_SPEC.  */
3091       if (reg_last->uses)
3092         {
3093           ds_t pro_spec_checked_ds;
3094
3095           pro_spec_checked_ds = INSN_SPEC_CHECKED_DS (has_dependence_data.pro);
3096           pro_spec_checked_ds = ds_get_max_dep_weak (pro_spec_checked_ds);
3097
3098           if (pro_spec_checked_ds != 0)
3099             /* Merge BE_IN_SPEC bits into *DSP.  */
3100             *dsp = ds_full_merge (*dsp, pro_spec_checked_ds,
3101                                   NULL_RTX, NULL_RTX);
3102         }
3103     }
3104 }
3105
3106 /* Note a memory dependence.  */
3107 static void
3108 has_dependence_note_mem_dep (rtx mem ATTRIBUTE_UNUSED,
3109                              rtx pending_mem ATTRIBUTE_UNUSED,
3110                              insn_t pending_insn ATTRIBUTE_UNUSED,
3111                              ds_t ds ATTRIBUTE_UNUSED)
3112 {
3113   if (!sched_insns_conditions_mutex_p (has_dependence_data.pro,
3114                                        VINSN_INSN_RTX (has_dependence_data.con)))
3115     {
3116       ds_t *dsp = &has_dependence_data.has_dep_p[has_dependence_data.where];
3117
3118       *dsp = ds_full_merge (ds, *dsp, pending_mem, mem);
3119     }
3120 }
3121
3122 /* Note a dependence.  */
3123 static void
3124 has_dependence_note_dep (insn_t pro ATTRIBUTE_UNUSED,
3125                          ds_t ds ATTRIBUTE_UNUSED)
3126 {
3127   if (!sched_insns_conditions_mutex_p (has_dependence_data.pro,
3128                                        VINSN_INSN_RTX (has_dependence_data.con)))
3129     {
3130       ds_t *dsp = &has_dependence_data.has_dep_p[has_dependence_data.where];
3131
3132       *dsp = ds_full_merge (ds, *dsp, NULL_RTX, NULL_RTX);
3133     }
3134 }
3135
3136 /* Mark the insn as having a hard dependence that prevents speculation.  */
3137 void
3138 sel_mark_hard_insn (rtx insn)
3139 {
3140   int i;
3141
3142   /* Only work when we're in has_dependence_p mode.
3143      ??? This is a hack, this should actually be a hook.  */
3144   if (!has_dependence_data.dc || !has_dependence_data.pro)
3145     return;
3146
3147   gcc_assert (insn == VINSN_INSN_RTX (has_dependence_data.con));
3148   gcc_assert (has_dependence_data.where == DEPS_IN_INSN);
3149
3150   for (i = 0; i < DEPS_IN_NOWHERE; i++)
3151     has_dependence_data.has_dep_p[i] &= ~SPECULATIVE;
3152 }
3153
3154 /* This structure holds the hooks for the dependency analysis used when
3155    actually processing dependencies in the scheduler.  */
3156 static struct sched_deps_info_def has_dependence_sched_deps_info;
3157
3158 /* This initializes most of the fields of the above structure.  */
3159 static const struct sched_deps_info_def const_has_dependence_sched_deps_info =
3160   {
3161     NULL,
3162
3163     has_dependence_start_insn,
3164     has_dependence_finish_insn,
3165     has_dependence_start_lhs,
3166     has_dependence_finish_lhs,
3167     has_dependence_start_rhs,
3168     has_dependence_finish_rhs,
3169     has_dependence_note_reg_set,
3170     has_dependence_note_reg_clobber,
3171     has_dependence_note_reg_use,
3172     has_dependence_note_mem_dep,
3173     has_dependence_note_dep,
3174
3175     0, /* use_cselib */
3176     0, /* use_deps_list */
3177     0 /* generate_spec_deps */
3178   };
3179
3180 /* Initialize has_dependence_sched_deps_info with extra spec field.  */
3181 static void
3182 setup_has_dependence_sched_deps_info (void)
3183 {
3184   memcpy (&has_dependence_sched_deps_info,
3185           &const_has_dependence_sched_deps_info,
3186           sizeof (has_dependence_sched_deps_info));
3187
3188   if (spec_info != NULL)
3189     has_dependence_sched_deps_info.generate_spec_deps = 1;
3190
3191   sched_deps_info = &has_dependence_sched_deps_info;
3192 }
3193
3194 /* Remove all dependences found and recorded in has_dependence_data array.  */
3195 void
3196 sel_clear_has_dependence (void)
3197 {
3198   int i;
3199
3200   for (i = 0; i < DEPS_IN_NOWHERE; i++)
3201     has_dependence_data.has_dep_p[i] = 0;
3202 }
3203
3204 /* Return nonzero if EXPR has is dependent upon PRED.  Return the pointer
3205    to the dependence information array in HAS_DEP_PP.  */
3206 ds_t
3207 has_dependence_p (expr_t expr, insn_t pred, ds_t **has_dep_pp)
3208 {
3209   int i;
3210   ds_t ds;
3211   struct deps *dc;
3212
3213   if (INSN_SIMPLEJUMP_P (pred))
3214     /* Unconditional jump is just a transfer of control flow.
3215        Ignore it.  */
3216     return false;
3217
3218   dc = &INSN_DEPS_CONTEXT (pred);
3219   if (!dc->readonly)
3220     {
3221       has_dependence_data.pro = NULL;
3222       /* Initialize empty dep context with information about PRED.  */
3223       advance_deps_context (dc, pred);
3224       dc->readonly = 1;
3225     }
3226
3227   has_dependence_data.where = DEPS_IN_NOWHERE;
3228   has_dependence_data.pro = pred;
3229   has_dependence_data.con = EXPR_VINSN (expr);
3230   has_dependence_data.dc = dc;
3231
3232   sel_clear_has_dependence ();
3233
3234   /* Now catch all dependencies that would be generated between PRED and
3235      INSN.  */
3236   setup_has_dependence_sched_deps_info ();
3237   deps_analyze_insn (dc, EXPR_INSN_RTX (expr));
3238   has_dependence_data.dc = NULL;
3239
3240   /* When a barrier was found, set DEPS_IN_INSN bits.  */
3241   if (dc->last_reg_pending_barrier == TRUE_BARRIER)
3242     has_dependence_data.has_dep_p[DEPS_IN_INSN] = DEP_TRUE;
3243   else if (dc->last_reg_pending_barrier == MOVE_BARRIER)
3244     has_dependence_data.has_dep_p[DEPS_IN_INSN] = DEP_ANTI;
3245
3246   /* Do not allow stores to memory to move through checks.  Currently
3247      we don't move this to sched-deps.c as the check doesn't have
3248      obvious places to which this dependence can be attached.  
3249      FIMXE: this should go to a hook.  */
3250   if (EXPR_LHS (expr)
3251       && MEM_P (EXPR_LHS (expr))
3252       && sel_insn_is_speculation_check (pred))
3253     has_dependence_data.has_dep_p[DEPS_IN_INSN] = DEP_ANTI;
3254   
3255   *has_dep_pp = has_dependence_data.has_dep_p;
3256   ds = 0;
3257   for (i = 0; i < DEPS_IN_NOWHERE; i++)
3258     ds = ds_full_merge (ds, has_dependence_data.has_dep_p[i],
3259                         NULL_RTX, NULL_RTX);
3260
3261   return ds;
3262 }
3263 \f
3264
3265 /* Dependence hooks implementation that checks dependence latency constraints 
3266    on the insns being scheduled.  The entry point for these routines is 
3267    tick_check_p predicate.  */ 
3268
3269 static struct
3270 {
3271   /* An expr we are currently checking.  */
3272   expr_t expr;
3273
3274   /* A minimal cycle for its scheduling.  */
3275   int cycle;
3276
3277   /* Whether we have seen a true dependence while checking.  */
3278   bool seen_true_dep_p;
3279 } tick_check_data;
3280
3281 /* Update minimal scheduling cycle for tick_check_insn given that it depends
3282    on PRO with status DS and weight DW.  */
3283 static void
3284 tick_check_dep_with_dw (insn_t pro_insn, ds_t ds, dw_t dw)
3285 {
3286   expr_t con_expr = tick_check_data.expr;
3287   insn_t con_insn = EXPR_INSN_RTX (con_expr);
3288
3289   if (con_insn != pro_insn)
3290     {
3291       enum reg_note dt;
3292       int tick;
3293
3294       if (/* PROducer was removed from above due to pipelining.  */
3295           !INSN_IN_STREAM_P (pro_insn)
3296           /* Or PROducer was originally on the next iteration regarding the
3297              CONsumer.  */
3298           || (INSN_SCHED_TIMES (pro_insn)
3299               - EXPR_SCHED_TIMES (con_expr)) > 1)
3300         /* Don't count this dependence.  */
3301         return;
3302
3303       dt = ds_to_dt (ds);
3304       if (dt == REG_DEP_TRUE)
3305         tick_check_data.seen_true_dep_p = true;
3306
3307       gcc_assert (INSN_SCHED_CYCLE (pro_insn) > 0);
3308
3309       {
3310         dep_def _dep, *dep = &_dep;
3311
3312         init_dep (dep, pro_insn, con_insn, dt);
3313
3314         tick = INSN_SCHED_CYCLE (pro_insn) + dep_cost_1 (dep, dw);
3315       }
3316
3317       /* When there are several kinds of dependencies between pro and con,
3318          only REG_DEP_TRUE should be taken into account.  */
3319       if (tick > tick_check_data.cycle
3320           && (dt == REG_DEP_TRUE || !tick_check_data.seen_true_dep_p))
3321         tick_check_data.cycle = tick;
3322     }
3323 }
3324
3325 /* An implementation of note_dep hook.  */
3326 static void
3327 tick_check_note_dep (insn_t pro, ds_t ds)
3328 {
3329   tick_check_dep_with_dw (pro, ds, 0);
3330 }
3331
3332 /* An implementation of note_mem_dep hook.  */
3333 static void
3334 tick_check_note_mem_dep (rtx mem1, rtx mem2, insn_t pro, ds_t ds)
3335 {
3336   dw_t dw;
3337
3338   dw = (ds_to_dt (ds) == REG_DEP_TRUE
3339         ? estimate_dep_weak (mem1, mem2)
3340         : 0);
3341
3342   tick_check_dep_with_dw (pro, ds, dw);
3343 }
3344
3345 /* This structure contains hooks for dependence analysis used when determining
3346    whether an insn is ready for scheduling.  */
3347 static struct sched_deps_info_def tick_check_sched_deps_info =
3348   {
3349     NULL,
3350
3351     NULL,
3352     NULL,
3353     NULL,
3354     NULL,
3355     NULL,
3356     NULL,
3357     haifa_note_reg_set,
3358     haifa_note_reg_clobber,
3359     haifa_note_reg_use,
3360     tick_check_note_mem_dep,
3361     tick_check_note_dep,
3362
3363     0, 0, 0
3364   };
3365
3366 /* Estimate number of cycles from the current cycle of FENCE until EXPR can be
3367    scheduled.  Return 0 if all data from producers in DC is ready.  */
3368 int
3369 tick_check_p (expr_t expr, deps_t dc, fence_t fence)
3370 {
3371   int cycles_left;
3372   /* Initialize variables.  */
3373   tick_check_data.expr = expr;
3374   tick_check_data.cycle = 0;
3375   tick_check_data.seen_true_dep_p = false;
3376   sched_deps_info = &tick_check_sched_deps_info;
3377   
3378   gcc_assert (!dc->readonly);
3379   dc->readonly = 1;
3380   deps_analyze_insn (dc, EXPR_INSN_RTX (expr));
3381   dc->readonly = 0;
3382
3383   cycles_left = tick_check_data.cycle - FENCE_CYCLE (fence);
3384
3385   return cycles_left >= 0 ? cycles_left : 0;
3386 }
3387 \f
3388
3389 /* Functions to work with insns.  */
3390
3391 /* Returns true if LHS of INSN is the same as DEST of an insn
3392    being moved.  */
3393 bool
3394 lhs_of_insn_equals_to_dest_p (insn_t insn, rtx dest)
3395 {
3396   rtx lhs = INSN_LHS (insn);
3397
3398   if (lhs == NULL || dest == NULL)
3399     return false;
3400   
3401   return rtx_equal_p (lhs, dest);
3402 }
3403
3404 /* Return s_i_d entry of INSN.  Callable from debugger.  */
3405 sel_insn_data_def
3406 insn_sid (insn_t insn)
3407 {
3408   return *SID (insn);
3409 }
3410
3411 /* True when INSN is a speculative check.  We can tell this by looking
3412    at the data structures of the selective scheduler, not by examining
3413    the pattern.  */
3414 bool
3415 sel_insn_is_speculation_check (rtx insn)
3416 {
3417   return s_i_d && !! INSN_SPEC_CHECKED_DS (insn);
3418 }
3419
3420 /* Extracts machine mode MODE and destination location DST_LOC 
3421    for given INSN.  */
3422 void
3423 get_dest_and_mode (rtx insn, rtx *dst_loc, enum machine_mode *mode)
3424 {
3425   rtx pat = PATTERN (insn);
3426
3427   gcc_assert (dst_loc);
3428   gcc_assert (GET_CODE (pat) == SET);
3429
3430   *dst_loc = SET_DEST (pat);
3431
3432   gcc_assert (*dst_loc);
3433   gcc_assert (MEM_P (*dst_loc) || REG_P (*dst_loc));
3434
3435   if (mode)
3436     *mode = GET_MODE (*dst_loc);
3437 }
3438
3439 /* Returns true when moving through JUMP will result in bookkeeping 
3440    creation.  */
3441 bool
3442 bookkeeping_can_be_created_if_moved_through_p (insn_t jump)
3443 {
3444   insn_t succ;
3445   succ_iterator si;
3446
3447   FOR_EACH_SUCC (succ, si, jump)
3448     if (sel_num_cfg_preds_gt_1 (succ))
3449       return true;
3450
3451   return false;
3452 }
3453
3454 /* Return 'true' if INSN is the only one in its basic block.  */
3455 static bool
3456 insn_is_the_only_one_in_bb_p (insn_t insn)
3457 {
3458   return sel_bb_head_p (insn) && sel_bb_end_p (insn);
3459 }
3460
3461 #ifdef ENABLE_CHECKING
3462 /* Check that the region we're scheduling still has at most one 
3463    backedge.  */
3464 static void
3465 verify_backedges (void)
3466 {
3467   if (pipelining_p)
3468     {
3469       int i, n = 0;
3470       edge e;
3471       edge_iterator ei;
3472           
3473       for (i = 0; i < current_nr_blocks; i++)
3474         FOR_EACH_EDGE (e, ei, BASIC_BLOCK (BB_TO_BLOCK (i))->succs)
3475           if (in_current_region_p (e->dest)
3476               && BLOCK_TO_BB (e->dest->index) < i)
3477             n++;
3478           
3479       gcc_assert (n <= 1);
3480     }
3481 }
3482 #endif
3483 \f
3484
3485 /* Functions to work with control flow.  */
3486
3487 /* Tidy the possibly empty block BB.  */
3488 bool
3489 maybe_tidy_empty_bb (basic_block bb)
3490 {
3491   basic_block succ_bb, pred_bb;
3492   bool rescan_p;
3493
3494   /* Keep empty bb only if this block immediately precedes EXIT and
3495      has incoming non-fallthrough edge.  Otherwise remove it.  */
3496   if (!sel_bb_empty_p (bb) 
3497       || (single_succ_p (bb) 
3498           && single_succ (bb) == EXIT_BLOCK_PTR
3499           && (!single_pred_p (bb) 
3500               || !(single_pred_edge (bb)->flags & EDGE_FALLTHRU))))
3501     return false;
3502
3503   free_data_sets (bb);
3504
3505   /* Do not delete BB if it has more than one successor.
3506      That can occur when we moving a jump.  */
3507   if (!single_succ_p (bb))
3508     {
3509       gcc_assert (can_merge_blocks_p (bb->prev_bb, bb));
3510       sel_merge_blocks (bb->prev_bb, bb);
3511       return true;
3512     }
3513
3514   succ_bb = single_succ (bb);
3515   rescan_p = true;
3516   pred_bb = NULL;
3517
3518   /* Redirect all non-fallthru edges to the next bb.  */
3519   while (rescan_p)
3520     {
3521       edge e;
3522       edge_iterator ei;
3523
3524       rescan_p = false;
3525
3526       FOR_EACH_EDGE (e, ei, bb->preds)
3527         {
3528           pred_bb = e->src;
3529
3530           if (!(e->flags & EDGE_FALLTHRU))
3531             {
3532               sel_redirect_edge_and_branch (e, succ_bb);
3533               rescan_p = true;
3534               break;
3535             }
3536         }
3537     }
3538
3539   /* If it is possible - merge BB with its predecessor.  */
3540   if (can_merge_blocks_p (bb->prev_bb, bb))
3541     sel_merge_blocks (bb->prev_bb, bb);
3542   else
3543     /* Otherwise this is a block without fallthru predecessor.
3544        Just delete it.  */
3545     {
3546       gcc_assert (pred_bb != NULL);
3547
3548       move_bb_info (pred_bb, bb);
3549       remove_empty_bb (bb, true);
3550     }
3551
3552 #ifdef ENABLE_CHECKING
3553   verify_backedges ();
3554 #endif
3555
3556   return true;
3557 }
3558
3559 /* Tidy the control flow after we have removed original insn from 
3560    XBB.  Return true if we have removed some blocks.  When FULL_TIDYING
3561    is true, also try to optimize control flow on non-empty blocks.  */
3562 bool
3563 tidy_control_flow (basic_block xbb, bool full_tidying)
3564 {
3565   bool changed = true;
3566   
3567   /* First check whether XBB is empty.  */
3568   changed = maybe_tidy_empty_bb (xbb);
3569   if (changed || !full_tidying)
3570     return changed;
3571   
3572   /* Check if there is a unnecessary jump after insn left.  */
3573   if (jump_leads_only_to_bb_p (BB_END (xbb), xbb->next_bb)
3574       && INSN_SCHED_TIMES (BB_END (xbb)) == 0
3575       && !IN_CURRENT_FENCE_P (BB_END (xbb)))
3576     {
3577       if (sel_remove_insn (BB_END (xbb), false, false))
3578         return true;
3579       tidy_fallthru_edge (EDGE_SUCC (xbb, 0));
3580     }
3581
3582   /* Check if there is an unnecessary jump in previous basic block leading
3583      to next basic block left after removing INSN from stream.  
3584      If it is so, remove that jump and redirect edge to current 
3585      basic block (where there was INSN before deletion).  This way 
3586      when NOP will be deleted several instructions later with its 
3587      basic block we will not get a jump to next instruction, which 
3588      can be harmful.  */
3589   if (sel_bb_head (xbb) == sel_bb_end (xbb) 
3590       && !sel_bb_empty_p (xbb)
3591       && INSN_NOP_P (sel_bb_end (xbb))
3592       /* Flow goes fallthru from current block to the next.  */
3593       && EDGE_COUNT (xbb->succs) == 1
3594       && (EDGE_SUCC (xbb, 0)->flags & EDGE_FALLTHRU)
3595       /* When successor is an EXIT block, it may not be the next block.  */
3596       && single_succ (xbb) != EXIT_BLOCK_PTR
3597       /* And unconditional jump in previous basic block leads to
3598          next basic block of XBB and this jump can be safely removed.  */
3599       && in_current_region_p (xbb->prev_bb)
3600       && jump_leads_only_to_bb_p (BB_END (xbb->prev_bb), xbb->next_bb)
3601       && INSN_SCHED_TIMES (BB_END (xbb->prev_bb)) == 0
3602       /* Also this jump is not at the scheduling boundary.  */
3603       && !IN_CURRENT_FENCE_P (BB_END (xbb->prev_bb)))
3604     {
3605       /* Clear data structures of jump - jump itself will be removed
3606          by sel_redirect_edge_and_branch.  */
3607       clear_expr (INSN_EXPR (BB_END (xbb->prev_bb)));
3608       sel_redirect_edge_and_branch (EDGE_SUCC (xbb->prev_bb, 0), xbb);
3609       gcc_assert (EDGE_SUCC (xbb->prev_bb, 0)->flags & EDGE_FALLTHRU);
3610
3611       /* It can turn out that after removing unused jump, basic block
3612          that contained that jump, becomes empty too.  In such case
3613          remove it too.  */
3614       if (sel_bb_empty_p (xbb->prev_bb))
3615         changed = maybe_tidy_empty_bb (xbb->prev_bb);
3616     }
3617
3618   return changed;
3619 }
3620
3621 /* Rip-off INSN from the insn stream.  When ONLY_DISCONNECT is true, 
3622    do not delete insn's data, because it will be later re-emitted.  
3623    Return true if we have removed some blocks afterwards.  */
3624 bool
3625 sel_remove_insn (insn_t insn, bool only_disconnect, bool full_tidying)
3626 {
3627   basic_block bb = BLOCK_FOR_INSN (insn);
3628
3629   gcc_assert (INSN_IN_STREAM_P (insn));
3630
3631   if (only_disconnect)
3632     {
3633       insn_t prev = PREV_INSN (insn);
3634       insn_t next = NEXT_INSN (insn);
3635       basic_block bb = BLOCK_FOR_INSN (insn);
3636
3637       NEXT_INSN (prev) = next;
3638       PREV_INSN (next) = prev;
3639
3640       if (BB_HEAD (bb) == insn)
3641         {
3642           gcc_assert (BLOCK_FOR_INSN (prev) == bb);
3643           BB_HEAD (bb) = prev;
3644         }
3645       if (BB_END (bb) == insn)
3646         BB_END (bb) = prev;
3647     }
3648   else
3649     {
3650       remove_insn (insn);
3651       clear_expr (INSN_EXPR (insn));
3652     }
3653
3654   /* It is necessary to null this fields before calling add_insn ().  */
3655   PREV_INSN (insn) = NULL_RTX;
3656   NEXT_INSN (insn) = NULL_RTX;
3657
3658   return tidy_control_flow (bb, full_tidying);
3659 }
3660
3661 /* Estimate number of the insns in BB.  */
3662 static int
3663 sel_estimate_number_of_insns (basic_block bb)
3664 {
3665   int res = 0;
3666   insn_t insn = NEXT_INSN (BB_HEAD (bb)), next_tail = NEXT_INSN (BB_END (bb));
3667
3668   for (; insn != next_tail; insn = NEXT_INSN (insn))
3669     if (INSN_P (insn))
3670       res++;
3671
3672   return res;
3673 }
3674
3675 /* We don't need separate luids for notes or labels.  */
3676 static int
3677 sel_luid_for_non_insn (rtx x)
3678 {
3679   gcc_assert (NOTE_P (x) || LABEL_P (x));
3680
3681   return -1;
3682 }
3683
3684 /* Return seqno of the only predecessor of INSN.  */
3685 static int
3686 get_seqno_of_a_pred (insn_t insn)
3687 {
3688   int seqno;
3689
3690   gcc_assert (INSN_SIMPLEJUMP_P (insn));
3691
3692   if (!sel_bb_head_p (insn))
3693     seqno = INSN_SEQNO (PREV_INSN (insn));
3694   else
3695     {
3696       basic_block bb = BLOCK_FOR_INSN (insn);
3697
3698       if (single_pred_p (bb)
3699           && !in_current_region_p (single_pred (bb)))
3700         {
3701           /* We can have preds outside a region when splitting edges
3702              for pipelining of an outer loop.  Use succ instead.  
3703              There should be only one of them.  */
3704           insn_t succ = NULL;
3705           succ_iterator si;
3706           bool first = true;
3707           
3708           gcc_assert (flag_sel_sched_pipelining_outer_loops
3709                       && current_loop_nest);
3710           FOR_EACH_SUCC_1 (succ, si, insn, 
3711                            SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
3712             {
3713               gcc_assert (first);
3714               first = false;
3715             }
3716
3717           gcc_assert (succ != NULL);
3718           seqno = INSN_SEQNO (succ);
3719         }
3720       else
3721         {
3722           insn_t *preds;
3723           int n;
3724
3725           cfg_preds (BLOCK_FOR_INSN (insn), &preds, &n);
3726           gcc_assert (n == 1);
3727
3728           seqno = INSN_SEQNO (preds[0]);
3729               
3730           free (preds);
3731         }
3732     }
3733
3734   return seqno;
3735 }
3736
3737 /*  Find the proper seqno for inserting at INSN.  */
3738 int
3739 get_seqno_by_preds (rtx insn)
3740 {
3741   basic_block bb = BLOCK_FOR_INSN (insn);
3742   rtx tmp = insn, head = BB_HEAD (bb);
3743   insn_t *preds;
3744   int n, i, seqno;
3745
3746   while (tmp != head)
3747     if (INSN_P (tmp))
3748       return INSN_SEQNO (tmp);
3749     else
3750       tmp = PREV_INSN (tmp);
3751   
3752   cfg_preds (bb, &preds, &n);
3753   for (i = 0, seqno = -1; i < n; i++)
3754     seqno = MAX (seqno, INSN_SEQNO (preds[i]));
3755
3756   gcc_assert (seqno > 0);
3757   return seqno;
3758 }
3759
3760 \f
3761
3762 /* Extend pass-scope data structures for basic blocks.  */
3763 void
3764 sel_extend_global_bb_info (void)
3765 {
3766   VEC_safe_grow_cleared (sel_global_bb_info_def, heap, sel_global_bb_info,
3767                          last_basic_block);
3768 }
3769
3770 /* Extend region-scope data structures for basic blocks.  */
3771 static void
3772 extend_region_bb_info (void)
3773 {
3774   VEC_safe_grow_cleared (sel_region_bb_info_def, heap, sel_region_bb_info,
3775                          last_basic_block);
3776 }
3777
3778 /* Extend all data structures to fit for all basic blocks.  */
3779 static void
3780 extend_bb_info (void)
3781 {
3782   sel_extend_global_bb_info ();
3783   extend_region_bb_info ();
3784 }
3785
3786 /* Finalize pass-scope data structures for basic blocks.  */
3787 void
3788 sel_finish_global_bb_info (void)
3789 {
3790   VEC_free (sel_global_bb_info_def, heap, sel_global_bb_info);
3791 }
3792
3793 /* Finalize region-scope data structures for basic blocks.  */
3794 static void
3795 finish_region_bb_info (void)
3796 {
3797   VEC_free (sel_region_bb_info_def, heap, sel_region_bb_info);
3798 }
3799 \f
3800
3801 /* Data for each insn in current region.  */
3802 VEC (sel_insn_data_def, heap) *s_i_d = NULL;
3803
3804 /* A vector for the insns we've emitted.  */
3805 static insn_vec_t new_insns = NULL;
3806
3807 /* Extend data structures for insns from current region.  */
3808 static void
3809 extend_insn_data (void)
3810 {
3811   int reserve;
3812   
3813   sched_extend_target ();
3814   sched_deps_init (false);
3815
3816   /* Extend data structures for insns from current region.  */
3817   reserve = (sched_max_luid + 1 
3818              - VEC_length (sel_insn_data_def, s_i_d));
3819   if (reserve > 0 
3820       && ! VEC_space (sel_insn_data_def, s_i_d, reserve))
3821     VEC_safe_grow_cleared (sel_insn_data_def, heap, s_i_d,
3822                            3 * sched_max_luid / 2);
3823 }
3824
3825 /* Finalize data structures for insns from current region.  */
3826 static void
3827 finish_insns (void)
3828 {
3829   unsigned i;
3830
3831   /* Clear here all dependence contexts that may have left from insns that were
3832      removed during the scheduling.  */
3833   for (i = 0; i < VEC_length (sel_insn_data_def, s_i_d); i++)
3834     {
3835       sel_insn_data_def *sid_entry = VEC_index (sel_insn_data_def, s_i_d, i);
3836       
3837       if (sid_entry->live)
3838         return_regset_to_pool (sid_entry->live);
3839       if (sid_entry->analyzed_deps)
3840         {
3841           BITMAP_FREE (sid_entry->analyzed_deps);
3842           BITMAP_FREE (sid_entry->found_deps);
3843           htab_delete (sid_entry->transformed_insns);
3844           free_deps (&sid_entry->deps_context);
3845         }
3846       if (EXPR_VINSN (&sid_entry->expr))
3847         {
3848           clear_expr (&sid_entry->expr);
3849           
3850           /* Also, clear CANT_MOVE bit here, because we really don't want it
3851              to be passed to the next region.  */
3852           CANT_MOVE_BY_LUID (i) = 0;
3853         }
3854     }
3855   
3856   VEC_free (sel_insn_data_def, heap, s_i_d);
3857 }
3858
3859 /* A proxy to pass initialization data to init_insn ().  */
3860 static sel_insn_data_def _insn_init_ssid;
3861 static sel_insn_data_t insn_init_ssid = &_insn_init_ssid;
3862
3863 /* If true create a new vinsn.  Otherwise use the one from EXPR.  */
3864 static bool insn_init_create_new_vinsn_p;
3865
3866 /* Set all necessary data for initialization of the new insn[s].  */
3867 static expr_t
3868 set_insn_init (expr_t expr, vinsn_t vi, int seqno)
3869 {
3870   expr_t x = &insn_init_ssid->expr;
3871
3872   copy_expr_onside (x, expr);
3873   if (vi != NULL)
3874     {
3875       insn_init_create_new_vinsn_p = false;
3876       change_vinsn_in_expr (x, vi);
3877     }
3878   else
3879     insn_init_create_new_vinsn_p = true;
3880
3881   insn_init_ssid->seqno = seqno;
3882   return x;
3883 }
3884
3885 /* Init data for INSN.  */
3886 static void
3887 init_insn_data (insn_t insn)
3888 {
3889   expr_t expr;
3890   sel_insn_data_t ssid = insn_init_ssid;
3891
3892   /* The fields mentioned below are special and hence are not being
3893      propagated to the new insns.  */
3894   gcc_assert (!ssid->asm_p && ssid->sched_next == NULL
3895               && !ssid->after_stall_p && ssid->sched_cycle == 0);
3896   gcc_assert (INSN_P (insn) && INSN_LUID (insn) > 0);
3897
3898   expr = INSN_EXPR (insn);
3899   copy_expr (expr, &ssid->expr);
3900   prepare_insn_expr (insn, ssid->seqno);
3901
3902   if (insn_init_create_new_vinsn_p)
3903     change_vinsn_in_expr (expr, vinsn_create (insn, init_insn_force_unique_p));
3904   
3905   if (first_time_insn_init (insn))
3906     init_first_time_insn_data (insn);
3907 }
3908
3909 /* This is used to initialize spurious jumps generated by
3910    sel_redirect_edge ().  */
3911 static void
3912 init_simplejump_data (insn_t insn)
3913 {
3914   init_expr (INSN_EXPR (insn), vinsn_create (insn, false), 0,
3915              REG_BR_PROB_BASE, 0, 0, 0, 0, 0, 0, NULL, true, false, false, 
3916              false, true);
3917   INSN_SEQNO (insn) = get_seqno_of_a_pred (insn);
3918   init_first_time_insn_data (insn);
3919 }
3920
3921 /* Perform deferred initialization of insns.  This is used to process 
3922    a new jump that may be created by redirect_edge.  */
3923 void
3924 sel_init_new_insn (insn_t insn, int flags)
3925 {
3926   /* We create data structures for bb when the first insn is emitted in it.  */
3927   if (INSN_P (insn)
3928       && INSN_IN_STREAM_P (insn)
3929       && insn_is_the_only_one_in_bb_p (insn))
3930     {
3931       extend_bb_info ();
3932       create_initial_data_sets (BLOCK_FOR_INSN (insn));
3933     }
3934   
3935   if (flags & INSN_INIT_TODO_LUID)
3936     sched_init_luids (NULL, NULL, NULL, insn);
3937
3938   if (flags & INSN_INIT_TODO_SSID)
3939     {
3940       extend_insn_data ();
3941       init_insn_data (insn);
3942       clear_expr (&insn_init_ssid->expr);
3943     }
3944
3945   if (flags & INSN_INIT_TODO_SIMPLEJUMP)
3946     {
3947       extend_insn_data ();
3948       init_simplejump_data (insn);
3949     }
3950   
3951   gcc_assert (CONTAINING_RGN (BLOCK_NUM (insn))
3952               == CONTAINING_RGN (BB_TO_BLOCK (0)));
3953 }
3954 \f
3955
3956 /* Functions to init/finish work with lv sets.  */
3957
3958 /* Init BB_LV_SET of BB from DF_LR_IN set of BB.  */
3959 static void
3960 init_lv_set (basic_block bb)
3961 {
3962   gcc_assert (!BB_LV_SET_VALID_P (bb));
3963
3964   BB_LV_SET (bb) = get_regset_from_pool ();
3965   COPY_REG_SET (BB_LV_SET (bb), DF_LR_IN (bb)); 
3966   BB_LV_SET_VALID_P (bb) = true;
3967 }
3968
3969 /* Copy liveness information to BB from FROM_BB.  */
3970 static void
3971 copy_lv_set_from (basic_block bb, basic_block from_bb)
3972 {
3973   gcc_assert (!BB_LV_SET_VALID_P (bb));
3974   
3975   COPY_REG_SET (BB_LV_SET (bb), BB_LV_SET (from_bb));
3976   BB_LV_SET_VALID_P (bb) = true;
3977 }                
3978
3979 /* Initialize lv set of all bb headers.  */
3980 void
3981 init_lv_sets (void)
3982 {
3983   basic_block bb;
3984
3985   /* Initialize of LV sets.  */
3986   FOR_EACH_BB (bb)
3987     init_lv_set (bb);
3988
3989   /* Don't forget EXIT_BLOCK.  */
3990   init_lv_set (EXIT_BLOCK_PTR);
3991 }
3992
3993 /* Release lv set of HEAD.  */
3994 static void
3995 free_lv_set (basic_block bb)
3996 {
3997   gcc_assert (BB_LV_SET (bb) != NULL);
3998
3999   return_regset_to_pool (BB_LV_SET (bb));
4000   BB_LV_SET (bb) = NULL;
4001   BB_LV_SET_VALID_P (bb) = false;
4002 }
4003
4004 /* Finalize lv sets of all bb headers.  */
4005 void
4006 free_lv_sets (void)
4007 {
4008   basic_block bb;
4009
4010   /* Don't forget EXIT_BLOCK.  */
4011   free_lv_set (EXIT_BLOCK_PTR);
4012
4013   /* Free LV sets.  */
4014   FOR_EACH_BB (bb)
4015     if (BB_LV_SET (bb))
4016       free_lv_set (bb);
4017 }
4018
4019 /* Initialize an invalid AV_SET for BB.
4020    This set will be updated next time compute_av () process BB.  */
4021 static void
4022 invalidate_av_set (basic_block bb)
4023 {
4024   gcc_assert (BB_AV_LEVEL (bb) <= 0
4025               && BB_AV_SET (bb) == NULL);
4026
4027   BB_AV_LEVEL (bb) = -1;
4028 }
4029
4030 /* Create initial data sets for BB (they will be invalid).  */
4031 static void
4032 create_initial_data_sets (basic_block bb)
4033 {
4034   if (BB_LV_SET (bb))
4035     BB_LV_SET_VALID_P (bb) = false;
4036   else
4037     BB_LV_SET (bb) = get_regset_from_pool ();
4038   invalidate_av_set (bb);
4039 }
4040
4041 /* Free av set of BB.  */
4042 static void
4043 free_av_set (basic_block bb)
4044 {
4045   av_set_clear (&BB_AV_SET (bb));
4046   BB_AV_LEVEL (bb) = 0;
4047 }
4048
4049 /* Free data sets of BB.  */
4050 void
4051 free_data_sets (basic_block bb)
4052 {
4053   free_lv_set (bb);
4054   free_av_set (bb);
4055 }
4056
4057 /* Exchange lv sets of TO and FROM.  */
4058 static void
4059 exchange_lv_sets (basic_block to, basic_block from)
4060 {
4061   {
4062     regset to_lv_set = BB_LV_SET (to);
4063
4064     BB_LV_SET (to) = BB_LV_SET (from);
4065     BB_LV_SET (from) = to_lv_set;
4066   }
4067
4068   {
4069     bool to_lv_set_valid_p = BB_LV_SET_VALID_P (to);
4070
4071     BB_LV_SET_VALID_P (to) = BB_LV_SET_VALID_P (from);
4072     BB_LV_SET_VALID_P (from) = to_lv_set_valid_p;
4073   }
4074 }
4075
4076
4077 /* Exchange av sets of TO and FROM.  */
4078 static void
4079 exchange_av_sets (basic_block to, basic_block from)
4080 {
4081   {
4082     av_set_t to_av_set = BB_AV_SET (to);
4083
4084     BB_AV_SET (to) = BB_AV_SET (from);
4085     BB_AV_SET (from) = to_av_set;
4086   }
4087
4088   {
4089     int to_av_level = BB_AV_LEVEL (to);
4090
4091     BB_AV_LEVEL (to) = BB_AV_LEVEL (from);
4092     BB_AV_LEVEL (from) = to_av_level;
4093   }
4094 }
4095
4096 /* Exchange data sets of TO and FROM.  */
4097 void
4098 exchange_data_sets (basic_block to, basic_block from)
4099 {
4100   exchange_lv_sets (to, from);
4101   exchange_av_sets (to, from);
4102 }
4103
4104 /* Copy data sets of FROM to TO.  */
4105 void
4106 copy_data_sets (basic_block to, basic_block from)
4107 {
4108   gcc_assert (!BB_LV_SET_VALID_P (to) && !BB_AV_SET_VALID_P (to));
4109   gcc_assert (BB_AV_SET (to) == NULL);
4110
4111   BB_AV_LEVEL (to) = BB_AV_LEVEL (from);
4112   BB_LV_SET_VALID_P (to) = BB_LV_SET_VALID_P (from);
4113
4114   if (BB_AV_SET_VALID_P (from))
4115     {
4116       BB_AV_SET (to) = av_set_copy (BB_AV_SET (from));
4117     }
4118   if (BB_LV_SET_VALID_P (from))
4119     {
4120       gcc_assert (BB_LV_SET (to) != NULL);
4121       COPY_REG_SET (BB_LV_SET (to), BB_LV_SET (from));
4122     }
4123 }
4124
4125 /* Return an av set for INSN, if any.  */
4126 av_set_t
4127 get_av_set (insn_t insn)
4128 {
4129   av_set_t av_set;
4130
4131   gcc_assert (AV_SET_VALID_P (insn));
4132
4133   if (sel_bb_head_p (insn))
4134     av_set = BB_AV_SET (BLOCK_FOR_INSN (insn));
4135   else
4136     av_set = NULL;
4137
4138   return av_set;
4139 }
4140
4141 /* Implementation of AV_LEVEL () macro.  Return AV_LEVEL () of INSN.  */
4142 int
4143 get_av_level (insn_t insn)
4144 {
4145   int av_level;
4146
4147   gcc_assert (INSN_P (insn));
4148
4149   if (sel_bb_head_p (insn))
4150     av_level = BB_AV_LEVEL (BLOCK_FOR_INSN (insn));
4151   else
4152     av_level = INSN_WS_LEVEL (insn);
4153
4154   return av_level;
4155 }
4156
4157 \f
4158
4159 /* Variables to work with control-flow graph.  */
4160
4161 /* The basic block that already has been processed by the sched_data_update (),
4162    but hasn't been in sel_add_bb () yet.  */
4163 static VEC (basic_block, heap) *last_added_blocks = NULL;
4164
4165 /* A pool for allocating successor infos.  */
4166 static struct
4167 {
4168   /* A stack for saving succs_info structures.  */
4169   struct succs_info *stack;
4170
4171   /* Its size.  */
4172   int size;
4173
4174   /* Top of the stack.  */
4175   int top;
4176
4177   /* Maximal value of the top.  */
4178   int max_top;
4179 }  succs_info_pool;
4180
4181 /* Functions to work with control-flow graph.  */
4182
4183 /* Return basic block note of BB.  */
4184 insn_t
4185 sel_bb_head (basic_block bb)
4186 {
4187   insn_t head;
4188
4189   if (bb == EXIT_BLOCK_PTR)
4190     {
4191       gcc_assert (exit_insn != NULL_RTX);
4192       head = exit_insn;
4193     }
4194   else
4195     {
4196       insn_t note;
4197
4198       note = bb_note (bb);
4199       head = next_nonnote_insn (note);
4200
4201       if (head && BLOCK_FOR_INSN (head) != bb)
4202         head = NULL_RTX;
4203     }
4204
4205   return head;
4206 }
4207
4208 /* Return true if INSN is a basic block header.  */
4209 bool
4210 sel_bb_head_p (insn_t insn)
4211 {
4212   return sel_bb_head (BLOCK_FOR_INSN (insn)) == insn;
4213 }
4214
4215 /* Return last insn of BB.  */
4216 insn_t
4217 sel_bb_end (basic_block bb)
4218 {
4219   if (sel_bb_empty_p (bb))
4220     return NULL_RTX;
4221
4222   gcc_assert (bb != EXIT_BLOCK_PTR);
4223
4224   return BB_END (bb);
4225 }
4226
4227 /* Return true if INSN is the last insn in its basic block.  */
4228 bool
4229 sel_bb_end_p (insn_t insn)
4230 {
4231   return insn == sel_bb_end (BLOCK_FOR_INSN (insn));
4232 }
4233
4234 /* Return true if BB consist of single NOTE_INSN_BASIC_BLOCK.  */
4235 bool
4236 sel_bb_empty_p (basic_block bb)
4237 {
4238   return sel_bb_head (bb) == NULL;
4239 }
4240
4241 /* True when BB belongs to the current scheduling region.  */
4242 bool
4243 in_current_region_p (basic_block bb)
4244 {
4245   if (bb->index < NUM_FIXED_BLOCKS)
4246     return false;
4247
4248   return CONTAINING_RGN (bb->index) == CONTAINING_RGN (BB_TO_BLOCK (0));
4249 }
4250
4251 /* Return the block which is a fallthru bb of a conditional jump JUMP.  */
4252 basic_block
4253 fallthru_bb_of_jump (rtx jump)
4254 {
4255   if (!JUMP_P (jump))
4256     return NULL;
4257
4258   if (any_uncondjump_p (jump))
4259     return single_succ (BLOCK_FOR_INSN (jump));
4260
4261   if (!any_condjump_p (jump))
4262     return NULL;
4263
4264   return FALLTHRU_EDGE (BLOCK_FOR_INSN (jump))->dest;
4265 }
4266
4267 /* Remove all notes from BB.  */
4268 static void
4269 init_bb (basic_block bb)
4270 {
4271   remove_notes (bb_note (bb), BB_END (bb));
4272   BB_NOTE_LIST (bb) = note_list;
4273 }
4274
4275 void
4276 sel_init_bbs (bb_vec_t bbs, basic_block bb)
4277 {
4278   const struct sched_scan_info_def ssi =
4279     {
4280       extend_bb_info, /* extend_bb */
4281       init_bb, /* init_bb */
4282       NULL, /* extend_insn */
4283       NULL /* init_insn */
4284     };
4285
4286   sched_scan (&ssi, bbs, bb, new_insns, NULL);
4287 }
4288
4289 /* Restore other notes for the whole region.  */
4290 static void
4291 sel_restore_other_notes (void)
4292 {
4293   int bb;
4294
4295   for (bb = 0; bb < current_nr_blocks; bb++)
4296     {
4297       basic_block first, last;
4298
4299       first = EBB_FIRST_BB (bb);
4300       last = EBB_LAST_BB (bb)->next_bb;
4301
4302       do
4303         {
4304           note_list = BB_NOTE_LIST (first);
4305           restore_other_notes (NULL, first);
4306           BB_NOTE_LIST (first) = NULL_RTX;
4307
4308           first = first->next_bb;
4309         }
4310       while (first != last);
4311     }
4312 }
4313
4314 /* Free per-bb data structures.  */
4315 void
4316 sel_finish_bbs (void)
4317 {
4318   sel_restore_other_notes ();
4319
4320   /* Remove current loop preheader from this loop.  */
4321   if (current_loop_nest)
4322     sel_remove_loop_preheader ();
4323
4324   finish_region_bb_info ();
4325 }
4326
4327 /* Return true if INSN has a single successor of type FLAGS.  */
4328 bool
4329 sel_insn_has_single_succ_p (insn_t insn, int flags)
4330 {
4331   insn_t succ;
4332   succ_iterator si;
4333   bool first_p = true;
4334
4335   FOR_EACH_SUCC_1 (succ, si, insn, flags)
4336     {
4337       if (first_p)
4338         first_p = false;
4339       else
4340         return false;
4341     }
4342
4343   return true;
4344 }
4345
4346 /* Allocate successor's info.  */
4347 static struct succs_info *
4348 alloc_succs_info (void)
4349 {
4350   if (succs_info_pool.top == succs_info_pool.max_top)
4351     {
4352       int i;
4353       
4354       if (++succs_info_pool.max_top >= succs_info_pool.size)
4355         gcc_unreachable ();
4356
4357       i = ++succs_info_pool.top;
4358       succs_info_pool.stack[i].succs_ok = VEC_alloc (rtx, heap, 10);
4359       succs_info_pool.stack[i].succs_other = VEC_alloc (rtx, heap, 10);
4360       succs_info_pool.stack[i].probs_ok = VEC_alloc (int, heap, 10);
4361     }
4362   else
4363     succs_info_pool.top++;
4364
4365   return &succs_info_pool.stack[succs_info_pool.top];
4366 }
4367
4368 /* Free successor's info.  */
4369 void
4370 free_succs_info (struct succs_info * sinfo)
4371 {
4372   gcc_assert (succs_info_pool.top >= 0 
4373               && &succs_info_pool.stack[succs_info_pool.top] == sinfo);
4374   succs_info_pool.top--;
4375
4376   /* Clear stale info.  */
4377   VEC_block_remove (rtx, sinfo->succs_ok, 
4378                     0, VEC_length (rtx, sinfo->succs_ok));
4379   VEC_block_remove (rtx, sinfo->succs_other, 
4380                     0, VEC_length (rtx, sinfo->succs_other));
4381   VEC_block_remove (int, sinfo->probs_ok, 
4382                     0, VEC_length (int, sinfo->probs_ok));
4383   sinfo->all_prob = 0;
4384   sinfo->succs_ok_n = 0;
4385   sinfo->all_succs_n = 0;
4386 }
4387
4388 /* Compute successor info for INSN.  FLAGS are the flags passed 
4389    to the FOR_EACH_SUCC_1 iterator.  */
4390 struct succs_info *
4391 compute_succs_info (insn_t insn, short flags)
4392 {
4393   succ_iterator si;
4394   insn_t succ;
4395   struct succs_info *sinfo = alloc_succs_info ();
4396
4397   /* Traverse *all* successors and decide what to do with each.  */
4398   FOR_EACH_SUCC_1 (succ, si, insn, SUCCS_ALL)
4399     {
4400       /* FIXME: this doesn't work for skipping to loop exits, as we don't
4401          perform code motion through inner loops.  */
4402       short current_flags = si.current_flags & ~SUCCS_SKIP_TO_LOOP_EXITS;
4403
4404       if (current_flags & flags)
4405         {
4406           VEC_safe_push (rtx, heap, sinfo->succs_ok, succ);
4407           VEC_safe_push (int, heap, sinfo->probs_ok,
4408                          /* FIXME: Improve calculation when skipping 
4409                             inner loop to exits.  */
4410                          (si.bb_end 
4411                           ? si.e1->probability 
4412                           : REG_BR_PROB_BASE));
4413           sinfo->succs_ok_n++;
4414         }
4415       else
4416         VEC_safe_push (rtx, heap, sinfo->succs_other, succ);
4417
4418       /* Compute all_prob.  */
4419       if (!si.bb_end)
4420         sinfo->all_prob = REG_BR_PROB_BASE;
4421       else
4422         sinfo->all_prob += si.e1->probability;
4423
4424       sinfo->all_succs_n++;
4425     }
4426
4427   return sinfo;
4428 }
4429
4430 /* Return the predecessors of BB in PREDS and their number in N. 
4431    Empty blocks are skipped.  SIZE is used to allocate PREDS.  */
4432 static void
4433 cfg_preds_1 (basic_block bb, insn_t **preds, int *n, int *size)
4434 {
4435   edge e;
4436   edge_iterator ei;
4437
4438   gcc_assert (BLOCK_TO_BB (bb->index) != 0);
4439
4440   FOR_EACH_EDGE (e, ei, bb->preds)
4441     {
4442       basic_block pred_bb = e->src;
4443       insn_t bb_end = BB_END (pred_bb);
4444
4445       /* ??? This code is not supposed to walk out of a region.  */
4446       gcc_assert (in_current_region_p (pred_bb));
4447
4448       if (sel_bb_empty_p (pred_bb))
4449         cfg_preds_1 (pred_bb, preds, n, size);
4450       else
4451         {
4452           if (*n == *size)
4453             *preds = XRESIZEVEC (insn_t, *preds, 
4454                                  (*size = 2 * *size + 1));
4455           (*preds)[(*n)++] = bb_end;
4456         }
4457     }
4458
4459   gcc_assert (*n != 0);
4460 }
4461
4462 /* Find all predecessors of BB and record them in PREDS and their number 
4463    in N.  Empty blocks are skipped, and only normal (forward in-region) 
4464    edges are processed.  */
4465 static void
4466 cfg_preds (basic_block bb, insn_t **preds, int *n)
4467 {
4468   int size = 0;
4469
4470   *preds = NULL;
4471   *n = 0;
4472   cfg_preds_1 (bb, preds, n, &size);
4473 }
4474
4475 /* Returns true if we are moving INSN through join point.  */
4476 bool
4477 sel_num_cfg_preds_gt_1 (insn_t insn)
4478 {
4479   basic_block bb;
4480
4481   if (!sel_bb_head_p (insn) || INSN_BB (insn) == 0)
4482     return false;
4483
4484   bb = BLOCK_FOR_INSN (insn);
4485
4486   while (1)
4487     {
4488       if (EDGE_COUNT (bb->preds) > 1)
4489         return true;
4490
4491       gcc_assert (EDGE_PRED (bb, 0)->dest == bb);
4492       bb = EDGE_PRED (bb, 0)->src;
4493
4494       if (!sel_bb_empty_p (bb))
4495         break;
4496     }
4497
4498   return false;
4499 }
4500
4501 /* Returns true when BB should be the end of an ebb.  Adapted from the 
4502    code in sched-ebb.c.  */
4503 bool
4504 bb_ends_ebb_p (basic_block bb)
4505 {
4506   basic_block next_bb = bb_next_bb (bb);
4507   edge e;
4508   edge_iterator ei;
4509   
4510   if (next_bb == EXIT_BLOCK_PTR
4511       || bitmap_bit_p (forced_ebb_heads, next_bb->index)
4512       || (LABEL_P (BB_HEAD (next_bb))
4513           /* NB: LABEL_NUSES () is not maintained outside of jump.c.
4514              Work around that.  */
4515           && !single_pred_p (next_bb)))
4516     return true;
4517
4518   if (!in_current_region_p (next_bb))
4519     return true;
4520
4521   FOR_EACH_EDGE (e, ei, bb->succs)
4522     if ((e->flags & EDGE_FALLTHRU) != 0)
4523       {
4524         gcc_assert (e->dest == next_bb);
4525
4526         return false;
4527       }
4528
4529   return true;
4530 }
4531
4532 /* Returns true when INSN and SUCC are in the same EBB, given that SUCC is a
4533    successor of INSN.  */
4534 bool
4535 in_same_ebb_p (insn_t insn, insn_t succ)
4536 {
4537   basic_block ptr = BLOCK_FOR_INSN (insn);
4538
4539   for(;;)
4540     {
4541       if (ptr == BLOCK_FOR_INSN (succ))
4542         return true;
4543     
4544       if (bb_ends_ebb_p (ptr))
4545         return false;
4546
4547       ptr = bb_next_bb (ptr);
4548     }
4549
4550   gcc_unreachable ();
4551   return false;
4552 }
4553
4554 /* Recomputes the reverse topological order for the function and
4555    saves it in REV_TOP_ORDER_INDEX.  REV_TOP_ORDER_INDEX_LEN is also
4556    modified appropriately.  */
4557 static void
4558 recompute_rev_top_order (void)
4559 {
4560   int *postorder;
4561   int n_blocks, i;
4562
4563   if (!rev_top_order_index || rev_top_order_index_len < last_basic_block)
4564     {
4565       rev_top_order_index_len = last_basic_block; 
4566       rev_top_order_index = XRESIZEVEC (int, rev_top_order_index,
4567                                         rev_top_order_index_len);
4568     }
4569
4570   postorder = XNEWVEC (int, n_basic_blocks);
4571
4572   n_blocks = post_order_compute (postorder, true, false);
4573   gcc_assert (n_basic_blocks == n_blocks);
4574
4575   /* Build reverse function: for each basic block with BB->INDEX == K
4576      rev_top_order_index[K] is it's reverse topological sort number.  */
4577   for (i = 0; i < n_blocks; i++)
4578     {
4579       gcc_assert (postorder[i] < rev_top_order_index_len);
4580       rev_top_order_index[postorder[i]] = i;
4581     }
4582
4583   free (postorder);
4584 }
4585
4586 /* Clear all flags from insns in BB that could spoil its rescheduling.  */
4587 void
4588 clear_outdated_rtx_info (basic_block bb)
4589 {
4590   rtx insn;
4591
4592   FOR_BB_INSNS (bb, insn)
4593     if (INSN_P (insn))
4594       {
4595         SCHED_GROUP_P (insn) = 0;
4596         INSN_AFTER_STALL_P (insn) = 0;
4597         INSN_SCHED_TIMES (insn) = 0;
4598         EXPR_PRIORITY_ADJ (INSN_EXPR (insn)) = 0;
4599
4600         /* We cannot use the changed caches, as previously we could ignore
4601            the LHS dependence due to enabled renaming and transform 
4602            the expression, and currently we'll be unable to do this.  */
4603         htab_empty (INSN_TRANSFORMED_INSNS (insn));
4604       }
4605 }
4606
4607 /* Add BB_NOTE to the pool of available basic block notes.  */
4608 static void
4609 return_bb_to_pool (basic_block bb)
4610 {
4611   rtx note = bb_note (bb);
4612
4613   gcc_assert (NOTE_BASIC_BLOCK (note) == bb
4614               && bb->aux == NULL);
4615
4616   /* It turns out that current cfg infrastructure does not support
4617      reuse of basic blocks.  Don't bother for now.  */
4618   /*VEC_safe_push (rtx, heap, bb_note_pool, note);*/
4619 }
4620
4621 /* Get a bb_note from pool or return NULL_RTX if pool is empty.  */
4622 static rtx
4623 get_bb_note_from_pool (void)
4624 {
4625   if (VEC_empty (rtx, bb_note_pool))
4626     return NULL_RTX;
4627   else
4628     {
4629       rtx note = VEC_pop (rtx, bb_note_pool);
4630
4631       PREV_INSN (note) = NULL_RTX;
4632       NEXT_INSN (note) = NULL_RTX;
4633
4634       return note;
4635     }
4636 }
4637
4638 /* Free bb_note_pool.  */
4639 void
4640 free_bb_note_pool (void)
4641 {
4642   VEC_free (rtx, heap, bb_note_pool);
4643 }
4644
4645 /* Setup scheduler pool and successor structure.  */
4646 void
4647 alloc_sched_pools (void)
4648 {
4649   int succs_size;
4650
4651   succs_size = MAX_WS + 1;
4652   succs_info_pool.stack = XCNEWVEC (struct succs_info, succs_size); 
4653   succs_info_pool.size = succs_size;
4654   succs_info_pool.top = -1;
4655   succs_info_pool.max_top = -1;
4656
4657   sched_lists_pool = create_alloc_pool ("sel-sched-lists", 
4658                                         sizeof (struct _list_node), 500);
4659 }
4660
4661 /* Free the pools.  */
4662 void
4663 free_sched_pools (void)
4664 {
4665   int i;
4666   
4667   free_alloc_pool (sched_lists_pool);
4668   gcc_assert (succs_info_pool.top == -1);
4669   for (i = 0; i < succs_info_pool.max_top; i++)
4670     {
4671       VEC_free (rtx, heap, succs_info_pool.stack[i].succs_ok);
4672       VEC_free (rtx, heap, succs_info_pool.stack[i].succs_other);
4673       VEC_free (int, heap, succs_info_pool.stack[i].probs_ok);
4674     }
4675   free (succs_info_pool.stack);
4676 }
4677 \f
4678
4679 /* Returns a position in RGN where BB can be inserted retaining 
4680    topological order.  */
4681 static int
4682 find_place_to_insert_bb (basic_block bb, int rgn)
4683 {
4684   bool has_preds_outside_rgn = false;
4685   edge e;
4686   edge_iterator ei;
4687   
4688   /* Find whether we have preds outside the region.  */
4689   FOR_EACH_EDGE (e, ei, bb->preds)
4690     if (!in_current_region_p (e->src))
4691       {
4692         has_preds_outside_rgn = true;
4693         break;
4694       }
4695   
4696   /* Recompute the top order -- needed when we have > 1 pred
4697      and in case we don't have preds outside.  */
4698   if (flag_sel_sched_pipelining_outer_loops
4699       && (has_preds_outside_rgn || EDGE_COUNT (bb->preds) > 1))
4700     {
4701       int i, bbi = bb->index, cur_bbi;
4702
4703       recompute_rev_top_order ();
4704       for (i = RGN_NR_BLOCKS (rgn) - 1; i >= 0; i--)
4705         {
4706           cur_bbi = BB_TO_BLOCK (i);
4707           if (rev_top_order_index[bbi] 
4708               < rev_top_order_index[cur_bbi])
4709             break;
4710         }
4711               
4712       /* We skipped the right block, so we increase i.  We accomodate
4713          it for increasing by step later, so we decrease i.  */
4714       return (i + 1) - 1;
4715     }
4716   else if (has_preds_outside_rgn)
4717     {
4718       /* This is the case when we generate an extra empty block
4719          to serve as region head during pipelining.  */
4720       e = EDGE_SUCC (bb, 0);
4721       gcc_assert (EDGE_COUNT (bb->succs) == 1
4722                   && in_current_region_p (EDGE_SUCC (bb, 0)->dest)
4723                   && (BLOCK_TO_BB (e->dest->index) == 0));
4724       return -1;
4725     }
4726
4727   /* We don't have preds outside the region.  We should have
4728      the only pred, because the multiple preds case comes from
4729      the pipelining of outer loops, and that is handled above.
4730      Just take the bbi of this single pred.  */
4731   if (EDGE_COUNT (bb->succs) > 0)
4732     {
4733       int pred_bbi;
4734           
4735       gcc_assert (EDGE_COUNT (bb->preds) == 1);
4736           
4737       pred_bbi = EDGE_PRED (bb, 0)->src->index;
4738       return BLOCK_TO_BB (pred_bbi);
4739     }
4740   else
4741     /* BB has no successors.  It is safe to put it in the end.  */
4742     return current_nr_blocks - 1;
4743 }
4744
4745 /* Deletes an empty basic block freeing its data.  */
4746 static void
4747 delete_and_free_basic_block (basic_block bb)
4748 {
4749   gcc_assert (sel_bb_empty_p (bb));
4750
4751   if (BB_LV_SET (bb))
4752     free_lv_set (bb);
4753
4754   bitmap_clear_bit (blocks_to_reschedule, bb->index);
4755
4756   /* Can't assert av_set properties because we use sel_aremove_bb 
4757      when removing loop preheader from the region.  At the point of 
4758      removing the preheader we already have deallocated sel_region_bb_info.  */
4759   gcc_assert (BB_LV_SET (bb) == NULL
4760               && !BB_LV_SET_VALID_P (bb)
4761               && BB_AV_LEVEL (bb) == 0
4762               && BB_AV_SET (bb) == NULL);
4763   
4764   delete_basic_block (bb);
4765 }
4766
4767 /* Add BB to the current region and update the region data.  */
4768 static void
4769 add_block_to_current_region (basic_block bb)
4770 {
4771   int i, pos, bbi = -2, rgn;
4772
4773   rgn = CONTAINING_RGN (BB_TO_BLOCK (0));
4774   bbi = find_place_to_insert_bb (bb, rgn);
4775   bbi += 1;
4776   pos = RGN_BLOCKS (rgn) + bbi;
4777
4778   gcc_assert (RGN_HAS_REAL_EBB (rgn) == 0
4779               && ebb_head[bbi] == pos);
4780   
4781   /* Make a place for the new block.  */
4782   extend_regions ();
4783
4784   for (i = RGN_BLOCKS (rgn + 1) - 1; i >= pos; i--)
4785     BLOCK_TO_BB (rgn_bb_table[i])++;
4786   
4787   memmove (rgn_bb_table + pos + 1,
4788            rgn_bb_table + pos,
4789            (RGN_BLOCKS (nr_regions) - pos) * sizeof (*rgn_bb_table));
4790
4791   /* Initialize data for BB.  */
4792   rgn_bb_table[pos] = bb->index;
4793   BLOCK_TO_BB (bb->index) = bbi;
4794   CONTAINING_RGN (bb->index) = rgn;
4795
4796   RGN_NR_BLOCKS (rgn)++;
4797   
4798   for (i = rgn + 1; i <= nr_regions; i++)
4799     RGN_BLOCKS (i)++;
4800 }
4801
4802 /* Remove BB from the current region and update the region data.  */
4803 static void
4804 remove_bb_from_region (basic_block bb)
4805 {
4806   int i, pos, bbi = -2, rgn;
4807
4808   rgn = CONTAINING_RGN (BB_TO_BLOCK (0));
4809   bbi = BLOCK_TO_BB (bb->index);
4810   pos = RGN_BLOCKS (rgn) + bbi;
4811
4812   gcc_assert (RGN_HAS_REAL_EBB (rgn) == 0
4813               && ebb_head[bbi] == pos);
4814
4815   for (i = RGN_BLOCKS (rgn + 1) - 1; i >= pos; i--)
4816     BLOCK_TO_BB (rgn_bb_table[i])--;
4817
4818   memmove (rgn_bb_table + pos,
4819            rgn_bb_table + pos + 1,
4820            (RGN_BLOCKS (nr_regions) - pos) * sizeof (*rgn_bb_table));
4821
4822   RGN_NR_BLOCKS (rgn)--;
4823   for (i = rgn + 1; i <= nr_regions; i++)
4824     RGN_BLOCKS (i)--;
4825 }
4826
4827 /* Add BB to the current region  and update all data.  If BB is NULL, add all 
4828    blocks from last_added_blocks vector.  */
4829 static void
4830 sel_add_bb (basic_block bb)
4831 {
4832   /* Extend luids so that new notes will receive zero luids.  */
4833   sched_init_luids (NULL, NULL, NULL, NULL);
4834   sched_init_bbs ();
4835   sel_init_bbs (last_added_blocks, NULL);
4836
4837   /* When bb is passed explicitly, the vector should contain 
4838      the only element that equals to bb; otherwise, the vector
4839      should not be NULL.  */
4840   gcc_assert (last_added_blocks != NULL);
4841   
4842   if (bb != NULL)
4843     {
4844       gcc_assert (VEC_length (basic_block, last_added_blocks) == 1
4845                   && VEC_index (basic_block, 
4846                                 last_added_blocks, 0) == bb);     
4847       add_block_to_current_region (bb);
4848
4849       /* We associate creating/deleting data sets with the first insn
4850          appearing / disappearing in the bb.  */
4851       if (!sel_bb_empty_p (bb) && BB_LV_SET (bb) == NULL)
4852         create_initial_data_sets (bb);
4853     
4854       VEC_free (basic_block, heap, last_added_blocks);
4855     }
4856   else
4857     /* BB is NULL - process LAST_ADDED_BLOCKS instead.  */
4858     {
4859       int i;
4860       basic_block temp_bb = NULL;
4861
4862       for (i = 0; 
4863            VEC_iterate (basic_block, last_added_blocks, i, bb); i++)
4864         {
4865           add_block_to_current_region (bb);
4866           temp_bb = bb;
4867         }
4868
4869       /* We need to fetch at least one bb so we know the region 
4870          to update.  */
4871       gcc_assert (temp_bb != NULL);
4872       bb = temp_bb;
4873
4874       VEC_free (basic_block, heap, last_added_blocks);
4875     }
4876
4877   rgn_setup_region (CONTAINING_RGN (bb->index));
4878 }
4879
4880 /* Remove BB from the current region and update all data.  
4881    If REMOVE_FROM_CFG_PBB is true, also remove the block cfom cfg.  */
4882 static void
4883 sel_remove_bb (basic_block bb, bool remove_from_cfg_p)
4884 {
4885   gcc_assert (bb != NULL && BB_NOTE_LIST (bb) == NULL_RTX);
4886   
4887   remove_bb_from_region (bb);
4888   return_bb_to_pool (bb);
4889   bitmap_clear_bit (blocks_to_reschedule, bb->index);
4890   
4891   if (remove_from_cfg_p)
4892     delete_and_free_basic_block (bb);
4893
4894   rgn_setup_region (CONTAINING_RGN (bb->index));
4895 }
4896
4897 /* Concatenate info of EMPTY_BB to info of MERGE_BB.  */
4898 static void
4899 move_bb_info (basic_block merge_bb, basic_block empty_bb)
4900 {
4901   gcc_assert (in_current_region_p (merge_bb));
4902
4903   concat_note_lists (BB_NOTE_LIST (empty_bb), 
4904                      &BB_NOTE_LIST (merge_bb));
4905   BB_NOTE_LIST (empty_bb) = NULL_RTX;
4906
4907 }
4908
4909 /* Remove an empty basic block EMPTY_BB.  When MERGE_UP_P is true, we put 
4910    EMPTY_BB's note lists into its predecessor instead of putting them 
4911    into the successor.  When REMOVE_FROM_CFG_P is true, also remove 
4912    the empty block.  */
4913 void
4914 sel_remove_empty_bb (basic_block empty_bb, bool merge_up_p,
4915                      bool remove_from_cfg_p)
4916 {
4917   basic_block merge_bb;
4918
4919   gcc_assert (sel_bb_empty_p (empty_bb));
4920
4921   if (merge_up_p)
4922     {
4923       merge_bb = empty_bb->prev_bb;
4924       gcc_assert (EDGE_COUNT (empty_bb->preds) == 1
4925                   && EDGE_PRED (empty_bb, 0)->src == merge_bb);
4926     }
4927   else
4928     {
4929       edge e;
4930       edge_iterator ei;
4931
4932       merge_bb = bb_next_bb (empty_bb);
4933
4934       /* Redirect incoming edges (except fallthrough one) of EMPTY_BB to its 
4935          successor block.  */
4936       for (ei = ei_start (empty_bb->preds);
4937            (e = ei_safe_edge (ei)); )
4938         {
4939           if (! (e->flags & EDGE_FALLTHRU))
4940             sel_redirect_edge_and_branch (e, merge_bb);
4941           else
4942             ei_next (&ei);
4943         }
4944
4945       gcc_assert (EDGE_COUNT (empty_bb->succs) == 1
4946                   && EDGE_SUCC (empty_bb, 0)->dest == merge_bb);
4947     }
4948
4949   move_bb_info (merge_bb, empty_bb);
4950   remove_empty_bb (empty_bb, remove_from_cfg_p);
4951 }
4952
4953 /* Remove EMPTY_BB.  If REMOVE_FROM_CFG_P is false, remove EMPTY_BB from
4954    region, but keep it in CFG.  */
4955 static void
4956 remove_empty_bb (basic_block empty_bb, bool remove_from_cfg_p)
4957 {
4958   /* The block should contain just a note or a label.
4959      We try to check whether it is unused below.  */
4960   gcc_assert (BB_HEAD (empty_bb) == BB_END (empty_bb)
4961               || LABEL_P (BB_HEAD (empty_bb)));
4962
4963   /* If basic block has predecessors or successors, redirect them.  */
4964   if (remove_from_cfg_p
4965       && (EDGE_COUNT (empty_bb->preds) > 0
4966           || EDGE_COUNT (empty_bb->succs) > 0))
4967     {
4968       basic_block pred;
4969       basic_block succ;
4970
4971       /* We need to init PRED and SUCC before redirecting edges.  */
4972       if (EDGE_COUNT (empty_bb->preds) > 0)
4973         {
4974           edge e;
4975
4976           gcc_assert (EDGE_COUNT (empty_bb->preds) == 1);
4977
4978           e = EDGE_PRED (empty_bb, 0);
4979           gcc_assert (e->src == empty_bb->prev_bb
4980                       && (e->flags & EDGE_FALLTHRU));
4981
4982           pred = empty_bb->prev_bb;
4983         }
4984       else
4985         pred = NULL;
4986
4987       if (EDGE_COUNT (empty_bb->succs) > 0)
4988         {
4989           /* We do not check fallthruness here as above, because
4990              after removing a jump the edge may actually be not fallthru.  */
4991           gcc_assert (EDGE_COUNT (empty_bb->succs) == 1);
4992           succ = EDGE_SUCC (empty_bb, 0)->dest;
4993         }
4994       else
4995         succ = NULL;
4996
4997       if (EDGE_COUNT (empty_bb->preds) > 0 && succ != NULL)
4998         {
4999           edge e = EDGE_PRED (empty_bb, 0);
5000
5001           if (e->flags & EDGE_FALLTHRU)
5002             redirect_edge_succ_nodup (e, succ);
5003           else
5004             sel_redirect_edge_and_branch (EDGE_PRED (empty_bb, 0), succ);
5005         }
5006
5007       if (EDGE_COUNT (empty_bb->succs) > 0 && pred != NULL)
5008         {
5009           edge e = EDGE_SUCC (empty_bb, 0);
5010
5011           if (find_edge (pred, e->dest) == NULL)
5012             redirect_edge_pred (e, pred);
5013         }
5014     }
5015
5016   /* Finish removing.  */
5017   sel_remove_bb (empty_bb, remove_from_cfg_p);
5018 }
5019
5020 /* An implementation of create_basic_block hook, which additionally updates 
5021    per-bb data structures.  */
5022 static basic_block
5023 sel_create_basic_block (void *headp, void *endp, basic_block after)
5024 {
5025   basic_block new_bb;
5026   insn_t new_bb_note;
5027   
5028   gcc_assert (flag_sel_sched_pipelining_outer_loops 
5029               || last_added_blocks == NULL);
5030
5031   new_bb_note = get_bb_note_from_pool ();
5032
5033   if (new_bb_note == NULL_RTX)
5034     new_bb = orig_cfg_hooks.create_basic_block (headp, endp, after);
5035   else
5036     {
5037       new_bb = create_basic_block_structure ((rtx) headp, (rtx) endp,
5038                                              new_bb_note, after);
5039       new_bb->aux = NULL;
5040     }
5041
5042   VEC_safe_push (basic_block, heap, last_added_blocks, new_bb);
5043
5044   return new_bb;
5045 }
5046
5047 /* Implement sched_init_only_bb ().  */
5048 static void
5049 sel_init_only_bb (basic_block bb, basic_block after)
5050 {
5051   gcc_assert (after == NULL);
5052
5053   extend_regions ();
5054   rgn_make_new_region_out_of_new_block (bb);
5055 }
5056
5057 /* Update the latch when we've splitted or merged it from FROM block to TO.
5058    This should be checked for all outer loops, too.  */
5059 static void
5060 change_loops_latches (basic_block from, basic_block to)
5061 {
5062   gcc_assert (from != to);
5063
5064   if (current_loop_nest)
5065     {
5066       struct loop *loop;
5067
5068       for (loop = current_loop_nest; loop; loop = loop_outer (loop))
5069         if (considered_for_pipelining_p (loop) && loop->latch == from)
5070           {
5071             gcc_assert (loop == current_loop_nest);
5072             loop->latch = to;
5073             gcc_assert (loop_latch_edge (loop));
5074           }
5075     }
5076 }
5077
5078 /* Splits BB on two basic blocks, adding it to the region and extending 
5079    per-bb data structures.  Returns the newly created bb.  */
5080 static basic_block
5081 sel_split_block (basic_block bb, rtx after)
5082 {
5083   basic_block new_bb;
5084   insn_t insn;
5085
5086   new_bb = sched_split_block_1 (bb, after);
5087   sel_add_bb (new_bb);
5088
5089   /* This should be called after sel_add_bb, because this uses
5090      CONTAINING_RGN for the new block, which is not yet initialized.  
5091      FIXME: this function may be a no-op now.  */
5092   change_loops_latches (bb, new_bb);
5093
5094   /* Update ORIG_BB_INDEX for insns moved into the new block.  */
5095   FOR_BB_INSNS (new_bb, insn)
5096    if (INSN_P (insn))
5097      EXPR_ORIG_BB_INDEX (INSN_EXPR (insn)) = new_bb->index;
5098
5099   if (sel_bb_empty_p (bb))
5100     {
5101       gcc_assert (!sel_bb_empty_p (new_bb));
5102
5103       /* NEW_BB has data sets that need to be updated and BB holds
5104          data sets that should be removed.  Exchange these data sets
5105          so that we won't lose BB's valid data sets.  */
5106       exchange_data_sets (new_bb, bb);
5107       free_data_sets (bb);
5108     }
5109
5110   if (!sel_bb_empty_p (new_bb)
5111       && bitmap_bit_p (blocks_to_reschedule, bb->index))
5112     bitmap_set_bit (blocks_to_reschedule, new_bb->index);
5113
5114   return new_bb;
5115 }
5116
5117 /* If BB ends with a jump insn whose ID is bigger then PREV_MAX_UID, return it.
5118    Otherwise returns NULL.  */
5119 static rtx
5120 check_for_new_jump (basic_block bb, int prev_max_uid)
5121 {
5122   rtx end;
5123
5124   end = sel_bb_end (bb);
5125   if (end && INSN_UID (end) >= prev_max_uid)
5126     return end;
5127   return NULL;
5128 }
5129
5130 /* Look for a new jump either in FROM_BB block or in newly created JUMP_BB block. 
5131    New means having UID at least equal to PREV_MAX_UID.  */
5132 static rtx
5133 find_new_jump (basic_block from, basic_block jump_bb, int prev_max_uid)
5134 {
5135   rtx jump;
5136
5137   /* Return immediately if no new insns were emitted.  */
5138   if (get_max_uid () == prev_max_uid)
5139     return NULL;
5140   
5141   /* Now check both blocks for new jumps.  It will ever be only one.  */
5142   if ((jump = check_for_new_jump (from, prev_max_uid)))
5143     return jump;
5144
5145   if (jump_bb != NULL
5146       && (jump = check_for_new_jump (jump_bb, prev_max_uid)))
5147     return jump;
5148   return NULL;
5149 }
5150
5151 /* Splits E and adds the newly created basic block to the current region.
5152    Returns this basic block.  */
5153 basic_block
5154 sel_split_edge (edge e)
5155 {
5156   basic_block new_bb, src, other_bb = NULL;
5157   int prev_max_uid;
5158   rtx jump;
5159
5160   src = e->src;
5161   prev_max_uid = get_max_uid ();
5162   new_bb = split_edge (e);
5163
5164   if (flag_sel_sched_pipelining_outer_loops 
5165       && current_loop_nest)
5166     {
5167       int i;
5168       basic_block bb;
5169
5170       /* Some of the basic blocks might not have been added to the loop.  
5171          Add them here, until this is fixed in force_fallthru.  */
5172       for (i = 0; 
5173            VEC_iterate (basic_block, last_added_blocks, i, bb); i++)
5174         if (!bb->loop_father)
5175           {
5176             add_bb_to_loop (bb, e->dest->loop_father);
5177
5178             gcc_assert (!other_bb && (new_bb->index != bb->index));
5179             other_bb = bb;
5180           }
5181     }
5182
5183   /* Add all last_added_blocks to the region.  */
5184   sel_add_bb (NULL);
5185
5186   jump = find_new_jump (src, new_bb, prev_max_uid);
5187   if (jump)
5188     sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
5189
5190   /* Put the correct lv set on this block.  */
5191   if (other_bb && !sel_bb_empty_p (other_bb))
5192     compute_live (sel_bb_head (other_bb));
5193
5194   return new_bb;
5195 }
5196
5197 /* Implement sched_create_empty_bb ().  */
5198 static basic_block
5199 sel_create_empty_bb (basic_block after)
5200 {
5201   basic_block new_bb;
5202
5203   new_bb = sched_create_empty_bb_1 (after);
5204
5205   /* We'll explicitly initialize NEW_BB via sel_init_only_bb () a bit
5206      later.  */
5207   gcc_assert (VEC_length (basic_block, last_added_blocks) == 1
5208               && VEC_index (basic_block, last_added_blocks, 0) == new_bb);
5209
5210   VEC_free (basic_block, heap, last_added_blocks);
5211   return new_bb;
5212 }
5213
5214 /* Implement sched_create_recovery_block.  ORIG_INSN is where block
5215    will be splitted to insert a check.  */
5216 basic_block
5217 sel_create_recovery_block (insn_t orig_insn)
5218 {
5219   basic_block first_bb, second_bb, recovery_block;
5220   basic_block before_recovery = NULL;
5221   rtx jump;
5222
5223   first_bb = BLOCK_FOR_INSN (orig_insn);
5224   if (sel_bb_end_p (orig_insn))
5225     {
5226       /* Avoid introducing an empty block while splitting.  */
5227       gcc_assert (single_succ_p (first_bb));
5228       second_bb = single_succ (first_bb);
5229     }
5230   else
5231     second_bb = sched_split_block (first_bb, orig_insn);
5232
5233   recovery_block = sched_create_recovery_block (&before_recovery);
5234   if (before_recovery)
5235     copy_lv_set_from (before_recovery, EXIT_BLOCK_PTR);
5236
5237   gcc_assert (sel_bb_empty_p (recovery_block));
5238   sched_create_recovery_edges (first_bb, recovery_block, second_bb);
5239   if (current_loops != NULL)
5240     add_bb_to_loop (recovery_block, first_bb->loop_father);
5241   
5242   sel_add_bb (recovery_block);
5243     
5244   jump = BB_END (recovery_block);
5245   gcc_assert (sel_bb_head (recovery_block) == jump);
5246   sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
5247
5248   return recovery_block;
5249 }
5250
5251 /* Merge basic block B into basic block A.  */
5252 void
5253 sel_merge_blocks (basic_block a, basic_block b)
5254 {
5255   gcc_assert (can_merge_blocks_p (a, b));
5256
5257   sel_remove_empty_bb (b, true, false);
5258   merge_blocks (a, b);
5259
5260   change_loops_latches (b, a);
5261 }
5262
5263 /* A wrapper for redirect_edge_and_branch_force, which also initializes
5264    data structures for possibly created bb and insns.  Returns the newly
5265    added bb or NULL, when a bb was not needed.  */
5266 void
5267 sel_redirect_edge_and_branch_force (edge e, basic_block to)
5268 {
5269   basic_block jump_bb, src;
5270   int prev_max_uid;
5271   rtx jump;
5272     
5273   gcc_assert (!sel_bb_empty_p (e->src));
5274   
5275   src = e->src;
5276   prev_max_uid = get_max_uid ();
5277   jump_bb = redirect_edge_and_branch_force (e, to);
5278
5279   if (jump_bb != NULL)
5280     sel_add_bb (jump_bb);
5281
5282   /* This function could not be used to spoil the loop structure by now,
5283      thus we don't care to update anything.  But check it to be sure.  */
5284   if (current_loop_nest
5285       && pipelining_p)
5286     gcc_assert (loop_latch_edge (current_loop_nest));
5287   
5288   jump = find_new_jump (src, jump_bb, prev_max_uid);
5289   if (jump)
5290     sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
5291 }
5292
5293 /* A wrapper for redirect_edge_and_branch.  */
5294 void
5295 sel_redirect_edge_and_branch (edge e, basic_block to)
5296 {
5297   bool latch_edge_p;
5298   basic_block src;
5299   int prev_max_uid;
5300   rtx jump;
5301
5302   latch_edge_p = (pipelining_p
5303                   && current_loop_nest
5304                   && e == loop_latch_edge (current_loop_nest));
5305
5306   src = e->src;
5307   prev_max_uid = get_max_uid ();
5308   
5309   redirect_edge_and_branch (e, to);
5310   gcc_assert (last_added_blocks == NULL);
5311
5312   /* When we've redirected a latch edge, update the header.  */
5313   if (latch_edge_p)
5314     {
5315       current_loop_nest->header = to;
5316       gcc_assert (loop_latch_edge (current_loop_nest));
5317     }
5318
5319   jump = find_new_jump (src, NULL, prev_max_uid);
5320   if (jump)
5321     sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
5322 }
5323
5324 /* This variable holds the cfg hooks used by the selective scheduler.  */
5325 static struct cfg_hooks sel_cfg_hooks;
5326
5327 /* Register sel-sched cfg hooks.  */
5328 void
5329 sel_register_cfg_hooks (void)
5330 {
5331   sched_split_block = sel_split_block;
5332
5333   orig_cfg_hooks = get_cfg_hooks ();
5334   sel_cfg_hooks = orig_cfg_hooks;
5335
5336   sel_cfg_hooks.create_basic_block = sel_create_basic_block;
5337
5338   set_cfg_hooks (sel_cfg_hooks);
5339
5340   sched_init_only_bb = sel_init_only_bb;
5341   sched_split_block = sel_split_block;
5342   sched_create_empty_bb = sel_create_empty_bb;
5343 }
5344
5345 /* Unregister sel-sched cfg hooks.  */
5346 void
5347 sel_unregister_cfg_hooks (void)
5348 {
5349   sched_create_empty_bb = NULL;
5350   sched_split_block = NULL;
5351   sched_init_only_bb = NULL;
5352
5353   set_cfg_hooks (orig_cfg_hooks);
5354 }
5355 \f
5356
5357 /* Emit an insn rtx based on PATTERN.  If a jump insn is wanted,
5358    LABEL is where this jump should be directed.  */
5359 rtx
5360 create_insn_rtx_from_pattern (rtx pattern, rtx label)
5361 {
5362   rtx insn_rtx;
5363
5364   gcc_assert (!INSN_P (pattern));
5365
5366   start_sequence ();
5367
5368   if (label == NULL_RTX)
5369     insn_rtx = emit_insn (pattern);
5370   else
5371     {
5372       insn_rtx = emit_jump_insn (pattern);
5373       JUMP_LABEL (insn_rtx) = label;
5374       ++LABEL_NUSES (label);
5375     }
5376
5377   end_sequence ();
5378
5379   sched_init_luids (NULL, NULL, NULL, NULL);
5380   sched_extend_target ();
5381   sched_deps_init (false);
5382
5383   /* Initialize INSN_CODE now.  */
5384   recog_memoized (insn_rtx);
5385   return insn_rtx;
5386 }
5387
5388 /* Create a new vinsn for INSN_RTX.  FORCE_UNIQUE_P is true when the vinsn
5389    must not be clonable.  */
5390 vinsn_t
5391 create_vinsn_from_insn_rtx (rtx insn_rtx, bool force_unique_p)
5392 {
5393   gcc_assert (INSN_P (insn_rtx) && !INSN_IN_STREAM_P (insn_rtx));
5394
5395   /* If VINSN_TYPE is not USE, retain its uniqueness.  */
5396   return vinsn_create (insn_rtx, force_unique_p);
5397 }
5398
5399 /* Create a copy of INSN_RTX.  */
5400 rtx
5401 create_copy_of_insn_rtx (rtx insn_rtx)
5402 {
5403   rtx res;
5404
5405   gcc_assert (NONJUMP_INSN_P (insn_rtx));
5406
5407   res = create_insn_rtx_from_pattern (copy_rtx (PATTERN (insn_rtx)),
5408                                       NULL_RTX);
5409   return res;
5410 }
5411
5412 /* Change vinsn field of EXPR to hold NEW_VINSN.  */
5413 void
5414 change_vinsn_in_expr (expr_t expr, vinsn_t new_vinsn)
5415 {
5416   vinsn_detach (EXPR_VINSN (expr));
5417
5418   EXPR_VINSN (expr) = new_vinsn;
5419   vinsn_attach (new_vinsn);
5420 }
5421
5422 /* Helpers for global init.  */
5423 /* This structure is used to be able to call existing bundling mechanism
5424    and calculate insn priorities.  */
5425 static struct haifa_sched_info sched_sel_haifa_sched_info = 
5426 {
5427   NULL, /* init_ready_list */
5428   NULL, /* can_schedule_ready_p */
5429   NULL, /* schedule_more_p */
5430   NULL, /* new_ready */
5431   NULL, /* rgn_rank */
5432   sel_print_insn, /* rgn_print_insn */
5433   contributes_to_priority,
5434
5435   NULL, NULL,
5436   NULL, NULL,
5437   0, 0,
5438
5439   NULL, /* add_remove_insn */
5440   NULL, /* begin_schedule_ready */
5441   NULL, /* advance_target_bb */
5442   SEL_SCHED | NEW_BBS
5443 };
5444
5445 /* Setup special insns used in the scheduler.  */
5446 void 
5447 setup_nop_and_exit_insns (void)
5448 {
5449   gcc_assert (nop_pattern == NULL_RTX
5450               && exit_insn == NULL_RTX);
5451
5452   nop_pattern = gen_nop ();
5453
5454   start_sequence ();
5455   emit_insn (nop_pattern);
5456   exit_insn = get_insns ();
5457   end_sequence ();
5458   set_block_for_insn (exit_insn, EXIT_BLOCK_PTR);
5459 }
5460
5461 /* Free special insns used in the scheduler.  */
5462 void
5463 free_nop_and_exit_insns (void)
5464 {
5465   exit_insn = NULL_RTX;
5466   nop_pattern = NULL_RTX;
5467 }
5468
5469 /* Setup a special vinsn used in new insns initialization.  */
5470 void
5471 setup_nop_vinsn (void)
5472 {
5473   nop_vinsn = vinsn_create (exit_insn, false);
5474   vinsn_attach (nop_vinsn);
5475 }
5476
5477 /* Free a special vinsn used in new insns initialization.  */
5478 void
5479 free_nop_vinsn (void)
5480 {
5481   gcc_assert (VINSN_COUNT (nop_vinsn) == 1);
5482   vinsn_detach (nop_vinsn);
5483   nop_vinsn = NULL;
5484 }
5485
5486 /* Call a set_sched_flags hook.  */
5487 void
5488 sel_set_sched_flags (void)
5489 {
5490   /* ??? This means that set_sched_flags were called, and we decided to 
5491      support speculation.  However, set_sched_flags also modifies flags
5492      on current_sched_info, doing this only at global init.  And we 
5493      sometimes change c_s_i later.  So put the correct flags again.  */
5494   if (spec_info && targetm.sched.set_sched_flags)
5495     targetm.sched.set_sched_flags (spec_info);
5496 }
5497
5498 /* Setup pointers to global sched info structures.  */
5499 void
5500 sel_setup_sched_infos (void)
5501 {
5502   rgn_setup_common_sched_info ();
5503
5504   memcpy (&sel_common_sched_info, common_sched_info,
5505           sizeof (sel_common_sched_info));
5506
5507   sel_common_sched_info.fix_recovery_cfg = NULL;
5508   sel_common_sched_info.add_block = NULL;
5509   sel_common_sched_info.estimate_number_of_insns
5510     = sel_estimate_number_of_insns;
5511   sel_common_sched_info.luid_for_non_insn = sel_luid_for_non_insn;
5512   sel_common_sched_info.sched_pass_id = SCHED_SEL_PASS;
5513
5514   common_sched_info = &sel_common_sched_info;
5515
5516   current_sched_info = &sched_sel_haifa_sched_info;
5517   current_sched_info->sched_max_insns_priority = 
5518     get_rgn_sched_max_insns_priority ();
5519   
5520   sel_set_sched_flags ();
5521 }
5522 \f
5523
5524 /* Adds basic block BB to region RGN at the position *BB_ORD_INDEX,
5525    *BB_ORD_INDEX after that is increased.  */
5526 static void
5527 sel_add_block_to_region (basic_block bb, int *bb_ord_index, int rgn)
5528 {
5529   RGN_NR_BLOCKS (rgn) += 1;
5530   RGN_DONT_CALC_DEPS (rgn) = 0;
5531   RGN_HAS_REAL_EBB (rgn) = 0;
5532   CONTAINING_RGN (bb->index) = rgn;
5533   BLOCK_TO_BB (bb->index) = *bb_ord_index;
5534   rgn_bb_table[RGN_BLOCKS (rgn) + *bb_ord_index] = bb->index;
5535   (*bb_ord_index)++;
5536
5537   /* FIXME: it is true only when not scheduling ebbs.  */
5538   RGN_BLOCKS (rgn + 1) = RGN_BLOCKS (rgn) + RGN_NR_BLOCKS (rgn);
5539 }
5540
5541 /* Functions to support pipelining of outer loops.  */
5542
5543 /* Creates a new empty region and returns it's number.  */
5544 static int
5545 sel_create_new_region (void)
5546 {
5547   int new_rgn_number = nr_regions;
5548
5549   RGN_NR_BLOCKS (new_rgn_number) = 0;
5550
5551   /* FIXME: This will work only when EBBs are not created.  */
5552   if (new_rgn_number != 0)
5553     RGN_BLOCKS (new_rgn_number) = RGN_BLOCKS (new_rgn_number - 1) + 
5554       RGN_NR_BLOCKS (new_rgn_number - 1);
5555   else
5556     RGN_BLOCKS (new_rgn_number) = 0;
5557
5558   /* Set the blocks of the next region so the other functions may
5559      calculate the number of blocks in the region.  */
5560   RGN_BLOCKS (new_rgn_number + 1) = RGN_BLOCKS (new_rgn_number) + 
5561     RGN_NR_BLOCKS (new_rgn_number);
5562
5563   nr_regions++;
5564
5565   return new_rgn_number;
5566 }
5567
5568 /* If X has a smaller topological sort number than Y, returns -1;
5569    if greater, returns 1.  */
5570 static int
5571 bb_top_order_comparator (const void *x, const void *y)
5572 {
5573   basic_block bb1 = *(const basic_block *) x;
5574   basic_block bb2 = *(const basic_block *) y;
5575
5576   gcc_assert (bb1 == bb2 
5577               || rev_top_order_index[bb1->index] 
5578                  != rev_top_order_index[bb2->index]);
5579
5580   /* It's a reverse topological order in REV_TOP_ORDER_INDEX, so
5581      bbs with greater number should go earlier.  */
5582   if (rev_top_order_index[bb1->index] > rev_top_order_index[bb2->index])
5583     return -1;
5584   else
5585     return 1;
5586 }
5587
5588 /* Create a region for LOOP and return its number.  If we don't want 
5589    to pipeline LOOP, return -1.  */
5590 static int
5591 make_region_from_loop (struct loop *loop)
5592 {
5593   unsigned int i;
5594   int new_rgn_number = -1;
5595   struct loop *inner;
5596
5597   /* Basic block index, to be assigned to BLOCK_TO_BB.  */
5598   int bb_ord_index = 0;
5599   basic_block *loop_blocks;
5600   basic_block preheader_block;
5601
5602   if (loop->num_nodes 
5603       > (unsigned) PARAM_VALUE (PARAM_MAX_PIPELINE_REGION_BLOCKS))
5604     return -1;
5605   
5606   /* Don't pipeline loops whose latch belongs to some of its inner loops.  */
5607   for (inner = loop->inner; inner; inner = inner->inner)
5608     if (flow_bb_inside_loop_p (inner, loop->latch))
5609       return -1;
5610
5611   loop->ninsns = num_loop_insns (loop);
5612   if ((int) loop->ninsns > PARAM_VALUE (PARAM_MAX_PIPELINE_REGION_INSNS))
5613     return -1;
5614
5615   loop_blocks = get_loop_body_in_custom_order (loop, bb_top_order_comparator);
5616
5617   for (i = 0; i < loop->num_nodes; i++)
5618     if (loop_blocks[i]->flags & BB_IRREDUCIBLE_LOOP)
5619       {
5620         free (loop_blocks);
5621         return -1;
5622       }
5623
5624   preheader_block = loop_preheader_edge (loop)->src;
5625   gcc_assert (preheader_block);
5626   gcc_assert (loop_blocks[0] == loop->header);
5627
5628   new_rgn_number = sel_create_new_region ();
5629
5630   sel_add_block_to_region (preheader_block, &bb_ord_index, new_rgn_number);
5631   SET_BIT (bbs_in_loop_rgns, preheader_block->index);
5632
5633   for (i = 0; i < loop->num_nodes; i++)
5634     {
5635       /* Add only those blocks that haven't been scheduled in the inner loop.
5636          The exception is the basic blocks with bookkeeping code - they should
5637          be added to the region (and they actually don't belong to the loop 
5638          body, but to the region containing that loop body).  */
5639
5640       gcc_assert (new_rgn_number >= 0);
5641
5642       if (! TEST_BIT (bbs_in_loop_rgns, loop_blocks[i]->index))
5643         {
5644           sel_add_block_to_region (loop_blocks[i], &bb_ord_index, 
5645                                    new_rgn_number);
5646           SET_BIT (bbs_in_loop_rgns, loop_blocks[i]->index);
5647         }
5648     }
5649
5650   free (loop_blocks);
5651   MARK_LOOP_FOR_PIPELINING (loop);
5652
5653   return new_rgn_number;
5654 }
5655
5656 /* Create a new region from preheader blocks LOOP_BLOCKS.  */
5657 void
5658 make_region_from_loop_preheader (VEC(basic_block, heap) **loop_blocks)
5659 {
5660   unsigned int i;
5661   int new_rgn_number = -1;
5662   basic_block bb;
5663
5664   /* Basic block index, to be assigned to BLOCK_TO_BB.  */
5665   int bb_ord_index = 0;
5666
5667   new_rgn_number = sel_create_new_region ();
5668
5669   for (i = 0; VEC_iterate (basic_block, *loop_blocks, i, bb); i++)
5670     {
5671       gcc_assert (new_rgn_number >= 0);
5672
5673       sel_add_block_to_region (bb, &bb_ord_index, new_rgn_number);
5674     }
5675
5676   VEC_free (basic_block, heap, *loop_blocks);
5677   gcc_assert (*loop_blocks == NULL);
5678 }
5679
5680
5681 /* Create region(s) from loop nest LOOP, such that inner loops will be
5682    pipelined before outer loops.  Returns true when a region for LOOP 
5683    is created.  */
5684 static bool
5685 make_regions_from_loop_nest (struct loop *loop)
5686 {   
5687   struct loop *cur_loop;
5688   int rgn_number;
5689
5690   /* Traverse all inner nodes of the loop.  */
5691   for (cur_loop = loop->inner; cur_loop; cur_loop = cur_loop->next)
5692     if (! TEST_BIT (bbs_in_loop_rgns, cur_loop->header->index))
5693       return false;
5694
5695   /* At this moment all regular inner loops should have been pipelined.
5696      Try to create a region from this loop.  */
5697   rgn_number = make_region_from_loop (loop);
5698
5699   if (rgn_number < 0)
5700     return false;
5701
5702   VEC_safe_push (loop_p, heap, loop_nests, loop);
5703   return true;
5704 }
5705
5706 /* Initalize data structures needed.  */
5707 void
5708 sel_init_pipelining (void)
5709 {
5710   /* Collect loop information to be used in outer loops pipelining.  */
5711   loop_optimizer_init (LOOPS_HAVE_PREHEADERS
5712                        | LOOPS_HAVE_FALLTHRU_PREHEADERS
5713                        | LOOPS_HAVE_RECORDED_EXITS
5714                        | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS);
5715   current_loop_nest = NULL;
5716
5717   bbs_in_loop_rgns = sbitmap_alloc (last_basic_block);
5718   sbitmap_zero (bbs_in_loop_rgns);
5719
5720   recompute_rev_top_order ();
5721 }
5722
5723 /* Returns a struct loop for region RGN.  */
5724 loop_p
5725 get_loop_nest_for_rgn (unsigned int rgn)
5726 {
5727   /* Regions created with extend_rgns don't have corresponding loop nests,
5728      because they don't represent loops.  */
5729   if (rgn < VEC_length (loop_p, loop_nests))
5730     return VEC_index (loop_p, loop_nests, rgn);
5731   else
5732     return NULL;
5733 }
5734
5735 /* True when LOOP was included into pipelining regions.   */
5736 bool
5737 considered_for_pipelining_p (struct loop *loop)
5738 {
5739   if (loop_depth (loop) == 0)
5740     return false;
5741
5742   /* Now, the loop could be too large or irreducible.  Check whether its 
5743      region is in LOOP_NESTS.  
5744      We determine the region number of LOOP as the region number of its 
5745      latch.  We can't use header here, because this header could be 
5746      just removed preheader and it will give us the wrong region number.
5747      Latch can't be used because it could be in the inner loop too.  */
5748   if (LOOP_MARKED_FOR_PIPELINING_P (loop) && pipelining_p)
5749     {
5750       int rgn = CONTAINING_RGN (loop->latch->index);
5751
5752       gcc_assert ((unsigned) rgn < VEC_length (loop_p, loop_nests));
5753       return true;
5754     }
5755   
5756   return false;
5757 }
5758
5759 /* Makes regions from the rest of the blocks, after loops are chosen 
5760    for pipelining.  */
5761 static void
5762 make_regions_from_the_rest (void)
5763 {
5764   int cur_rgn_blocks;
5765   int *loop_hdr;
5766   int i;
5767
5768   basic_block bb;
5769   edge e;
5770   edge_iterator ei;
5771   int *degree;
5772   int new_regions;
5773
5774   /* Index in rgn_bb_table where to start allocating new regions.  */
5775   cur_rgn_blocks = nr_regions ? RGN_BLOCKS (nr_regions) : 0;
5776   new_regions = nr_regions;
5777
5778   /* Make regions from all the rest basic blocks - those that don't belong to 
5779      any loop or belong to irreducible loops.  Prepare the data structures
5780      for extend_rgns.  */
5781
5782   /* LOOP_HDR[I] == -1 if I-th bb doesn't belong to any loop,
5783      LOOP_HDR[I] == LOOP_HDR[J] iff basic blocks I and J reside within the same
5784      loop.  */
5785   loop_hdr = XNEWVEC (int, last_basic_block);
5786   degree = XCNEWVEC (int, last_basic_block);
5787
5788
5789   /* For each basic block that belongs to some loop assign the number
5790      of innermost loop it belongs to.  */
5791   for (i = 0; i < last_basic_block; i++)
5792     loop_hdr[i] = -1;
5793
5794   FOR_EACH_BB (bb)
5795     {
5796       if (bb->loop_father && !bb->loop_father->num == 0
5797           && !(bb->flags & BB_IRREDUCIBLE_LOOP))
5798         loop_hdr[bb->index] = bb->loop_father->num;
5799     }
5800
5801   /* For each basic block degree is calculated as the number of incoming 
5802      edges, that are going out of bbs that are not yet scheduled.
5803      The basic blocks that are scheduled have degree value of zero.  */
5804   FOR_EACH_BB (bb) 
5805     {
5806       degree[bb->index] = 0;
5807
5808       if (!TEST_BIT (bbs_in_loop_rgns, bb->index))
5809         {
5810           FOR_EACH_EDGE (e, ei, bb->preds)
5811             if (!TEST_BIT (bbs_in_loop_rgns, e->src->index))
5812               degree[bb->index]++;
5813         }
5814       else
5815         degree[bb->index] = -1;
5816     }
5817
5818   extend_rgns (degree, &cur_rgn_blocks, bbs_in_loop_rgns, loop_hdr);
5819
5820   /* Any block that did not end up in a region is placed into a region
5821      by itself.  */
5822   FOR_EACH_BB (bb)
5823     if (degree[bb->index] >= 0)
5824       {
5825         rgn_bb_table[cur_rgn_blocks] = bb->index;
5826         RGN_NR_BLOCKS (nr_regions) = 1;
5827         RGN_BLOCKS (nr_regions) = cur_rgn_blocks++;
5828         RGN_DONT_CALC_DEPS (nr_regions) = 0;
5829         RGN_HAS_REAL_EBB (nr_regions) = 0;
5830         CONTAINING_RGN (bb->index) = nr_regions++;
5831         BLOCK_TO_BB (bb->index) = 0;
5832       }
5833
5834   free (degree);
5835   free (loop_hdr);
5836 }
5837
5838 /* Free data structures used in pipelining of loops.  */
5839 void sel_finish_pipelining (void)
5840 {
5841   loop_iterator li;
5842   struct loop *loop;
5843
5844   /* Release aux fields so we don't free them later by mistake.  */
5845   FOR_EACH_LOOP (li, loop, 0)
5846     loop->aux = NULL;
5847
5848   loop_optimizer_finalize ();
5849
5850   VEC_free (loop_p, heap, loop_nests);
5851
5852   free (rev_top_order_index);
5853   rev_top_order_index = NULL;
5854 }
5855
5856 /* This function replaces the find_rgns when 
5857    FLAG_SEL_SCHED_PIPELINING_OUTER_LOOPS is set.  */
5858 void 
5859 sel_find_rgns (void)
5860 {
5861   sel_init_pipelining ();
5862   extend_regions ();
5863
5864   if (current_loops)
5865     {
5866       loop_p loop;
5867       loop_iterator li;
5868
5869       FOR_EACH_LOOP (li, loop, (flag_sel_sched_pipelining_outer_loops
5870                                 ? LI_FROM_INNERMOST
5871                                 : LI_ONLY_INNERMOST))
5872         make_regions_from_loop_nest (loop);
5873     }
5874
5875   /* Make regions from all the rest basic blocks and schedule them.
5876      These blocks include blocks that don't belong to any loop or belong  
5877      to irreducible loops.  */
5878   make_regions_from_the_rest ();
5879
5880   /* We don't need bbs_in_loop_rgns anymore.  */
5881   sbitmap_free (bbs_in_loop_rgns);
5882   bbs_in_loop_rgns = NULL;
5883 }
5884
5885 /* Adds the preheader blocks from previous loop to current region taking 
5886    it from LOOP_PREHEADER_BLOCKS (current_loop_nest).  
5887    This function is only used with -fsel-sched-pipelining-outer-loops.  */
5888 void
5889 sel_add_loop_preheaders (void)
5890 {
5891   int i;
5892   basic_block bb;
5893   VEC(basic_block, heap) *preheader_blocks 
5894     = LOOP_PREHEADER_BLOCKS (current_loop_nest);
5895
5896   for (i = 0;
5897        VEC_iterate (basic_block, preheader_blocks, i, bb);
5898        i++)
5899       sel_add_bb (bb);
5900
5901   VEC_free (basic_block, heap, preheader_blocks);
5902 }
5903
5904 /* While pipelining outer loops, returns TRUE if BB is a loop preheader.  
5905    Please note that the function should also work when pipelining_p is 
5906    false, because it is used when deciding whether we should or should 
5907    not reschedule pipelined code.  */
5908 bool
5909 sel_is_loop_preheader_p (basic_block bb)
5910 {
5911   if (current_loop_nest)
5912     {
5913       struct loop *outer;
5914
5915       if (preheader_removed)
5916         return false;
5917
5918       /* Preheader is the first block in the region.  */
5919       if (BLOCK_TO_BB (bb->index) == 0)
5920         return true;
5921
5922       /* We used to find a preheader with the topological information.
5923          Check that the above code is equivalent to what we did before.  */
5924
5925       if (in_current_region_p (current_loop_nest->header))
5926         gcc_assert (!(BLOCK_TO_BB (bb->index) 
5927                       < BLOCK_TO_BB (current_loop_nest->header->index)));
5928
5929       /* Support the situation when the latch block of outer loop
5930          could be from here.  */
5931       for (outer = loop_outer (current_loop_nest);
5932            outer;
5933            outer = loop_outer (outer))
5934         if (considered_for_pipelining_p (outer) && outer->latch == bb)
5935           gcc_unreachable ();
5936     }
5937
5938   return false;
5939 }
5940
5941 /* Checks whether JUMP leads to basic block DEST_BB and no other blocks.  */
5942 bool
5943 jump_leads_only_to_bb_p (insn_t jump, basic_block dest_bb)
5944 {
5945   basic_block jump_bb = BLOCK_FOR_INSN (jump);
5946
5947   /* It is not jump, jump with side-effects or jump can lead to several 
5948      basic blocks.  */
5949   if (!onlyjump_p (jump)
5950       || !any_uncondjump_p (jump))
5951     return false;
5952
5953   /* Several outgoing edges, abnormal edge or destination of jump is 
5954      not DEST_BB.  */
5955   if (EDGE_COUNT (jump_bb->succs) != 1
5956       || EDGE_SUCC (jump_bb, 0)->flags & EDGE_ABNORMAL
5957       || EDGE_SUCC (jump_bb, 0)->dest != dest_bb)
5958     return false;
5959
5960   /* If not anything of the upper.  */
5961   return true;
5962 }
5963
5964 /* Removes the loop preheader from the current region and saves it in
5965    PREHEADER_BLOCKS of the father loop, so they will be added later to 
5966    region that represents an outer loop.  */
5967 static void
5968 sel_remove_loop_preheader (void)
5969 {
5970   int i, old_len;
5971   int cur_rgn = CONTAINING_RGN (BB_TO_BLOCK (0));
5972   basic_block bb;
5973   bool all_empty_p = true;
5974   VEC(basic_block, heap) *preheader_blocks 
5975     = LOOP_PREHEADER_BLOCKS (loop_outer (current_loop_nest));
5976
5977   gcc_assert (current_loop_nest);
5978   old_len = VEC_length (basic_block, preheader_blocks);
5979
5980   /* Add blocks that aren't within the current loop to PREHEADER_BLOCKS.  */
5981   for (i = 0; i < RGN_NR_BLOCKS (cur_rgn); i++)
5982     {
5983       bb = BASIC_BLOCK (BB_TO_BLOCK (i));
5984
5985       /* If the basic block belongs to region, but doesn't belong to 
5986          corresponding loop, then it should be a preheader.  */
5987       if (sel_is_loop_preheader_p (bb))
5988         {
5989           VEC_safe_push (basic_block, heap, preheader_blocks, bb);
5990           if (BB_END (bb) != bb_note (bb))
5991             all_empty_p = false;
5992         }
5993     }
5994   
5995   /* Remove these blocks only after iterating over the whole region.  */
5996   for (i = VEC_length (basic_block, preheader_blocks) - 1;
5997        i >= old_len;
5998        i--)
5999     {
6000       bb =  VEC_index (basic_block, preheader_blocks, i); 
6001       sel_remove_bb (bb, false);
6002     }
6003
6004   if (!considered_for_pipelining_p (loop_outer (current_loop_nest)))
6005     {
6006       if (!all_empty_p)
6007         /* Immediately create new region from preheader.  */
6008         make_region_from_loop_preheader (&preheader_blocks);
6009       else
6010         {
6011           /* If all preheader blocks are empty - dont create new empty region.
6012              Instead, remove them completely.  */
6013           for (i = 0; VEC_iterate (basic_block, preheader_blocks, i, bb); i++)
6014             {
6015               edge e;
6016               edge_iterator ei;
6017               basic_block prev_bb = bb->prev_bb, next_bb = bb->next_bb;
6018
6019               /* Redirect all incoming edges to next basic block.  */
6020               for (ei = ei_start (bb->preds); (e = ei_safe_edge (ei)); )
6021                 {
6022                   if (! (e->flags & EDGE_FALLTHRU))
6023                     redirect_edge_and_branch (e, bb->next_bb);
6024                   else
6025                     redirect_edge_succ (e, bb->next_bb);
6026                 }
6027               gcc_assert (BB_NOTE_LIST (bb) == NULL);
6028               delete_and_free_basic_block (bb);
6029
6030               /* Check if after deleting preheader there is a nonconditional 
6031                  jump in PREV_BB that leads to the next basic block NEXT_BB.  
6032                  If it is so - delete this jump and clear data sets of its 
6033                  basic block if it becomes empty.  */
6034               if (next_bb->prev_bb == prev_bb
6035                   && prev_bb != ENTRY_BLOCK_PTR
6036                   && jump_leads_only_to_bb_p (BB_END (prev_bb), next_bb))
6037                 {
6038                   redirect_edge_and_branch (EDGE_SUCC (prev_bb, 0), next_bb);
6039                   if (BB_END (prev_bb) == bb_note (prev_bb))
6040                     free_data_sets (prev_bb);
6041                 }
6042             }
6043         }
6044       VEC_free (basic_block, heap, preheader_blocks);
6045     }
6046   else
6047     /* Store preheader within the father's loop structure.  */
6048     SET_LOOP_PREHEADER_BLOCKS (loop_outer (current_loop_nest),
6049                                preheader_blocks);
6050 }
6051 #endif