Mercurial > hg > CbC > CbC_gcc
comparison gcc/sel-sched-ir.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Instruction scheduling pass. Selective scheduler and pipeliner. | 1 /* Instruction scheduling pass. Selective scheduler and pipeliner. |
2 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. | 2 Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 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 | 7 the terms of the GNU General Public License as published by the Free |
120 | 120 |
121 /* Its pointer. */ | 121 /* Its pointer. */ |
122 int n; | 122 int n; |
123 | 123 |
124 /* Its size. */ | 124 /* Its size. */ |
125 int s; | 125 int s; |
126 } nop_pool = { NULL, 0, 0 }; | 126 } nop_pool = { NULL, 0, 0 }; |
127 | 127 |
128 /* The pool for basic block notes. */ | 128 /* The pool for basic block notes. */ |
129 static rtx_vec_t bb_note_pool; | 129 static rtx_vec_t bb_note_pool; |
130 | 130 |
132 rtx nop_pattern = NULL_RTX; | 132 rtx nop_pattern = NULL_RTX; |
133 /* A special instruction that resides in EXIT_BLOCK. | 133 /* A special instruction that resides in EXIT_BLOCK. |
134 EXIT_INSN is successor of the insns that lead to EXIT_BLOCK. */ | 134 EXIT_INSN is successor of the insns that lead to EXIT_BLOCK. */ |
135 rtx exit_insn = NULL_RTX; | 135 rtx exit_insn = NULL_RTX; |
136 | 136 |
137 /* TRUE if while scheduling current region, which is loop, its preheader | 137 /* TRUE if while scheduling current region, which is loop, its preheader |
138 was removed. */ | 138 was removed. */ |
139 bool preheader_removed = false; | 139 bool preheader_removed = false; |
140 | 140 |
141 | 141 |
142 /* Forward static declarations. */ | 142 /* Forward static declarations. */ |
155 static void sel_remove_loop_preheader (void); | 155 static void sel_remove_loop_preheader (void); |
156 | 156 |
157 static bool insn_is_the_only_one_in_bb_p (insn_t); | 157 static bool insn_is_the_only_one_in_bb_p (insn_t); |
158 static void create_initial_data_sets (basic_block); | 158 static void create_initial_data_sets (basic_block); |
159 | 159 |
160 static void free_av_set (basic_block); | |
160 static void invalidate_av_set (basic_block); | 161 static void invalidate_av_set (basic_block); |
161 static void extend_insn_data (void); | 162 static void extend_insn_data (void); |
162 static void sel_init_new_insn (insn_t, int); | 163 static void sel_init_new_insn (insn_t, int); |
163 static void finish_insns (void); | 164 static void finish_insns (void); |
164 | 165 |
256 FENCE_SCHEDULED_P (f) = false; | 257 FENCE_SCHEDULED_P (f) = false; |
257 } | 258 } |
258 | 259 |
259 /* Add new fence consisting of INSN and STATE to the list pointed to by LP. */ | 260 /* Add new fence consisting of INSN and STATE to the list pointed to by LP. */ |
260 static void | 261 static void |
261 flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc, | 262 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 insn_t last_scheduled_insn, VEC(rtx,gc) *executing_insns, |
263 int *ready_ticks, int ready_ticks_size, insn_t sched_next, | 264 int *ready_ticks, int ready_ticks_size, insn_t sched_next, |
264 int cycle, int cycle_issued_insns, | 265 int cycle, int cycle_issued_insns, |
265 bool starts_cycle_p, bool after_stall_p) | 266 bool starts_cycle_p, bool after_stall_p) |
266 { | 267 { |
267 fence_t f; | 268 fence_t f; |
268 | 269 |
269 _list_add (lp); | 270 _list_add (lp); |
314 /* Add ORIGINAL_INSN the def list DL honoring CROSSES_CALL. */ | 315 /* Add ORIGINAL_INSN the def list DL honoring CROSSES_CALL. */ |
315 void | 316 void |
316 def_list_add (def_list_t *dl, insn_t original_insn, bool crosses_call) | 317 def_list_add (def_list_t *dl, insn_t original_insn, bool crosses_call) |
317 { | 318 { |
318 def_t d; | 319 def_t d; |
319 | 320 |
320 _list_add (dl); | 321 _list_add (dl); |
321 d = DEF_LIST_DEF (*dl); | 322 d = DEF_LIST_DEF (*dl); |
322 | 323 |
323 d->orig_insn = original_insn; | 324 d->orig_insn = original_insn; |
324 d->crosses_call = crosses_call; | 325 d->crosses_call = crosses_call; |
325 } | 326 } |
326 | 327 |
327 | 328 |
328 /* Functions to work with target contexts. */ | 329 /* Functions to work with target contexts. */ |
329 | 330 |
330 /* Bulk target context. It is convenient for debugging purposes to ensure | 331 /* Bulk target context. It is convenient for debugging purposes to ensure |
331 that there are no uninitialized (null) target contexts. */ | 332 that there are no uninitialized (null) target contexts. */ |
332 static tc_t bulk_tc = (tc_t) 1; | 333 static tc_t bulk_tc = (tc_t) 1; |
333 | 334 |
334 /* Target hooks wrappers. In the future we can provide some default | 335 /* Target hooks wrappers. In the future we can provide some default |
335 implementations for them. */ | 336 implementations for them. */ |
336 | 337 |
337 /* Allocate a store for the target context. */ | 338 /* Allocate a store for the target context. */ |
338 static tc_t | 339 static tc_t |
339 alloc_target_context (void) | 340 alloc_target_context (void) |
421 { | 422 { |
422 clear_target_context (tc); | 423 clear_target_context (tc); |
423 init_target_context (tc, clean_p); | 424 init_target_context (tc, clean_p); |
424 } | 425 } |
425 | 426 |
426 /* Functions to work with dependence contexts. | 427 /* Functions to work with dependence contexts. |
427 Dc (aka deps context, aka deps_t, aka struct deps *) is short for dependence | 428 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 context. It accumulates information about processed insns to decide if |
429 current insn is dependent on the processed ones. */ | 430 current insn is dependent on the processed ones. */ |
430 | 431 |
431 /* Make a copy of FROM in TO. */ | 432 /* Make a copy of FROM in TO. */ |
432 static void | 433 static void |
433 copy_deps_context (deps_t to, deps_t from) | 434 copy_deps_context (deps_t to, deps_t from) |
434 { | 435 { |
435 init_deps (to); | 436 init_deps (to, false); |
436 deps_join (to, from); | 437 deps_join (to, from); |
437 } | 438 } |
438 | 439 |
439 /* Allocate store for dep context. */ | 440 /* Allocate store for dep context. */ |
440 static deps_t | 441 static deps_t |
447 static deps_t | 448 static deps_t |
448 create_deps_context (void) | 449 create_deps_context (void) |
449 { | 450 { |
450 deps_t dc = alloc_deps_context (); | 451 deps_t dc = alloc_deps_context (); |
451 | 452 |
452 init_deps (dc); | 453 init_deps (dc, false); |
453 return dc; | 454 return dc; |
454 } | 455 } |
455 | 456 |
456 /* Create a copy of FROM. */ | 457 /* Create a copy of FROM. */ |
457 static deps_t | 458 static deps_t |
481 /* Clear and init DC. */ | 482 /* Clear and init DC. */ |
482 static void | 483 static void |
483 reset_deps_context (deps_t dc) | 484 reset_deps_context (deps_t dc) |
484 { | 485 { |
485 clear_deps_context (dc); | 486 clear_deps_context (dc); |
486 init_deps (dc); | 487 init_deps (dc, false); |
487 } | 488 } |
488 | 489 |
489 /* This structure describes the dependence analysis hooks for advancing | 490 /* This structure describes the dependence analysis hooks for advancing |
490 dependence context. */ | 491 dependence context. */ |
491 static struct sched_deps_info_def advance_deps_context_sched_deps_info = | 492 static struct sched_deps_info_def advance_deps_context_sched_deps_info = |
492 { | 493 { |
493 NULL, | 494 NULL, |
494 | 495 |
595 { | 596 { |
596 insn_t succ; | 597 insn_t succ; |
597 succ_iterator si; | 598 succ_iterator si; |
598 bool first = true; | 599 bool first = true; |
599 int ready_ticks_size = get_max_uid () + 1; | 600 int ready_ticks_size = get_max_uid () + 1; |
600 | 601 |
601 FOR_EACH_SUCC_1 (succ, si, old_fence, | 602 FOR_EACH_SUCC_1 (succ, si, old_fence, |
602 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS) | 603 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS) |
603 { | 604 { |
604 | 605 |
605 if (first) | 606 if (first) |
606 first = false; | 607 first = false; |
607 else | 608 else |
608 gcc_assert (flag_sel_sched_pipelining_outer_loops); | 609 gcc_assert (flag_sel_sched_pipelining_outer_loops); |
609 | 610 |
610 flist_add (&fences, succ, | 611 flist_add (&fences, succ, |
611 state_create (), | 612 state_create (), |
612 create_deps_context () /* dc */, | 613 create_deps_context () /* dc */, |
613 create_target_context (true) /* tc */, | 614 create_target_context (true) /* tc */, |
614 NULL_RTX /* last_scheduled_insn */, | 615 NULL_RTX /* last_scheduled_insn */, |
615 NULL, /* executing_insns */ | 616 NULL, /* executing_insns */ |
616 XCNEWVEC (int, ready_ticks_size), /* ready_ticks */ | 617 XCNEWVEC (int, ready_ticks_size), /* ready_ticks */ |
617 ready_ticks_size, | 618 ready_ticks_size, |
618 NULL_RTX /* sched_next */, | 619 NULL_RTX /* sched_next */, |
619 1 /* cycle */, 0 /* cycle_issued_insns */, | 620 1 /* cycle */, 0 /* cycle_issued_insns */, |
620 1 /* starts_cycle_p */, 0 /* after_stall_p */); | 621 1 /* starts_cycle_p */, 0 /* after_stall_p */); |
621 } | 622 } |
622 } | 623 } |
623 | 624 |
624 /* Merges two fences (filling fields of fence F with resulting values) by | 625 /* 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 following rules: 1) state, target context and last scheduled insn are |
626 propagated from fallthrough edge if it is available; | 627 propagated from fallthrough edge if it is available; |
627 2) deps context and cycle is propagated from more probable edge; | 628 2) deps context and cycle is propagated from more probable edge; |
628 3) all other fields are set to corresponding constant values. | 629 3) all other fields are set to corresponding constant values. |
629 | 630 |
630 INSN, STATE, DC, TC, LAST_SCHEDULED_INSN, EXECUTING_INSNS, | 631 INSN, STATE, DC, TC, LAST_SCHEDULED_INSN, EXECUTING_INSNS, |
631 READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE and AFTER_STALL_P | 632 READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE and AFTER_STALL_P |
632 are the corresponding fields of the second fence. */ | 633 are the corresponding fields of the second fence. */ |
633 static void | 634 static void |
634 merge_fences (fence_t f, insn_t insn, | 635 merge_fences (fence_t f, insn_t insn, |
635 state_t state, deps_t dc, void *tc, | 636 state_t state, deps_t dc, void *tc, |
636 rtx last_scheduled_insn, VEC(rtx, gc) *executing_insns, | 637 rtx last_scheduled_insn, VEC(rtx, gc) *executing_insns, |
637 int *ready_ticks, int ready_ticks_size, | 638 int *ready_ticks, int ready_ticks_size, |
638 rtx sched_next, int cycle, bool after_stall_p) | 639 rtx sched_next, int cycle, bool after_stall_p) |
639 { | 640 { |
640 insn_t last_scheduled_insn_old = FENCE_LAST_SCHEDULED_INSN (f); | 641 insn_t last_scheduled_insn_old = FENCE_LAST_SCHEDULED_INSN (f); |
641 | 642 |
642 gcc_assert (sel_bb_head_p (FENCE_INSN (f)) | 643 gcc_assert (sel_bb_head_p (FENCE_INSN (f)) |
643 && !sched_next && !FENCE_SCHED_NEXT (f)); | 644 && !sched_next && !FENCE_SCHED_NEXT (f)); |
644 | 645 |
645 /* Check if we can decide which path fences came. | 646 /* Check if we can decide which path fences came. |
646 If we can't (or don't want to) - reset all. */ | 647 If we can't (or don't want to) - reset all. */ |
647 if (last_scheduled_insn == NULL | 648 if (last_scheduled_insn == NULL |
648 || last_scheduled_insn_old == NULL | 649 || last_scheduled_insn_old == NULL |
649 /* This is a case when INSN is reachable on several paths from | 650 /* 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 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 there are two edges: one going around of inner loop and the other - |
652 right through it; in such case just reset everything). */ | 653 right through it; in such case just reset everything). */ |
653 || last_scheduled_insn == last_scheduled_insn_old) | 654 || last_scheduled_insn == last_scheduled_insn_old) |
654 { | 655 { |
655 state_reset (FENCE_STATE (f)); | 656 state_reset (FENCE_STATE (f)); |
656 state_free (state); | 657 state_free (state); |
657 | 658 |
658 reset_deps_context (FENCE_DC (f)); | 659 reset_deps_context (FENCE_DC (f)); |
659 delete_deps_context (dc); | 660 delete_deps_context (dc); |
660 | 661 |
661 reset_target_context (FENCE_TC (f), true); | 662 reset_target_context (FENCE_TC (f), true); |
662 delete_target_context (tc); | 663 delete_target_context (tc); |
663 | 664 |
664 if (cycle > FENCE_CYCLE (f)) | 665 if (cycle > FENCE_CYCLE (f)) |
665 FENCE_CYCLE (f) = cycle; | 666 FENCE_CYCLE (f) = cycle; |
666 | 667 |
667 FENCE_LAST_SCHEDULED_INSN (f) = NULL; | 668 FENCE_LAST_SCHEDULED_INSN (f) = NULL; |
668 VEC_free (rtx, gc, executing_insns); | 669 VEC_free (rtx, gc, executing_insns); |
669 free (ready_ticks); | 670 free (ready_ticks); |
670 if (FENCE_EXECUTING_INSNS (f)) | 671 if (FENCE_EXECUTING_INSNS (f)) |
671 VEC_block_remove (rtx, FENCE_EXECUTING_INSNS (f), 0, | 672 VEC_block_remove (rtx, FENCE_EXECUTING_INSNS (f), 0, |
672 VEC_length (rtx, FENCE_EXECUTING_INSNS (f))); | 673 VEC_length (rtx, FENCE_EXECUTING_INSNS (f))); |
673 if (FENCE_READY_TICKS (f)) | 674 if (FENCE_READY_TICKS (f)) |
674 memset (FENCE_READY_TICKS (f), 0, FENCE_READY_TICKS_SIZE (f)); | 675 memset (FENCE_READY_TICKS (f), 0, FENCE_READY_TICKS_SIZE (f)); |
675 } | 676 } |
676 else | 677 else |
677 { | 678 { |
678 edge edge_old = NULL, edge_new = NULL; | 679 edge edge_old = NULL, edge_new = NULL; |
679 edge candidate; | 680 edge candidate; |
680 succ_iterator si; | 681 succ_iterator si; |
681 insn_t succ; | 682 insn_t succ; |
682 | 683 |
683 /* Find fallthrough edge. */ | 684 /* Find fallthrough edge. */ |
684 gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb); | 685 gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb); |
685 candidate = find_fallthru_edge (BLOCK_FOR_INSN (insn)->prev_bb); | 686 candidate = find_fallthru_edge (BLOCK_FOR_INSN (insn)->prev_bb); |
686 | 687 |
687 if (!candidate | 688 if (!candidate |
689 && candidate->src != BLOCK_FOR_INSN (last_scheduled_insn_old))) | 690 && candidate->src != BLOCK_FOR_INSN (last_scheduled_insn_old))) |
690 { | 691 { |
691 /* No fallthrough edge leading to basic block of INSN. */ | 692 /* No fallthrough edge leading to basic block of INSN. */ |
692 state_reset (FENCE_STATE (f)); | 693 state_reset (FENCE_STATE (f)); |
693 state_free (state); | 694 state_free (state); |
694 | 695 |
695 reset_target_context (FENCE_TC (f), true); | 696 reset_target_context (FENCE_TC (f), true); |
696 delete_target_context (tc); | 697 delete_target_context (tc); |
697 | 698 |
698 FENCE_LAST_SCHEDULED_INSN (f) = NULL; | 699 FENCE_LAST_SCHEDULED_INSN (f) = NULL; |
699 } | 700 } |
700 else | 701 else |
701 if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn)) | 702 if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn)) |
702 { | 703 { |
703 /* Would be weird if same insn is successor of several fallthrough | 704 /* Would be weird if same insn is successor of several fallthrough |
704 edges. */ | 705 edges. */ |
705 gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb | 706 gcc_assert (BLOCK_FOR_INSN (insn)->prev_bb |
706 != BLOCK_FOR_INSN (last_scheduled_insn_old)); | 707 != BLOCK_FOR_INSN (last_scheduled_insn_old)); |
707 | 708 |
708 state_free (FENCE_STATE (f)); | 709 state_free (FENCE_STATE (f)); |
751 { | 752 { |
752 reset_deps_context (FENCE_DC (f)); | 753 reset_deps_context (FENCE_DC (f)); |
753 delete_deps_context (dc); | 754 delete_deps_context (dc); |
754 VEC_free (rtx, gc, executing_insns); | 755 VEC_free (rtx, gc, executing_insns); |
755 free (ready_ticks); | 756 free (ready_ticks); |
756 | 757 |
757 FENCE_CYCLE (f) = MAX (FENCE_CYCLE (f), cycle); | 758 FENCE_CYCLE (f) = MAX (FENCE_CYCLE (f), cycle); |
758 if (FENCE_EXECUTING_INSNS (f)) | 759 if (FENCE_EXECUTING_INSNS (f)) |
759 VEC_block_remove (rtx, FENCE_EXECUTING_INSNS (f), 0, | 760 VEC_block_remove (rtx, FENCE_EXECUTING_INSNS (f), 0, |
760 VEC_length (rtx, FENCE_EXECUTING_INSNS (f))); | 761 VEC_length (rtx, FENCE_EXECUTING_INSNS (f))); |
761 if (FENCE_READY_TICKS (f)) | 762 if (FENCE_READY_TICKS (f)) |
762 memset (FENCE_READY_TICKS (f), 0, FENCE_READY_TICKS_SIZE (f)); | 763 memset (FENCE_READY_TICKS (f), 0, FENCE_READY_TICKS_SIZE (f)); |
763 } | 764 } |
764 else | 765 else |
789 FENCE_ISSUED_INSNS (f) = 0; | 790 FENCE_ISSUED_INSNS (f) = 0; |
790 FENCE_STARTS_CYCLE_P (f) = 1; | 791 FENCE_STARTS_CYCLE_P (f) = 1; |
791 FENCE_SCHED_NEXT (f) = NULL; | 792 FENCE_SCHED_NEXT (f) = NULL; |
792 } | 793 } |
793 | 794 |
794 /* Add a new fence to NEW_FENCES list, initializing it from all | 795 /* Add a new fence to NEW_FENCES list, initializing it from all |
795 other parameters. */ | 796 other parameters. */ |
796 static void | 797 static void |
797 add_to_fences (flist_tail_t new_fences, insn_t insn, | 798 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 state_t state, deps_t dc, void *tc, rtx last_scheduled_insn, |
799 VEC(rtx, gc) *executing_insns, int *ready_ticks, | 800 VEC(rtx, gc) *executing_insns, int *ready_ticks, |
800 int ready_ticks_size, rtx sched_next, int cycle, | 801 int ready_ticks_size, rtx sched_next, int cycle, |
801 int cycle_issued_insns, bool starts_cycle_p, bool after_stall_p) | 802 int cycle_issued_insns, bool starts_cycle_p, bool after_stall_p) |
802 { | 803 { |
803 fence_t f = flist_lookup (FLIST_TAIL_HEAD (new_fences), insn); | 804 fence_t f = flist_lookup (FLIST_TAIL_HEAD (new_fences), insn); |
804 | 805 |
805 if (! f) | 806 if (! f) |
806 { | 807 { |
807 flist_add (FLIST_TAIL_TAILP (new_fences), insn, state, dc, tc, | 808 flist_add (FLIST_TAIL_TAILP (new_fences), insn, state, dc, tc, |
808 last_scheduled_insn, executing_insns, ready_ticks, | 809 last_scheduled_insn, executing_insns, ready_ticks, |
809 ready_ticks_size, sched_next, cycle, cycle_issued_insns, | 810 ready_ticks_size, sched_next, cycle, cycle_issued_insns, |
810 starts_cycle_p, after_stall_p); | 811 starts_cycle_p, after_stall_p); |
811 | 812 |
812 FLIST_TAIL_TAILP (new_fences) | 813 FLIST_TAIL_TAILP (new_fences) |
813 = &FLIST_NEXT (*FLIST_TAIL_TAILP (new_fences)); | 814 = &FLIST_NEXT (*FLIST_TAIL_TAILP (new_fences)); |
814 } | 815 } |
815 else | 816 else |
816 { | 817 { |
817 merge_fences (f, insn, state, dc, tc, last_scheduled_insn, | 818 merge_fences (f, insn, state, dc, tc, last_scheduled_insn, |
818 executing_insns, ready_ticks, ready_ticks_size, | 819 executing_insns, ready_ticks, ready_ticks_size, |
819 sched_next, cycle, after_stall_p); | 820 sched_next, cycle, after_stall_p); |
820 } | 821 } |
821 } | 822 } |
822 | 823 |
823 /* Move the first fence in the OLD_FENCES list to NEW_FENCES. */ | 824 /* Move the first fence in the OLD_FENCES list to NEW_FENCES. */ |
826 { | 827 { |
827 fence_t f, old; | 828 fence_t f, old; |
828 flist_t *tailp = FLIST_TAIL_TAILP (new_fences); | 829 flist_t *tailp = FLIST_TAIL_TAILP (new_fences); |
829 | 830 |
830 old = FLIST_FENCE (old_fences); | 831 old = FLIST_FENCE (old_fences); |
831 f = flist_lookup (FLIST_TAIL_HEAD (new_fences), | 832 f = flist_lookup (FLIST_TAIL_HEAD (new_fences), |
832 FENCE_INSN (FLIST_FENCE (old_fences))); | 833 FENCE_INSN (FLIST_FENCE (old_fences))); |
833 if (f) | 834 if (f) |
834 { | 835 { |
835 merge_fences (f, old->insn, old->state, old->dc, old->tc, | 836 merge_fences (f, old->insn, old->state, old->dc, old->tc, |
836 old->last_scheduled_insn, old->executing_insns, | 837 old->last_scheduled_insn, old->executing_insns, |
837 old->ready_ticks, old->ready_ticks_size, | 838 old->ready_ticks, old->ready_ticks_size, |
838 old->sched_next, old->cycle, | 839 old->sched_next, old->cycle, |
839 old->after_stall_p); | 840 old->after_stall_p); |
840 } | 841 } |
841 else | 842 else |
842 { | 843 { |
843 _list_add (tailp); | 844 _list_add (tailp); |
846 init_fence_for_scheduling (FLIST_FENCE (*tailp)); | 847 init_fence_for_scheduling (FLIST_FENCE (*tailp)); |
847 } | 848 } |
848 FENCE_INSN (old) = NULL; | 849 FENCE_INSN (old) = NULL; |
849 } | 850 } |
850 | 851 |
851 /* Add a new fence to NEW_FENCES list and initialize most of its data | 852 /* Add a new fence to NEW_FENCES list and initialize most of its data |
852 as a clean one. */ | 853 as a clean one. */ |
853 void | 854 void |
854 add_clean_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence) | 855 add_clean_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence) |
855 { | 856 { |
856 int ready_ticks_size = get_max_uid () + 1; | 857 int ready_ticks_size = get_max_uid () + 1; |
857 | 858 |
858 add_to_fences (new_fences, | 859 add_to_fences (new_fences, |
859 succ, state_create (), create_deps_context (), | 860 succ, state_create (), create_deps_context (), |
860 create_target_context (true), | 861 create_target_context (true), |
861 NULL_RTX, NULL, | 862 NULL_RTX, NULL, |
862 XCNEWVEC (int, ready_ticks_size), ready_ticks_size, | 863 XCNEWVEC (int, ready_ticks_size), ready_ticks_size, |
863 NULL_RTX, FENCE_CYCLE (fence) + 1, | 864 NULL_RTX, FENCE_CYCLE (fence) + 1, |
864 0, 1, FENCE_AFTER_STALL_P (fence)); | 865 0, 1, FENCE_AFTER_STALL_P (fence)); |
865 } | 866 } |
866 | 867 |
867 /* Add a new fence to NEW_FENCES list and initialize all of its data | 868 /* Add a new fence to NEW_FENCES list and initialize all of its data |
868 from FENCE and SUCC. */ | 869 from FENCE and SUCC. */ |
869 void | 870 void |
870 add_dirty_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence) | 871 add_dirty_fence_to_fences (flist_tail_t new_fences, insn_t succ, fence_t fence) |
871 { | 872 { |
872 int * new_ready_ticks | 873 int * new_ready_ticks |
873 = XNEWVEC (int, FENCE_READY_TICKS_SIZE (fence)); | 874 = XNEWVEC (int, FENCE_READY_TICKS_SIZE (fence)); |
874 | 875 |
875 memcpy (new_ready_ticks, FENCE_READY_TICKS (fence), | 876 memcpy (new_ready_ticks, FENCE_READY_TICKS (fence), |
876 FENCE_READY_TICKS_SIZE (fence) * sizeof (int)); | 877 FENCE_READY_TICKS_SIZE (fence) * sizeof (int)); |
877 add_to_fences (new_fences, | 878 add_to_fences (new_fences, |
878 succ, state_create_copy (FENCE_STATE (fence)), | 879 succ, state_create_copy (FENCE_STATE (fence)), |
879 create_copy_of_deps_context (FENCE_DC (fence)), | 880 create_copy_of_deps_context (FENCE_DC (fence)), |
880 create_copy_of_target_context (FENCE_TC (fence)), | 881 create_copy_of_target_context (FENCE_TC (fence)), |
881 FENCE_LAST_SCHEDULED_INSN (fence), | 882 FENCE_LAST_SCHEDULED_INSN (fence), |
882 VEC_copy (rtx, gc, FENCE_EXECUTING_INSNS (fence)), | 883 VEC_copy (rtx, gc, FENCE_EXECUTING_INSNS (fence)), |
883 new_ready_ticks, | 884 new_ready_ticks, |
884 FENCE_READY_TICKS_SIZE (fence), | 885 FENCE_READY_TICKS_SIZE (fence), |
885 FENCE_SCHED_NEXT (fence), | 886 FENCE_SCHED_NEXT (fence), |
886 FENCE_CYCLE (fence), | 887 FENCE_CYCLE (fence), |
956 #ifdef ENABLE_CHECKING | 957 #ifdef ENABLE_CHECKING |
957 { | 958 { |
958 regset *v = regset_pool.v; | 959 regset *v = regset_pool.v; |
959 int i = 0; | 960 int i = 0; |
960 int n = regset_pool.n; | 961 int n = regset_pool.n; |
961 | 962 |
962 regset *vv = regset_pool.vv; | 963 regset *vv = regset_pool.vv; |
963 int ii = 0; | 964 int ii = 0; |
964 int nn = regset_pool.nn; | 965 int nn = regset_pool.nn; |
965 | 966 |
966 int diff = 0; | 967 int diff = 0; |
967 | 968 |
968 gcc_assert (n <= nn); | 969 gcc_assert (n <= nn); |
969 | 970 |
970 /* Sort both vectors so it will be possible to compare them. */ | 971 /* Sort both vectors so it will be possible to compare them. */ |
971 qsort (v, n, sizeof (*v), cmp_v_in_regset_pool); | 972 qsort (v, n, sizeof (*v), cmp_v_in_regset_pool); |
972 qsort (vv, nn, sizeof (*vv), cmp_v_in_regset_pool); | 973 qsort (vv, nn, sizeof (*vv), cmp_v_in_regset_pool); |
973 | 974 |
974 while (ii < nn) | 975 while (ii < nn) |
975 { | 976 { |
976 if (v[i] == vv[ii]) | 977 if (v[i] == vv[ii]) |
977 i++; | 978 i++; |
978 else | 979 else |
979 /* VV[II] was lost. */ | 980 /* VV[II] was lost. */ |
980 diff++; | 981 diff++; |
981 | 982 |
982 ii++; | 983 ii++; |
983 } | 984 } |
984 | 985 |
985 gcc_assert (diff == regset_pool.diff); | 986 gcc_assert (diff == regset_pool.diff); |
986 } | 987 } |
987 #endif | 988 #endif |
988 | 989 |
989 /* If not true - we have a memory leak. */ | 990 /* If not true - we have a memory leak. */ |
990 gcc_assert (regset_pool.diff == 0); | 991 gcc_assert (regset_pool.diff == 0); |
991 | 992 |
992 while (regset_pool.n) | 993 while (regset_pool.n) |
993 { | 994 { |
994 --regset_pool.n; | 995 --regset_pool.n; |
995 FREE_REG_SET (regset_pool.v[regset_pool.n]); | 996 FREE_REG_SET (regset_pool.v[regset_pool.n]); |
996 } | 997 } |
997 | 998 |
998 free (regset_pool.v); | 999 free (regset_pool.v); |
999 regset_pool.v = NULL; | 1000 regset_pool.v = NULL; |
1000 regset_pool.s = 0; | 1001 regset_pool.s = 0; |
1001 | 1002 |
1002 free (regset_pool.vv); | 1003 free (regset_pool.vv); |
1003 regset_pool.vv = NULL; | 1004 regset_pool.vv = NULL; |
1004 regset_pool.nn = 0; | 1005 regset_pool.nn = 0; |
1005 regset_pool.ss = 0; | 1006 regset_pool.ss = 0; |
1006 | 1007 |
1007 regset_pool.diff = 0; | 1008 regset_pool.diff = 0; |
1008 } | 1009 } |
1009 | 1010 |
1010 | 1011 |
1011 /* Functions to work with nop pools. NOP insns are used as temporary | 1012 /* 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 placeholders of the insns being scheduled to allow correct update of |
1013 the data sets. When update is finished, NOPs are deleted. */ | 1014 the data sets. When update is finished, NOPs are deleted. */ |
1014 | 1015 |
1015 /* A vinsn that is used to represent a nop. This vinsn is shared among all | 1016 /* A vinsn that is used to represent a nop. This vinsn is shared among all |
1016 nops sel-sched generates. */ | 1017 nops sel-sched generates. */ |
1017 static vinsn_t nop_vinsn = NULL; | 1018 static vinsn_t nop_vinsn = NULL; |
1042 return nop; | 1043 return nop; |
1043 } | 1044 } |
1044 | 1045 |
1045 /* Remove NOP from the instruction stream and return it to the pool. */ | 1046 /* Remove NOP from the instruction stream and return it to the pool. */ |
1046 void | 1047 void |
1047 return_nop_to_pool (insn_t nop) | 1048 return_nop_to_pool (insn_t nop, bool full_tidying) |
1048 { | 1049 { |
1049 gcc_assert (INSN_IN_STREAM_P (nop)); | 1050 gcc_assert (INSN_IN_STREAM_P (nop)); |
1050 sel_remove_insn (nop, false, true); | 1051 sel_remove_insn (nop, false, full_tidying); |
1051 | 1052 |
1052 if (nop_pool.n == nop_pool.s) | 1053 if (nop_pool.n == nop_pool.s) |
1053 nop_pool.v = XRESIZEVEC (rtx, nop_pool.v, | 1054 nop_pool.v = XRESIZEVEC (rtx, nop_pool.v, |
1054 (nop_pool.s = 2 * nop_pool.s + 1)); | 1055 (nop_pool.s = 2 * nop_pool.s + 1)); |
1055 nop_pool.v[nop_pool.n++] = nop; | 1056 nop_pool.v[nop_pool.n++] = nop; |
1056 } | 1057 } |
1057 | 1058 |
1058 /* Free the nop pool. */ | 1059 /* Free the nop pool. */ |
1064 free (nop_pool.v); | 1065 free (nop_pool.v); |
1065 nop_pool.v = NULL; | 1066 nop_pool.v = NULL; |
1066 } | 1067 } |
1067 | 1068 |
1068 | 1069 |
1069 /* Skip unspec to support ia64 speculation. Called from rtx_equal_p_cb. | 1070 /* 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 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 to NX and NY in case some needs to be skipped. */ |
1072 static int | 1073 static int |
1073 skip_unspecs_callback (const_rtx *xx, const_rtx *yy, rtx *nx, rtx* ny) | 1074 skip_unspecs_callback (const_rtx *xx, const_rtx *yy, rtx *nx, rtx* ny) |
1074 { | 1075 { |
1075 const_rtx x = *xx; | 1076 const_rtx x = *xx; |
1076 const_rtx y = *yy; | 1077 const_rtx y = *yy; |
1077 | 1078 |
1078 if (GET_CODE (x) == UNSPEC | 1079 if (GET_CODE (x) == UNSPEC |
1079 && (targetm.sched.skip_rtx_p == NULL | 1080 && (targetm.sched.skip_rtx_p == NULL |
1080 || targetm.sched.skip_rtx_p (x))) | 1081 || targetm.sched.skip_rtx_p (x))) |
1081 { | 1082 { |
1082 *nx = XVECEXP (x, 0, 0); | 1083 *nx = XVECEXP (x, 0, 0); |
1083 *ny = CONST_CAST_RTX (y); | 1084 *ny = CONST_CAST_RTX (y); |
1084 return 1; | 1085 return 1; |
1085 } | 1086 } |
1086 | 1087 |
1087 if (GET_CODE (y) == UNSPEC | 1088 if (GET_CODE (y) == UNSPEC |
1088 && (targetm.sched.skip_rtx_p == NULL | 1089 && (targetm.sched.skip_rtx_p == NULL |
1089 || targetm.sched.skip_rtx_p (y))) | 1090 || targetm.sched.skip_rtx_p (y))) |
1090 { | 1091 { |
1091 *nx = CONST_CAST_RTX (x); | 1092 *nx = CONST_CAST_RTX (x); |
1092 *ny = XVECEXP (y, 0, 0); | 1093 *ny = XVECEXP (y, 0, 0); |
1093 return 1; | 1094 return 1; |
1094 } | 1095 } |
1095 | 1096 |
1096 return 0; | 1097 return 0; |
1097 } | 1098 } |
1098 | 1099 |
1099 /* Callback, called from hash_rtx_cb. Helps to hash UNSPEC rtx X in a correct way | 1100 /* 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 to support ia64 speculation. When changes are needed, new rtx X and new mode |
1101 NMODE are written, and the callback returns true. */ | 1102 NMODE are written, and the callback returns true. */ |
1102 static int | 1103 static int |
1103 hash_with_unspec_callback (const_rtx x, enum machine_mode mode ATTRIBUTE_UNUSED, | 1104 hash_with_unspec_callback (const_rtx x, enum machine_mode mode ATTRIBUTE_UNUSED, |
1104 rtx *nx, enum machine_mode* nmode) | 1105 rtx *nx, enum machine_mode* nmode) |
1105 { | 1106 { |
1106 if (GET_CODE (x) == UNSPEC | 1107 if (GET_CODE (x) == UNSPEC |
1107 && targetm.sched.skip_rtx_p | 1108 && targetm.sched.skip_rtx_p |
1108 && targetm.sched.skip_rtx_p (x)) | 1109 && targetm.sched.skip_rtx_p (x)) |
1109 { | 1110 { |
1110 *nx = XVECEXP (x, 0 ,0); | 1111 *nx = XVECEXP (x, 0 ,0); |
1111 *nmode = 0; | 1112 *nmode = VOIDmode; |
1112 return 1; | 1113 return 1; |
1113 } | 1114 } |
1114 | 1115 |
1115 return 0; | 1116 return 0; |
1116 } | 1117 } |
1117 | 1118 |
1118 /* Returns LHS and RHS are ok to be scheduled separately. */ | 1119 /* Returns LHS and RHS are ok to be scheduled separately. */ |
1119 static bool | 1120 static bool |
1120 lhs_and_rhs_separable_p (rtx lhs, rtx rhs) | 1121 lhs_and_rhs_separable_p (rtx lhs, rtx rhs) |
1121 { | 1122 { |
1122 if (lhs == NULL || rhs == NULL) | 1123 if (lhs == NULL || rhs == NULL) |
1123 return false; | 1124 return false; |
1124 | 1125 |
1125 /* Do not schedule CONST, CONST_INT and CONST_DOUBLE etc as rhs: no point | 1126 /* 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 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 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 merged from branches where the same const used in different modes. */ |
1129 if (CONSTANT_P (rhs)) | 1130 if (CONSTANT_P (rhs)) |
1130 return false; | 1131 return false; |
1131 | 1132 |
1132 /* ??? Do not rename predicate registers to avoid ICEs in bundling. */ | 1133 /* ??? Do not rename predicate registers to avoid ICEs in bundling. */ |
1135 | 1136 |
1136 /* Do not allow single REG to be an rhs. */ | 1137 /* Do not allow single REG to be an rhs. */ |
1137 if (REG_P (rhs)) | 1138 if (REG_P (rhs)) |
1138 return false; | 1139 return false; |
1139 | 1140 |
1140 /* See comment at find_used_regs_1 (*1) for explanation of this | 1141 /* See comment at find_used_regs_1 (*1) for explanation of this |
1141 restriction. */ | 1142 restriction. */ |
1142 /* FIXME: remove this later. */ | 1143 /* FIXME: remove this later. */ |
1143 if (MEM_P (lhs)) | 1144 if (MEM_P (lhs)) |
1144 return false; | 1145 return false; |
1145 | 1146 |
1149 return false; | 1150 return false; |
1150 | 1151 |
1151 return true; | 1152 return true; |
1152 } | 1153 } |
1153 | 1154 |
1154 /* Initialize vinsn VI for INSN. Only for use from vinsn_create (). When | 1155 /* 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 FORCE_UNIQUE_P is true, the resulting vinsn will not be clonable. This is |
1156 used e.g. for insns from recovery blocks. */ | 1157 used e.g. for insns from recovery blocks. */ |
1157 static void | 1158 static void |
1158 vinsn_init (vinsn_t vi, insn_t insn, bool force_unique_p) | 1159 vinsn_init (vinsn_t vi, insn_t insn, bool force_unique_p) |
1159 { | 1160 { |
1160 hash_rtx_callback_function hrcf; | 1161 hash_rtx_callback_function hrcf; |
1161 int insn_class; | 1162 int insn_class; |
1162 | 1163 |
1163 VINSN_INSN_RTX (vi) = insn; | 1164 VINSN_INSN_RTX (vi) = insn; |
1164 VINSN_COUNT (vi) = 0; | 1165 VINSN_COUNT (vi) = 0; |
1165 vi->cost = -1; | 1166 vi->cost = -1; |
1166 | 1167 |
1167 if (DF_INSN_UID_SAFE_GET (INSN_UID (insn)) != NULL) | 1168 if (DF_INSN_UID_SAFE_GET (INSN_UID (insn)) != NULL) |
1168 init_id_from_df (VINSN_ID (vi), insn, force_unique_p); | 1169 init_id_from_df (VINSN_ID (vi), insn, force_unique_p); |
1169 else | 1170 else |
1170 deps_init_id (VINSN_ID (vi), insn, force_unique_p); | 1171 deps_init_id (VINSN_ID (vi), insn, force_unique_p); |
1171 | 1172 |
1172 /* Hash vinsn depending on whether it is separable or not. */ | 1173 /* Hash vinsn depending on whether it is separable or not. */ |
1173 hrcf = targetm.sched.skip_rtx_p ? hash_with_unspec_callback : NULL; | 1174 hrcf = targetm.sched.skip_rtx_p ? hash_with_unspec_callback : NULL; |
1174 if (VINSN_SEPARABLE_P (vi)) | 1175 if (VINSN_SEPARABLE_P (vi)) |
1175 { | 1176 { |
1176 rtx rhs = VINSN_RHS (vi); | 1177 rtx rhs = VINSN_RHS (vi); |
1185 { | 1186 { |
1186 VINSN_HASH (vi) = hash_rtx_cb (VINSN_PATTERN (vi), VOIDmode, | 1187 VINSN_HASH (vi) = hash_rtx_cb (VINSN_PATTERN (vi), VOIDmode, |
1187 NULL, NULL, false, hrcf); | 1188 NULL, NULL, false, hrcf); |
1188 VINSN_HASH_RTX (vi) = VINSN_HASH (vi); | 1189 VINSN_HASH_RTX (vi) = VINSN_HASH (vi); |
1189 } | 1190 } |
1190 | 1191 |
1191 insn_class = haifa_classify_insn (insn); | 1192 insn_class = haifa_classify_insn (insn); |
1192 if (insn_class >= 2 | 1193 if (insn_class >= 2 |
1193 && (!targetm.sched.get_insn_spec_ds | 1194 && (!targetm.sched.get_insn_spec_ds |
1194 || ((targetm.sched.get_insn_spec_ds (insn) & BEGIN_CONTROL) | 1195 || ((targetm.sched.get_insn_spec_ds (insn) & BEGIN_CONTROL) |
1195 == 0))) | 1196 == 0))) |
1206 gcc_assert (VINSN_INSN_RTX (vi)); | 1207 gcc_assert (VINSN_INSN_RTX (vi)); |
1207 | 1208 |
1208 VINSN_COUNT (vi)++; | 1209 VINSN_COUNT (vi)++; |
1209 } | 1210 } |
1210 | 1211 |
1211 /* Create and init VI from the INSN. Use UNIQUE_P for determining the correct | 1212 /* Create and init VI from the INSN. Use UNIQUE_P for determining the correct |
1212 VINSN_TYPE (VI). */ | 1213 VINSN_TYPE (VI). */ |
1213 static vinsn_t | 1214 static vinsn_t |
1214 vinsn_create (insn_t insn, bool force_unique_p) | 1215 vinsn_create (insn_t insn, bool force_unique_p) |
1215 { | 1216 { |
1216 vinsn_t vi = XCNEW (struct vinsn_def); | 1217 vinsn_t vi = XCNEW (struct vinsn_def); |
1219 return vi; | 1220 return vi; |
1220 } | 1221 } |
1221 | 1222 |
1222 /* Return a copy of VI. When REATTACH_P is true, detach VI and attach | 1223 /* Return a copy of VI. When REATTACH_P is true, detach VI and attach |
1223 the copy. */ | 1224 the copy. */ |
1224 vinsn_t | 1225 vinsn_t |
1225 vinsn_copy (vinsn_t vi, bool reattach_p) | 1226 vinsn_copy (vinsn_t vi, bool reattach_p) |
1226 { | 1227 { |
1227 rtx copy; | 1228 rtx copy; |
1228 bool unique = VINSN_UNIQUE_P (vi); | 1229 bool unique = VINSN_UNIQUE_P (vi); |
1229 vinsn_t new_vi; | 1230 vinsn_t new_vi; |
1230 | 1231 |
1231 copy = create_copy_of_insn_rtx (VINSN_INSN_RTX (vi)); | 1232 copy = create_copy_of_insn_rtx (VINSN_INSN_RTX (vi)); |
1232 new_vi = create_vinsn_from_insn_rtx (copy, unique); | 1233 new_vi = create_vinsn_from_insn_rtx (copy, unique); |
1233 if (reattach_p) | 1234 if (reattach_p) |
1234 { | 1235 { |
1235 vinsn_detach (vi); | 1236 vinsn_detach (vi); |
1250 return_regset_to_pool (VINSN_REG_CLOBBERS (vi)); | 1251 return_regset_to_pool (VINSN_REG_CLOBBERS (vi)); |
1251 | 1252 |
1252 free (vi); | 1253 free (vi); |
1253 } | 1254 } |
1254 | 1255 |
1255 /* Indicate that VI is no longer a part of some rtx object. | 1256 /* Indicate that VI is no longer a part of some rtx object. |
1256 Remove VI if it is no longer needed. */ | 1257 Remove VI if it is no longer needed. */ |
1257 void | 1258 void |
1258 vinsn_detach (vinsn_t vi) | 1259 vinsn_detach (vinsn_t vi) |
1259 { | 1260 { |
1260 gcc_assert (VINSN_COUNT (vi) > 0); | 1261 gcc_assert (VINSN_COUNT (vi) > 0); |
1357 | 1358 |
1358 return insn; | 1359 return insn; |
1359 } | 1360 } |
1360 | 1361 |
1361 /* Emit new insn after AFTER based on EXPR and SEQNO. If VINSN is not NULL, | 1362 /* 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 take it as a new vinsn instead of EXPR's vinsn. |
1363 We simplify insns later, after scheduling region in | 1364 We simplify insns later, after scheduling region in |
1364 simplify_changed_insns. */ | 1365 simplify_changed_insns. */ |
1365 insn_t | 1366 insn_t |
1366 sel_gen_insn_from_expr_after (expr_t expr, vinsn_t vinsn, int seqno, | 1367 sel_gen_insn_from_expr_after (expr_t expr, vinsn_t vinsn, int seqno, |
1367 insn_t after) | 1368 insn_t after) |
1368 { | 1369 { |
1369 expr_t emit_expr; | 1370 expr_t emit_expr; |
1370 insn_t insn; | 1371 insn_t insn; |
1371 int flags; | 1372 int flags; |
1372 | 1373 |
1373 emit_expr = set_insn_init (expr, vinsn ? vinsn : EXPR_VINSN (expr), | 1374 emit_expr = set_insn_init (expr, vinsn ? vinsn : EXPR_VINSN (expr), |
1374 seqno); | 1375 seqno); |
1375 insn = EXPR_INSN_RTX (emit_expr); | 1376 insn = EXPR_INSN_RTX (emit_expr); |
1376 add_insn_after (insn, after, BLOCK_FOR_INSN (insn)); | 1377 add_insn_after (insn, after, BLOCK_FOR_INSN (insn)); |
1377 | 1378 |
1378 flags = INSN_INIT_TODO_SSID; | 1379 flags = INSN_INIT_TODO_SSID; |
1379 if (INSN_LUID (insn) == 0) | 1380 if (INSN_LUID (insn) == 0) |
1380 flags |= INSN_INIT_TODO_LUID; | 1381 flags |= INSN_INIT_TODO_LUID; |
1381 sel_init_new_insn (insn, flags); | 1382 sel_init_new_insn (insn, flags); |
1401 | 1402 |
1402 /* Update links from insn to bb and vice versa. */ | 1403 /* Update links from insn to bb and vice versa. */ |
1403 df_insn_change_bb (insn, bb); | 1404 df_insn_change_bb (insn, bb); |
1404 if (BB_END (bb) == after) | 1405 if (BB_END (bb) == after) |
1405 BB_END (bb) = insn; | 1406 BB_END (bb) = insn; |
1406 | 1407 |
1407 prepare_insn_expr (insn, seqno); | 1408 prepare_insn_expr (insn, seqno); |
1408 return insn; | 1409 return insn; |
1409 } | 1410 } |
1410 | 1411 |
1411 | 1412 |
1412 /* Functions to work with right-hand sides. */ | 1413 /* Functions to work with right-hand sides. */ |
1413 | 1414 |
1414 /* Search for a hash value determined by UID/NEW_VINSN in a sorted vector | 1415 /* 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 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 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 the search has stopped, such that inserting the new element at INDP will |
1418 retain VECT's sort order. */ | 1419 retain VECT's sort order. */ |
1419 static bool | 1420 static bool |
1420 find_in_history_vect_1 (VEC(expr_history_def, heap) *vect, | 1421 find_in_history_vect_1 (VEC(expr_history_def, heap) *vect, |
1421 unsigned uid, vinsn_t new_vinsn, | 1422 unsigned uid, vinsn_t new_vinsn, |
1422 bool compare_vinsns, int *indp) | 1423 bool compare_vinsns, int *indp) |
1423 { | 1424 { |
1424 expr_history_def *arr; | 1425 expr_history_def *arr; |
1425 int i, j, len = VEC_length (expr_history_def, vect); | 1426 int i, j, len = VEC_length (expr_history_def, vect); |
1426 | 1427 |
1434 i = 0, j = len - 1; | 1435 i = 0, j = len - 1; |
1435 | 1436 |
1436 while (i <= j) | 1437 while (i <= j) |
1437 { | 1438 { |
1438 unsigned auid = arr[i].uid; | 1439 unsigned auid = arr[i].uid; |
1439 vinsn_t avinsn = arr[i].new_expr_vinsn; | 1440 vinsn_t avinsn = arr[i].new_expr_vinsn; |
1440 | 1441 |
1441 if (auid == uid | 1442 if (auid == uid |
1442 /* When undoing transformation on a bookkeeping copy, the new vinsn | 1443 /* 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 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 This is because the insn whose copy we're checking was possibly |
1445 substituted itself. */ | 1446 substituted itself. */ |
1446 && (! compare_vinsns | 1447 && (! compare_vinsns |
1447 || vinsn_equal_p (avinsn, new_vinsn))) | 1448 || vinsn_equal_p (avinsn, new_vinsn))) |
1448 { | 1449 { |
1449 *indp = i; | 1450 *indp = i; |
1450 return true; | 1451 return true; |
1451 } | 1452 } |
1456 | 1457 |
1457 *indp = i; | 1458 *indp = i; |
1458 return false; | 1459 return false; |
1459 } | 1460 } |
1460 | 1461 |
1461 /* Search for a uid of INSN and NEW_VINSN in a sorted vector VECT. Return | 1462 /* 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 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 Search also for UIDs of insn's originators, if ORIGINATORS_P is true. */ |
1464 int | 1465 int |
1465 find_in_history_vect (VEC(expr_history_def, heap) *vect, rtx insn, | 1466 find_in_history_vect (VEC(expr_history_def, heap) *vect, rtx insn, |
1466 vinsn_t new_vinsn, bool originators_p) | 1467 vinsn_t new_vinsn, bool originators_p) |
1467 { | 1468 { |
1468 int ind; | 1469 int ind; |
1469 | 1470 |
1470 if (find_in_history_vect_1 (vect, INSN_UID (insn), new_vinsn, | 1471 if (find_in_history_vect_1 (vect, INSN_UID (insn), new_vinsn, |
1471 false, &ind)) | 1472 false, &ind)) |
1472 return ind; | 1473 return ind; |
1473 | 1474 |
1474 if (INSN_ORIGINATORS (insn) && originators_p) | 1475 if (INSN_ORIGINATORS (insn) && originators_p) |
1475 { | 1476 { |
1478 | 1479 |
1479 EXECUTE_IF_SET_IN_BITMAP (INSN_ORIGINATORS (insn), 0, uid, bi) | 1480 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 if (find_in_history_vect_1 (vect, uid, new_vinsn, false, &ind)) |
1481 return ind; | 1482 return ind; |
1482 } | 1483 } |
1483 | 1484 |
1484 return -1; | 1485 return -1; |
1485 } | 1486 } |
1486 | 1487 |
1487 /* Insert new element in a sorted history vector pointed to by PVECT, | 1488 /* 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 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 UID/NEW_EXPR_VINSN pair. TYPE, OLD_EXPR_VINSN and SPEC_DS save |
1490 the history of a transformation. */ | 1491 the history of a transformation. */ |
1491 void | 1492 void |
1492 insert_in_history_vect (VEC (expr_history_def, heap) **pvect, | 1493 insert_in_history_vect (VEC (expr_history_def, heap) **pvect, |
1493 unsigned uid, enum local_trans_type type, | 1494 unsigned uid, enum local_trans_type type, |
1494 vinsn_t old_expr_vinsn, vinsn_t new_expr_vinsn, | 1495 vinsn_t old_expr_vinsn, vinsn_t new_expr_vinsn, |
1495 ds_t spec_ds) | 1496 ds_t spec_ds) |
1496 { | 1497 { |
1497 VEC(expr_history_def, heap) *vect = *pvect; | 1498 VEC(expr_history_def, heap) *vect = *pvect; |
1498 expr_history_def temp; | 1499 expr_history_def temp; |
1499 bool res; | 1500 bool res; |
1503 | 1504 |
1504 if (res) | 1505 if (res) |
1505 { | 1506 { |
1506 expr_history_def *phist = VEC_index (expr_history_def, vect, ind); | 1507 expr_history_def *phist = VEC_index (expr_history_def, vect, ind); |
1507 | 1508 |
1508 /* When merging, either old vinsns are the *same* or, if not, both | 1509 /* It is possible that speculation types of expressions that were |
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 | 1510 propagated through different paths will be different here. In this |
1518 case, merge the status to get the correct check later. */ | 1511 case, merge the status to get the correct check later. */ |
1519 if (phist->spec_ds != spec_ds) | 1512 if (phist->spec_ds != spec_ds) |
1520 phist->spec_ds = ds_max_merge (phist->spec_ds, spec_ds); | 1513 phist->spec_ds = ds_max_merge (phist->spec_ds, spec_ds); |
1521 return; | 1514 return; |
1522 } | 1515 } |
1523 | 1516 |
1524 temp.uid = uid; | 1517 temp.uid = uid; |
1525 temp.old_expr_vinsn = old_expr_vinsn; | 1518 temp.old_expr_vinsn = old_expr_vinsn; |
1526 temp.new_expr_vinsn = new_expr_vinsn; | 1519 temp.new_expr_vinsn = new_expr_vinsn; |
1527 temp.spec_ds = spec_ds; | 1520 temp.spec_ds = spec_ds; |
1528 temp.type = type; | 1521 temp.type = type; |
1529 | 1522 |
1530 vinsn_attach (old_expr_vinsn); | 1523 vinsn_attach (old_expr_vinsn); |
1531 vinsn_attach (new_expr_vinsn); | 1524 vinsn_attach (new_expr_vinsn); |
1540 unsigned i; | 1533 unsigned i; |
1541 expr_history_def *phist; | 1534 expr_history_def *phist; |
1542 | 1535 |
1543 if (! *pvect) | 1536 if (! *pvect) |
1544 return; | 1537 return; |
1545 | 1538 |
1546 for (i = 0; | 1539 for (i = 0; |
1547 VEC_iterate (expr_history_def, *pvect, i, phist); | 1540 VEC_iterate (expr_history_def, *pvect, i, phist); |
1548 i++) | 1541 i++) |
1549 { | 1542 { |
1550 vinsn_detach (phist->old_expr_vinsn); | 1543 vinsn_detach (phist->old_expr_vinsn); |
1551 vinsn_detach (phist->new_expr_vinsn); | 1544 vinsn_detach (phist->new_expr_vinsn); |
1552 } | 1545 } |
1553 | 1546 |
1554 VEC_free (expr_history_def, heap, *pvect); | 1547 VEC_free (expr_history_def, heap, *pvect); |
1555 *pvect = NULL; | 1548 *pvect = NULL; |
1556 } | 1549 } |
1557 | 1550 |
1558 | 1551 |
1570 | 1563 |
1571 if (VINSN_HASH (x) != VINSN_HASH (y)) | 1564 if (VINSN_HASH (x) != VINSN_HASH (y)) |
1572 return false; | 1565 return false; |
1573 | 1566 |
1574 repcf = targetm.sched.skip_rtx_p ? skip_unspecs_callback : NULL; | 1567 repcf = targetm.sched.skip_rtx_p ? skip_unspecs_callback : NULL; |
1575 if (VINSN_SEPARABLE_P (x)) | 1568 if (VINSN_SEPARABLE_P (x)) |
1576 { | 1569 { |
1577 /* Compare RHSes of VINSNs. */ | 1570 /* Compare RHSes of VINSNs. */ |
1578 gcc_assert (VINSN_RHS (x)); | 1571 gcc_assert (VINSN_RHS (x)); |
1579 gcc_assert (VINSN_RHS (y)); | 1572 gcc_assert (VINSN_RHS (y)); |
1580 | 1573 |
1590 /* Initialize EXPR. */ | 1583 /* Initialize EXPR. */ |
1591 static void | 1584 static void |
1592 init_expr (expr_t expr, vinsn_t vi, int spec, int use, int priority, | 1585 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, | 1586 int sched_times, int orig_bb_index, ds_t spec_done_ds, |
1594 ds_t spec_to_check_ds, int orig_sched_cycle, | 1587 ds_t spec_to_check_ds, int orig_sched_cycle, |
1595 VEC(expr_history_def, heap) *history, bool target_available, | 1588 VEC(expr_history_def, heap) *history, bool target_available, |
1596 bool was_substituted, bool was_renamed, bool needs_spec_check_p, | 1589 bool was_substituted, bool was_renamed, bool needs_spec_check_p, |
1597 bool cant_move) | 1590 bool cant_move) |
1598 { | 1591 { |
1599 vinsn_attach (vi); | 1592 vinsn_attach (vi); |
1600 | 1593 |
1631 { | 1624 { |
1632 unsigned i; | 1625 unsigned i; |
1633 expr_history_def *phist; | 1626 expr_history_def *phist; |
1634 | 1627 |
1635 temp = VEC_copy (expr_history_def, heap, EXPR_HISTORY_OF_CHANGES (from)); | 1628 temp = VEC_copy (expr_history_def, heap, EXPR_HISTORY_OF_CHANGES (from)); |
1636 for (i = 0; | 1629 for (i = 0; |
1637 VEC_iterate (expr_history_def, temp, i, phist); | 1630 VEC_iterate (expr_history_def, temp, i, phist); |
1638 i++) | 1631 i++) |
1639 { | 1632 { |
1640 vinsn_attach (phist->old_expr_vinsn); | 1633 vinsn_attach (phist->old_expr_vinsn); |
1641 vinsn_attach (phist->new_expr_vinsn); | 1634 vinsn_attach (phist->new_expr_vinsn); |
1642 } | 1635 } |
1643 } | 1636 } |
1644 | 1637 |
1645 init_expr (to, EXPR_VINSN (from), EXPR_SPEC (from), | 1638 init_expr (to, EXPR_VINSN (from), EXPR_SPEC (from), |
1646 EXPR_USEFULNESS (from), EXPR_PRIORITY (from), | 1639 EXPR_USEFULNESS (from), EXPR_PRIORITY (from), |
1647 EXPR_SCHED_TIMES (from), EXPR_ORIG_BB_INDEX (from), | 1640 EXPR_SCHED_TIMES (from), EXPR_ORIG_BB_INDEX (from), |
1648 EXPR_SPEC_DONE_DS (from), EXPR_SPEC_TO_CHECK_DS (from), | 1641 EXPR_SPEC_DONE_DS (from), EXPR_SPEC_TO_CHECK_DS (from), |
1649 EXPR_ORIG_SCHED_CYCLE (from), temp, | 1642 EXPR_ORIG_SCHED_CYCLE (from), temp, |
1650 EXPR_TARGET_AVAILABLE (from), EXPR_WAS_SUBSTITUTED (from), | 1643 EXPR_TARGET_AVAILABLE (from), EXPR_WAS_SUBSTITUTED (from), |
1651 EXPR_WAS_RENAMED (from), EXPR_NEEDS_SPEC_CHECK_P (from), | 1644 EXPR_WAS_RENAMED (from), EXPR_NEEDS_SPEC_CHECK_P (from), |
1652 EXPR_CANT_MOVE (from)); | 1645 EXPR_CANT_MOVE (from)); |
1653 } | 1646 } |
1654 | 1647 |
1655 /* Same, but the final expr will not ever be in av sets, so don't copy | 1648 /* Same, but the final expr will not ever be in av sets, so don't copy |
1656 "uninteresting" data such as bitmap cache. */ | 1649 "uninteresting" data such as bitmap cache. */ |
1657 void | 1650 void |
1658 copy_expr_onside (expr_t to, expr_t from) | 1651 copy_expr_onside (expr_t to, expr_t from) |
1659 { | 1652 { |
1660 init_expr (to, EXPR_VINSN (from), EXPR_SPEC (from), EXPR_USEFULNESS (from), | 1653 init_expr (to, EXPR_VINSN (from), EXPR_SPEC (from), EXPR_USEFULNESS (from), |
1670 static void | 1663 static void |
1671 prepare_insn_expr (insn_t insn, int seqno) | 1664 prepare_insn_expr (insn_t insn, int seqno) |
1672 { | 1665 { |
1673 expr_t expr = INSN_EXPR (insn); | 1666 expr_t expr = INSN_EXPR (insn); |
1674 ds_t ds; | 1667 ds_t ds; |
1675 | 1668 |
1676 INSN_SEQNO (insn) = seqno; | 1669 INSN_SEQNO (insn) = seqno; |
1677 EXPR_ORIG_BB_INDEX (expr) = BLOCK_NUM (insn); | 1670 EXPR_ORIG_BB_INDEX (expr) = BLOCK_NUM (insn); |
1678 EXPR_SPEC (expr) = 0; | 1671 EXPR_SPEC (expr) = 0; |
1679 EXPR_ORIG_SCHED_CYCLE (expr) = 0; | 1672 EXPR_ORIG_SCHED_CYCLE (expr) = 0; |
1680 EXPR_WAS_SUBSTITUTED (expr) = 0; | 1673 EXPR_WAS_SUBSTITUTED (expr) = 0; |
1693 | 1686 |
1694 free_history_vect (&EXPR_HISTORY_OF_CHANGES (expr)); | 1687 free_history_vect (&EXPR_HISTORY_OF_CHANGES (expr)); |
1695 } | 1688 } |
1696 | 1689 |
1697 /* Update target_available bits when merging exprs TO and FROM. SPLIT_POINT | 1690 /* Update target_available bits when merging exprs TO and FROM. SPLIT_POINT |
1698 is non-null when expressions are merged from different successors at | 1691 is non-null when expressions are merged from different successors at |
1699 a split point. */ | 1692 a split point. */ |
1700 static void | 1693 static void |
1701 update_target_availability (expr_t to, expr_t from, insn_t split_point) | 1694 update_target_availability (expr_t to, expr_t from, insn_t split_point) |
1702 { | 1695 { |
1703 if (EXPR_TARGET_AVAILABLE (to) < 0 | 1696 if (EXPR_TARGET_AVAILABLE (to) < 0 |
1704 || EXPR_TARGET_AVAILABLE (from) < 0) | 1697 || EXPR_TARGET_AVAILABLE (from) < 0) |
1705 EXPR_TARGET_AVAILABLE (to) = -1; | 1698 EXPR_TARGET_AVAILABLE (to) = -1; |
1706 else | 1699 else |
1707 { | 1700 { |
1708 /* We try to detect the case when one of the expressions | 1701 /* We try to detect the case when one of the expressions |
1712 { | 1705 { |
1713 int toind, fromind; | 1706 int toind, fromind; |
1714 | 1707 |
1715 toind = EXPR_ORIG_BB_INDEX (to); | 1708 toind = EXPR_ORIG_BB_INDEX (to); |
1716 fromind = EXPR_ORIG_BB_INDEX (from); | 1709 fromind = EXPR_ORIG_BB_INDEX (from); |
1717 | 1710 |
1718 if (toind && toind == fromind) | 1711 if (toind && toind == fromind) |
1719 /* Do nothing -- everything is done in | 1712 /* Do nothing -- everything is done in |
1720 merge_with_other_exprs. */ | 1713 merge_with_other_exprs. */ |
1721 ; | 1714 ; |
1722 else | 1715 else |
1723 EXPR_TARGET_AVAILABLE (to) = -1; | 1716 EXPR_TARGET_AVAILABLE (to) = -1; |
1724 } | 1717 } |
1726 EXPR_TARGET_AVAILABLE (to) &= EXPR_TARGET_AVAILABLE (from); | 1719 EXPR_TARGET_AVAILABLE (to) &= EXPR_TARGET_AVAILABLE (from); |
1727 } | 1720 } |
1728 } | 1721 } |
1729 | 1722 |
1730 /* Update speculation bits when merging exprs TO and FROM. SPLIT_POINT | 1723 /* Update speculation bits when merging exprs TO and FROM. SPLIT_POINT |
1731 is non-null when expressions are merged from different successors at | 1724 is non-null when expressions are merged from different successors at |
1732 a split point. */ | 1725 a split point. */ |
1733 static void | 1726 static void |
1734 update_speculative_bits (expr_t to, expr_t from, insn_t split_point) | 1727 update_speculative_bits (expr_t to, expr_t from, insn_t split_point) |
1735 { | 1728 { |
1736 ds_t old_to_ds, old_from_ds; | 1729 ds_t old_to_ds, old_from_ds; |
1737 | 1730 |
1738 old_to_ds = EXPR_SPEC_DONE_DS (to); | 1731 old_to_ds = EXPR_SPEC_DONE_DS (to); |
1739 old_from_ds = EXPR_SPEC_DONE_DS (from); | 1732 old_from_ds = EXPR_SPEC_DONE_DS (from); |
1740 | 1733 |
1741 EXPR_SPEC_DONE_DS (to) = ds_max_merge (old_to_ds, old_from_ds); | 1734 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); | 1735 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); | 1736 EXPR_NEEDS_SPEC_CHECK_P (to) |= EXPR_NEEDS_SPEC_CHECK_P (from); |
1744 | 1737 |
1745 /* When merging e.g. control & data speculative exprs, or a control | 1738 /* When merging e.g. control & data speculative exprs, or a control |
1746 speculative with a control&data speculative one, we really have | 1739 speculative with a control&data speculative one, we really have |
1747 to change vinsn too. Also, when speculative status is changed, | 1740 to change vinsn too. Also, when speculative status is changed, |
1748 we also need to record this as a transformation in expr's history. */ | 1741 we also need to record this as a transformation in expr's history. */ |
1749 if ((old_to_ds & SPECULATIVE) || (old_from_ds & SPECULATIVE)) | 1742 if ((old_to_ds & SPECULATIVE) || (old_from_ds & SPECULATIVE)) |
1750 { | 1743 { |
1751 old_to_ds = ds_get_speculation_types (old_to_ds); | 1744 old_to_ds = ds_get_speculation_types (old_to_ds); |
1752 old_from_ds = ds_get_speculation_types (old_from_ds); | 1745 old_from_ds = ds_get_speculation_types (old_from_ds); |
1753 | 1746 |
1754 if (old_to_ds != old_from_ds) | 1747 if (old_to_ds != old_from_ds) |
1755 { | 1748 { |
1756 ds_t record_ds; | 1749 ds_t record_ds; |
1757 | 1750 |
1758 /* When both expressions are speculative, we need to change | 1751 /* When both expressions are speculative, we need to change |
1759 the vinsn first. */ | 1752 the vinsn first. */ |
1760 if ((old_to_ds & SPECULATIVE) && (old_from_ds & SPECULATIVE)) | 1753 if ((old_to_ds & SPECULATIVE) && (old_from_ds & SPECULATIVE)) |
1761 { | 1754 { |
1762 int res; | 1755 int res; |
1763 | 1756 |
1764 res = speculate_expr (to, EXPR_SPEC_DONE_DS (to)); | 1757 res = speculate_expr (to, EXPR_SPEC_DONE_DS (to)); |
1765 gcc_assert (res >= 0); | 1758 gcc_assert (res >= 0); |
1766 } | 1759 } |
1767 | 1760 |
1768 if (split_point != NULL) | 1761 if (split_point != NULL) |
1769 { | 1762 { |
1770 /* Record the change with proper status. */ | 1763 /* Record the change with proper status. */ |
1771 record_ds = EXPR_SPEC_DONE_DS (to) & SPECULATIVE; | 1764 record_ds = EXPR_SPEC_DONE_DS (to) & SPECULATIVE; |
1772 record_ds &= ~(old_to_ds & SPECULATIVE); | 1765 record_ds &= ~(old_to_ds & SPECULATIVE); |
1773 record_ds &= ~(old_from_ds & SPECULATIVE); | 1766 record_ds &= ~(old_from_ds & SPECULATIVE); |
1774 | 1767 |
1775 insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (to), | 1768 insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (to), |
1776 INSN_UID (split_point), TRANS_SPECULATION, | 1769 INSN_UID (split_point), TRANS_SPECULATION, |
1777 EXPR_VINSN (from), EXPR_VINSN (to), | 1770 EXPR_VINSN (from), EXPR_VINSN (to), |
1778 record_ds); | 1771 record_ds); |
1779 } | 1772 } |
1780 } | 1773 } |
1781 } | 1774 } |
1787 void | 1780 void |
1788 merge_expr_data (expr_t to, expr_t from, insn_t split_point) | 1781 merge_expr_data (expr_t to, expr_t from, insn_t split_point) |
1789 { | 1782 { |
1790 int i; | 1783 int i; |
1791 expr_history_def *phist; | 1784 expr_history_def *phist; |
1792 | 1785 |
1793 /* For now, we just set the spec of resulting expr to be minimum of the specs | 1786 /* For now, we just set the spec of resulting expr to be minimum of the specs |
1794 of merged exprs. */ | 1787 of merged exprs. */ |
1795 if (EXPR_SPEC (to) > EXPR_SPEC (from)) | 1788 if (EXPR_SPEC (to) > EXPR_SPEC (from)) |
1796 EXPR_SPEC (to) = EXPR_SPEC (from); | 1789 EXPR_SPEC (to) = EXPR_SPEC (from); |
1797 | 1790 |
1798 if (split_point) | 1791 if (split_point) |
1799 EXPR_USEFULNESS (to) += EXPR_USEFULNESS (from); | 1792 EXPR_USEFULNESS (to) += EXPR_USEFULNESS (from); |
1800 else | 1793 else |
1801 EXPR_USEFULNESS (to) = MAX (EXPR_USEFULNESS (to), | 1794 EXPR_USEFULNESS (to) = MAX (EXPR_USEFULNESS (to), |
1802 EXPR_USEFULNESS (from)); | 1795 EXPR_USEFULNESS (from)); |
1803 | 1796 |
1804 if (EXPR_PRIORITY (to) < EXPR_PRIORITY (from)) | 1797 if (EXPR_PRIORITY (to) < EXPR_PRIORITY (from)) |
1805 EXPR_PRIORITY (to) = EXPR_PRIORITY (from); | 1798 EXPR_PRIORITY (to) = EXPR_PRIORITY (from); |
1806 | 1799 |
1808 EXPR_SCHED_TIMES (to) = EXPR_SCHED_TIMES (from); | 1801 EXPR_SCHED_TIMES (to) = EXPR_SCHED_TIMES (from); |
1809 | 1802 |
1810 if (EXPR_ORIG_BB_INDEX (to) != EXPR_ORIG_BB_INDEX (from)) | 1803 if (EXPR_ORIG_BB_INDEX (to) != EXPR_ORIG_BB_INDEX (from)) |
1811 EXPR_ORIG_BB_INDEX (to) = 0; | 1804 EXPR_ORIG_BB_INDEX (to) = 0; |
1812 | 1805 |
1813 EXPR_ORIG_SCHED_CYCLE (to) = MIN (EXPR_ORIG_SCHED_CYCLE (to), | 1806 EXPR_ORIG_SCHED_CYCLE (to) = MIN (EXPR_ORIG_SCHED_CYCLE (to), |
1814 EXPR_ORIG_SCHED_CYCLE (from)); | 1807 EXPR_ORIG_SCHED_CYCLE (from)); |
1815 | 1808 |
1816 /* We keep this vector sorted. */ | 1809 /* We keep this vector sorted. */ |
1817 for (i = 0; | 1810 for (i = 0; |
1818 VEC_iterate (expr_history_def, EXPR_HISTORY_OF_CHANGES (from), | 1811 VEC_iterate (expr_history_def, EXPR_HISTORY_OF_CHANGES (from), |
1819 i, phist); | 1812 i, phist); |
1820 i++) | 1813 i++) |
1821 insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (to), | 1814 insert_in_history_vect (&EXPR_HISTORY_OF_CHANGES (to), |
1822 phist->uid, phist->type, | 1815 phist->uid, phist->type, |
1823 phist->old_expr_vinsn, phist->new_expr_vinsn, | 1816 phist->old_expr_vinsn, phist->new_expr_vinsn, |
1824 phist->spec_ds); | 1817 phist->spec_ds); |
1825 | 1818 |
1826 EXPR_WAS_SUBSTITUTED (to) |= EXPR_WAS_SUBSTITUTED (from); | 1819 EXPR_WAS_SUBSTITUTED (to) |= EXPR_WAS_SUBSTITUTED (from); |
1827 EXPR_WAS_RENAMED (to) |= EXPR_WAS_RENAMED (from); | 1820 EXPR_WAS_RENAMED (to) |= EXPR_WAS_RENAMED (from); |
1828 EXPR_CANT_MOVE (to) |= EXPR_CANT_MOVE (from); | 1821 EXPR_CANT_MOVE (to) |= EXPR_CANT_MOVE (from); |
1830 update_target_availability (to, from, split_point); | 1823 update_target_availability (to, from, split_point); |
1831 update_speculative_bits (to, from, split_point); | 1824 update_speculative_bits (to, from, split_point); |
1832 } | 1825 } |
1833 | 1826 |
1834 /* Merge bits of FROM expr to TO expr. Vinsns in the exprs should be equal | 1827 /* 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 | 1828 in terms of vinsn_equal_p. SPLIT_POINT is non-null when expressions |
1836 are merged from different successors at a split point. */ | 1829 are merged from different successors at a split point. */ |
1837 void | 1830 void |
1838 merge_expr (expr_t to, expr_t from, insn_t split_point) | 1831 merge_expr (expr_t to, expr_t from, insn_t split_point) |
1839 { | 1832 { |
1840 vinsn_t to_vi = EXPR_VINSN (to); | 1833 vinsn_t to_vi = EXPR_VINSN (to); |
1855 | 1848 |
1856 /* Clear the information of this EXPR. */ | 1849 /* Clear the information of this EXPR. */ |
1857 void | 1850 void |
1858 clear_expr (expr_t expr) | 1851 clear_expr (expr_t expr) |
1859 { | 1852 { |
1860 | 1853 |
1861 vinsn_detach (EXPR_VINSN (expr)); | 1854 vinsn_detach (EXPR_VINSN (expr)); |
1862 EXPR_VINSN (expr) = NULL; | 1855 EXPR_VINSN (expr) = NULL; |
1863 | 1856 |
1864 free_history_vect (&EXPR_HISTORY_OF_CHANGES (expr)); | 1857 free_history_vect (&EXPR_HISTORY_OF_CHANGES (expr)); |
1865 } | 1858 } |
1871 if (EXPR_SEPARABLE_P (expr)) | 1864 if (EXPR_SEPARABLE_P (expr)) |
1872 { | 1865 { |
1873 if (REG_P (EXPR_LHS (expr)) | 1866 if (REG_P (EXPR_LHS (expr)) |
1874 && bitmap_bit_p (lv_set, REGNO (EXPR_LHS (expr)))) | 1867 && bitmap_bit_p (lv_set, REGNO (EXPR_LHS (expr)))) |
1875 { | 1868 { |
1876 /* If it's an insn like r1 = use (r1, ...), and it exists in | 1869 /* 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 | 1870 different forms in each of the av_sets being merged, we can't say |
1878 whether original destination register is available or not. | 1871 whether original destination register is available or not. |
1879 However, this still works if destination register is not used | 1872 However, this still works if destination register is not used |
1880 in the original expression: if the branch at which LV_SET we're | 1873 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 | 1874 looking here is not actually 'other branch' in sense that same |
1882 expression is available through it (but it can't be determined | 1875 expression is available through it (but it can't be determined |
1883 at computation stage because of transformations on one of the | 1876 at computation stage because of transformations on one of the |
1884 branches), it still won't affect the availability. | 1877 branches), it still won't affect the availability. |
1885 Liveness of a register somewhere on a code motion path means | 1878 Liveness of a register somewhere on a code motion path means |
1886 it's either read somewhere on a codemotion path, live on | 1879 it's either read somewhere on a codemotion path, live on |
1887 'other' branch, live at the point immediately following | 1880 'other' branch, live at the point immediately following |
1888 the original operation, or is read by the original operation. | 1881 the original operation, or is read by the original operation. |
1889 The latter case is filtered out in the condition below. | 1882 The latter case is filtered out in the condition below. |
1890 It still doesn't cover the case when register is defined and used | 1883 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 | 1884 somewhere within the code motion path, and in this case we could |
1892 miss a unifying code motion along both branches using a renamed | 1885 miss a unifying code motion along both branches using a renamed |
1893 register, but it won't affect a code correctness since upon | 1886 register, but it won't affect a code correctness since upon |
1894 an actual code motion a bookkeeping code would be generated. */ | 1887 an actual code motion a bookkeeping code would be generated. */ |
1895 if (bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)), | 1888 if (bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)), |
1896 REGNO (EXPR_LHS (expr)))) | 1889 REGNO (EXPR_LHS (expr)))) |
1897 EXPR_TARGET_AVAILABLE (expr) = -1; | 1890 EXPR_TARGET_AVAILABLE (expr) = -1; |
1898 else | 1891 else |
1899 EXPR_TARGET_AVAILABLE (expr) = false; | 1892 EXPR_TARGET_AVAILABLE (expr) = false; |
1900 } | 1893 } |
1901 } | 1894 } |
1902 else | 1895 else |
1903 { | 1896 { |
1904 unsigned regno; | 1897 unsigned regno; |
1905 reg_set_iterator rsi; | 1898 reg_set_iterator rsi; |
1906 | 1899 |
1907 EXECUTE_IF_SET_IN_REG_SET (VINSN_REG_SETS (EXPR_VINSN (expr)), | 1900 EXECUTE_IF_SET_IN_REG_SET (VINSN_REG_SETS (EXPR_VINSN (expr)), |
1908 0, regno, rsi) | 1901 0, regno, rsi) |
1909 if (bitmap_bit_p (lv_set, regno)) | 1902 if (bitmap_bit_p (lv_set, regno)) |
1910 { | 1903 { |
1911 EXPR_TARGET_AVAILABLE (expr) = false; | 1904 EXPR_TARGET_AVAILABLE (expr) = false; |
1912 break; | 1905 break; |
1920 break; | 1913 break; |
1921 } | 1914 } |
1922 } | 1915 } |
1923 } | 1916 } |
1924 | 1917 |
1925 /* Try to make EXPR speculative. Return 1 when EXPR's pattern | 1918 /* Try to make EXPR speculative. Return 1 when EXPR's pattern |
1926 or dependence status have changed, 2 when also the target register | 1919 or dependence status have changed, 2 when also the target register |
1927 became unavailable, 0 if nothing had to be changed. */ | 1920 became unavailable, 0 if nothing had to be changed. */ |
1928 int | 1921 int |
1929 speculate_expr (expr_t expr, ds_t ds) | 1922 speculate_expr (expr_t expr, ds_t ds) |
1930 { | 1923 { |
1945 switch (res) | 1938 switch (res) |
1946 { | 1939 { |
1947 case 0: | 1940 case 0: |
1948 EXPR_SPEC_DONE_DS (expr) = ds; | 1941 EXPR_SPEC_DONE_DS (expr) = ds; |
1949 return current_ds != ds ? 1 : 0; | 1942 return current_ds != ds ? 1 : 0; |
1950 | 1943 |
1951 case 1: | 1944 case 1: |
1952 { | 1945 { |
1953 rtx spec_insn_rtx = create_insn_rtx_from_pattern (spec_pat, NULL_RTX); | 1946 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); | 1947 vinsn_t spec_vinsn = create_vinsn_from_insn_rtx (spec_insn_rtx, false); |
1955 | 1948 |
1956 change_vinsn_in_expr (expr, spec_vinsn); | 1949 change_vinsn_in_expr (expr, spec_vinsn); |
1957 EXPR_SPEC_DONE_DS (expr) = ds; | 1950 EXPR_SPEC_DONE_DS (expr) = ds; |
1958 EXPR_NEEDS_SPEC_CHECK_P (expr) = true; | 1951 EXPR_NEEDS_SPEC_CHECK_P (expr) = true; |
1959 | 1952 |
1960 /* Do not allow clobbering the address register of speculative | 1953 /* Do not allow clobbering the address register of speculative |
1961 insns. */ | 1954 insns. */ |
1962 if (bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)), | 1955 if (bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)), |
1963 expr_dest_regno (expr))) | 1956 expr_dest_regno (expr))) |
1964 { | 1957 { |
1965 EXPR_TARGET_AVAILABLE (expr) = false; | 1958 EXPR_TARGET_AVAILABLE (expr) = false; |
1966 return 2; | 1959 return 2; |
1967 } | 1960 } |
1998 | 1991 |
1999 gcc_assert (dest != NULL_RTX); | 1992 gcc_assert (dest != NULL_RTX); |
2000 return REGNO (dest); | 1993 return REGNO (dest); |
2001 } | 1994 } |
2002 | 1995 |
2003 /* For a given LV_SET, mark all expressions in JOIN_SET, but not present in | 1996 /* For a given LV_SET, mark all expressions in JOIN_SET, but not present in |
2004 AV_SET having unavailable target register. */ | 1997 AV_SET having unavailable target register. */ |
2005 void | 1998 void |
2006 mark_unavailable_targets (av_set_t join_set, av_set_t av_set, regset lv_set) | 1999 mark_unavailable_targets (av_set_t join_set, av_set_t av_set, regset lv_set) |
2007 { | 2000 { |
2008 expr_t expr; | 2001 expr_t expr; |
2029 /* Add EXPR to SETP. */ | 2022 /* Add EXPR to SETP. */ |
2030 void | 2023 void |
2031 av_set_add (av_set_t *setp, expr_t expr) | 2024 av_set_add (av_set_t *setp, expr_t expr) |
2032 { | 2025 { |
2033 av_set_t elem; | 2026 av_set_t elem; |
2034 | 2027 |
2035 gcc_assert (!INSN_NOP_P (EXPR_INSN_RTX (expr))); | 2028 gcc_assert (!INSN_NOP_P (EXPR_INSN_RTX (expr))); |
2036 elem = av_set_add_element (setp); | 2029 elem = av_set_add_element (setp); |
2037 copy_expr (_AV_SET_EXPR (elem), expr); | 2030 copy_expr (_AV_SET_EXPR (elem), expr); |
2038 } | 2031 } |
2039 | 2032 |
2119 of the exprs would be controversial for different code. */ | 2112 of the exprs would be controversial for different code. */ |
2120 EXPR_TARGET_AVAILABLE (expr2) = -1; | 2113 EXPR_TARGET_AVAILABLE (expr2) = -1; |
2121 EXPR_USEFULNESS (expr2) = 0; | 2114 EXPR_USEFULNESS (expr2) = 0; |
2122 | 2115 |
2123 merge_expr (expr2, expr, NULL); | 2116 merge_expr (expr2, expr, NULL); |
2124 | 2117 |
2125 /* Fix usefulness as it should be now REG_BR_PROB_BASE. */ | 2118 /* Fix usefulness as it should be now REG_BR_PROB_BASE. */ |
2126 EXPR_USEFULNESS (expr2) = REG_BR_PROB_BASE; | 2119 EXPR_USEFULNESS (expr2) = REG_BR_PROB_BASE; |
2127 | 2120 |
2128 av_set_iter_remove (ip); | 2121 av_set_iter_remove (ip); |
2129 return expr2; | 2122 return expr2; |
2130 } | 2123 } |
2131 | 2124 |
2132 return expr; | 2125 return expr; |
2185 } | 2178 } |
2186 | 2179 |
2187 join_distinct_sets (i.lp, fromp); | 2180 join_distinct_sets (i.lp, fromp); |
2188 } | 2181 } |
2189 | 2182 |
2190 /* Same as above, but also update availability of target register in | 2183 /* Same as above, but also update availability of target register in |
2191 TOP judging by TO_LV_SET and FROM_LV_SET. */ | 2184 TOP judging by TO_LV_SET and FROM_LV_SET. */ |
2192 void | 2185 void |
2193 av_set_union_and_live (av_set_t *top, av_set_t *fromp, regset to_lv_set, | 2186 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) | 2187 regset from_lv_set, insn_t insn) |
2195 { | 2188 { |
2202 { | 2195 { |
2203 expr_t expr2 = av_set_lookup_and_remove (fromp, EXPR_VINSN (expr1)); | 2196 expr_t expr2 = av_set_lookup_and_remove (fromp, EXPR_VINSN (expr1)); |
2204 | 2197 |
2205 if (expr2) | 2198 if (expr2) |
2206 { | 2199 { |
2207 /* It may be that the expressions have different destination | 2200 /* It may be that the expressions have different destination |
2208 registers, in which case we need to check liveness here. */ | 2201 registers, in which case we need to check liveness here. */ |
2209 if (EXPR_SEPARABLE_P (expr1)) | 2202 if (EXPR_SEPARABLE_P (expr1)) |
2210 { | 2203 { |
2211 int regno1 = (REG_P (EXPR_LHS (expr1)) | 2204 int regno1 = (REG_P (EXPR_LHS (expr1)) |
2212 ? (int) expr_dest_regno (expr1) : -1); | 2205 ? (int) expr_dest_regno (expr1) : -1); |
2213 int regno2 = (REG_P (EXPR_LHS (expr2)) | 2206 int regno2 = (REG_P (EXPR_LHS (expr2)) |
2214 ? (int) expr_dest_regno (expr2) : -1); | 2207 ? (int) expr_dest_regno (expr2) : -1); |
2215 | 2208 |
2216 /* ??? We don't have a way to check restrictions for | 2209 /* ??? We don't have a way to check restrictions for |
2217 *other* register on the current path, we did it only | 2210 *other* register on the current path, we did it only |
2218 for the current target register. Give up. */ | 2211 for the current target register. Give up. */ |
2219 if (regno1 != regno2) | 2212 if (regno1 != regno2) |
2220 EXPR_TARGET_AVAILABLE (expr2) = -1; | 2213 EXPR_TARGET_AVAILABLE (expr2) = -1; |
2221 } | 2214 } |
2225 merge_expr (expr2, expr1, insn); | 2218 merge_expr (expr2, expr1, insn); |
2226 av_set_add_nocopy (&in_both_set, expr2); | 2219 av_set_add_nocopy (&in_both_set, expr2); |
2227 av_set_iter_remove (&i); | 2220 av_set_iter_remove (&i); |
2228 } | 2221 } |
2229 else | 2222 else |
2230 /* EXPR1 is present in TOP, but not in FROMP. Check it on | 2223 /* EXPR1 is present in TOP, but not in FROMP. Check it on |
2231 FROM_LV_SET. */ | 2224 FROM_LV_SET. */ |
2232 set_unavailable_target_for_expr (expr1, from_lv_set); | 2225 set_unavailable_target_for_expr (expr1, from_lv_set); |
2233 } | 2226 } |
2234 to_tailp = i.lp; | 2227 to_tailp = i.lp; |
2235 | 2228 |
2261 { | 2254 { |
2262 expr_t expr; | 2255 expr_t expr; |
2263 av_set_iterator i; | 2256 av_set_iterator i; |
2264 bool has_one_nonspec = false; | 2257 bool has_one_nonspec = false; |
2265 | 2258 |
2266 /* Keep all speculative exprs, and leave one non-speculative | 2259 /* Keep all speculative exprs, and leave one non-speculative |
2267 (the first one). */ | 2260 (the first one). */ |
2268 FOR_EACH_EXPR_1 (expr, i, setp) | 2261 FOR_EACH_EXPR_1 (expr, i, setp) |
2269 { | 2262 { |
2270 if (!EXPR_SPEC_DONE_DS (expr)) | 2263 if (!EXPR_SPEC_DONE_DS (expr)) |
2271 { | 2264 { |
2302 FOR_EACH_EXPR_1 (expr, i, avp) | 2295 FOR_EACH_EXPR_1 (expr, i, avp) |
2303 if (vinsn_cond_branch_p (EXPR_VINSN (expr))) | 2296 if (vinsn_cond_branch_p (EXPR_VINSN (expr))) |
2304 av_set_iter_remove (&i); | 2297 av_set_iter_remove (&i); |
2305 } | 2298 } |
2306 | 2299 |
2307 /* Multiplies usefulness attribute of each member of av-set *AVP by | 2300 /* Multiplies usefulness attribute of each member of av-set *AVP by |
2308 value PROB / ALL_PROB. */ | 2301 value PROB / ALL_PROB. */ |
2309 void | 2302 void |
2310 av_set_split_usefulness (av_set_t av, int prob, int all_prob) | 2303 av_set_split_usefulness (av_set_t av, int prob, int all_prob) |
2311 { | 2304 { |
2312 av_set_iterator i; | 2305 av_set_iterator i; |
2313 expr_t expr; | 2306 expr_t expr; |
2314 | 2307 |
2315 FOR_EACH_EXPR (expr, i, av) | 2308 FOR_EACH_EXPR (expr, i, av) |
2316 EXPR_USEFULNESS (expr) = (all_prob | 2309 EXPR_USEFULNESS (expr) = (all_prob |
2317 ? (EXPR_USEFULNESS (expr) * prob) / all_prob | 2310 ? (EXPR_USEFULNESS (expr) * prob) / all_prob |
2318 : 0); | 2311 : 0); |
2319 } | 2312 } |
2320 | 2313 |
2321 /* Leave in AVP only those expressions, which are present in AV, | 2314 /* Leave in AVP only those expressions, which are present in AV, |
2351 /* True when insn should be treated as of type USE, i.e. never renamed. */ | 2344 /* True when insn should be treated as of type USE, i.e. never renamed. */ |
2352 bool force_use_p; | 2345 bool force_use_p; |
2353 } deps_init_id_data; | 2346 } deps_init_id_data; |
2354 | 2347 |
2355 | 2348 |
2356 /* Setup ID for INSN. FORCE_UNIQUE_P is true when INSN should not be | 2349 /* Setup ID for INSN. FORCE_UNIQUE_P is true when INSN should not be |
2357 clonable. */ | 2350 clonable. */ |
2358 static void | 2351 static void |
2359 setup_id_for_insn (idata_t id, insn_t insn, bool force_unique_p) | 2352 setup_id_for_insn (idata_t id, insn_t insn, bool force_unique_p) |
2360 { | 2353 { |
2361 int type; | 2354 int type; |
2362 | 2355 |
2363 /* Determine whether INSN could be cloned and return appropriate vinsn type. | 2356 /* 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. | 2357 That clonable insns which can be separated into lhs and rhs have type SET. |
2365 Other clonable insns have type USE. */ | 2358 Other clonable insns have type USE. */ |
2366 type = GET_CODE (insn); | 2359 type = GET_CODE (insn); |
2367 | 2360 |
2368 /* Only regular insns could be cloned. */ | 2361 /* Only regular insns could be cloned. */ |
2369 if (type == INSN && !force_unique_p) | 2362 if (type == INSN && !force_unique_p) |
2370 type = SET; | 2363 type = SET; |
2371 else if (type == JUMP_INSN && simplejump_p (insn)) | 2364 else if (type == JUMP_INSN && simplejump_p (insn)) |
2372 type = PC; | 2365 type = PC; |
2373 | 2366 else if (type == DEBUG_INSN) |
2367 type = !force_unique_p ? USE : INSN; | |
2368 | |
2374 IDATA_TYPE (id) = type; | 2369 IDATA_TYPE (id) = type; |
2375 IDATA_REG_SETS (id) = get_clear_regset_from_pool (); | 2370 IDATA_REG_SETS (id) = get_clear_regset_from_pool (); |
2376 IDATA_REG_USES (id) = get_clear_regset_from_pool (); | 2371 IDATA_REG_USES (id) = get_clear_regset_from_pool (); |
2377 IDATA_REG_CLOBBERS (id) = get_clear_regset_from_pool (); | 2372 IDATA_REG_CLOBBERS (id) = get_clear_regset_from_pool (); |
2378 } | 2373 } |
2420 | 2415 |
2421 if (IDATA_TYPE (deps_init_id_data.id) != PC) | 2416 if (IDATA_TYPE (deps_init_id_data.id) != PC) |
2422 SET_REGNO_REG_SET (IDATA_REG_SETS (deps_init_id_data.id), regno); | 2417 SET_REGNO_REG_SET (IDATA_REG_SETS (deps_init_id_data.id), regno); |
2423 | 2418 |
2424 #ifdef STACK_REGS | 2419 #ifdef STACK_REGS |
2425 /* Make instructions that set stack registers to be ineligible for | 2420 /* Make instructions that set stack registers to be ineligible for |
2426 renaming to avoid issues with find_used_regs. */ | 2421 renaming to avoid issues with find_used_regs. */ |
2427 if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG)) | 2422 if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG)) |
2428 deps_init_id_data.force_use_p = true; | 2423 deps_init_id_data.force_use_p = true; |
2429 #endif | 2424 #endif |
2430 } | 2425 } |
2487 rtx rhs = IDATA_RHS (deps_init_id_data.id); | 2482 rtx rhs = IDATA_RHS (deps_init_id_data.id); |
2488 | 2483 |
2489 if (lhs == NULL || rhs == NULL || !lhs_and_rhs_separable_p (lhs, rhs) | 2484 if (lhs == NULL || rhs == NULL || !lhs_and_rhs_separable_p (lhs, rhs) |
2490 || deps_init_id_data.force_use_p) | 2485 || deps_init_id_data.force_use_p) |
2491 { | 2486 { |
2492 /* This should be a USE, as we don't want to schedule its RHS | 2487 /* This should be a USE, as we don't want to schedule its RHS |
2493 separately. However, we still want to have them recorded | 2488 separately. However, we still want to have them recorded |
2494 for the purposes of substitution. That's why we don't | 2489 for the purposes of substitution. That's why we don't |
2495 simply call downgrade_to_use () here. */ | 2490 simply call downgrade_to_use () here. */ |
2496 gcc_assert (IDATA_TYPE (deps_init_id_data.id) == SET); | 2491 gcc_assert (IDATA_TYPE (deps_init_id_data.id) == SET); |
2497 gcc_assert (!lhs == !rhs); | 2492 gcc_assert (!lhs == !rhs); |
2498 | 2493 |
2499 IDATA_TYPE (deps_init_id_data.id) = USE; | 2494 IDATA_TYPE (deps_init_id_data.id) = USE; |
2532 we don't actually need information about lhs and rhs. */ | 2527 we don't actually need information about lhs and rhs. */ |
2533 static void | 2528 static void |
2534 setup_id_lhs_rhs (idata_t id, insn_t insn, bool force_unique_p) | 2529 setup_id_lhs_rhs (idata_t id, insn_t insn, bool force_unique_p) |
2535 { | 2530 { |
2536 rtx pat = PATTERN (insn); | 2531 rtx pat = PATTERN (insn); |
2537 | 2532 |
2538 if (GET_CODE (insn) == INSN | 2533 if (NONJUMP_INSN_P (insn) |
2539 && GET_CODE (pat) == SET | 2534 && GET_CODE (pat) == SET |
2540 && !force_unique_p) | 2535 && !force_unique_p) |
2541 { | 2536 { |
2542 IDATA_RHS (id) = SET_SRC (pat); | 2537 IDATA_RHS (id) = SET_SRC (pat); |
2543 IDATA_LHS (id) = SET_DEST (pat); | 2538 IDATA_LHS (id) = SET_DEST (pat); |
2544 } | 2539 } |
2553 bool must_be_use = false; | 2548 bool must_be_use = false; |
2554 unsigned uid = INSN_UID (insn); | 2549 unsigned uid = INSN_UID (insn); |
2555 df_ref *rec; | 2550 df_ref *rec; |
2556 rtx lhs = IDATA_LHS (id); | 2551 rtx lhs = IDATA_LHS (id); |
2557 rtx rhs = IDATA_RHS (id); | 2552 rtx rhs = IDATA_RHS (id); |
2558 | 2553 |
2559 /* We downgrade only SETs. */ | 2554 /* We downgrade only SETs. */ |
2560 if (IDATA_TYPE (id) != SET) | 2555 if (IDATA_TYPE (id) != SET) |
2561 return; | 2556 return; |
2562 | 2557 |
2563 if (!lhs || !lhs_and_rhs_separable_p (lhs, rhs)) | 2558 if (!lhs || !lhs_and_rhs_separable_p (lhs, rhs)) |
2564 { | 2559 { |
2565 IDATA_TYPE (id) = USE; | 2560 IDATA_TYPE (id) = USE; |
2566 return; | 2561 return; |
2567 } | 2562 } |
2568 | 2563 |
2569 for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++) | 2564 for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++) |
2570 { | 2565 { |
2571 df_ref def = *rec; | 2566 df_ref def = *rec; |
2572 | 2567 |
2573 if (DF_REF_INSN (def) | 2568 if (DF_REF_INSN (def) |
2574 && DF_REF_FLAGS_IS_SET (def, DF_REF_PRE_POST_MODIFY) | 2569 && DF_REF_FLAGS_IS_SET (def, DF_REF_PRE_POST_MODIFY) |
2575 && loc_mentioned_in_p (DF_REF_LOC (def), IDATA_RHS (id))) | 2570 && loc_mentioned_in_p (DF_REF_LOC (def), IDATA_RHS (id))) |
2576 { | 2571 { |
2577 must_be_use = true; | 2572 must_be_use = true; |
2578 break; | 2573 break; |
2579 } | 2574 } |
2580 | 2575 |
2581 #ifdef STACK_REGS | 2576 #ifdef STACK_REGS |
2582 /* Make instructions that set stack registers to be ineligible for | 2577 /* Make instructions that set stack registers to be ineligible for |
2583 renaming to avoid issues with find_used_regs. */ | 2578 renaming to avoid issues with find_used_regs. */ |
2584 if (IN_RANGE (DF_REF_REGNO (def), FIRST_STACK_REG, LAST_STACK_REG)) | 2579 if (IN_RANGE (DF_REF_REGNO (def), FIRST_STACK_REG, LAST_STACK_REG)) |
2585 { | 2580 { |
2586 must_be_use = true; | 2581 must_be_use = true; |
2587 break; | 2582 break; |
2588 } | 2583 } |
2589 #endif | 2584 #endif |
2590 } | 2585 } |
2591 | 2586 |
2592 if (must_be_use) | 2587 if (must_be_use) |
2593 IDATA_TYPE (id) = USE; | 2588 IDATA_TYPE (id) = USE; |
2594 } | 2589 } |
2595 | 2590 |
2596 /* Setup register sets describing INSN in ID. */ | 2591 /* Setup register sets describing INSN in ID. */ |
2598 setup_id_reg_sets (idata_t id, insn_t insn) | 2593 setup_id_reg_sets (idata_t id, insn_t insn) |
2599 { | 2594 { |
2600 unsigned uid = INSN_UID (insn); | 2595 unsigned uid = INSN_UID (insn); |
2601 df_ref *rec; | 2596 df_ref *rec; |
2602 regset tmp = get_clear_regset_from_pool (); | 2597 regset tmp = get_clear_regset_from_pool (); |
2603 | 2598 |
2604 for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++) | 2599 for (rec = DF_INSN_UID_DEFS (uid); *rec; rec++) |
2605 { | 2600 { |
2606 df_ref def = *rec; | 2601 df_ref def = *rec; |
2607 unsigned int regno = DF_REF_REGNO (def); | 2602 unsigned int regno = DF_REF_REGNO (def); |
2608 | 2603 |
2609 /* Post modifies are treated like clobbers by sched-deps.c. */ | 2604 /* Post modifies are treated like clobbers by sched-deps.c. */ |
2610 if (DF_REF_FLAGS_IS_SET (def, (DF_REF_MUST_CLOBBER | 2605 if (DF_REF_FLAGS_IS_SET (def, (DF_REF_MUST_CLOBBER |
2611 | DF_REF_PRE_POST_MODIFY))) | 2606 | DF_REF_PRE_POST_MODIFY))) |
2612 SET_REGNO_REG_SET (IDATA_REG_CLOBBERS (id), regno); | 2607 SET_REGNO_REG_SET (IDATA_REG_CLOBBERS (id), regno); |
2613 else if (! DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)) | 2608 else if (! DF_REF_FLAGS_IS_SET (def, DF_REF_MAY_CLOBBER)) |
2614 { | 2609 { |
2615 SET_REGNO_REG_SET (IDATA_REG_SETS (id), regno); | 2610 SET_REGNO_REG_SET (IDATA_REG_SETS (id), regno); |
2616 | 2611 |
2617 #ifdef STACK_REGS | 2612 #ifdef STACK_REGS |
2618 /* For stack registers, treat writes to them as writes | 2613 /* For stack registers, treat writes to them as writes |
2619 to the first one to be consistent with sched-deps.c. */ | 2614 to the first one to be consistent with sched-deps.c. */ |
2620 if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG)) | 2615 if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG)) |
2621 SET_REGNO_REG_SET (IDATA_REG_SETS (id), FIRST_STACK_REG); | 2616 SET_REGNO_REG_SET (IDATA_REG_SETS (id), FIRST_STACK_REG); |
2622 #endif | 2617 #endif |
2623 } | 2618 } |
2624 /* Mark special refs that generate read/write def pair. */ | 2619 /* Mark special refs that generate read/write def pair. */ |
2625 if (DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL) | 2620 if (DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL) |
2626 || regno == STACK_POINTER_REGNUM) | 2621 || regno == STACK_POINTER_REGNUM) |
2627 bitmap_set_bit (tmp, regno); | 2622 bitmap_set_bit (tmp, regno); |
2628 } | 2623 } |
2629 | 2624 |
2630 for (rec = DF_INSN_UID_USES (uid); *rec; rec++) | 2625 for (rec = DF_INSN_UID_USES (uid); *rec; rec++) |
2631 { | 2626 { |
2632 df_ref use = *rec; | 2627 df_ref use = *rec; |
2633 unsigned int regno = DF_REF_REGNO (use); | 2628 unsigned int regno = DF_REF_REGNO (use); |
2634 | 2629 |
2639 else if (! DF_REF_FLAGS_IS_SET (use, DF_REF_CALL_STACK_USAGE)) | 2634 else if (! DF_REF_FLAGS_IS_SET (use, DF_REF_CALL_STACK_USAGE)) |
2640 { | 2635 { |
2641 SET_REGNO_REG_SET (IDATA_REG_USES (id), regno); | 2636 SET_REGNO_REG_SET (IDATA_REG_USES (id), regno); |
2642 | 2637 |
2643 #ifdef STACK_REGS | 2638 #ifdef STACK_REGS |
2644 /* For stack registers, treat reads from them as reads from | 2639 /* For stack registers, treat reads from them as reads from |
2645 the first one to be consistent with sched-deps.c. */ | 2640 the first one to be consistent with sched-deps.c. */ |
2646 if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG)) | 2641 if (IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG)) |
2647 SET_REGNO_REG_SET (IDATA_REG_USES (id), FIRST_STACK_REG); | 2642 SET_REGNO_REG_SET (IDATA_REG_USES (id), FIRST_STACK_REG); |
2648 #endif | 2643 #endif |
2649 } | 2644 } |
2677 deps_init_id_data.where = DEPS_IN_NOWHERE; | 2672 deps_init_id_data.where = DEPS_IN_NOWHERE; |
2678 deps_init_id_data.id = id; | 2673 deps_init_id_data.id = id; |
2679 deps_init_id_data.force_unique_p = force_unique_p; | 2674 deps_init_id_data.force_unique_p = force_unique_p; |
2680 deps_init_id_data.force_use_p = false; | 2675 deps_init_id_data.force_use_p = false; |
2681 | 2676 |
2682 init_deps (dc); | 2677 init_deps (dc, false); |
2683 | 2678 |
2684 memcpy (&deps_init_id_sched_deps_info, | 2679 memcpy (&deps_init_id_sched_deps_info, |
2685 &const_deps_init_id_sched_deps_info, | 2680 &const_deps_init_id_sched_deps_info, |
2686 sizeof (deps_init_id_sched_deps_info)); | 2681 sizeof (deps_init_id_sched_deps_info)); |
2687 | 2682 |
2737 vinsn_detach (pti->vinsn_old); | 2732 vinsn_detach (pti->vinsn_old); |
2738 vinsn_detach (pti->vinsn_new); | 2733 vinsn_detach (pti->vinsn_new); |
2739 free (pti); | 2734 free (pti); |
2740 } | 2735 } |
2741 | 2736 |
2742 /* Init the s_i_d data for INSN which should be inited just once, when | 2737 /* Init the s_i_d data for INSN which should be inited just once, when |
2743 we first see the insn. */ | 2738 we first see the insn. */ |
2744 static void | 2739 static void |
2745 init_first_time_insn_data (insn_t insn) | 2740 init_first_time_insn_data (insn_t insn) |
2746 { | 2741 { |
2747 /* This should not be set if this is the first time we init data for | 2742 /* This should not be set if this is the first time we init data for |
2748 insn. */ | 2743 insn. */ |
2749 gcc_assert (first_time_insn_init (insn)); | 2744 gcc_assert (first_time_insn_init (insn)); |
2750 | 2745 |
2751 /* These are needed for nops too. */ | 2746 /* These are needed for nops too. */ |
2752 INSN_LIVE (insn) = get_regset_from_pool (); | 2747 INSN_LIVE (insn) = get_regset_from_pool (); |
2753 INSN_LIVE_VALID_P (insn) = false; | 2748 INSN_LIVE_VALID_P (insn) = false; |
2754 | 2749 |
2755 if (!INSN_NOP_P (insn)) | 2750 if (!INSN_NOP_P (insn)) |
2756 { | 2751 { |
2757 INSN_ANALYZED_DEPS (insn) = BITMAP_ALLOC (NULL); | 2752 INSN_ANALYZED_DEPS (insn) = BITMAP_ALLOC (NULL); |
2758 INSN_FOUND_DEPS (insn) = BITMAP_ALLOC (NULL); | 2753 INSN_FOUND_DEPS (insn) = BITMAP_ALLOC (NULL); |
2759 INSN_TRANSFORMED_INSNS (insn) | 2754 INSN_TRANSFORMED_INSNS (insn) |
2760 = htab_create (16, hash_transformed_insns, | 2755 = htab_create (16, hash_transformed_insns, |
2761 eq_transformed_insns, free_transformed_insns); | 2756 eq_transformed_insns, free_transformed_insns); |
2762 init_deps (&INSN_DEPS_CONTEXT (insn)); | 2757 init_deps (&INSN_DEPS_CONTEXT (insn), true); |
2763 } | 2758 } |
2764 } | 2759 } |
2765 | 2760 |
2766 /* Free the same data as above for INSN. */ | 2761 /* Free almost all above data for INSN that is scheduled already. |
2767 static void | 2762 Used for extra-large basic blocks. */ |
2768 free_first_time_insn_data (insn_t insn) | 2763 void |
2764 free_data_for_scheduled_insn (insn_t insn) | |
2769 { | 2765 { |
2770 gcc_assert (! first_time_insn_init (insn)); | 2766 gcc_assert (! first_time_insn_init (insn)); |
2767 | |
2768 if (! INSN_ANALYZED_DEPS (insn)) | |
2769 return; | |
2771 | 2770 |
2772 BITMAP_FREE (INSN_ANALYZED_DEPS (insn)); | 2771 BITMAP_FREE (INSN_ANALYZED_DEPS (insn)); |
2773 BITMAP_FREE (INSN_FOUND_DEPS (insn)); | 2772 BITMAP_FREE (INSN_FOUND_DEPS (insn)); |
2774 htab_delete (INSN_TRANSFORMED_INSNS (insn)); | 2773 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 | 2774 |
2779 /* This is allocated only for bookkeeping insns. */ | 2775 /* This is allocated only for bookkeeping insns. */ |
2780 if (INSN_ORIGINATORS (insn)) | 2776 if (INSN_ORIGINATORS (insn)) |
2781 BITMAP_FREE (INSN_ORIGINATORS (insn)); | 2777 BITMAP_FREE (INSN_ORIGINATORS (insn)); |
2782 free_deps (&INSN_DEPS_CONTEXT (insn)); | 2778 free_deps (&INSN_DEPS_CONTEXT (insn)); |
2779 | |
2780 INSN_ANALYZED_DEPS (insn) = NULL; | |
2781 | |
2782 /* Clear the readonly flag so we would ICE when trying to recalculate | |
2783 the deps context (as we believe that it should not happen). */ | |
2784 (&INSN_DEPS_CONTEXT (insn))->readonly = 0; | |
2785 } | |
2786 | |
2787 /* Free the same data as above for INSN. */ | |
2788 static void | |
2789 free_first_time_insn_data (insn_t insn) | |
2790 { | |
2791 gcc_assert (! first_time_insn_init (insn)); | |
2792 | |
2793 free_data_for_scheduled_insn (insn); | |
2794 return_regset_to_pool (INSN_LIVE (insn)); | |
2795 INSN_LIVE (insn) = NULL; | |
2796 INSN_LIVE_VALID_P (insn) = false; | |
2783 } | 2797 } |
2784 | 2798 |
2785 /* Initialize region-scope data structures for basic blocks. */ | 2799 /* Initialize region-scope data structures for basic blocks. */ |
2786 static void | 2800 static void |
2787 init_global_and_expr_for_bb (basic_block bb) | 2801 init_global_and_expr_for_bb (basic_block bb) |
2840 | 2854 |
2841 /* Certain instructions cannot be cloned. */ | 2855 /* Certain instructions cannot be cloned. */ |
2842 if (CANT_MOVE (insn) | 2856 if (CANT_MOVE (insn) |
2843 || INSN_ASM_P (insn) | 2857 || INSN_ASM_P (insn) |
2844 || SCHED_GROUP_P (insn) | 2858 || SCHED_GROUP_P (insn) |
2845 || prologue_epilogue_contains (insn) | 2859 || prologue_epilogue_contains (insn) |
2846 /* Exception handling insns are always unique. */ | 2860 /* Exception handling insns are always unique. */ |
2847 || (flag_non_call_exceptions && can_throw_internal (insn)) | 2861 || (flag_non_call_exceptions && can_throw_internal (insn)) |
2848 /* TRAP_IF though have an INSN code is control_flow_insn_p (). */ | 2862 /* TRAP_IF though have an INSN code is control_flow_insn_p (). */ |
2849 || control_flow_insn_p (insn)) | 2863 || control_flow_insn_p (insn)) |
2850 force_unique_p = true; | 2864 force_unique_p = true; |
2860 spec_done_ds = 0; | 2874 spec_done_ds = 0; |
2861 | 2875 |
2862 /* Initialize INSN's expr. */ | 2876 /* Initialize INSN's expr. */ |
2863 init_expr (INSN_EXPR (insn), vinsn_create (insn, force_unique_p), 0, | 2877 init_expr (INSN_EXPR (insn), vinsn_create (insn, force_unique_p), 0, |
2864 REG_BR_PROB_BASE, INSN_PRIORITY (insn), 0, BLOCK_NUM (insn), | 2878 REG_BR_PROB_BASE, INSN_PRIORITY (insn), 0, BLOCK_NUM (insn), |
2865 spec_done_ds, 0, 0, NULL, true, false, false, false, | 2879 spec_done_ds, 0, 0, NULL, true, false, false, false, |
2866 CANT_MOVE (insn)); | 2880 CANT_MOVE (insn)); |
2867 } | 2881 } |
2868 | 2882 |
2869 init_first_time_insn_data (insn); | 2883 init_first_time_insn_data (insn); |
2870 } | 2884 } |
2879 NULL, /* extend_bb */ | 2893 NULL, /* extend_bb */ |
2880 init_global_and_expr_for_bb, /* init_bb */ | 2894 init_global_and_expr_for_bb, /* init_bb */ |
2881 extend_insn_data, /* extend_insn */ | 2895 extend_insn_data, /* extend_insn */ |
2882 init_global_and_expr_for_insn /* init_insn */ | 2896 init_global_and_expr_for_insn /* init_insn */ |
2883 }; | 2897 }; |
2884 | 2898 |
2885 sched_scan (&ssi, bbs, NULL, NULL, NULL); | 2899 sched_scan (&ssi, bbs, NULL, NULL, NULL); |
2886 } | 2900 } |
2887 | 2901 |
2888 /* Finalize region-scope data structures for basic blocks. */ | 2902 /* Finalize region-scope data structures for basic blocks. */ |
2889 static void | 2903 static void |
2905 if (INSN_LUID (insn) > 0) | 2919 if (INSN_LUID (insn) > 0) |
2906 { | 2920 { |
2907 free_first_time_insn_data (insn); | 2921 free_first_time_insn_data (insn); |
2908 INSN_WS_LEVEL (insn) = 0; | 2922 INSN_WS_LEVEL (insn) = 0; |
2909 CANT_MOVE (insn) = 0; | 2923 CANT_MOVE (insn) = 0; |
2910 | 2924 |
2911 /* We can no longer assert this, as vinsns of this insn could be | 2925 /* 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 | 2926 easily live in other insn's caches. This should be changed to |
2913 a counter-like approach among all vinsns. */ | 2927 a counter-like approach among all vinsns. */ |
2914 gcc_assert (true || VINSN_COUNT (INSN_VINSN (insn)) == 1); | 2928 gcc_assert (true || VINSN_COUNT (INSN_VINSN (insn)) == 1); |
2915 clear_expr (INSN_EXPR (insn)); | 2929 clear_expr (INSN_EXPR (insn)); |
2916 } | 2930 } |
2917 } | 2931 } |
2947 | 2961 |
2948 finish_insns (); | 2962 finish_insns (); |
2949 } | 2963 } |
2950 | 2964 |
2951 | 2965 |
2952 /* In the below hooks, we merely calculate whether or not a dependence | 2966 /* 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 | 2967 exists, and in what part of insn. However, we will need more data |
2954 when we'll start caching dependence requests. */ | 2968 when we'll start caching dependence requests. */ |
2955 | 2969 |
2956 /* Container to hold information for dependency analysis. */ | 2970 /* Container to hold information for dependency analysis. */ |
2957 static struct | 2971 static struct |
2958 { | 2972 { |
3061 { | 3075 { |
3062 ds_t *dsp = &has_dependence_data.has_dep_p[has_dependence_data.where]; | 3076 ds_t *dsp = &has_dependence_data.has_dep_p[has_dependence_data.where]; |
3063 | 3077 |
3064 if (reg_last->sets) | 3078 if (reg_last->sets) |
3065 *dsp = (*dsp & ~SPECULATIVE) | DEP_OUTPUT; | 3079 *dsp = (*dsp & ~SPECULATIVE) | DEP_OUTPUT; |
3066 | 3080 |
3067 if (reg_last->uses) | 3081 if (reg_last->uses) |
3068 *dsp = (*dsp & ~SPECULATIVE) | DEP_ANTI; | 3082 *dsp = (*dsp & ~SPECULATIVE) | DEP_ANTI; |
3069 } | 3083 } |
3070 } | 3084 } |
3071 | 3085 |
3214 /* Unconditional jump is just a transfer of control flow. | 3228 /* Unconditional jump is just a transfer of control flow. |
3215 Ignore it. */ | 3229 Ignore it. */ |
3216 return false; | 3230 return false; |
3217 | 3231 |
3218 dc = &INSN_DEPS_CONTEXT (pred); | 3232 dc = &INSN_DEPS_CONTEXT (pred); |
3233 | |
3234 /* We init this field lazily. */ | |
3235 if (dc->reg_last == NULL) | |
3236 init_deps_reg_last (dc); | |
3237 | |
3219 if (!dc->readonly) | 3238 if (!dc->readonly) |
3220 { | 3239 { |
3221 has_dependence_data.pro = NULL; | 3240 has_dependence_data.pro = NULL; |
3222 /* Initialize empty dep context with information about PRED. */ | 3241 /* Initialize empty dep context with information about PRED. */ |
3223 advance_deps_context (dc, pred); | 3242 advance_deps_context (dc, pred); |
3243 else if (dc->last_reg_pending_barrier == MOVE_BARRIER) | 3262 else if (dc->last_reg_pending_barrier == MOVE_BARRIER) |
3244 has_dependence_data.has_dep_p[DEPS_IN_INSN] = DEP_ANTI; | 3263 has_dependence_data.has_dep_p[DEPS_IN_INSN] = DEP_ANTI; |
3245 | 3264 |
3246 /* Do not allow stores to memory to move through checks. Currently | 3265 /* 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 | 3266 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. | 3267 obvious places to which this dependence can be attached. |
3249 FIMXE: this should go to a hook. */ | 3268 FIMXE: this should go to a hook. */ |
3250 if (EXPR_LHS (expr) | 3269 if (EXPR_LHS (expr) |
3251 && MEM_P (EXPR_LHS (expr)) | 3270 && MEM_P (EXPR_LHS (expr)) |
3252 && sel_insn_is_speculation_check (pred)) | 3271 && sel_insn_is_speculation_check (pred)) |
3253 has_dependence_data.has_dep_p[DEPS_IN_INSN] = DEP_ANTI; | 3272 has_dependence_data.has_dep_p[DEPS_IN_INSN] = DEP_ANTI; |
3254 | 3273 |
3255 *has_dep_pp = has_dependence_data.has_dep_p; | 3274 *has_dep_pp = has_dependence_data.has_dep_p; |
3256 ds = 0; | 3275 ds = 0; |
3257 for (i = 0; i < DEPS_IN_NOWHERE; i++) | 3276 for (i = 0; i < DEPS_IN_NOWHERE; i++) |
3258 ds = ds_full_merge (ds, has_dependence_data.has_dep_p[i], | 3277 ds = ds_full_merge (ds, has_dependence_data.has_dep_p[i], |
3259 NULL_RTX, NULL_RTX); | 3278 NULL_RTX, NULL_RTX); |
3260 | 3279 |
3261 return ds; | 3280 return ds; |
3262 } | 3281 } |
3263 | 3282 |
3264 | 3283 |
3265 /* Dependence hooks implementation that checks dependence latency constraints | 3284 /* Dependence hooks implementation that checks dependence latency constraints |
3266 on the insns being scheduled. The entry point for these routines is | 3285 on the insns being scheduled. The entry point for these routines is |
3267 tick_check_p predicate. */ | 3286 tick_check_p predicate. */ |
3268 | 3287 |
3269 static struct | 3288 static struct |
3270 { | 3289 { |
3271 /* An expr we are currently checking. */ | 3290 /* An expr we are currently checking. */ |
3272 expr_t expr; | 3291 expr_t expr; |
3372 /* Initialize variables. */ | 3391 /* Initialize variables. */ |
3373 tick_check_data.expr = expr; | 3392 tick_check_data.expr = expr; |
3374 tick_check_data.cycle = 0; | 3393 tick_check_data.cycle = 0; |
3375 tick_check_data.seen_true_dep_p = false; | 3394 tick_check_data.seen_true_dep_p = false; |
3376 sched_deps_info = &tick_check_sched_deps_info; | 3395 sched_deps_info = &tick_check_sched_deps_info; |
3377 | 3396 |
3378 gcc_assert (!dc->readonly); | 3397 gcc_assert (!dc->readonly); |
3379 dc->readonly = 1; | 3398 dc->readonly = 1; |
3380 deps_analyze_insn (dc, EXPR_INSN_RTX (expr)); | 3399 deps_analyze_insn (dc, EXPR_INSN_RTX (expr)); |
3381 dc->readonly = 0; | 3400 dc->readonly = 0; |
3382 | 3401 |
3395 { | 3414 { |
3396 rtx lhs = INSN_LHS (insn); | 3415 rtx lhs = INSN_LHS (insn); |
3397 | 3416 |
3398 if (lhs == NULL || dest == NULL) | 3417 if (lhs == NULL || dest == NULL) |
3399 return false; | 3418 return false; |
3400 | 3419 |
3401 return rtx_equal_p (lhs, dest); | 3420 return rtx_equal_p (lhs, dest); |
3402 } | 3421 } |
3403 | 3422 |
3404 /* Return s_i_d entry of INSN. Callable from debugger. */ | 3423 /* Return s_i_d entry of INSN. Callable from debugger. */ |
3405 sel_insn_data_def | 3424 sel_insn_data_def |
3415 sel_insn_is_speculation_check (rtx insn) | 3434 sel_insn_is_speculation_check (rtx insn) |
3416 { | 3435 { |
3417 return s_i_d && !! INSN_SPEC_CHECKED_DS (insn); | 3436 return s_i_d && !! INSN_SPEC_CHECKED_DS (insn); |
3418 } | 3437 } |
3419 | 3438 |
3420 /* Extracts machine mode MODE and destination location DST_LOC | 3439 /* Extracts machine mode MODE and destination location DST_LOC |
3421 for given INSN. */ | 3440 for given INSN. */ |
3422 void | 3441 void |
3423 get_dest_and_mode (rtx insn, rtx *dst_loc, enum machine_mode *mode) | 3442 get_dest_and_mode (rtx insn, rtx *dst_loc, enum machine_mode *mode) |
3424 { | 3443 { |
3425 rtx pat = PATTERN (insn); | 3444 rtx pat = PATTERN (insn); |
3434 | 3453 |
3435 if (mode) | 3454 if (mode) |
3436 *mode = GET_MODE (*dst_loc); | 3455 *mode = GET_MODE (*dst_loc); |
3437 } | 3456 } |
3438 | 3457 |
3439 /* Returns true when moving through JUMP will result in bookkeeping | 3458 /* Returns true when moving through JUMP will result in bookkeeping |
3440 creation. */ | 3459 creation. */ |
3441 bool | 3460 bool |
3442 bookkeeping_can_be_created_if_moved_through_p (insn_t jump) | 3461 bookkeeping_can_be_created_if_moved_through_p (insn_t jump) |
3443 { | 3462 { |
3444 insn_t succ; | 3463 insn_t succ; |
3457 { | 3476 { |
3458 return sel_bb_head_p (insn) && sel_bb_end_p (insn); | 3477 return sel_bb_head_p (insn) && sel_bb_end_p (insn); |
3459 } | 3478 } |
3460 | 3479 |
3461 #ifdef ENABLE_CHECKING | 3480 #ifdef ENABLE_CHECKING |
3462 /* Check that the region we're scheduling still has at most one | 3481 /* Check that the region we're scheduling still has at most one |
3463 backedge. */ | 3482 backedge. */ |
3464 static void | 3483 static void |
3465 verify_backedges (void) | 3484 verify_backedges (void) |
3466 { | 3485 { |
3467 if (pipelining_p) | 3486 if (pipelining_p) |
3468 { | 3487 { |
3469 int i, n = 0; | 3488 int i, n = 0; |
3470 edge e; | 3489 edge e; |
3471 edge_iterator ei; | 3490 edge_iterator ei; |
3472 | 3491 |
3473 for (i = 0; i < current_nr_blocks; i++) | 3492 for (i = 0; i < current_nr_blocks; i++) |
3474 FOR_EACH_EDGE (e, ei, BASIC_BLOCK (BB_TO_BLOCK (i))->succs) | 3493 FOR_EACH_EDGE (e, ei, BASIC_BLOCK (BB_TO_BLOCK (i))->succs) |
3475 if (in_current_region_p (e->dest) | 3494 if (in_current_region_p (e->dest) |
3476 && BLOCK_TO_BB (e->dest->index) < i) | 3495 && BLOCK_TO_BB (e->dest->index) < i) |
3477 n++; | 3496 n++; |
3478 | 3497 |
3479 gcc_assert (n <= 1); | 3498 gcc_assert (n <= 1); |
3480 } | 3499 } |
3481 } | 3500 } |
3482 #endif | 3501 #endif |
3483 | 3502 |
3487 /* Tidy the possibly empty block BB. */ | 3506 /* Tidy the possibly empty block BB. */ |
3488 bool | 3507 bool |
3489 maybe_tidy_empty_bb (basic_block bb) | 3508 maybe_tidy_empty_bb (basic_block bb) |
3490 { | 3509 { |
3491 basic_block succ_bb, pred_bb; | 3510 basic_block succ_bb, pred_bb; |
3511 edge e; | |
3512 edge_iterator ei; | |
3492 bool rescan_p; | 3513 bool rescan_p; |
3493 | 3514 |
3494 /* Keep empty bb only if this block immediately precedes EXIT and | 3515 /* Keep empty bb only if this block immediately precedes EXIT and |
3495 has incoming non-fallthrough edge. Otherwise remove it. */ | 3516 has incoming non-fallthrough edge. Otherwise remove it. */ |
3496 if (!sel_bb_empty_p (bb) | 3517 if (!sel_bb_empty_p (bb) |
3497 || (single_succ_p (bb) | 3518 || (single_succ_p (bb) |
3498 && single_succ (bb) == EXIT_BLOCK_PTR | 3519 && single_succ (bb) == EXIT_BLOCK_PTR |
3499 && (!single_pred_p (bb) | 3520 && (!single_pred_p (bb) |
3500 || !(single_pred_edge (bb)->flags & EDGE_FALLTHRU)))) | 3521 || !(single_pred_edge (bb)->flags & EDGE_FALLTHRU)))) |
3501 return false; | 3522 return false; |
3523 | |
3524 /* Do not attempt to redirect complex edges. */ | |
3525 FOR_EACH_EDGE (e, ei, bb->preds) | |
3526 if (e->flags & EDGE_COMPLEX) | |
3527 return false; | |
3502 | 3528 |
3503 free_data_sets (bb); | 3529 free_data_sets (bb); |
3504 | 3530 |
3505 /* Do not delete BB if it has more than one successor. | 3531 /* Do not delete BB if it has more than one successor. |
3506 That can occur when we moving a jump. */ | 3532 That can occur when we moving a jump. */ |
3516 pred_bb = NULL; | 3542 pred_bb = NULL; |
3517 | 3543 |
3518 /* Redirect all non-fallthru edges to the next bb. */ | 3544 /* Redirect all non-fallthru edges to the next bb. */ |
3519 while (rescan_p) | 3545 while (rescan_p) |
3520 { | 3546 { |
3521 edge e; | |
3522 edge_iterator ei; | |
3523 | |
3524 rescan_p = false; | 3547 rescan_p = false; |
3525 | 3548 |
3526 FOR_EACH_EDGE (e, ei, bb->preds) | 3549 FOR_EACH_EDGE (e, ei, bb->preds) |
3527 { | 3550 { |
3528 pred_bb = e->src; | 3551 pred_bb = e->src; |
3554 #endif | 3577 #endif |
3555 | 3578 |
3556 return true; | 3579 return true; |
3557 } | 3580 } |
3558 | 3581 |
3559 /* Tidy the control flow after we have removed original insn from | 3582 /* Tidy the control flow after we have removed original insn from |
3560 XBB. Return true if we have removed some blocks. When FULL_TIDYING | 3583 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. */ | 3584 is true, also try to optimize control flow on non-empty blocks. */ |
3562 bool | 3585 bool |
3563 tidy_control_flow (basic_block xbb, bool full_tidying) | 3586 tidy_control_flow (basic_block xbb, bool full_tidying) |
3564 { | 3587 { |
3565 bool changed = true; | 3588 bool changed = true; |
3566 | 3589 insn_t first, last; |
3590 | |
3567 /* First check whether XBB is empty. */ | 3591 /* First check whether XBB is empty. */ |
3568 changed = maybe_tidy_empty_bb (xbb); | 3592 changed = maybe_tidy_empty_bb (xbb); |
3569 if (changed || !full_tidying) | 3593 if (changed || !full_tidying) |
3570 return changed; | 3594 return changed; |
3571 | 3595 |
3572 /* Check if there is a unnecessary jump after insn left. */ | 3596 /* Check if there is a unnecessary jump after insn left. */ |
3573 if (jump_leads_only_to_bb_p (BB_END (xbb), xbb->next_bb) | 3597 if (jump_leads_only_to_bb_p (BB_END (xbb), xbb->next_bb) |
3574 && INSN_SCHED_TIMES (BB_END (xbb)) == 0 | 3598 && INSN_SCHED_TIMES (BB_END (xbb)) == 0 |
3575 && !IN_CURRENT_FENCE_P (BB_END (xbb))) | 3599 && !IN_CURRENT_FENCE_P (BB_END (xbb))) |
3576 { | 3600 { |
3577 if (sel_remove_insn (BB_END (xbb), false, false)) | 3601 if (sel_remove_insn (BB_END (xbb), false, false)) |
3578 return true; | 3602 return true; |
3579 tidy_fallthru_edge (EDGE_SUCC (xbb, 0)); | 3603 tidy_fallthru_edge (EDGE_SUCC (xbb, 0)); |
3580 } | 3604 } |
3581 | 3605 |
3606 first = sel_bb_head (xbb); | |
3607 last = sel_bb_end (xbb); | |
3608 if (MAY_HAVE_DEBUG_INSNS) | |
3609 { | |
3610 if (first != last && DEBUG_INSN_P (first)) | |
3611 do | |
3612 first = NEXT_INSN (first); | |
3613 while (first != last && (DEBUG_INSN_P (first) || NOTE_P (first))); | |
3614 | |
3615 if (first != last && DEBUG_INSN_P (last)) | |
3616 do | |
3617 last = PREV_INSN (last); | |
3618 while (first != last && (DEBUG_INSN_P (last) || NOTE_P (last))); | |
3619 } | |
3582 /* Check if there is an unnecessary jump in previous basic block leading | 3620 /* Check if there is an unnecessary jump in previous basic block leading |
3583 to next basic block left after removing INSN from stream. | 3621 to next basic block left after removing INSN from stream. |
3584 If it is so, remove that jump and redirect edge to current | 3622 If it is so, remove that jump and redirect edge to current |
3585 basic block (where there was INSN before deletion). This way | 3623 basic block (where there was INSN before deletion). This way |
3586 when NOP will be deleted several instructions later with its | 3624 when NOP will be deleted several instructions later with its |
3587 basic block we will not get a jump to next instruction, which | 3625 basic block we will not get a jump to next instruction, which |
3588 can be harmful. */ | 3626 can be harmful. */ |
3589 if (sel_bb_head (xbb) == sel_bb_end (xbb) | 3627 if (first == last |
3590 && !sel_bb_empty_p (xbb) | 3628 && !sel_bb_empty_p (xbb) |
3591 && INSN_NOP_P (sel_bb_end (xbb)) | 3629 && INSN_NOP_P (last) |
3592 /* Flow goes fallthru from current block to the next. */ | 3630 /* Flow goes fallthru from current block to the next. */ |
3593 && EDGE_COUNT (xbb->succs) == 1 | 3631 && EDGE_COUNT (xbb->succs) == 1 |
3594 && (EDGE_SUCC (xbb, 0)->flags & EDGE_FALLTHRU) | 3632 && (EDGE_SUCC (xbb, 0)->flags & EDGE_FALLTHRU) |
3595 /* When successor is an EXIT block, it may not be the next block. */ | 3633 /* When successor is an EXIT block, it may not be the next block. */ |
3596 && single_succ (xbb) != EXIT_BLOCK_PTR | 3634 && single_succ (xbb) != EXIT_BLOCK_PTR |
3616 } | 3654 } |
3617 | 3655 |
3618 return changed; | 3656 return changed; |
3619 } | 3657 } |
3620 | 3658 |
3621 /* Rip-off INSN from the insn stream. When ONLY_DISCONNECT is true, | 3659 /* 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. | 3660 do not delete insn's data, because it will be later re-emitted. |
3623 Return true if we have removed some blocks afterwards. */ | 3661 Return true if we have removed some blocks afterwards. */ |
3624 bool | 3662 bool |
3625 sel_remove_insn (insn_t insn, bool only_disconnect, bool full_tidying) | 3663 sel_remove_insn (insn_t insn, bool only_disconnect, bool full_tidying) |
3626 { | 3664 { |
3627 basic_block bb = BLOCK_FOR_INSN (insn); | 3665 basic_block bb = BLOCK_FOR_INSN (insn); |
3628 | 3666 |
3629 gcc_assert (INSN_IN_STREAM_P (insn)); | 3667 gcc_assert (INSN_IN_STREAM_P (insn)); |
3668 | |
3669 if (DEBUG_INSN_P (insn) && BB_AV_SET_VALID_P (bb)) | |
3670 { | |
3671 expr_t expr; | |
3672 av_set_iterator i; | |
3673 | |
3674 /* When we remove a debug insn that is head of a BB, it remains | |
3675 in the AV_SET of the block, but it shouldn't. */ | |
3676 FOR_EACH_EXPR_1 (expr, i, &BB_AV_SET (bb)) | |
3677 if (EXPR_INSN_RTX (expr) == insn) | |
3678 { | |
3679 av_set_iter_remove (&i); | |
3680 break; | |
3681 } | |
3682 } | |
3630 | 3683 |
3631 if (only_disconnect) | 3684 if (only_disconnect) |
3632 { | 3685 { |
3633 insn_t prev = PREV_INSN (insn); | 3686 insn_t prev = PREV_INSN (insn); |
3634 insn_t next = NEXT_INSN (insn); | 3687 insn_t next = NEXT_INSN (insn); |
3664 { | 3717 { |
3665 int res = 0; | 3718 int res = 0; |
3666 insn_t insn = NEXT_INSN (BB_HEAD (bb)), next_tail = NEXT_INSN (BB_END (bb)); | 3719 insn_t insn = NEXT_INSN (BB_HEAD (bb)), next_tail = NEXT_INSN (BB_END (bb)); |
3667 | 3720 |
3668 for (; insn != next_tail; insn = NEXT_INSN (insn)) | 3721 for (; insn != next_tail; insn = NEXT_INSN (insn)) |
3669 if (INSN_P (insn)) | 3722 if (NONDEBUG_INSN_P (insn)) |
3670 res++; | 3723 res++; |
3671 | 3724 |
3672 return res; | 3725 return res; |
3673 } | 3726 } |
3674 | 3727 |
3697 | 3750 |
3698 if (single_pred_p (bb) | 3751 if (single_pred_p (bb) |
3699 && !in_current_region_p (single_pred (bb))) | 3752 && !in_current_region_p (single_pred (bb))) |
3700 { | 3753 { |
3701 /* We can have preds outside a region when splitting edges | 3754 /* We can have preds outside a region when splitting edges |
3702 for pipelining of an outer loop. Use succ instead. | 3755 for pipelining of an outer loop. Use succ instead. |
3703 There should be only one of them. */ | 3756 There should be only one of them. */ |
3704 insn_t succ = NULL; | 3757 insn_t succ = NULL; |
3705 succ_iterator si; | 3758 succ_iterator si; |
3706 bool first = true; | 3759 bool first = true; |
3707 | 3760 |
3708 gcc_assert (flag_sel_sched_pipelining_outer_loops | 3761 gcc_assert (flag_sel_sched_pipelining_outer_loops |
3709 && current_loop_nest); | 3762 && current_loop_nest); |
3710 FOR_EACH_SUCC_1 (succ, si, insn, | 3763 FOR_EACH_SUCC_1 (succ, si, insn, |
3711 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS) | 3764 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS) |
3712 { | 3765 { |
3713 gcc_assert (first); | 3766 gcc_assert (first); |
3714 first = false; | 3767 first = false; |
3715 } | 3768 } |
3724 | 3777 |
3725 cfg_preds (BLOCK_FOR_INSN (insn), &preds, &n); | 3778 cfg_preds (BLOCK_FOR_INSN (insn), &preds, &n); |
3726 gcc_assert (n == 1); | 3779 gcc_assert (n == 1); |
3727 | 3780 |
3728 seqno = INSN_SEQNO (preds[0]); | 3781 seqno = INSN_SEQNO (preds[0]); |
3729 | 3782 |
3730 free (preds); | 3783 free (preds); |
3731 } | 3784 } |
3732 } | 3785 } |
3733 | 3786 |
3734 return seqno; | 3787 return seqno; |
3735 } | 3788 } |
3736 | 3789 |
3737 /* Find the proper seqno for inserting at INSN. */ | 3790 /* Find the proper seqno for inserting at INSN. Returns -1 if no predecessors |
3791 with positive seqno exist. */ | |
3738 int | 3792 int |
3739 get_seqno_by_preds (rtx insn) | 3793 get_seqno_by_preds (rtx insn) |
3740 { | 3794 { |
3741 basic_block bb = BLOCK_FOR_INSN (insn); | 3795 basic_block bb = BLOCK_FOR_INSN (insn); |
3742 rtx tmp = insn, head = BB_HEAD (bb); | 3796 rtx tmp = insn, head = BB_HEAD (bb); |
3746 while (tmp != head) | 3800 while (tmp != head) |
3747 if (INSN_P (tmp)) | 3801 if (INSN_P (tmp)) |
3748 return INSN_SEQNO (tmp); | 3802 return INSN_SEQNO (tmp); |
3749 else | 3803 else |
3750 tmp = PREV_INSN (tmp); | 3804 tmp = PREV_INSN (tmp); |
3751 | 3805 |
3752 cfg_preds (bb, &preds, &n); | 3806 cfg_preds (bb, &preds, &n); |
3753 for (i = 0, seqno = -1; i < n; i++) | 3807 for (i = 0, seqno = -1; i < n; i++) |
3754 seqno = MAX (seqno, INSN_SEQNO (preds[i])); | 3808 seqno = MAX (seqno, INSN_SEQNO (preds[i])); |
3755 | 3809 |
3756 gcc_assert (seqno > 0); | |
3757 return seqno; | 3810 return seqno; |
3758 } | 3811 } |
3759 | 3812 |
3760 | 3813 |
3761 | 3814 |
3807 /* Extend data structures for insns from current region. */ | 3860 /* Extend data structures for insns from current region. */ |
3808 static void | 3861 static void |
3809 extend_insn_data (void) | 3862 extend_insn_data (void) |
3810 { | 3863 { |
3811 int reserve; | 3864 int reserve; |
3812 | 3865 |
3813 sched_extend_target (); | 3866 sched_extend_target (); |
3814 sched_deps_init (false); | 3867 sched_deps_init (false); |
3815 | 3868 |
3816 /* Extend data structures for insns from current region. */ | 3869 /* Extend data structures for insns from current region. */ |
3817 reserve = (sched_max_luid + 1 | 3870 reserve = (sched_max_luid + 1 |
3818 - VEC_length (sel_insn_data_def, s_i_d)); | 3871 - VEC_length (sel_insn_data_def, s_i_d)); |
3819 if (reserve > 0 | 3872 if (reserve > 0 |
3820 && ! VEC_space (sel_insn_data_def, s_i_d, reserve)) | 3873 && ! VEC_space (sel_insn_data_def, s_i_d, reserve)) |
3821 VEC_safe_grow_cleared (sel_insn_data_def, heap, s_i_d, | 3874 { |
3822 3 * sched_max_luid / 2); | 3875 int size; |
3876 | |
3877 if (sched_max_luid / 2 > 1024) | |
3878 size = sched_max_luid + 1024; | |
3879 else | |
3880 size = 3 * sched_max_luid / 2; | |
3881 | |
3882 | |
3883 VEC_safe_grow_cleared (sel_insn_data_def, heap, s_i_d, size); | |
3884 } | |
3823 } | 3885 } |
3824 | 3886 |
3825 /* Finalize data structures for insns from current region. */ | 3887 /* Finalize data structures for insns from current region. */ |
3826 static void | 3888 static void |
3827 finish_insns (void) | 3889 finish_insns (void) |
3831 /* Clear here all dependence contexts that may have left from insns that were | 3893 /* Clear here all dependence contexts that may have left from insns that were |
3832 removed during the scheduling. */ | 3894 removed during the scheduling. */ |
3833 for (i = 0; i < VEC_length (sel_insn_data_def, s_i_d); i++) | 3895 for (i = 0; i < VEC_length (sel_insn_data_def, s_i_d); i++) |
3834 { | 3896 { |
3835 sel_insn_data_def *sid_entry = VEC_index (sel_insn_data_def, s_i_d, i); | 3897 sel_insn_data_def *sid_entry = VEC_index (sel_insn_data_def, s_i_d, i); |
3836 | 3898 |
3837 if (sid_entry->live) | 3899 if (sid_entry->live) |
3838 return_regset_to_pool (sid_entry->live); | 3900 return_regset_to_pool (sid_entry->live); |
3839 if (sid_entry->analyzed_deps) | 3901 if (sid_entry->analyzed_deps) |
3840 { | 3902 { |
3841 BITMAP_FREE (sid_entry->analyzed_deps); | 3903 BITMAP_FREE (sid_entry->analyzed_deps); |
3844 free_deps (&sid_entry->deps_context); | 3906 free_deps (&sid_entry->deps_context); |
3845 } | 3907 } |
3846 if (EXPR_VINSN (&sid_entry->expr)) | 3908 if (EXPR_VINSN (&sid_entry->expr)) |
3847 { | 3909 { |
3848 clear_expr (&sid_entry->expr); | 3910 clear_expr (&sid_entry->expr); |
3849 | 3911 |
3850 /* Also, clear CANT_MOVE bit here, because we really don't want it | 3912 /* Also, clear CANT_MOVE bit here, because we really don't want it |
3851 to be passed to the next region. */ | 3913 to be passed to the next region. */ |
3852 CANT_MOVE_BY_LUID (i) = 0; | 3914 CANT_MOVE_BY_LUID (i) = 0; |
3853 } | 3915 } |
3854 } | 3916 } |
3855 | 3917 |
3856 VEC_free (sel_insn_data_def, heap, s_i_d); | 3918 VEC_free (sel_insn_data_def, heap, s_i_d); |
3857 } | 3919 } |
3858 | 3920 |
3859 /* A proxy to pass initialization data to init_insn (). */ | 3921 /* A proxy to pass initialization data to init_insn (). */ |
3860 static sel_insn_data_def _insn_init_ssid; | 3922 static sel_insn_data_def _insn_init_ssid; |
3899 copy_expr (expr, &ssid->expr); | 3961 copy_expr (expr, &ssid->expr); |
3900 prepare_insn_expr (insn, ssid->seqno); | 3962 prepare_insn_expr (insn, ssid->seqno); |
3901 | 3963 |
3902 if (insn_init_create_new_vinsn_p) | 3964 if (insn_init_create_new_vinsn_p) |
3903 change_vinsn_in_expr (expr, vinsn_create (insn, init_insn_force_unique_p)); | 3965 change_vinsn_in_expr (expr, vinsn_create (insn, init_insn_force_unique_p)); |
3904 | 3966 |
3905 if (first_time_insn_init (insn)) | 3967 if (first_time_insn_init (insn)) |
3906 init_first_time_insn_data (insn); | 3968 init_first_time_insn_data (insn); |
3907 } | 3969 } |
3908 | 3970 |
3909 /* This is used to initialize spurious jumps generated by | 3971 /* This is used to initialize spurious jumps generated by |
3910 sel_redirect_edge (). */ | 3972 sel_redirect_edge (). */ |
3911 static void | 3973 static void |
3912 init_simplejump_data (insn_t insn) | 3974 init_simplejump_data (insn_t insn) |
3913 { | 3975 { |
3914 init_expr (INSN_EXPR (insn), vinsn_create (insn, false), 0, | 3976 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, | 3977 REG_BR_PROB_BASE, 0, 0, 0, 0, 0, 0, NULL, true, false, false, |
3916 false, true); | 3978 false, true); |
3917 INSN_SEQNO (insn) = get_seqno_of_a_pred (insn); | 3979 INSN_SEQNO (insn) = get_seqno_of_a_pred (insn); |
3918 init_first_time_insn_data (insn); | 3980 init_first_time_insn_data (insn); |
3919 } | 3981 } |
3920 | 3982 |
3921 /* Perform deferred initialization of insns. This is used to process | 3983 /* Perform deferred initialization of insns. This is used to process |
3922 a new jump that may be created by redirect_edge. */ | 3984 a new jump that may be created by redirect_edge. */ |
3923 void | 3985 void |
3924 sel_init_new_insn (insn_t insn, int flags) | 3986 sel_init_new_insn (insn_t insn, int flags) |
3925 { | 3987 { |
3926 /* We create data structures for bb when the first insn is emitted in it. */ | 3988 /* We create data structures for bb when the first insn is emitted in it. */ |
3929 && insn_is_the_only_one_in_bb_p (insn)) | 3991 && insn_is_the_only_one_in_bb_p (insn)) |
3930 { | 3992 { |
3931 extend_bb_info (); | 3993 extend_bb_info (); |
3932 create_initial_data_sets (BLOCK_FOR_INSN (insn)); | 3994 create_initial_data_sets (BLOCK_FOR_INSN (insn)); |
3933 } | 3995 } |
3934 | 3996 |
3935 if (flags & INSN_INIT_TODO_LUID) | 3997 if (flags & INSN_INIT_TODO_LUID) |
3936 sched_init_luids (NULL, NULL, NULL, insn); | 3998 sched_init_luids (NULL, NULL, NULL, insn); |
3937 | 3999 |
3938 if (flags & INSN_INIT_TODO_SSID) | 4000 if (flags & INSN_INIT_TODO_SSID) |
3939 { | 4001 { |
3945 if (flags & INSN_INIT_TODO_SIMPLEJUMP) | 4007 if (flags & INSN_INIT_TODO_SIMPLEJUMP) |
3946 { | 4008 { |
3947 extend_insn_data (); | 4009 extend_insn_data (); |
3948 init_simplejump_data (insn); | 4010 init_simplejump_data (insn); |
3949 } | 4011 } |
3950 | 4012 |
3951 gcc_assert (CONTAINING_RGN (BLOCK_NUM (insn)) | 4013 gcc_assert (CONTAINING_RGN (BLOCK_NUM (insn)) |
3952 == CONTAINING_RGN (BB_TO_BLOCK (0))); | 4014 == CONTAINING_RGN (BB_TO_BLOCK (0))); |
3953 } | 4015 } |
3954 | 4016 |
3955 | 4017 |
3960 init_lv_set (basic_block bb) | 4022 init_lv_set (basic_block bb) |
3961 { | 4023 { |
3962 gcc_assert (!BB_LV_SET_VALID_P (bb)); | 4024 gcc_assert (!BB_LV_SET_VALID_P (bb)); |
3963 | 4025 |
3964 BB_LV_SET (bb) = get_regset_from_pool (); | 4026 BB_LV_SET (bb) = get_regset_from_pool (); |
3965 COPY_REG_SET (BB_LV_SET (bb), DF_LR_IN (bb)); | 4027 COPY_REG_SET (BB_LV_SET (bb), DF_LR_IN (bb)); |
3966 BB_LV_SET_VALID_P (bb) = true; | 4028 BB_LV_SET_VALID_P (bb) = true; |
3967 } | 4029 } |
3968 | 4030 |
3969 /* Copy liveness information to BB from FROM_BB. */ | 4031 /* Copy liveness information to BB from FROM_BB. */ |
3970 static void | 4032 static void |
3971 copy_lv_set_from (basic_block bb, basic_block from_bb) | 4033 copy_lv_set_from (basic_block bb, basic_block from_bb) |
3972 { | 4034 { |
3973 gcc_assert (!BB_LV_SET_VALID_P (bb)); | 4035 gcc_assert (!BB_LV_SET_VALID_P (bb)); |
3974 | 4036 |
3975 COPY_REG_SET (BB_LV_SET (bb), BB_LV_SET (from_bb)); | 4037 COPY_REG_SET (BB_LV_SET (bb), BB_LV_SET (from_bb)); |
3976 BB_LV_SET_VALID_P (bb) = true; | 4038 BB_LV_SET_VALID_P (bb) = true; |
3977 } | 4039 } |
3978 | 4040 |
3979 /* Initialize lv set of all bb headers. */ | 4041 /* Initialize lv set of all bb headers. */ |
3980 void | 4042 void |
3981 init_lv_sets (void) | 4043 init_lv_sets (void) |
3982 { | 4044 { |
4259 return single_succ (BLOCK_FOR_INSN (jump)); | 4321 return single_succ (BLOCK_FOR_INSN (jump)); |
4260 | 4322 |
4261 if (!any_condjump_p (jump)) | 4323 if (!any_condjump_p (jump)) |
4262 return NULL; | 4324 return NULL; |
4263 | 4325 |
4326 /* A basic block that ends with a conditional jump may still have one successor | |
4327 (and be followed by a barrier), we are not interested. */ | |
4328 if (single_succ_p (BLOCK_FOR_INSN (jump))) | |
4329 return NULL; | |
4330 | |
4264 return FALLTHRU_EDGE (BLOCK_FOR_INSN (jump))->dest; | 4331 return FALLTHRU_EDGE (BLOCK_FOR_INSN (jump))->dest; |
4265 } | 4332 } |
4266 | 4333 |
4267 /* Remove all notes from BB. */ | 4334 /* Remove all notes from BB. */ |
4268 static void | 4335 static void |
4348 alloc_succs_info (void) | 4415 alloc_succs_info (void) |
4349 { | 4416 { |
4350 if (succs_info_pool.top == succs_info_pool.max_top) | 4417 if (succs_info_pool.top == succs_info_pool.max_top) |
4351 { | 4418 { |
4352 int i; | 4419 int i; |
4353 | 4420 |
4354 if (++succs_info_pool.max_top >= succs_info_pool.size) | 4421 if (++succs_info_pool.max_top >= succs_info_pool.size) |
4355 gcc_unreachable (); | 4422 gcc_unreachable (); |
4356 | 4423 |
4357 i = ++succs_info_pool.top; | 4424 i = ++succs_info_pool.top; |
4358 succs_info_pool.stack[i].succs_ok = VEC_alloc (rtx, heap, 10); | 4425 succs_info_pool.stack[i].succs_ok = VEC_alloc (rtx, heap, 10); |
4367 | 4434 |
4368 /* Free successor's info. */ | 4435 /* Free successor's info. */ |
4369 void | 4436 void |
4370 free_succs_info (struct succs_info * sinfo) | 4437 free_succs_info (struct succs_info * sinfo) |
4371 { | 4438 { |
4372 gcc_assert (succs_info_pool.top >= 0 | 4439 gcc_assert (succs_info_pool.top >= 0 |
4373 && &succs_info_pool.stack[succs_info_pool.top] == sinfo); | 4440 && &succs_info_pool.stack[succs_info_pool.top] == sinfo); |
4374 succs_info_pool.top--; | 4441 succs_info_pool.top--; |
4375 | 4442 |
4376 /* Clear stale info. */ | 4443 /* Clear stale info. */ |
4377 VEC_block_remove (rtx, sinfo->succs_ok, | 4444 VEC_block_remove (rtx, sinfo->succs_ok, |
4378 0, VEC_length (rtx, sinfo->succs_ok)); | 4445 0, VEC_length (rtx, sinfo->succs_ok)); |
4379 VEC_block_remove (rtx, sinfo->succs_other, | 4446 VEC_block_remove (rtx, sinfo->succs_other, |
4380 0, VEC_length (rtx, sinfo->succs_other)); | 4447 0, VEC_length (rtx, sinfo->succs_other)); |
4381 VEC_block_remove (int, sinfo->probs_ok, | 4448 VEC_block_remove (int, sinfo->probs_ok, |
4382 0, VEC_length (int, sinfo->probs_ok)); | 4449 0, VEC_length (int, sinfo->probs_ok)); |
4383 sinfo->all_prob = 0; | 4450 sinfo->all_prob = 0; |
4384 sinfo->succs_ok_n = 0; | 4451 sinfo->succs_ok_n = 0; |
4385 sinfo->all_succs_n = 0; | 4452 sinfo->all_succs_n = 0; |
4386 } | 4453 } |
4387 | 4454 |
4388 /* Compute successor info for INSN. FLAGS are the flags passed | 4455 /* Compute successor info for INSN. FLAGS are the flags passed |
4389 to the FOR_EACH_SUCC_1 iterator. */ | 4456 to the FOR_EACH_SUCC_1 iterator. */ |
4390 struct succs_info * | 4457 struct succs_info * |
4391 compute_succs_info (insn_t insn, short flags) | 4458 compute_succs_info (insn_t insn, short flags) |
4392 { | 4459 { |
4393 succ_iterator si; | 4460 succ_iterator si; |
4403 | 4470 |
4404 if (current_flags & flags) | 4471 if (current_flags & flags) |
4405 { | 4472 { |
4406 VEC_safe_push (rtx, heap, sinfo->succs_ok, succ); | 4473 VEC_safe_push (rtx, heap, sinfo->succs_ok, succ); |
4407 VEC_safe_push (int, heap, sinfo->probs_ok, | 4474 VEC_safe_push (int, heap, sinfo->probs_ok, |
4408 /* FIXME: Improve calculation when skipping | 4475 /* FIXME: Improve calculation when skipping |
4409 inner loop to exits. */ | 4476 inner loop to exits. */ |
4410 (si.bb_end | 4477 (si.bb_end |
4411 ? si.e1->probability | 4478 ? si.e1->probability |
4412 : REG_BR_PROB_BASE)); | 4479 : REG_BR_PROB_BASE)); |
4413 sinfo->succs_ok_n++; | 4480 sinfo->succs_ok_n++; |
4414 } | 4481 } |
4415 else | 4482 else |
4416 VEC_safe_push (rtx, heap, sinfo->succs_other, succ); | 4483 VEC_safe_push (rtx, heap, sinfo->succs_other, succ); |
4425 } | 4492 } |
4426 | 4493 |
4427 return sinfo; | 4494 return sinfo; |
4428 } | 4495 } |
4429 | 4496 |
4430 /* Return the predecessors of BB in PREDS and their number in N. | 4497 /* Return the predecessors of BB in PREDS and their number in N. |
4431 Empty blocks are skipped. SIZE is used to allocate PREDS. */ | 4498 Empty blocks are skipped. SIZE is used to allocate PREDS. */ |
4432 static void | 4499 static void |
4433 cfg_preds_1 (basic_block bb, insn_t **preds, int *n, int *size) | 4500 cfg_preds_1 (basic_block bb, insn_t **preds, int *n, int *size) |
4434 { | 4501 { |
4435 edge e; | 4502 edge e; |
4448 if (sel_bb_empty_p (pred_bb)) | 4515 if (sel_bb_empty_p (pred_bb)) |
4449 cfg_preds_1 (pred_bb, preds, n, size); | 4516 cfg_preds_1 (pred_bb, preds, n, size); |
4450 else | 4517 else |
4451 { | 4518 { |
4452 if (*n == *size) | 4519 if (*n == *size) |
4453 *preds = XRESIZEVEC (insn_t, *preds, | 4520 *preds = XRESIZEVEC (insn_t, *preds, |
4454 (*size = 2 * *size + 1)); | 4521 (*size = 2 * *size + 1)); |
4455 (*preds)[(*n)++] = bb_end; | 4522 (*preds)[(*n)++] = bb_end; |
4456 } | 4523 } |
4457 } | 4524 } |
4458 | 4525 |
4459 gcc_assert (*n != 0); | 4526 gcc_assert (*n != 0); |
4460 } | 4527 } |
4461 | 4528 |
4462 /* Find all predecessors of BB and record them in PREDS and their number | 4529 /* 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) | 4530 in N. Empty blocks are skipped, and only normal (forward in-region) |
4464 edges are processed. */ | 4531 edges are processed. */ |
4465 static void | 4532 static void |
4466 cfg_preds (basic_block bb, insn_t **preds, int *n) | 4533 cfg_preds (basic_block bb, insn_t **preds, int *n) |
4467 { | 4534 { |
4468 int size = 0; | 4535 int size = 0; |
4496 } | 4563 } |
4497 | 4564 |
4498 return false; | 4565 return false; |
4499 } | 4566 } |
4500 | 4567 |
4501 /* Returns true when BB should be the end of an ebb. Adapted from the | 4568 /* Returns true when BB should be the end of an ebb. Adapted from the |
4502 code in sched-ebb.c. */ | 4569 code in sched-ebb.c. */ |
4503 bool | 4570 bool |
4504 bb_ends_ebb_p (basic_block bb) | 4571 bb_ends_ebb_p (basic_block bb) |
4505 { | 4572 { |
4506 basic_block next_bb = bb_next_bb (bb); | 4573 basic_block next_bb = bb_next_bb (bb); |
4507 edge e; | 4574 edge e; |
4508 edge_iterator ei; | 4575 edge_iterator ei; |
4509 | 4576 |
4510 if (next_bb == EXIT_BLOCK_PTR | 4577 if (next_bb == EXIT_BLOCK_PTR |
4511 || bitmap_bit_p (forced_ebb_heads, next_bb->index) | 4578 || bitmap_bit_p (forced_ebb_heads, next_bb->index) |
4512 || (LABEL_P (BB_HEAD (next_bb)) | 4579 || (LABEL_P (BB_HEAD (next_bb)) |
4513 /* NB: LABEL_NUSES () is not maintained outside of jump.c. | 4580 /* NB: LABEL_NUSES () is not maintained outside of jump.c. |
4514 Work around that. */ | 4581 Work around that. */ |
4538 | 4605 |
4539 for(;;) | 4606 for(;;) |
4540 { | 4607 { |
4541 if (ptr == BLOCK_FOR_INSN (succ)) | 4608 if (ptr == BLOCK_FOR_INSN (succ)) |
4542 return true; | 4609 return true; |
4543 | 4610 |
4544 if (bb_ends_ebb_p (ptr)) | 4611 if (bb_ends_ebb_p (ptr)) |
4545 return false; | 4612 return false; |
4546 | 4613 |
4547 ptr = bb_next_bb (ptr); | 4614 ptr = bb_next_bb (ptr); |
4548 } | 4615 } |
4560 int *postorder; | 4627 int *postorder; |
4561 int n_blocks, i; | 4628 int n_blocks, i; |
4562 | 4629 |
4563 if (!rev_top_order_index || rev_top_order_index_len < last_basic_block) | 4630 if (!rev_top_order_index || rev_top_order_index_len < last_basic_block) |
4564 { | 4631 { |
4565 rev_top_order_index_len = last_basic_block; | 4632 rev_top_order_index_len = last_basic_block; |
4566 rev_top_order_index = XRESIZEVEC (int, rev_top_order_index, | 4633 rev_top_order_index = XRESIZEVEC (int, rev_top_order_index, |
4567 rev_top_order_index_len); | 4634 rev_top_order_index_len); |
4568 } | 4635 } |
4569 | 4636 |
4570 postorder = XNEWVEC (int, n_basic_blocks); | 4637 postorder = XNEWVEC (int, n_basic_blocks); |
4596 INSN_AFTER_STALL_P (insn) = 0; | 4663 INSN_AFTER_STALL_P (insn) = 0; |
4597 INSN_SCHED_TIMES (insn) = 0; | 4664 INSN_SCHED_TIMES (insn) = 0; |
4598 EXPR_PRIORITY_ADJ (INSN_EXPR (insn)) = 0; | 4665 EXPR_PRIORITY_ADJ (INSN_EXPR (insn)) = 0; |
4599 | 4666 |
4600 /* We cannot use the changed caches, as previously we could ignore | 4667 /* We cannot use the changed caches, as previously we could ignore |
4601 the LHS dependence due to enabled renaming and transform | 4668 the LHS dependence due to enabled renaming and transform |
4602 the expression, and currently we'll be unable to do this. */ | 4669 the expression, and currently we'll be unable to do this. */ |
4603 htab_empty (INSN_TRANSFORMED_INSNS (insn)); | 4670 htab_empty (INSN_TRANSFORMED_INSNS (insn)); |
4604 } | 4671 } |
4605 } | 4672 } |
4606 | 4673 |
4647 alloc_sched_pools (void) | 4714 alloc_sched_pools (void) |
4648 { | 4715 { |
4649 int succs_size; | 4716 int succs_size; |
4650 | 4717 |
4651 succs_size = MAX_WS + 1; | 4718 succs_size = MAX_WS + 1; |
4652 succs_info_pool.stack = XCNEWVEC (struct succs_info, succs_size); | 4719 succs_info_pool.stack = XCNEWVEC (struct succs_info, succs_size); |
4653 succs_info_pool.size = succs_size; | 4720 succs_info_pool.size = succs_size; |
4654 succs_info_pool.top = -1; | 4721 succs_info_pool.top = -1; |
4655 succs_info_pool.max_top = -1; | 4722 succs_info_pool.max_top = -1; |
4656 | 4723 |
4657 sched_lists_pool = create_alloc_pool ("sel-sched-lists", | 4724 sched_lists_pool = create_alloc_pool ("sel-sched-lists", |
4658 sizeof (struct _list_node), 500); | 4725 sizeof (struct _list_node), 500); |
4659 } | 4726 } |
4660 | 4727 |
4661 /* Free the pools. */ | 4728 /* Free the pools. */ |
4662 void | 4729 void |
4663 free_sched_pools (void) | 4730 free_sched_pools (void) |
4664 { | 4731 { |
4665 int i; | 4732 int i; |
4666 | 4733 |
4667 free_alloc_pool (sched_lists_pool); | 4734 free_alloc_pool (sched_lists_pool); |
4668 gcc_assert (succs_info_pool.top == -1); | 4735 gcc_assert (succs_info_pool.top == -1); |
4669 for (i = 0; i < succs_info_pool.max_top; i++) | 4736 for (i = 0; i < succs_info_pool.max_top; i++) |
4670 { | 4737 { |
4671 VEC_free (rtx, heap, succs_info_pool.stack[i].succs_ok); | 4738 VEC_free (rtx, heap, succs_info_pool.stack[i].succs_ok); |
4674 } | 4741 } |
4675 free (succs_info_pool.stack); | 4742 free (succs_info_pool.stack); |
4676 } | 4743 } |
4677 | 4744 |
4678 | 4745 |
4679 /* Returns a position in RGN where BB can be inserted retaining | 4746 /* Returns a position in RGN where BB can be inserted retaining |
4680 topological order. */ | 4747 topological order. */ |
4681 static int | 4748 static int |
4682 find_place_to_insert_bb (basic_block bb, int rgn) | 4749 find_place_to_insert_bb (basic_block bb, int rgn) |
4683 { | 4750 { |
4684 bool has_preds_outside_rgn = false; | 4751 bool has_preds_outside_rgn = false; |
4685 edge e; | 4752 edge e; |
4686 edge_iterator ei; | 4753 edge_iterator ei; |
4687 | 4754 |
4688 /* Find whether we have preds outside the region. */ | 4755 /* Find whether we have preds outside the region. */ |
4689 FOR_EACH_EDGE (e, ei, bb->preds) | 4756 FOR_EACH_EDGE (e, ei, bb->preds) |
4690 if (!in_current_region_p (e->src)) | 4757 if (!in_current_region_p (e->src)) |
4691 { | 4758 { |
4692 has_preds_outside_rgn = true; | 4759 has_preds_outside_rgn = true; |
4693 break; | 4760 break; |
4694 } | 4761 } |
4695 | 4762 |
4696 /* Recompute the top order -- needed when we have > 1 pred | 4763 /* Recompute the top order -- needed when we have > 1 pred |
4697 and in case we don't have preds outside. */ | 4764 and in case we don't have preds outside. */ |
4698 if (flag_sel_sched_pipelining_outer_loops | 4765 if (flag_sel_sched_pipelining_outer_loops |
4699 && (has_preds_outside_rgn || EDGE_COUNT (bb->preds) > 1)) | 4766 && (has_preds_outside_rgn || EDGE_COUNT (bb->preds) > 1)) |
4700 { | 4767 { |
4702 | 4769 |
4703 recompute_rev_top_order (); | 4770 recompute_rev_top_order (); |
4704 for (i = RGN_NR_BLOCKS (rgn) - 1; i >= 0; i--) | 4771 for (i = RGN_NR_BLOCKS (rgn) - 1; i >= 0; i--) |
4705 { | 4772 { |
4706 cur_bbi = BB_TO_BLOCK (i); | 4773 cur_bbi = BB_TO_BLOCK (i); |
4707 if (rev_top_order_index[bbi] | 4774 if (rev_top_order_index[bbi] |
4708 < rev_top_order_index[cur_bbi]) | 4775 < rev_top_order_index[cur_bbi]) |
4709 break; | 4776 break; |
4710 } | 4777 } |
4711 | 4778 |
4712 /* We skipped the right block, so we increase i. We accomodate | 4779 /* We skipped the right block, so we increase i. We accomodate |
4713 it for increasing by step later, so we decrease i. */ | 4780 it for increasing by step later, so we decrease i. */ |
4714 return (i + 1) - 1; | 4781 return (i + 1) - 1; |
4715 } | 4782 } |
4716 else if (has_preds_outside_rgn) | 4783 else if (has_preds_outside_rgn) |
4729 the pipelining of outer loops, and that is handled above. | 4796 the pipelining of outer loops, and that is handled above. |
4730 Just take the bbi of this single pred. */ | 4797 Just take the bbi of this single pred. */ |
4731 if (EDGE_COUNT (bb->succs) > 0) | 4798 if (EDGE_COUNT (bb->succs) > 0) |
4732 { | 4799 { |
4733 int pred_bbi; | 4800 int pred_bbi; |
4734 | 4801 |
4735 gcc_assert (EDGE_COUNT (bb->preds) == 1); | 4802 gcc_assert (EDGE_COUNT (bb->preds) == 1); |
4736 | 4803 |
4737 pred_bbi = EDGE_PRED (bb, 0)->src->index; | 4804 pred_bbi = EDGE_PRED (bb, 0)->src->index; |
4738 return BLOCK_TO_BB (pred_bbi); | 4805 return BLOCK_TO_BB (pred_bbi); |
4739 } | 4806 } |
4740 else | 4807 else |
4741 /* BB has no successors. It is safe to put it in the end. */ | 4808 /* BB has no successors. It is safe to put it in the end. */ |
4751 if (BB_LV_SET (bb)) | 4818 if (BB_LV_SET (bb)) |
4752 free_lv_set (bb); | 4819 free_lv_set (bb); |
4753 | 4820 |
4754 bitmap_clear_bit (blocks_to_reschedule, bb->index); | 4821 bitmap_clear_bit (blocks_to_reschedule, bb->index); |
4755 | 4822 |
4756 /* Can't assert av_set properties because we use sel_aremove_bb | 4823 /* Can't assert av_set properties because we use sel_aremove_bb |
4757 when removing loop preheader from the region. At the point of | 4824 when removing loop preheader from the region. At the point of |
4758 removing the preheader we already have deallocated sel_region_bb_info. */ | 4825 removing the preheader we already have deallocated sel_region_bb_info. */ |
4759 gcc_assert (BB_LV_SET (bb) == NULL | 4826 gcc_assert (BB_LV_SET (bb) == NULL |
4760 && !BB_LV_SET_VALID_P (bb) | 4827 && !BB_LV_SET_VALID_P (bb) |
4761 && BB_AV_LEVEL (bb) == 0 | 4828 && BB_AV_LEVEL (bb) == 0 |
4762 && BB_AV_SET (bb) == NULL); | 4829 && BB_AV_SET (bb) == NULL); |
4763 | 4830 |
4764 delete_basic_block (bb); | 4831 delete_basic_block (bb); |
4765 } | 4832 } |
4766 | 4833 |
4767 /* Add BB to the current region and update the region data. */ | 4834 /* Add BB to the current region and update the region data. */ |
4768 static void | 4835 static void |
4775 bbi += 1; | 4842 bbi += 1; |
4776 pos = RGN_BLOCKS (rgn) + bbi; | 4843 pos = RGN_BLOCKS (rgn) + bbi; |
4777 | 4844 |
4778 gcc_assert (RGN_HAS_REAL_EBB (rgn) == 0 | 4845 gcc_assert (RGN_HAS_REAL_EBB (rgn) == 0 |
4779 && ebb_head[bbi] == pos); | 4846 && ebb_head[bbi] == pos); |
4780 | 4847 |
4781 /* Make a place for the new block. */ | 4848 /* Make a place for the new block. */ |
4782 extend_regions (); | 4849 extend_regions (); |
4783 | 4850 |
4784 for (i = RGN_BLOCKS (rgn + 1) - 1; i >= pos; i--) | 4851 for (i = RGN_BLOCKS (rgn + 1) - 1; i >= pos; i--) |
4785 BLOCK_TO_BB (rgn_bb_table[i])++; | 4852 BLOCK_TO_BB (rgn_bb_table[i])++; |
4786 | 4853 |
4787 memmove (rgn_bb_table + pos + 1, | 4854 memmove (rgn_bb_table + pos + 1, |
4788 rgn_bb_table + pos, | 4855 rgn_bb_table + pos, |
4789 (RGN_BLOCKS (nr_regions) - pos) * sizeof (*rgn_bb_table)); | 4856 (RGN_BLOCKS (nr_regions) - pos) * sizeof (*rgn_bb_table)); |
4790 | 4857 |
4791 /* Initialize data for BB. */ | 4858 /* Initialize data for BB. */ |
4792 rgn_bb_table[pos] = bb->index; | 4859 rgn_bb_table[pos] = bb->index; |
4793 BLOCK_TO_BB (bb->index) = bbi; | 4860 BLOCK_TO_BB (bb->index) = bbi; |
4794 CONTAINING_RGN (bb->index) = rgn; | 4861 CONTAINING_RGN (bb->index) = rgn; |
4795 | 4862 |
4796 RGN_NR_BLOCKS (rgn)++; | 4863 RGN_NR_BLOCKS (rgn)++; |
4797 | 4864 |
4798 for (i = rgn + 1; i <= nr_regions; i++) | 4865 for (i = rgn + 1; i <= nr_regions; i++) |
4799 RGN_BLOCKS (i)++; | 4866 RGN_BLOCKS (i)++; |
4800 } | 4867 } |
4801 | 4868 |
4802 /* Remove BB from the current region and update the region data. */ | 4869 /* Remove BB from the current region and update the region data. */ |
4822 RGN_NR_BLOCKS (rgn)--; | 4889 RGN_NR_BLOCKS (rgn)--; |
4823 for (i = rgn + 1; i <= nr_regions; i++) | 4890 for (i = rgn + 1; i <= nr_regions; i++) |
4824 RGN_BLOCKS (i)--; | 4891 RGN_BLOCKS (i)--; |
4825 } | 4892 } |
4826 | 4893 |
4827 /* Add BB to the current region and update all data. If BB is NULL, add all | 4894 /* Add BB to the current region and update all data. If BB is NULL, add all |
4828 blocks from last_added_blocks vector. */ | 4895 blocks from last_added_blocks vector. */ |
4829 static void | 4896 static void |
4830 sel_add_bb (basic_block bb) | 4897 sel_add_bb (basic_block bb) |
4831 { | 4898 { |
4832 /* Extend luids so that new notes will receive zero luids. */ | 4899 /* Extend luids so that new notes will receive zero luids. */ |
4833 sched_init_luids (NULL, NULL, NULL, NULL); | 4900 sched_init_luids (NULL, NULL, NULL, NULL); |
4834 sched_init_bbs (); | 4901 sched_init_bbs (); |
4835 sel_init_bbs (last_added_blocks, NULL); | 4902 sel_init_bbs (last_added_blocks, NULL); |
4836 | 4903 |
4837 /* When bb is passed explicitly, the vector should contain | 4904 /* When bb is passed explicitly, the vector should contain |
4838 the only element that equals to bb; otherwise, the vector | 4905 the only element that equals to bb; otherwise, the vector |
4839 should not be NULL. */ | 4906 should not be NULL. */ |
4840 gcc_assert (last_added_blocks != NULL); | 4907 gcc_assert (last_added_blocks != NULL); |
4841 | 4908 |
4842 if (bb != NULL) | 4909 if (bb != NULL) |
4843 { | 4910 { |
4844 gcc_assert (VEC_length (basic_block, last_added_blocks) == 1 | 4911 gcc_assert (VEC_length (basic_block, last_added_blocks) == 1 |
4845 && VEC_index (basic_block, | 4912 && VEC_index (basic_block, |
4846 last_added_blocks, 0) == bb); | 4913 last_added_blocks, 0) == bb); |
4847 add_block_to_current_region (bb); | 4914 add_block_to_current_region (bb); |
4848 | 4915 |
4849 /* We associate creating/deleting data sets with the first insn | 4916 /* We associate creating/deleting data sets with the first insn |
4850 appearing / disappearing in the bb. */ | 4917 appearing / disappearing in the bb. */ |
4851 if (!sel_bb_empty_p (bb) && BB_LV_SET (bb) == NULL) | 4918 if (!sel_bb_empty_p (bb) && BB_LV_SET (bb) == NULL) |
4852 create_initial_data_sets (bb); | 4919 create_initial_data_sets (bb); |
4853 | 4920 |
4854 VEC_free (basic_block, heap, last_added_blocks); | 4921 VEC_free (basic_block, heap, last_added_blocks); |
4855 } | 4922 } |
4856 else | 4923 else |
4857 /* BB is NULL - process LAST_ADDED_BLOCKS instead. */ | 4924 /* BB is NULL - process LAST_ADDED_BLOCKS instead. */ |
4858 { | 4925 { |
4859 int i; | 4926 int i; |
4860 basic_block temp_bb = NULL; | 4927 basic_block temp_bb = NULL; |
4861 | 4928 |
4862 for (i = 0; | 4929 for (i = 0; |
4863 VEC_iterate (basic_block, last_added_blocks, i, bb); i++) | 4930 VEC_iterate (basic_block, last_added_blocks, i, bb); i++) |
4864 { | 4931 { |
4865 add_block_to_current_region (bb); | 4932 add_block_to_current_region (bb); |
4866 temp_bb = bb; | 4933 temp_bb = bb; |
4867 } | 4934 } |
4868 | 4935 |
4869 /* We need to fetch at least one bb so we know the region | 4936 /* We need to fetch at least one bb so we know the region |
4870 to update. */ | 4937 to update. */ |
4871 gcc_assert (temp_bb != NULL); | 4938 gcc_assert (temp_bb != NULL); |
4872 bb = temp_bb; | 4939 bb = temp_bb; |
4873 | 4940 |
4874 VEC_free (basic_block, heap, last_added_blocks); | 4941 VEC_free (basic_block, heap, last_added_blocks); |
4875 } | 4942 } |
4876 | 4943 |
4877 rgn_setup_region (CONTAINING_RGN (bb->index)); | 4944 rgn_setup_region (CONTAINING_RGN (bb->index)); |
4878 } | 4945 } |
4879 | 4946 |
4880 /* Remove BB from the current region and update all data. | 4947 /* Remove BB from the current region and update all data. |
4881 If REMOVE_FROM_CFG_PBB is true, also remove the block cfom cfg. */ | 4948 If REMOVE_FROM_CFG_PBB is true, also remove the block cfom cfg. */ |
4882 static void | 4949 static void |
4883 sel_remove_bb (basic_block bb, bool remove_from_cfg_p) | 4950 sel_remove_bb (basic_block bb, bool remove_from_cfg_p) |
4884 { | 4951 { |
4885 gcc_assert (bb != NULL && BB_NOTE_LIST (bb) == NULL_RTX); | 4952 gcc_assert (bb != NULL && BB_NOTE_LIST (bb) == NULL_RTX); |
4886 | 4953 |
4887 remove_bb_from_region (bb); | 4954 remove_bb_from_region (bb); |
4888 return_bb_to_pool (bb); | 4955 return_bb_to_pool (bb); |
4889 bitmap_clear_bit (blocks_to_reschedule, bb->index); | 4956 bitmap_clear_bit (blocks_to_reschedule, bb->index); |
4890 | 4957 |
4891 if (remove_from_cfg_p) | 4958 if (remove_from_cfg_p) |
4892 delete_and_free_basic_block (bb); | 4959 delete_and_free_basic_block (bb); |
4893 | 4960 |
4894 rgn_setup_region (CONTAINING_RGN (bb->index)); | 4961 rgn_setup_region (CONTAINING_RGN (bb->index)); |
4895 } | 4962 } |
4898 static void | 4965 static void |
4899 move_bb_info (basic_block merge_bb, basic_block empty_bb) | 4966 move_bb_info (basic_block merge_bb, basic_block empty_bb) |
4900 { | 4967 { |
4901 gcc_assert (in_current_region_p (merge_bb)); | 4968 gcc_assert (in_current_region_p (merge_bb)); |
4902 | 4969 |
4903 concat_note_lists (BB_NOTE_LIST (empty_bb), | 4970 concat_note_lists (BB_NOTE_LIST (empty_bb), |
4904 &BB_NOTE_LIST (merge_bb)); | 4971 &BB_NOTE_LIST (merge_bb)); |
4905 BB_NOTE_LIST (empty_bb) = NULL_RTX; | 4972 BB_NOTE_LIST (empty_bb) = NULL_RTX; |
4906 | 4973 |
4907 } | 4974 } |
4908 | 4975 |
4909 /* Remove an empty basic block EMPTY_BB. When MERGE_UP_P is true, we put | 4976 /* 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 | 4977 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 | 4978 into the successor. When REMOVE_FROM_CFG_P is true, also remove |
4912 the empty block. */ | 4979 the empty block. */ |
4913 void | 4980 void |
4914 sel_remove_empty_bb (basic_block empty_bb, bool merge_up_p, | 4981 sel_remove_empty_bb (basic_block empty_bb, bool merge_up_p, |
4915 bool remove_from_cfg_p) | 4982 bool remove_from_cfg_p) |
4916 { | 4983 { |
4929 edge e; | 4996 edge e; |
4930 edge_iterator ei; | 4997 edge_iterator ei; |
4931 | 4998 |
4932 merge_bb = bb_next_bb (empty_bb); | 4999 merge_bb = bb_next_bb (empty_bb); |
4933 | 5000 |
4934 /* Redirect incoming edges (except fallthrough one) of EMPTY_BB to its | 5001 /* Redirect incoming edges (except fallthrough one) of EMPTY_BB to its |
4935 successor block. */ | 5002 successor block. */ |
4936 for (ei = ei_start (empty_bb->preds); | 5003 for (ei = ei_start (empty_bb->preds); |
4937 (e = ei_safe_edge (ei)); ) | 5004 (e = ei_safe_edge (ei)); ) |
4938 { | 5005 { |
4939 if (! (e->flags & EDGE_FALLTHRU)) | 5006 if (! (e->flags & EDGE_FALLTHRU)) |
5015 | 5082 |
5016 /* Finish removing. */ | 5083 /* Finish removing. */ |
5017 sel_remove_bb (empty_bb, remove_from_cfg_p); | 5084 sel_remove_bb (empty_bb, remove_from_cfg_p); |
5018 } | 5085 } |
5019 | 5086 |
5020 /* An implementation of create_basic_block hook, which additionally updates | 5087 /* An implementation of create_basic_block hook, which additionally updates |
5021 per-bb data structures. */ | 5088 per-bb data structures. */ |
5022 static basic_block | 5089 static basic_block |
5023 sel_create_basic_block (void *headp, void *endp, basic_block after) | 5090 sel_create_basic_block (void *headp, void *endp, basic_block after) |
5024 { | 5091 { |
5025 basic_block new_bb; | 5092 basic_block new_bb; |
5026 insn_t new_bb_note; | 5093 insn_t new_bb_note; |
5027 | 5094 |
5028 gcc_assert (flag_sel_sched_pipelining_outer_loops | 5095 gcc_assert (flag_sel_sched_pipelining_outer_loops |
5029 || last_added_blocks == NULL); | 5096 || last_added_blocks == NULL); |
5030 | 5097 |
5031 new_bb_note = get_bb_note_from_pool (); | 5098 new_bb_note = get_bb_note_from_pool (); |
5032 | 5099 |
5033 if (new_bb_note == NULL_RTX) | 5100 if (new_bb_note == NULL_RTX) |
5073 gcc_assert (loop_latch_edge (loop)); | 5140 gcc_assert (loop_latch_edge (loop)); |
5074 } | 5141 } |
5075 } | 5142 } |
5076 } | 5143 } |
5077 | 5144 |
5078 /* Splits BB on two basic blocks, adding it to the region and extending | 5145 /* Splits BB on two basic blocks, adding it to the region and extending |
5079 per-bb data structures. Returns the newly created bb. */ | 5146 per-bb data structures. Returns the newly created bb. */ |
5080 static basic_block | 5147 static basic_block |
5081 sel_split_block (basic_block bb, rtx after) | 5148 sel_split_block (basic_block bb, rtx after) |
5082 { | 5149 { |
5083 basic_block new_bb; | 5150 basic_block new_bb; |
5085 | 5152 |
5086 new_bb = sched_split_block_1 (bb, after); | 5153 new_bb = sched_split_block_1 (bb, after); |
5087 sel_add_bb (new_bb); | 5154 sel_add_bb (new_bb); |
5088 | 5155 |
5089 /* This should be called after sel_add_bb, because this uses | 5156 /* This should be called after sel_add_bb, because this uses |
5090 CONTAINING_RGN for the new block, which is not yet initialized. | 5157 CONTAINING_RGN for the new block, which is not yet initialized. |
5091 FIXME: this function may be a no-op now. */ | 5158 FIXME: this function may be a no-op now. */ |
5092 change_loops_latches (bb, new_bb); | 5159 change_loops_latches (bb, new_bb); |
5093 | 5160 |
5094 /* Update ORIG_BB_INDEX for insns moved into the new block. */ | 5161 /* Update ORIG_BB_INDEX for insns moved into the new block. */ |
5095 FOR_BB_INSNS (new_bb, insn) | 5162 FOR_BB_INSNS (new_bb, insn) |
5125 if (end && INSN_UID (end) >= prev_max_uid) | 5192 if (end && INSN_UID (end) >= prev_max_uid) |
5126 return end; | 5193 return end; |
5127 return NULL; | 5194 return NULL; |
5128 } | 5195 } |
5129 | 5196 |
5130 /* Look for a new jump either in FROM_BB block or in newly created JUMP_BB block. | 5197 /* 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. */ | 5198 New means having UID at least equal to PREV_MAX_UID. */ |
5132 static rtx | 5199 static rtx |
5133 find_new_jump (basic_block from, basic_block jump_bb, int prev_max_uid) | 5200 find_new_jump (basic_block from, basic_block jump_bb, int prev_max_uid) |
5134 { | 5201 { |
5135 rtx jump; | 5202 rtx jump; |
5136 | 5203 |
5137 /* Return immediately if no new insns were emitted. */ | 5204 /* Return immediately if no new insns were emitted. */ |
5138 if (get_max_uid () == prev_max_uid) | 5205 if (get_max_uid () == prev_max_uid) |
5139 return NULL; | 5206 return NULL; |
5140 | 5207 |
5141 /* Now check both blocks for new jumps. It will ever be only one. */ | 5208 /* Now check both blocks for new jumps. It will ever be only one. */ |
5142 if ((jump = check_for_new_jump (from, prev_max_uid))) | 5209 if ((jump = check_for_new_jump (from, prev_max_uid))) |
5143 return jump; | 5210 return jump; |
5144 | 5211 |
5145 if (jump_bb != NULL | 5212 if (jump_bb != NULL |
5159 | 5226 |
5160 src = e->src; | 5227 src = e->src; |
5161 prev_max_uid = get_max_uid (); | 5228 prev_max_uid = get_max_uid (); |
5162 new_bb = split_edge (e); | 5229 new_bb = split_edge (e); |
5163 | 5230 |
5164 if (flag_sel_sched_pipelining_outer_loops | 5231 if (flag_sel_sched_pipelining_outer_loops |
5165 && current_loop_nest) | 5232 && current_loop_nest) |
5166 { | 5233 { |
5167 int i; | 5234 int i; |
5168 basic_block bb; | 5235 basic_block bb; |
5169 | 5236 |
5170 /* Some of the basic blocks might not have been added to the loop. | 5237 /* Some of the basic blocks might not have been added to the loop. |
5171 Add them here, until this is fixed in force_fallthru. */ | 5238 Add them here, until this is fixed in force_fallthru. */ |
5172 for (i = 0; | 5239 for (i = 0; |
5173 VEC_iterate (basic_block, last_added_blocks, i, bb); i++) | 5240 VEC_iterate (basic_block, last_added_blocks, i, bb); i++) |
5174 if (!bb->loop_father) | 5241 if (!bb->loop_father) |
5175 { | 5242 { |
5176 add_bb_to_loop (bb, e->dest->loop_father); | 5243 add_bb_to_loop (bb, e->dest->loop_father); |
5177 | 5244 |
5236 | 5303 |
5237 gcc_assert (sel_bb_empty_p (recovery_block)); | 5304 gcc_assert (sel_bb_empty_p (recovery_block)); |
5238 sched_create_recovery_edges (first_bb, recovery_block, second_bb); | 5305 sched_create_recovery_edges (first_bb, recovery_block, second_bb); |
5239 if (current_loops != NULL) | 5306 if (current_loops != NULL) |
5240 add_bb_to_loop (recovery_block, first_bb->loop_father); | 5307 add_bb_to_loop (recovery_block, first_bb->loop_father); |
5241 | 5308 |
5242 sel_add_bb (recovery_block); | 5309 sel_add_bb (recovery_block); |
5243 | 5310 |
5244 jump = BB_END (recovery_block); | 5311 jump = BB_END (recovery_block); |
5245 gcc_assert (sel_bb_head (recovery_block) == jump); | 5312 gcc_assert (sel_bb_head (recovery_block) == jump); |
5246 sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP); | 5313 sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP); |
5247 | 5314 |
5248 return recovery_block; | 5315 return recovery_block; |
5250 | 5317 |
5251 /* Merge basic block B into basic block A. */ | 5318 /* Merge basic block B into basic block A. */ |
5252 void | 5319 void |
5253 sel_merge_blocks (basic_block a, basic_block b) | 5320 sel_merge_blocks (basic_block a, basic_block b) |
5254 { | 5321 { |
5255 gcc_assert (can_merge_blocks_p (a, b)); | |
5256 | |
5257 sel_remove_empty_bb (b, true, false); | 5322 sel_remove_empty_bb (b, true, false); |
5258 merge_blocks (a, b); | 5323 merge_blocks (a, b); |
5259 | 5324 |
5260 change_loops_latches (b, a); | 5325 change_loops_latches (b, a); |
5261 } | 5326 } |
5267 sel_redirect_edge_and_branch_force (edge e, basic_block to) | 5332 sel_redirect_edge_and_branch_force (edge e, basic_block to) |
5268 { | 5333 { |
5269 basic_block jump_bb, src; | 5334 basic_block jump_bb, src; |
5270 int prev_max_uid; | 5335 int prev_max_uid; |
5271 rtx jump; | 5336 rtx jump; |
5272 | 5337 |
5273 gcc_assert (!sel_bb_empty_p (e->src)); | 5338 gcc_assert (!sel_bb_empty_p (e->src)); |
5274 | 5339 |
5275 src = e->src; | 5340 src = e->src; |
5276 prev_max_uid = get_max_uid (); | 5341 prev_max_uid = get_max_uid (); |
5277 jump_bb = redirect_edge_and_branch_force (e, to); | 5342 jump_bb = redirect_edge_and_branch_force (e, to); |
5278 | 5343 |
5279 if (jump_bb != NULL) | 5344 if (jump_bb != NULL) |
5282 /* This function could not be used to spoil the loop structure by now, | 5347 /* 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. */ | 5348 thus we don't care to update anything. But check it to be sure. */ |
5284 if (current_loop_nest | 5349 if (current_loop_nest |
5285 && pipelining_p) | 5350 && pipelining_p) |
5286 gcc_assert (loop_latch_edge (current_loop_nest)); | 5351 gcc_assert (loop_latch_edge (current_loop_nest)); |
5287 | 5352 |
5288 jump = find_new_jump (src, jump_bb, prev_max_uid); | 5353 jump = find_new_jump (src, jump_bb, prev_max_uid); |
5289 if (jump) | 5354 if (jump) |
5290 sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP); | 5355 sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP); |
5291 } | 5356 } |
5292 | 5357 |
5296 { | 5361 { |
5297 bool latch_edge_p; | 5362 bool latch_edge_p; |
5298 basic_block src; | 5363 basic_block src; |
5299 int prev_max_uid; | 5364 int prev_max_uid; |
5300 rtx jump; | 5365 rtx jump; |
5366 edge redirected; | |
5301 | 5367 |
5302 latch_edge_p = (pipelining_p | 5368 latch_edge_p = (pipelining_p |
5303 && current_loop_nest | 5369 && current_loop_nest |
5304 && e == loop_latch_edge (current_loop_nest)); | 5370 && e == loop_latch_edge (current_loop_nest)); |
5305 | 5371 |
5306 src = e->src; | 5372 src = e->src; |
5307 prev_max_uid = get_max_uid (); | 5373 prev_max_uid = get_max_uid (); |
5308 | 5374 |
5309 redirect_edge_and_branch (e, to); | 5375 redirected = redirect_edge_and_branch (e, to); |
5310 gcc_assert (last_added_blocks == NULL); | 5376 |
5377 gcc_assert (redirected && last_added_blocks == NULL); | |
5311 | 5378 |
5312 /* When we've redirected a latch edge, update the header. */ | 5379 /* When we've redirected a latch edge, update the header. */ |
5313 if (latch_edge_p) | 5380 if (latch_edge_p) |
5314 { | 5381 { |
5315 current_loop_nest->header = to; | 5382 current_loop_nest->header = to; |
5365 | 5432 |
5366 start_sequence (); | 5433 start_sequence (); |
5367 | 5434 |
5368 if (label == NULL_RTX) | 5435 if (label == NULL_RTX) |
5369 insn_rtx = emit_insn (pattern); | 5436 insn_rtx = emit_insn (pattern); |
5437 else if (DEBUG_INSN_P (label)) | |
5438 insn_rtx = emit_debug_insn (pattern); | |
5370 else | 5439 else |
5371 { | 5440 { |
5372 insn_rtx = emit_jump_insn (pattern); | 5441 insn_rtx = emit_jump_insn (pattern); |
5373 JUMP_LABEL (insn_rtx) = label; | 5442 JUMP_LABEL (insn_rtx) = label; |
5374 ++LABEL_NUSES (label); | 5443 ++LABEL_NUSES (label); |
5400 rtx | 5469 rtx |
5401 create_copy_of_insn_rtx (rtx insn_rtx) | 5470 create_copy_of_insn_rtx (rtx insn_rtx) |
5402 { | 5471 { |
5403 rtx res; | 5472 rtx res; |
5404 | 5473 |
5474 if (DEBUG_INSN_P (insn_rtx)) | |
5475 return create_insn_rtx_from_pattern (copy_rtx (PATTERN (insn_rtx)), | |
5476 insn_rtx); | |
5477 | |
5405 gcc_assert (NONJUMP_INSN_P (insn_rtx)); | 5478 gcc_assert (NONJUMP_INSN_P (insn_rtx)); |
5406 | 5479 |
5407 res = create_insn_rtx_from_pattern (copy_rtx (PATTERN (insn_rtx)), | 5480 res = create_insn_rtx_from_pattern (copy_rtx (PATTERN (insn_rtx)), |
5408 NULL_RTX); | 5481 NULL_RTX); |
5409 return res; | 5482 return res; |
5420 } | 5493 } |
5421 | 5494 |
5422 /* Helpers for global init. */ | 5495 /* Helpers for global init. */ |
5423 /* This structure is used to be able to call existing bundling mechanism | 5496 /* This structure is used to be able to call existing bundling mechanism |
5424 and calculate insn priorities. */ | 5497 and calculate insn priorities. */ |
5425 static struct haifa_sched_info sched_sel_haifa_sched_info = | 5498 static struct haifa_sched_info sched_sel_haifa_sched_info = |
5426 { | 5499 { |
5427 NULL, /* init_ready_list */ | 5500 NULL, /* init_ready_list */ |
5428 NULL, /* can_schedule_ready_p */ | 5501 NULL, /* can_schedule_ready_p */ |
5429 NULL, /* schedule_more_p */ | 5502 NULL, /* schedule_more_p */ |
5430 NULL, /* new_ready */ | 5503 NULL, /* new_ready */ |
5431 NULL, /* rgn_rank */ | 5504 NULL, /* rgn_rank */ |
5432 sel_print_insn, /* rgn_print_insn */ | 5505 sel_print_insn, /* rgn_print_insn */ |
5433 contributes_to_priority, | 5506 contributes_to_priority, |
5507 NULL, /* insn_finishes_block_p */ | |
5434 | 5508 |
5435 NULL, NULL, | 5509 NULL, NULL, |
5436 NULL, NULL, | 5510 NULL, NULL, |
5437 0, 0, | 5511 0, 0, |
5438 | 5512 |
5441 NULL, /* advance_target_bb */ | 5515 NULL, /* advance_target_bb */ |
5442 SEL_SCHED | NEW_BBS | 5516 SEL_SCHED | NEW_BBS |
5443 }; | 5517 }; |
5444 | 5518 |
5445 /* Setup special insns used in the scheduler. */ | 5519 /* Setup special insns used in the scheduler. */ |
5446 void | 5520 void |
5447 setup_nop_and_exit_insns (void) | 5521 setup_nop_and_exit_insns (void) |
5448 { | 5522 { |
5449 gcc_assert (nop_pattern == NULL_RTX | 5523 gcc_assert (nop_pattern == NULL_RTX |
5450 && exit_insn == NULL_RTX); | 5524 && exit_insn == NULL_RTX); |
5451 | 5525 |
5485 | 5559 |
5486 /* Call a set_sched_flags hook. */ | 5560 /* Call a set_sched_flags hook. */ |
5487 void | 5561 void |
5488 sel_set_sched_flags (void) | 5562 sel_set_sched_flags (void) |
5489 { | 5563 { |
5490 /* ??? This means that set_sched_flags were called, and we decided to | 5564 /* ??? This means that set_sched_flags were called, and we decided to |
5491 support speculation. However, set_sched_flags also modifies flags | 5565 support speculation. However, set_sched_flags also modifies flags |
5492 on current_sched_info, doing this only at global init. And we | 5566 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. */ | 5567 sometimes change c_s_i later. So put the correct flags again. */ |
5494 if (spec_info && targetm.sched.set_sched_flags) | 5568 if (spec_info && targetm.sched.set_sched_flags) |
5495 targetm.sched.set_sched_flags (spec_info); | 5569 targetm.sched.set_sched_flags (spec_info); |
5496 } | 5570 } |
5497 | 5571 |
5512 sel_common_sched_info.sched_pass_id = SCHED_SEL_PASS; | 5586 sel_common_sched_info.sched_pass_id = SCHED_SEL_PASS; |
5513 | 5587 |
5514 common_sched_info = &sel_common_sched_info; | 5588 common_sched_info = &sel_common_sched_info; |
5515 | 5589 |
5516 current_sched_info = &sched_sel_haifa_sched_info; | 5590 current_sched_info = &sched_sel_haifa_sched_info; |
5517 current_sched_info->sched_max_insns_priority = | 5591 current_sched_info->sched_max_insns_priority = |
5518 get_rgn_sched_max_insns_priority (); | 5592 get_rgn_sched_max_insns_priority (); |
5519 | 5593 |
5520 sel_set_sched_flags (); | 5594 sel_set_sched_flags (); |
5521 } | 5595 } |
5522 | 5596 |
5523 | 5597 |
5524 /* Adds basic block BB to region RGN at the position *BB_ORD_INDEX, | 5598 /* Adds basic block BB to region RGN at the position *BB_ORD_INDEX, |
5548 | 5622 |
5549 RGN_NR_BLOCKS (new_rgn_number) = 0; | 5623 RGN_NR_BLOCKS (new_rgn_number) = 0; |
5550 | 5624 |
5551 /* FIXME: This will work only when EBBs are not created. */ | 5625 /* FIXME: This will work only when EBBs are not created. */ |
5552 if (new_rgn_number != 0) | 5626 if (new_rgn_number != 0) |
5553 RGN_BLOCKS (new_rgn_number) = RGN_BLOCKS (new_rgn_number - 1) + | 5627 RGN_BLOCKS (new_rgn_number) = RGN_BLOCKS (new_rgn_number - 1) + |
5554 RGN_NR_BLOCKS (new_rgn_number - 1); | 5628 RGN_NR_BLOCKS (new_rgn_number - 1); |
5555 else | 5629 else |
5556 RGN_BLOCKS (new_rgn_number) = 0; | 5630 RGN_BLOCKS (new_rgn_number) = 0; |
5557 | 5631 |
5558 /* Set the blocks of the next region so the other functions may | 5632 /* Set the blocks of the next region so the other functions may |
5559 calculate the number of blocks in the region. */ | 5633 calculate the number of blocks in the region. */ |
5560 RGN_BLOCKS (new_rgn_number + 1) = RGN_BLOCKS (new_rgn_number) + | 5634 RGN_BLOCKS (new_rgn_number + 1) = RGN_BLOCKS (new_rgn_number) + |
5561 RGN_NR_BLOCKS (new_rgn_number); | 5635 RGN_NR_BLOCKS (new_rgn_number); |
5562 | 5636 |
5563 nr_regions++; | 5637 nr_regions++; |
5564 | 5638 |
5565 return new_rgn_number; | 5639 return new_rgn_number; |
5571 bb_top_order_comparator (const void *x, const void *y) | 5645 bb_top_order_comparator (const void *x, const void *y) |
5572 { | 5646 { |
5573 basic_block bb1 = *(const basic_block *) x; | 5647 basic_block bb1 = *(const basic_block *) x; |
5574 basic_block bb2 = *(const basic_block *) y; | 5648 basic_block bb2 = *(const basic_block *) y; |
5575 | 5649 |
5576 gcc_assert (bb1 == bb2 | 5650 gcc_assert (bb1 == bb2 |
5577 || rev_top_order_index[bb1->index] | 5651 || rev_top_order_index[bb1->index] |
5578 != rev_top_order_index[bb2->index]); | 5652 != rev_top_order_index[bb2->index]); |
5579 | 5653 |
5580 /* It's a reverse topological order in REV_TOP_ORDER_INDEX, so | 5654 /* It's a reverse topological order in REV_TOP_ORDER_INDEX, so |
5581 bbs with greater number should go earlier. */ | 5655 bbs with greater number should go earlier. */ |
5582 if (rev_top_order_index[bb1->index] > rev_top_order_index[bb2->index]) | 5656 if (rev_top_order_index[bb1->index] > rev_top_order_index[bb2->index]) |
5583 return -1; | 5657 return -1; |
5584 else | 5658 else |
5585 return 1; | 5659 return 1; |
5586 } | 5660 } |
5587 | 5661 |
5588 /* Create a region for LOOP and return its number. If we don't want | 5662 /* Create a region for LOOP and return its number. If we don't want |
5589 to pipeline LOOP, return -1. */ | 5663 to pipeline LOOP, return -1. */ |
5590 static int | 5664 static int |
5591 make_region_from_loop (struct loop *loop) | 5665 make_region_from_loop (struct loop *loop) |
5592 { | 5666 { |
5593 unsigned int i; | 5667 unsigned int i; |
5597 /* Basic block index, to be assigned to BLOCK_TO_BB. */ | 5671 /* Basic block index, to be assigned to BLOCK_TO_BB. */ |
5598 int bb_ord_index = 0; | 5672 int bb_ord_index = 0; |
5599 basic_block *loop_blocks; | 5673 basic_block *loop_blocks; |
5600 basic_block preheader_block; | 5674 basic_block preheader_block; |
5601 | 5675 |
5602 if (loop->num_nodes | 5676 if (loop->num_nodes |
5603 > (unsigned) PARAM_VALUE (PARAM_MAX_PIPELINE_REGION_BLOCKS)) | 5677 > (unsigned) PARAM_VALUE (PARAM_MAX_PIPELINE_REGION_BLOCKS)) |
5604 return -1; | 5678 return -1; |
5605 | 5679 |
5606 /* Don't pipeline loops whose latch belongs to some of its inner loops. */ | 5680 /* Don't pipeline loops whose latch belongs to some of its inner loops. */ |
5607 for (inner = loop->inner; inner; inner = inner->inner) | 5681 for (inner = loop->inner; inner; inner = inner->inner) |
5608 if (flow_bb_inside_loop_p (inner, loop->latch)) | 5682 if (flow_bb_inside_loop_p (inner, loop->latch)) |
5609 return -1; | 5683 return -1; |
5610 | 5684 |
5632 | 5706 |
5633 for (i = 0; i < loop->num_nodes; i++) | 5707 for (i = 0; i < loop->num_nodes; i++) |
5634 { | 5708 { |
5635 /* Add only those blocks that haven't been scheduled in the inner loop. | 5709 /* 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 | 5710 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 | 5711 be added to the region (and they actually don't belong to the loop |
5638 body, but to the region containing that loop body). */ | 5712 body, but to the region containing that loop body). */ |
5639 | 5713 |
5640 gcc_assert (new_rgn_number >= 0); | 5714 gcc_assert (new_rgn_number >= 0); |
5641 | 5715 |
5642 if (! TEST_BIT (bbs_in_loop_rgns, loop_blocks[i]->index)) | 5716 if (! TEST_BIT (bbs_in_loop_rgns, loop_blocks[i]->index)) |
5643 { | 5717 { |
5644 sel_add_block_to_region (loop_blocks[i], &bb_ord_index, | 5718 sel_add_block_to_region (loop_blocks[i], &bb_ord_index, |
5645 new_rgn_number); | 5719 new_rgn_number); |
5646 SET_BIT (bbs_in_loop_rgns, loop_blocks[i]->index); | 5720 SET_BIT (bbs_in_loop_rgns, loop_blocks[i]->index); |
5647 } | 5721 } |
5648 } | 5722 } |
5649 | 5723 |
5677 gcc_assert (*loop_blocks == NULL); | 5751 gcc_assert (*loop_blocks == NULL); |
5678 } | 5752 } |
5679 | 5753 |
5680 | 5754 |
5681 /* Create region(s) from loop nest LOOP, such that inner loops will be | 5755 /* 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 | 5756 pipelined before outer loops. Returns true when a region for LOOP |
5683 is created. */ | 5757 is created. */ |
5684 static bool | 5758 static bool |
5685 make_regions_from_loop_nest (struct loop *loop) | 5759 make_regions_from_loop_nest (struct loop *loop) |
5686 { | 5760 { |
5687 struct loop *cur_loop; | 5761 struct loop *cur_loop; |
5688 int rgn_number; | 5762 int rgn_number; |
5689 | 5763 |
5690 /* Traverse all inner nodes of the loop. */ | 5764 /* Traverse all inner nodes of the loop. */ |
5691 for (cur_loop = loop->inner; cur_loop; cur_loop = cur_loop->next) | 5765 for (cur_loop = loop->inner; cur_loop; cur_loop = cur_loop->next) |
5737 considered_for_pipelining_p (struct loop *loop) | 5811 considered_for_pipelining_p (struct loop *loop) |
5738 { | 5812 { |
5739 if (loop_depth (loop) == 0) | 5813 if (loop_depth (loop) == 0) |
5740 return false; | 5814 return false; |
5741 | 5815 |
5742 /* Now, the loop could be too large or irreducible. Check whether its | 5816 /* Now, the loop could be too large or irreducible. Check whether its |
5743 region is in LOOP_NESTS. | 5817 region is in LOOP_NESTS. |
5744 We determine the region number of LOOP as the region number of its | 5818 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 | 5819 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. | 5820 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. */ | 5821 Latch can't be used because it could be in the inner loop too. */ |
5748 if (LOOP_MARKED_FOR_PIPELINING_P (loop) && pipelining_p) | 5822 if (LOOP_MARKED_FOR_PIPELINING_P (loop) && pipelining_p) |
5749 { | 5823 { |
5750 int rgn = CONTAINING_RGN (loop->latch->index); | 5824 int rgn = CONTAINING_RGN (loop->latch->index); |
5751 | 5825 |
5752 gcc_assert ((unsigned) rgn < VEC_length (loop_p, loop_nests)); | 5826 gcc_assert ((unsigned) rgn < VEC_length (loop_p, loop_nests)); |
5753 return true; | 5827 return true; |
5754 } | 5828 } |
5755 | 5829 |
5756 return false; | 5830 return false; |
5757 } | 5831 } |
5758 | 5832 |
5759 /* Makes regions from the rest of the blocks, after loops are chosen | 5833 /* Makes regions from the rest of the blocks, after loops are chosen |
5760 for pipelining. */ | 5834 for pipelining. */ |
5761 static void | 5835 static void |
5762 make_regions_from_the_rest (void) | 5836 make_regions_from_the_rest (void) |
5763 { | 5837 { |
5764 int cur_rgn_blocks; | 5838 int cur_rgn_blocks; |
5767 | 5841 |
5768 basic_block bb; | 5842 basic_block bb; |
5769 edge e; | 5843 edge e; |
5770 edge_iterator ei; | 5844 edge_iterator ei; |
5771 int *degree; | 5845 int *degree; |
5772 int new_regions; | |
5773 | 5846 |
5774 /* Index in rgn_bb_table where to start allocating new regions. */ | 5847 /* Index in rgn_bb_table where to start allocating new regions. */ |
5775 cur_rgn_blocks = nr_regions ? RGN_BLOCKS (nr_regions) : 0; | 5848 cur_rgn_blocks = nr_regions ? RGN_BLOCKS (nr_regions) : 0; |
5776 new_regions = nr_regions; | 5849 |
5777 | 5850 /* Make regions from all the rest basic blocks - those that don't belong to |
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 | 5851 any loop or belong to irreducible loops. Prepare the data structures |
5780 for extend_rgns. */ | 5852 for extend_rgns. */ |
5781 | 5853 |
5782 /* LOOP_HDR[I] == -1 if I-th bb doesn't belong to any loop, | 5854 /* 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 | 5855 LOOP_HDR[I] == LOOP_HDR[J] iff basic blocks I and J reside within the same |
5796 if (bb->loop_father && !bb->loop_father->num == 0 | 5868 if (bb->loop_father && !bb->loop_father->num == 0 |
5797 && !(bb->flags & BB_IRREDUCIBLE_LOOP)) | 5869 && !(bb->flags & BB_IRREDUCIBLE_LOOP)) |
5798 loop_hdr[bb->index] = bb->loop_father->num; | 5870 loop_hdr[bb->index] = bb->loop_father->num; |
5799 } | 5871 } |
5800 | 5872 |
5801 /* For each basic block degree is calculated as the number of incoming | 5873 /* 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. | 5874 edges, that are going out of bbs that are not yet scheduled. |
5803 The basic blocks that are scheduled have degree value of zero. */ | 5875 The basic blocks that are scheduled have degree value of zero. */ |
5804 FOR_EACH_BB (bb) | 5876 FOR_EACH_BB (bb) |
5805 { | 5877 { |
5806 degree[bb->index] = 0; | 5878 degree[bb->index] = 0; |
5807 | 5879 |
5808 if (!TEST_BIT (bbs_in_loop_rgns, bb->index)) | 5880 if (!TEST_BIT (bbs_in_loop_rgns, bb->index)) |
5809 { | 5881 { |
5851 | 5923 |
5852 free (rev_top_order_index); | 5924 free (rev_top_order_index); |
5853 rev_top_order_index = NULL; | 5925 rev_top_order_index = NULL; |
5854 } | 5926 } |
5855 | 5927 |
5856 /* This function replaces the find_rgns when | 5928 /* This function replaces the find_rgns when |
5857 FLAG_SEL_SCHED_PIPELINING_OUTER_LOOPS is set. */ | 5929 FLAG_SEL_SCHED_PIPELINING_OUTER_LOOPS is set. */ |
5858 void | 5930 void |
5859 sel_find_rgns (void) | 5931 sel_find_rgns (void) |
5860 { | 5932 { |
5861 sel_init_pipelining (); | 5933 sel_init_pipelining (); |
5862 extend_regions (); | 5934 extend_regions (); |
5863 | 5935 |
5871 : LI_ONLY_INNERMOST)) | 5943 : LI_ONLY_INNERMOST)) |
5872 make_regions_from_loop_nest (loop); | 5944 make_regions_from_loop_nest (loop); |
5873 } | 5945 } |
5874 | 5946 |
5875 /* Make regions from all the rest basic blocks and schedule them. | 5947 /* 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 | 5948 These blocks include blocks that don't belong to any loop or belong |
5877 to irreducible loops. */ | 5949 to irreducible loops. */ |
5878 make_regions_from_the_rest (); | 5950 make_regions_from_the_rest (); |
5879 | 5951 |
5880 /* We don't need bbs_in_loop_rgns anymore. */ | 5952 /* We don't need bbs_in_loop_rgns anymore. */ |
5881 sbitmap_free (bbs_in_loop_rgns); | 5953 sbitmap_free (bbs_in_loop_rgns); |
5882 bbs_in_loop_rgns = NULL; | 5954 bbs_in_loop_rgns = NULL; |
5883 } | 5955 } |
5884 | 5956 |
5885 /* Adds the preheader blocks from previous loop to current region taking | 5957 /* Adds the preheader blocks from previous loop to current region taking |
5886 it from LOOP_PREHEADER_BLOCKS (current_loop_nest). | 5958 it from LOOP_PREHEADER_BLOCKS (current_loop_nest). |
5887 This function is only used with -fsel-sched-pipelining-outer-loops. */ | 5959 This function is only used with -fsel-sched-pipelining-outer-loops. */ |
5888 void | 5960 void |
5889 sel_add_loop_preheaders (void) | 5961 sel_add_loop_preheaders (void) |
5890 { | 5962 { |
5891 int i; | 5963 int i; |
5892 basic_block bb; | 5964 basic_block bb; |
5893 VEC(basic_block, heap) *preheader_blocks | 5965 VEC(basic_block, heap) *preheader_blocks |
5894 = LOOP_PREHEADER_BLOCKS (current_loop_nest); | 5966 = LOOP_PREHEADER_BLOCKS (current_loop_nest); |
5895 | 5967 |
5896 for (i = 0; | 5968 for (i = 0; |
5897 VEC_iterate (basic_block, preheader_blocks, i, bb); | 5969 VEC_iterate (basic_block, preheader_blocks, i, bb); |
5898 i++) | 5970 i++) |
5899 sel_add_bb (bb); | 5971 sel_add_bb (bb); |
5900 | 5972 |
5901 VEC_free (basic_block, heap, preheader_blocks); | 5973 VEC_free (basic_block, heap, preheader_blocks); |
5902 } | 5974 } |
5903 | 5975 |
5904 /* While pipelining outer loops, returns TRUE if BB is a loop preheader. | 5976 /* 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 | 5977 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 | 5978 false, because it is used when deciding whether we should or should |
5907 not reschedule pipelined code. */ | 5979 not reschedule pipelined code. */ |
5908 bool | 5980 bool |
5909 sel_is_loop_preheader_p (basic_block bb) | 5981 sel_is_loop_preheader_p (basic_block bb) |
5910 { | 5982 { |
5911 if (current_loop_nest) | 5983 if (current_loop_nest) |
5921 | 5993 |
5922 /* We used to find a preheader with the topological information. | 5994 /* We used to find a preheader with the topological information. |
5923 Check that the above code is equivalent to what we did before. */ | 5995 Check that the above code is equivalent to what we did before. */ |
5924 | 5996 |
5925 if (in_current_region_p (current_loop_nest->header)) | 5997 if (in_current_region_p (current_loop_nest->header)) |
5926 gcc_assert (!(BLOCK_TO_BB (bb->index) | 5998 gcc_assert (!(BLOCK_TO_BB (bb->index) |
5927 < BLOCK_TO_BB (current_loop_nest->header->index))); | 5999 < BLOCK_TO_BB (current_loop_nest->header->index))); |
5928 | 6000 |
5929 /* Support the situation when the latch block of outer loop | 6001 /* Support the situation when the latch block of outer loop |
5930 could be from here. */ | 6002 could be from here. */ |
5931 for (outer = loop_outer (current_loop_nest); | 6003 for (outer = loop_outer (current_loop_nest); |
5942 bool | 6014 bool |
5943 jump_leads_only_to_bb_p (insn_t jump, basic_block dest_bb) | 6015 jump_leads_only_to_bb_p (insn_t jump, basic_block dest_bb) |
5944 { | 6016 { |
5945 basic_block jump_bb = BLOCK_FOR_INSN (jump); | 6017 basic_block jump_bb = BLOCK_FOR_INSN (jump); |
5946 | 6018 |
5947 /* It is not jump, jump with side-effects or jump can lead to several | 6019 /* It is not jump, jump with side-effects or jump can lead to several |
5948 basic blocks. */ | 6020 basic blocks. */ |
5949 if (!onlyjump_p (jump) | 6021 if (!onlyjump_p (jump) |
5950 || !any_uncondjump_p (jump)) | 6022 || !any_uncondjump_p (jump)) |
5951 return false; | 6023 return false; |
5952 | 6024 |
5953 /* Several outgoing edges, abnormal edge or destination of jump is | 6025 /* Several outgoing edges, abnormal edge or destination of jump is |
5954 not DEST_BB. */ | 6026 not DEST_BB. */ |
5955 if (EDGE_COUNT (jump_bb->succs) != 1 | 6027 if (EDGE_COUNT (jump_bb->succs) != 1 |
5956 || EDGE_SUCC (jump_bb, 0)->flags & EDGE_ABNORMAL | 6028 || EDGE_SUCC (jump_bb, 0)->flags & EDGE_ABNORMAL |
5957 || EDGE_SUCC (jump_bb, 0)->dest != dest_bb) | 6029 || EDGE_SUCC (jump_bb, 0)->dest != dest_bb) |
5958 return false; | 6030 return false; |
5960 /* If not anything of the upper. */ | 6032 /* If not anything of the upper. */ |
5961 return true; | 6033 return true; |
5962 } | 6034 } |
5963 | 6035 |
5964 /* Removes the loop preheader from the current region and saves it in | 6036 /* 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 | 6037 PREHEADER_BLOCKS of the father loop, so they will be added later to |
5966 region that represents an outer loop. */ | 6038 region that represents an outer loop. */ |
5967 static void | 6039 static void |
5968 sel_remove_loop_preheader (void) | 6040 sel_remove_loop_preheader (void) |
5969 { | 6041 { |
5970 int i, old_len; | 6042 int i, old_len; |
5971 int cur_rgn = CONTAINING_RGN (BB_TO_BLOCK (0)); | 6043 int cur_rgn = CONTAINING_RGN (BB_TO_BLOCK (0)); |
5972 basic_block bb; | 6044 basic_block bb; |
5973 bool all_empty_p = true; | 6045 bool all_empty_p = true; |
5974 VEC(basic_block, heap) *preheader_blocks | 6046 VEC(basic_block, heap) *preheader_blocks |
5975 = LOOP_PREHEADER_BLOCKS (loop_outer (current_loop_nest)); | 6047 = LOOP_PREHEADER_BLOCKS (loop_outer (current_loop_nest)); |
5976 | 6048 |
5977 gcc_assert (current_loop_nest); | 6049 gcc_assert (current_loop_nest); |
5978 old_len = VEC_length (basic_block, preheader_blocks); | 6050 old_len = VEC_length (basic_block, preheader_blocks); |
5979 | 6051 |
5980 /* Add blocks that aren't within the current loop to PREHEADER_BLOCKS. */ | 6052 /* Add blocks that aren't within the current loop to PREHEADER_BLOCKS. */ |
5981 for (i = 0; i < RGN_NR_BLOCKS (cur_rgn); i++) | 6053 for (i = 0; i < RGN_NR_BLOCKS (cur_rgn); i++) |
5982 { | 6054 { |
5983 bb = BASIC_BLOCK (BB_TO_BLOCK (i)); | 6055 bb = BASIC_BLOCK (BB_TO_BLOCK (i)); |
5984 | 6056 |
5985 /* If the basic block belongs to region, but doesn't belong to | 6057 /* If the basic block belongs to region, but doesn't belong to |
5986 corresponding loop, then it should be a preheader. */ | 6058 corresponding loop, then it should be a preheader. */ |
5987 if (sel_is_loop_preheader_p (bb)) | 6059 if (sel_is_loop_preheader_p (bb)) |
5988 { | 6060 { |
5989 VEC_safe_push (basic_block, heap, preheader_blocks, bb); | 6061 VEC_safe_push (basic_block, heap, preheader_blocks, bb); |
5990 if (BB_END (bb) != bb_note (bb)) | 6062 if (BB_END (bb) != bb_note (bb)) |
5991 all_empty_p = false; | 6063 all_empty_p = false; |
5992 } | 6064 } |
5993 } | 6065 } |
5994 | 6066 |
5995 /* Remove these blocks only after iterating over the whole region. */ | 6067 /* Remove these blocks only after iterating over the whole region. */ |
5996 for (i = VEC_length (basic_block, preheader_blocks) - 1; | 6068 for (i = VEC_length (basic_block, preheader_blocks) - 1; |
5997 i >= old_len; | 6069 i >= old_len; |
5998 i--) | 6070 i--) |
5999 { | 6071 { |
6000 bb = VEC_index (basic_block, preheader_blocks, i); | 6072 bb = VEC_index (basic_block, preheader_blocks, i); |
6001 sel_remove_bb (bb, false); | 6073 sel_remove_bb (bb, false); |
6002 } | 6074 } |
6003 | 6075 |
6004 if (!considered_for_pipelining_p (loop_outer (current_loop_nest))) | 6076 if (!considered_for_pipelining_p (loop_outer (current_loop_nest))) |
6005 { | 6077 { |
6025 redirect_edge_succ (e, bb->next_bb); | 6097 redirect_edge_succ (e, bb->next_bb); |
6026 } | 6098 } |
6027 gcc_assert (BB_NOTE_LIST (bb) == NULL); | 6099 gcc_assert (BB_NOTE_LIST (bb) == NULL); |
6028 delete_and_free_basic_block (bb); | 6100 delete_and_free_basic_block (bb); |
6029 | 6101 |
6030 /* Check if after deleting preheader there is a nonconditional | 6102 /* Check if after deleting preheader there is a nonconditional |
6031 jump in PREV_BB that leads to the next basic block NEXT_BB. | 6103 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 | 6104 If it is so - delete this jump and clear data sets of its |
6033 basic block if it becomes empty. */ | 6105 basic block if it becomes empty. */ |
6034 if (next_bb->prev_bb == prev_bb | 6106 if (next_bb->prev_bb == prev_bb |
6035 && prev_bb != ENTRY_BLOCK_PTR | 6107 && prev_bb != ENTRY_BLOCK_PTR |
6036 && jump_leads_only_to_bb_p (BB_END (prev_bb), next_bb)) | 6108 && jump_leads_only_to_bb_p (BB_END (prev_bb), next_bb)) |
6037 { | 6109 { |