comparison gcc/sel-sched.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Instruction scheduling pass. Selective scheduler and pipeliner. 1 /* Instruction scheduling pass. Selective scheduler and pipeliner.
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 2 Copyright (C) 2006-2017 Free Software Foundation, Inc.
3 Free Software Foundation, Inc.
4 3
5 This file is part of GCC. 4 This file is part of GCC.
6 5
7 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
8 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
19 <http://www.gnu.org/licenses/>. */ 18 <http://www.gnu.org/licenses/>. */
20 19
21 #include "config.h" 20 #include "config.h"
22 #include "system.h" 21 #include "system.h"
23 #include "coretypes.h" 22 #include "coretypes.h"
24 #include "tm.h" 23 #include "backend.h"
25 #include "rtl-error.h" 24 #include "tree.h"
25 #include "rtl.h"
26 #include "df.h"
27 #include "memmodel.h"
26 #include "tm_p.h" 28 #include "tm_p.h"
27 #include "hard-reg-set.h"
28 #include "regs.h" 29 #include "regs.h"
29 #include "function.h" 30 #include "cfgbuild.h"
30 #include "flags.h"
31 #include "insn-config.h" 31 #include "insn-config.h"
32 #include "insn-attr.h" 32 #include "insn-attr.h"
33 #include "except.h"
34 #include "recog.h"
35 #include "params.h" 33 #include "params.h"
36 #include "target.h" 34 #include "target.h"
37 #include "output.h"
38 #include "timevar.h"
39 #include "tree-pass.h"
40 #include "sched-int.h" 35 #include "sched-int.h"
41 #include "ggc.h"
42 #include "tree.h"
43 #include "vec.h"
44 #include "langhooks.h"
45 #include "rtlhooks-def.h" 36 #include "rtlhooks-def.h"
46 #include "output.h" 37 #include "ira.h"
47 #include "emit-rtl.h" 38 #include "ira-int.h"
39 #include "rtl-iter.h"
48 40
49 #ifdef INSN_SCHEDULING 41 #ifdef INSN_SCHEDULING
42 #include "regset.h"
43 #include "cfgloop.h"
50 #include "sel-sched-ir.h" 44 #include "sel-sched-ir.h"
51 #include "sel-sched-dump.h" 45 #include "sel-sched-dump.h"
52 #include "sel-sched.h" 46 #include "sel-sched.h"
53 #include "dbgcnt.h" 47 #include "dbgcnt.h"
54 48
283 struct rtx_search_arg 277 struct rtx_search_arg
284 { 278 {
285 /* What we are searching for. */ 279 /* What we are searching for. */
286 rtx x; 280 rtx x;
287 281
288 /* The occurence counter. */ 282 /* The occurrence counter. */
289 int n; 283 int n;
290 }; 284 };
291 285
292 typedef struct rtx_search_arg *rtx_search_arg_p; 286 typedef struct rtx_search_arg *rtx_search_arg_p;
293 287
377 371
378 /* An UID of expr_vliw which is to be moved up. If we find other exprs, 372 /* An UID of expr_vliw which is to be moved up. If we find other exprs,
379 they are to be removed. */ 373 they are to be removed. */
380 int uid; 374 int uid;
381 375
382 #ifdef ENABLE_CHECKING
383 /* This is initialized to the insn on which the driver stopped its traversal. */ 376 /* This is initialized to the insn on which the driver stopped its traversal. */
384 insn_t failed_insn; 377 insn_t failed_insn;
385 #endif
386 378
387 /* True if we scheduled an insn with different register. */ 379 /* True if we scheduled an insn with different register. */
388 bool was_renamed; 380 bool was_renamed;
389 }; 381 };
390 382
403 395
404 typedef struct fur_static_params *fur_static_params_p; 396 typedef struct fur_static_params *fur_static_params_p;
405 typedef struct cmpd_local_params *cmpd_local_params_p; 397 typedef struct cmpd_local_params *cmpd_local_params_p;
406 typedef struct moveop_static_params *moveop_static_params_p; 398 typedef struct moveop_static_params *moveop_static_params_p;
407 399
408 /* Set of hooks and parameters that determine behaviour specific to 400 /* Set of hooks and parameters that determine behavior specific to
409 move_op or find_used_regs functions. */ 401 move_op or find_used_regs functions. */
410 struct code_motion_path_driver_info_def 402 struct code_motion_path_driver_info_def
411 { 403 {
412 /* Called on enter to the basic block. */ 404 /* Called on enter to the basic block. */
413 int (*on_enter) (insn_t, cmpd_local_params_p, void *, bool); 405 int (*on_enter) (insn_t, cmpd_local_params_p, void *, bool);
501 493
502 /* Number of insns scheduled in current region. */ 494 /* Number of insns scheduled in current region. */
503 static int num_insns_scheduled; 495 static int num_insns_scheduled;
504 496
505 /* A vector of expressions is used to be able to sort them. */ 497 /* A vector of expressions is used to be able to sort them. */
506 DEF_VEC_P(expr_t); 498 static vec<expr_t> vec_av_set;
507 DEF_VEC_ALLOC_P(expr_t,heap);
508 static VEC(expr_t, heap) *vec_av_set = NULL;
509 499
510 /* A vector of vinsns is used to hold temporary lists of vinsns. */ 500 /* A vector of vinsns is used to hold temporary lists of vinsns. */
511 DEF_VEC_P(vinsn_t); 501 typedef vec<vinsn_t> vinsn_vec_t;
512 DEF_VEC_ALLOC_P(vinsn_t,heap);
513 typedef VEC(vinsn_t, heap) *vinsn_vec_t;
514 502
515 /* This vector has the exprs which may still present in av_sets, but actually 503 /* This vector has the exprs which may still present in av_sets, but actually
516 can't be moved up due to bookkeeping created during code motion to another 504 can't be moved up due to bookkeeping created during code motion to another
517 fence. See comment near the call to update_and_record_unavailable_insns 505 fence. See comment near the call to update_and_record_unavailable_insns
518 for the detailed explanations. */ 506 for the detailed explanations. */
519 static vinsn_vec_t vec_bookkeeping_blocked_vinsns = NULL; 507 static vinsn_vec_t vec_bookkeeping_blocked_vinsns = vinsn_vec_t ();
520 508
521 /* This vector has vinsns which are scheduled with renaming on the first fence 509 /* This vector has vinsns which are scheduled with renaming on the first fence
522 and then seen on the second. For expressions with such vinsns, target 510 and then seen on the second. For expressions with such vinsns, target
523 availability information may be wrong. */ 511 availability information may be wrong. */
524 static vinsn_vec_t vec_target_unavailable_vinsns = NULL; 512 static vinsn_vec_t vec_target_unavailable_vinsns = vinsn_vec_t ();
525 513
526 /* Vector to store temporary nops inserted in move_op to prevent removal 514 /* Vector to store temporary nops inserted in move_op to prevent removal
527 of empty bbs. */ 515 of empty bbs. */
528 DEF_VEC_P(insn_t); 516 static vec<insn_t> vec_temp_moveop_nops;
529 DEF_VEC_ALLOC_P(insn_t,heap);
530 static VEC(insn_t, heap) *vec_temp_moveop_nops = NULL;
531 517
532 /* These bitmaps record original instructions scheduled on the current 518 /* These bitmaps record original instructions scheduled on the current
533 iteration and bookkeeping copies created by them. */ 519 iteration and bookkeeping copies created by them. */
534 static bitmap current_originators = NULL; 520 static bitmap current_originators = NULL;
535 static bitmap current_copies = NULL; 521 static bitmap current_copies = NULL;
579 static void 565 static void
580 advance_one_cycle (fence_t fence) 566 advance_one_cycle (fence_t fence)
581 { 567 {
582 unsigned i; 568 unsigned i;
583 int cycle; 569 int cycle;
584 rtx insn; 570 rtx_insn *insn;
585 571
586 advance_state (FENCE_STATE (fence)); 572 advance_state (FENCE_STATE (fence));
587 cycle = ++FENCE_CYCLE (fence); 573 cycle = ++FENCE_CYCLE (fence);
588 FENCE_ISSUED_INSNS (fence) = 0; 574 FENCE_ISSUED_INSNS (fence) = 0;
589 FENCE_STARTS_CYCLE_P (fence) = 1; 575 FENCE_STARTS_CYCLE_P (fence) = 1;
590 can_issue_more = issue_rate; 576 can_issue_more = issue_rate;
591 FENCE_ISSUE_MORE (fence) = can_issue_more; 577 FENCE_ISSUE_MORE (fence) = can_issue_more;
592 578
593 for (i = 0; VEC_iterate (rtx, FENCE_EXECUTING_INSNS (fence), i, insn); ) 579 for (i = 0; vec_safe_iterate (FENCE_EXECUTING_INSNS (fence), i, &insn); )
594 { 580 {
595 if (INSN_READY_CYCLE (insn) < cycle) 581 if (INSN_READY_CYCLE (insn) < cycle)
596 { 582 {
597 remove_from_deps (FENCE_DC (fence), insn); 583 remove_from_deps (FENCE_DC (fence), insn);
598 VEC_unordered_remove (rtx, FENCE_EXECUTING_INSNS (fence), i); 584 FENCE_EXECUTING_INSNS (fence)->unordered_remove (i);
599 continue; 585 continue;
600 } 586 }
601 i++; 587 i++;
602 } 588 }
603 if (sched_verbose >= 2) 589 if (sched_verbose >= 2)
608 } 594 }
609 595
610 /* Returns true when SUCC in a fallthru bb of INSN, possibly 596 /* Returns true when SUCC in a fallthru bb of INSN, possibly
611 skipping empty basic blocks. */ 597 skipping empty basic blocks. */
612 static bool 598 static bool
613 in_fallthru_bb_p (rtx insn, rtx succ) 599 in_fallthru_bb_p (rtx_insn *insn, rtx succ)
614 { 600 {
615 basic_block bb = BLOCK_FOR_INSN (insn); 601 basic_block bb = BLOCK_FOR_INSN (insn);
616 edge e; 602 edge e;
617 603
618 if (bb == BLOCK_FOR_INSN (succ)) 604 if (bb == BLOCK_FOR_INSN (succ))
637 static void 623 static void
638 extract_new_fences_from (flist_t old_fences, flist_tail_t new_fences, 624 extract_new_fences_from (flist_t old_fences, flist_tail_t new_fences,
639 int orig_max_seqno) 625 int orig_max_seqno)
640 { 626 {
641 bool was_here_p = false; 627 bool was_here_p = false;
642 insn_t insn = NULL_RTX; 628 insn_t insn = NULL;
643 insn_t succ; 629 insn_t succ;
644 succ_iterator si; 630 succ_iterator si;
645 ilist_iterator ii; 631 ilist_iterator ii;
646 fence_t fence = FLIST_FENCE (old_fences); 632 fence_t fence = FLIST_FENCE (old_fences);
647 basic_block bb; 633 basic_block bb;
731 && REG_P (INSN_RHS (insn))) 717 && REG_P (INSN_RHS (insn)))
732 return true; 718 return true;
733 return false; 719 return false;
734 } 720 }
735 721
736 /* Substitute all occurences of INSN's destination in EXPR' vinsn with INSN's 722 /* Substitute all occurrences of INSN's destination in EXPR' vinsn with INSN's
737 source (if INSN is eligible for substitution). Returns TRUE if 723 source (if INSN is eligible for substitution). Returns TRUE if
738 substitution was actually performed, FALSE otherwise. Substitution might 724 substitution was actually performed, FALSE otherwise. Substitution might
739 be not performed because it's either EXPR' vinsn doesn't contain INSN's 725 be not performed because it's either EXPR' vinsn doesn't contain INSN's
740 destination or the resulting insn is invalid for the target machine. 726 destination or the resulting insn is invalid for the target machine.
741 When UNDO is true, perform unsubstitution instead (the difference is in 727 When UNDO is true, perform unsubstitution instead (the difference is in
760 old = undo ? INSN_RHS (insn) : INSN_LHS (insn); 746 old = undo ? INSN_RHS (insn) : INSN_LHS (insn);
761 747
762 /* Substitute if INSN has a form of x:=y and LHS(INSN) occurs in *VI. */ 748 /* Substitute if INSN has a form of x:=y and LHS(INSN) occurs in *VI. */
763 if (rtx_ok_for_substitution_p (old, *where)) 749 if (rtx_ok_for_substitution_p (old, *where))
764 { 750 {
765 rtx new_insn; 751 rtx_insn *new_insn;
766 rtx *where_replace; 752 rtx *where_replace;
767 753
768 /* We should copy these rtxes before substitution. */ 754 /* We should copy these rtxes before substitution. */
769 new_rtx = copy_rtx (undo ? INSN_LHS (insn) : INSN_RHS (insn)); 755 new_rtx = copy_rtx (undo ? INSN_LHS (insn) : INSN_RHS (insn));
770 new_insn = create_copy_of_insn_rtx (VINSN_INSN_RTX (*vi)); 756 new_insn = create_copy_of_insn_rtx (VINSN_INSN_RTX (*vi));
792 create_vinsn_from_insn_rtx (new_insn, false)); 778 create_vinsn_from_insn_rtx (new_insn, false));
793 779
794 /* Do not allow clobbering the address register of speculative 780 /* Do not allow clobbering the address register of speculative
795 insns. */ 781 insns. */
796 if ((EXPR_SPEC_DONE_DS (expr) & SPECULATIVE) 782 if ((EXPR_SPEC_DONE_DS (expr) & SPECULATIVE)
797 && bitmap_bit_p (VINSN_REG_USES (EXPR_VINSN (expr)), 783 && register_unavailable_p (VINSN_REG_USES (EXPR_VINSN (expr)),
798 expr_dest_regno (expr))) 784 expr_dest_reg (expr)))
799 EXPR_TARGET_AVAILABLE (expr) = false; 785 EXPR_TARGET_AVAILABLE (expr) = false;
800 786
801 return true; 787 return true;
802 } 788 }
803 else 789 else
805 } 791 }
806 else 792 else
807 return false; 793 return false;
808 } 794 }
809 795
810 /* Helper function for count_occurences_equiv. */
811 static int
812 count_occurrences_1 (rtx *cur_rtx, void *arg)
813 {
814 rtx_search_arg_p p = (rtx_search_arg_p) arg;
815
816 /* The last param FOR_GCSE is true, because otherwise it performs excessive
817 substitutions like
818 r8 = r33
819 r16 = r33
820 for the last insn it presumes r33 equivalent to r8, so it changes it to
821 r33. Actually, there's no change, but it spoils debugging. */
822 if (exp_equiv_p (*cur_rtx, p->x, 0, true))
823 {
824 /* Bail out if we occupy more than one register. */
825 if (REG_P (*cur_rtx)
826 && HARD_REGISTER_P (*cur_rtx)
827 && hard_regno_nregs[REGNO(*cur_rtx)][GET_MODE (*cur_rtx)] > 1)
828 {
829 p->n = 0;
830 return 1;
831 }
832
833 p->n++;
834
835 /* Do not traverse subexprs. */
836 return -1;
837 }
838
839 if (GET_CODE (*cur_rtx) == SUBREG
840 && REG_P (p->x)
841 && (!REG_P (SUBREG_REG (*cur_rtx))
842 || REGNO (SUBREG_REG (*cur_rtx)) == REGNO (p->x)))
843 {
844 /* ??? Do not support substituting regs inside subregs. In that case,
845 simplify_subreg will be called by validate_replace_rtx, and
846 unsubstitution will fail later. */
847 p->n = 0;
848 return 1;
849 }
850
851 /* Continue search. */
852 return 0;
853 }
854
855 /* Return the number of places WHAT appears within WHERE. 796 /* Return the number of places WHAT appears within WHERE.
856 Bail out when we found a reference occupying several hard registers. */ 797 Bail out when we found a reference occupying several hard registers. */
857 static int 798 static int
858 count_occurrences_equiv (rtx what, rtx where) 799 count_occurrences_equiv (const_rtx what, const_rtx where)
859 { 800 {
860 struct rtx_search_arg arg; 801 int count = 0;
861 802 subrtx_iterator::array_type array;
862 arg.x = what; 803 FOR_EACH_SUBRTX (iter, array, where, NONCONST)
863 arg.n = 0; 804 {
864 805 const_rtx x = *iter;
865 for_each_rtx (&where, &count_occurrences_1, (void *) &arg); 806 if (REG_P (x) && REGNO (x) == REGNO (what))
866 807 {
867 return arg.n; 808 /* Bail out if mode is different or more than one register is
809 used. */
810 if (GET_MODE (x) != GET_MODE (what) || REG_NREGS (x) > 1)
811 return 0;
812 count += 1;
813 }
814 else if (GET_CODE (x) == SUBREG
815 && (!REG_P (SUBREG_REG (x))
816 || REGNO (SUBREG_REG (x)) == REGNO (what)))
817 /* ??? Do not support substituting regs inside subregs. In that case,
818 simplify_subreg will be called by validate_replace_rtx, and
819 unsubstitution will fail later. */
820 return 0;
821 }
822 return count;
868 } 823 }
869 824
870 /* Returns TRUE if WHAT is found in WHERE rtx tree. */ 825 /* Returns TRUE if WHAT is found in WHERE rtx tree. */
871 static bool 826 static bool
872 rtx_ok_for_substitution_p (rtx what, rtx where) 827 rtx_ok_for_substitution_p (rtx what, rtx where)
877 832
878 /* Functions to support register renaming. */ 833 /* Functions to support register renaming. */
879 834
880 /* Substitute VI's set source with REGNO. Returns newly created pattern 835 /* Substitute VI's set source with REGNO. Returns newly created pattern
881 that has REGNO as its source. */ 836 that has REGNO as its source. */
882 static rtx 837 static rtx_insn *
883 create_insn_rtx_with_rhs (vinsn_t vi, rtx rhs_rtx) 838 create_insn_rtx_with_rhs (vinsn_t vi, rtx rhs_rtx)
884 { 839 {
885 rtx lhs_rtx; 840 rtx lhs_rtx;
886 rtx pattern; 841 rtx pattern;
887 rtx insn_rtx; 842 rtx_insn *insn_rtx;
888 843
889 lhs_rtx = copy_rtx (VINSN_LHS (vi)); 844 lhs_rtx = copy_rtx (VINSN_LHS (vi));
890 845
891 pattern = gen_rtx_SET (VOIDmode, lhs_rtx, rhs_rtx); 846 pattern = gen_rtx_SET (lhs_rtx, rhs_rtx);
892 insn_rtx = create_insn_rtx_from_pattern (pattern, NULL_RTX); 847 insn_rtx = create_insn_rtx_from_pattern (pattern, NULL_RTX);
893 848
894 return insn_rtx; 849 return insn_rtx;
895 } 850 }
896 851
917 872
918 static bool 873 static bool
919 replace_src_with_reg_ok_p (insn_t insn, rtx new_src_reg) 874 replace_src_with_reg_ok_p (insn_t insn, rtx new_src_reg)
920 { 875 {
921 vinsn_t vi = INSN_VINSN (insn); 876 vinsn_t vi = INSN_VINSN (insn);
922 enum machine_mode mode; 877 machine_mode mode;
923 rtx dst_loc; 878 rtx dst_loc;
924 bool res; 879 bool res;
925 880
926 gcc_assert (VINSN_SEPARABLE_P (vi)); 881 gcc_assert (VINSN_SEPARABLE_P (vi));
927 882
958 913
959 return res; 914 return res;
960 } 915 }
961 916
962 /* Create a pattern with rhs of VI and lhs of LHS_RTX. */ 917 /* Create a pattern with rhs of VI and lhs of LHS_RTX. */
963 static rtx 918 static rtx_insn *
964 create_insn_rtx_with_lhs (vinsn_t vi, rtx lhs_rtx) 919 create_insn_rtx_with_lhs (vinsn_t vi, rtx lhs_rtx)
965 { 920 {
966 rtx rhs_rtx; 921 rtx rhs_rtx;
967 rtx pattern; 922 rtx pattern;
968 rtx insn_rtx; 923 rtx_insn *insn_rtx;
969 924
970 rhs_rtx = copy_rtx (VINSN_RHS (vi)); 925 rhs_rtx = copy_rtx (VINSN_RHS (vi));
971 926
972 pattern = gen_rtx_SET (VOIDmode, lhs_rtx, rhs_rtx); 927 pattern = gen_rtx_SET (lhs_rtx, rhs_rtx);
973 insn_rtx = create_insn_rtx_from_pattern (pattern, NULL_RTX); 928 insn_rtx = create_insn_rtx_from_pattern (pattern, NULL_RTX);
974 929
975 return insn_rtx; 930 return insn_rtx;
976 } 931 }
977 932
978 /* Substitute lhs in the given expression EXPR for the register with number 933 /* Substitute lhs in the given expression EXPR for the register with number
979 NEW_REGNO. SET_DEST may be arbitrary rtx, not only register. */ 934 NEW_REGNO. SET_DEST may be arbitrary rtx, not only register. */
980 static void 935 static void
981 replace_dest_with_reg_in_expr (expr_t expr, rtx new_reg) 936 replace_dest_with_reg_in_expr (expr_t expr, rtx new_reg)
982 { 937 {
983 rtx insn_rtx; 938 rtx_insn *insn_rtx;
984 vinsn_t vinsn; 939 vinsn_t vinsn;
985 940
986 insn_rtx = create_insn_rtx_with_lhs (EXPR_VINSN (expr), new_reg); 941 insn_rtx = create_insn_rtx_with_lhs (EXPR_VINSN (expr), new_reg);
987 vinsn = create_vinsn_from_insn_rtx (insn_rtx, false); 942 vinsn = create_vinsn_from_insn_rtx (insn_rtx, false);
988 943
1025 Returns NO_REGS for call insns because some targets have constraints on 980 Returns NO_REGS for call insns because some targets have constraints on
1026 destination register of a call insn. 981 destination register of a call insn.
1027 982
1028 Code adopted from regrename.c::build_def_use. */ 983 Code adopted from regrename.c::build_def_use. */
1029 static enum reg_class 984 static enum reg_class
1030 get_reg_class (rtx insn) 985 get_reg_class (rtx_insn *insn)
1031 { 986 {
1032 int alt, i, n_ops; 987 int i, n_ops;
1033 988
1034 extract_insn (insn); 989 extract_constrain_insn (insn);
1035 if (! constrain_operands (1)) 990 preprocess_constraints (insn);
1036 fatal_insn_not_found (insn);
1037 preprocess_constraints ();
1038 alt = which_alternative;
1039 n_ops = recog_data.n_operands; 991 n_ops = recog_data.n_operands;
1040 992
1041 for (i = 0; i < n_ops; ++i) 993 const operand_alternative *op_alt = which_op_alt ();
1042 {
1043 int matches = recog_op_alt[i][alt].matches;
1044 if (matches >= 0)
1045 recog_op_alt[i][alt].cl = recog_op_alt[matches][alt].cl;
1046 }
1047
1048 if (asm_noperands (PATTERN (insn)) > 0) 994 if (asm_noperands (PATTERN (insn)) > 0)
1049 { 995 {
1050 for (i = 0; i < n_ops; i++) 996 for (i = 0; i < n_ops; i++)
1051 if (recog_data.operand_type[i] == OP_OUT) 997 if (recog_data.operand_type[i] == OP_OUT)
1052 { 998 {
1053 rtx *loc = recog_data.operand_loc[i]; 999 rtx *loc = recog_data.operand_loc[i];
1054 rtx op = *loc; 1000 rtx op = *loc;
1055 enum reg_class cl = recog_op_alt[i][alt].cl; 1001 enum reg_class cl = alternative_class (op_alt, i);
1056 1002
1057 if (REG_P (op) 1003 if (REG_P (op)
1058 && REGNO (op) == ORIGINAL_REGNO (op)) 1004 && REGNO (op) == ORIGINAL_REGNO (op))
1059 continue; 1005 continue;
1060 1006
1064 else if (!CALL_P (insn)) 1010 else if (!CALL_P (insn))
1065 { 1011 {
1066 for (i = 0; i < n_ops + recog_data.n_dups; i++) 1012 for (i = 0; i < n_ops + recog_data.n_dups; i++)
1067 { 1013 {
1068 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops]; 1014 int opn = i < n_ops ? i : recog_data.dup_num[i - n_ops];
1069 enum reg_class cl = recog_op_alt[opn][alt].cl; 1015 enum reg_class cl = alternative_class (op_alt, opn);
1070 1016
1071 if (recog_data.operand_type[opn] == OP_OUT || 1017 if (recog_data.operand_type[opn] == OP_OUT ||
1072 recog_data.operand_type[opn] == OP_INOUT) 1018 recog_data.operand_type[opn] == OP_INOUT)
1073 return cl; 1019 return cl;
1074 } 1020 }
1079 may result in returning NO_REGS, cause flags is written implicitly through 1025 may result in returning NO_REGS, cause flags is written implicitly through
1080 CMP insn, which has no OP_OUT | OP_INOUT operands. */ 1026 CMP insn, which has no OP_OUT | OP_INOUT operands. */
1081 return NO_REGS; 1027 return NO_REGS;
1082 } 1028 }
1083 1029
1084 #ifdef HARD_REGNO_RENAME_OK
1085 /* Calculate HARD_REGNO_RENAME_OK data for REGNO. */ 1030 /* Calculate HARD_REGNO_RENAME_OK data for REGNO. */
1086 static void 1031 static void
1087 init_hard_regno_rename (int regno) 1032 init_hard_regno_rename (int regno)
1088 { 1033 {
1089 int cur_reg; 1034 int cur_reg;
1098 1043
1099 if (HARD_REGNO_RENAME_OK (regno, cur_reg)) 1044 if (HARD_REGNO_RENAME_OK (regno, cur_reg))
1100 SET_HARD_REG_BIT (sel_hrd.regs_for_rename[regno], cur_reg); 1045 SET_HARD_REG_BIT (sel_hrd.regs_for_rename[regno], cur_reg);
1101 } 1046 }
1102 } 1047 }
1103 #endif
1104 1048
1105 /* A wrapper around HARD_REGNO_RENAME_OK that will look into the hard regs 1049 /* A wrapper around HARD_REGNO_RENAME_OK that will look into the hard regs
1106 data first. */ 1050 data first. */
1107 static inline bool 1051 static inline bool
1108 sel_hard_regno_rename_ok (int from ATTRIBUTE_UNUSED, int to ATTRIBUTE_UNUSED) 1052 sel_hard_regno_rename_ok (int from ATTRIBUTE_UNUSED, int to ATTRIBUTE_UNUSED)
1109 { 1053 {
1110 #ifdef HARD_REGNO_RENAME_OK
1111 /* Check whether this is all calculated. */ 1054 /* Check whether this is all calculated. */
1112 if (TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], from)) 1055 if (TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], from))
1113 return TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], to); 1056 return TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], to);
1114 1057
1115 init_hard_regno_rename (from); 1058 init_hard_regno_rename (from);
1116 1059
1117 return TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], to); 1060 return TEST_HARD_REG_BIT (sel_hrd.regs_for_rename[from], to);
1118 #else
1119 return true;
1120 #endif
1121 } 1061 }
1122 1062
1123 /* Calculate set of registers that are capable of holding MODE. */ 1063 /* Calculate set of registers that are capable of holding MODE. */
1124 static void 1064 static void
1125 init_regs_for_mode (enum machine_mode mode) 1065 init_regs_for_mode (machine_mode mode)
1126 { 1066 {
1127 int cur_reg; 1067 int cur_reg;
1128 1068
1129 CLEAR_HARD_REG_SET (sel_hrd.regs_for_mode[mode]); 1069 CLEAR_HARD_REG_SET (sel_hrd.regs_for_mode[mode]);
1130 CLEAR_HARD_REG_SET (sel_hrd.regs_for_call_clobbered[mode]); 1070 CLEAR_HARD_REG_SET (sel_hrd.regs_for_call_clobbered[mode]);
1131 1071
1132 for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++) 1072 for (cur_reg = 0; cur_reg < FIRST_PSEUDO_REGISTER; cur_reg++)
1133 { 1073 {
1134 int nregs = hard_regno_nregs[cur_reg][mode]; 1074 int nregs;
1135 int i; 1075 int i;
1076
1077 /* See whether it accepts all modes that occur in
1078 original insns. */
1079 if (!targetm.hard_regno_mode_ok (cur_reg, mode))
1080 continue;
1081
1082 nregs = hard_regno_nregs (cur_reg, mode);
1136 1083
1137 for (i = nregs - 1; i >= 0; --i) 1084 for (i = nregs - 1; i >= 0; --i)
1138 if (fixed_regs[cur_reg + i] 1085 if (fixed_regs[cur_reg + i]
1139 || global_regs[cur_reg + i] 1086 || global_regs[cur_reg + i]
1140 /* Can't use regs which aren't saved by 1087 /* Can't use regs which aren't saved by
1144 it affects aliasing globally and invalidates all AV sets. */ 1091 it affects aliasing globally and invalidates all AV sets. */
1145 || get_reg_base_value (cur_reg + i) 1092 || get_reg_base_value (cur_reg + i)
1146 #ifdef LEAF_REGISTERS 1093 #ifdef LEAF_REGISTERS
1147 /* We can't use a non-leaf register if we're in a 1094 /* We can't use a non-leaf register if we're in a
1148 leaf function. */ 1095 leaf function. */
1149 || (current_function_is_leaf 1096 || (crtl->is_leaf
1150 && !LEAF_REGISTERS[cur_reg + i]) 1097 && !LEAF_REGISTERS[cur_reg + i])
1151 #endif 1098 #endif
1152 ) 1099 )
1153 break; 1100 break;
1154 1101
1155 if (i >= 0) 1102 if (i >= 0)
1156 continue; 1103 continue;
1157 1104
1158 /* See whether it accepts all modes that occur in 1105 if (targetm.hard_regno_call_part_clobbered (cur_reg, mode))
1159 original insns. */
1160 if (! HARD_REGNO_MODE_OK (cur_reg, mode))
1161 continue;
1162
1163 if (HARD_REGNO_CALL_PART_CLOBBERED (cur_reg, mode))
1164 SET_HARD_REG_BIT (sel_hrd.regs_for_call_clobbered[mode], 1106 SET_HARD_REG_BIT (sel_hrd.regs_for_call_clobbered[mode],
1165 cur_reg); 1107 cur_reg);
1166 1108
1167 /* If the CUR_REG passed all the checks above, 1109 /* If the CUR_REG passed all the checks above,
1168 then it's ok. */ 1110 then it's ok. */
1211 1153
1212 static void 1154 static void
1213 mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p, 1155 mark_unavailable_hard_regs (def_t def, struct reg_rename *reg_rename_p,
1214 regset used_regs ATTRIBUTE_UNUSED) 1156 regset used_regs ATTRIBUTE_UNUSED)
1215 { 1157 {
1216 enum machine_mode mode; 1158 machine_mode mode;
1217 enum reg_class cl = NO_REGS; 1159 enum reg_class cl = NO_REGS;
1218 rtx orig_dest; 1160 rtx orig_dest;
1219 unsigned cur_reg, regno; 1161 unsigned cur_reg, regno;
1220 hard_reg_set_iterator hrsi; 1162 hard_reg_set_iterator hrsi;
1221 1163
1240 1182
1241 /* Stop if the original register is one of the fixed_regs, global_regs or 1183 /* Stop if the original register is one of the fixed_regs, global_regs or
1242 frame pointer, or we could not discover its class. */ 1184 frame pointer, or we could not discover its class. */
1243 if (fixed_regs[regno] 1185 if (fixed_regs[regno]
1244 || global_regs[regno] 1186 || global_regs[regno]
1245 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER 1187 || (!HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
1246 || (frame_pointer_needed && regno == HARD_FRAME_POINTER_REGNUM) 1188 && regno == HARD_FRAME_POINTER_REGNUM)
1247 #else 1189 || (HARD_FRAME_POINTER_IS_FRAME_POINTER && frame_pointer_needed
1248 || (frame_pointer_needed && regno == FRAME_POINTER_REGNUM) 1190 && regno == FRAME_POINTER_REGNUM)
1249 #endif
1250 || (reload_completed && cl == NO_REGS)) 1191 || (reload_completed && cl == NO_REGS))
1251 { 1192 {
1252 SET_HARD_REG_SET (reg_rename_p->unavailable_hard_regs); 1193 SET_HARD_REG_SET (reg_rename_p->unavailable_hard_regs);
1253 1194
1254 /* Give a chance for original register, if it isn't in used_regs. */ 1195 /* Give a chance for original register, if it isn't in used_regs. */
1261 /* If something allocated on stack in this function, mark frame pointer 1202 /* If something allocated on stack in this function, mark frame pointer
1262 register unavailable, considering also modes. 1203 register unavailable, considering also modes.
1263 FIXME: it is enough to do this once per all original defs. */ 1204 FIXME: it is enough to do this once per all original defs. */
1264 if (frame_pointer_needed) 1205 if (frame_pointer_needed)
1265 { 1206 {
1266 int i; 1207 add_to_hard_reg_set (&reg_rename_p->unavailable_hard_regs,
1267 1208 Pmode, FRAME_POINTER_REGNUM);
1268 for (i = hard_regno_nregs[FRAME_POINTER_REGNUM][Pmode]; i--;) 1209
1269 SET_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, 1210 if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
1270 FRAME_POINTER_REGNUM + i); 1211 add_to_hard_reg_set (&reg_rename_p->unavailable_hard_regs,
1271 1212 Pmode, HARD_FRAME_POINTER_REGNUM);
1272 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
1273 for (i = hard_regno_nregs[HARD_FRAME_POINTER_REGNUM][Pmode]; i--;)
1274 SET_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs,
1275 HARD_FRAME_POINTER_REGNUM + i);
1276 #endif
1277 } 1213 }
1278 1214
1279 #ifdef STACK_REGS 1215 #ifdef STACK_REGS
1280 /* For the stack registers the presence of FIRST_STACK_REG in USED_REGS 1216 /* For the stack registers the presence of FIRST_STACK_REG in USED_REGS
1281 is equivalent to as if all stack regs were in this set. 1217 is equivalent to as if all stack regs were in this set.
1313 AND_HARD_REG_SET (reg_rename_p->available_for_renaming, 1249 AND_HARD_REG_SET (reg_rename_p->available_for_renaming,
1314 sel_hrd.regs_for_mode[mode]); 1250 sel_hrd.regs_for_mode[mode]);
1315 1251
1316 /* Exclude registers that are partially call clobbered. */ 1252 /* Exclude registers that are partially call clobbered. */
1317 if (def->crosses_call 1253 if (def->crosses_call
1318 && ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) 1254 && !targetm.hard_regno_call_part_clobbered (regno, mode))
1319 AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming, 1255 AND_COMPL_HARD_REG_SET (reg_rename_p->available_for_renaming,
1320 sel_hrd.regs_for_call_clobbered[mode]); 1256 sel_hrd.regs_for_call_clobbered[mode]);
1321 1257
1322 /* Leave only those that are ok to rename. */ 1258 /* Leave only those that are ok to rename. */
1323 EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming, 1259 EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming,
1324 0, cur_reg, hrsi) 1260 0, cur_reg, hrsi)
1325 { 1261 {
1326 int nregs; 1262 int nregs;
1327 int i; 1263 int i;
1328 1264
1329 nregs = hard_regno_nregs[cur_reg][mode]; 1265 nregs = hard_regno_nregs (cur_reg, mode);
1330 gcc_assert (nregs > 0); 1266 gcc_assert (nregs > 0);
1331 1267
1332 for (i = nregs - 1; i >= 0; --i) 1268 for (i = nregs - 1; i >= 0; --i)
1333 if (! sel_hard_regno_rename_ok (regno + i, cur_reg + i)) 1269 if (! sel_hard_regno_rename_ok (regno + i, cur_reg + i))
1334 break; 1270 break;
1386 struct reg_rename *reg_rename_p, 1322 struct reg_rename *reg_rename_p,
1387 def_list_t original_insns, bool *is_orig_reg_p_ptr) 1323 def_list_t original_insns, bool *is_orig_reg_p_ptr)
1388 { 1324 {
1389 int best_new_reg; 1325 int best_new_reg;
1390 unsigned cur_reg; 1326 unsigned cur_reg;
1391 enum machine_mode mode = VOIDmode; 1327 machine_mode mode = VOIDmode;
1392 unsigned regno, i, n; 1328 unsigned regno, i, n;
1393 hard_reg_set_iterator hrsi; 1329 hard_reg_set_iterator hrsi;
1394 def_list_iterator di; 1330 def_list_iterator di;
1395 def_t def; 1331 def_t def;
1396 1332
1410 if (mode == VOIDmode) 1346 if (mode == VOIDmode)
1411 mode = GET_MODE (orig_dest); 1347 mode = GET_MODE (orig_dest);
1412 gcc_assert (mode == GET_MODE (orig_dest)); 1348 gcc_assert (mode == GET_MODE (orig_dest));
1413 1349
1414 regno = REGNO (orig_dest); 1350 regno = REGNO (orig_dest);
1415 for (i = 0, n = hard_regno_nregs[regno][mode]; i < n; i++) 1351 for (i = 0, n = REG_NREGS (orig_dest); i < n; i++)
1416 if (TEST_HARD_REG_BIT (hard_regs_used, regno + i)) 1352 if (TEST_HARD_REG_BIT (hard_regs_used, regno + i))
1417 break; 1353 break;
1418 1354
1419 /* All hard registers are available. */ 1355 /* All hard registers are available. */
1420 if (i == n) 1356 if (i == n)
1434 EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming, 1370 EXECUTE_IF_SET_IN_HARD_REG_SET (reg_rename_p->available_for_renaming,
1435 0, cur_reg, hrsi) 1371 0, cur_reg, hrsi)
1436 if (! TEST_HARD_REG_BIT (hard_regs_used, cur_reg)) 1372 if (! TEST_HARD_REG_BIT (hard_regs_used, cur_reg))
1437 { 1373 {
1438 /* Check that all hard regs for mode are available. */ 1374 /* Check that all hard regs for mode are available. */
1439 for (i = 1, n = hard_regno_nregs[cur_reg][mode]; i < n; i++) 1375 for (i = 1, n = hard_regno_nregs (cur_reg, mode); i < n; i++)
1440 if (TEST_HARD_REG_BIT (hard_regs_used, cur_reg + i) 1376 if (TEST_HARD_REG_BIT (hard_regs_used, cur_reg + i)
1441 || !TEST_HARD_REG_BIT (reg_rename_p->available_for_renaming, 1377 || !TEST_HARD_REG_BIT (reg_rename_p->available_for_renaming,
1442 cur_reg + i)) 1378 cur_reg + i))
1443 break; 1379 break;
1444 1380
1497 struct reg_rename *reg_rename_p, 1433 struct reg_rename *reg_rename_p,
1498 def_list_t original_insns, bool *is_orig_reg_p_ptr) 1434 def_list_t original_insns, bool *is_orig_reg_p_ptr)
1499 { 1435 {
1500 def_list_iterator i; 1436 def_list_iterator i;
1501 def_t def; 1437 def_t def;
1502 enum machine_mode mode = VOIDmode; 1438 machine_mode mode = VOIDmode;
1503 bool bad_hard_regs = false; 1439 bool bad_hard_regs = false;
1504 1440
1505 /* We should not use this after reload. */ 1441 /* We should not use this after reload. */
1506 gcc_assert (!reload_completed); 1442 gcc_assert (!reload_completed);
1507 1443
1520 mode = GET_MODE (dest); 1456 mode = GET_MODE (dest);
1521 else 1457 else
1522 gcc_assert (mode == GET_MODE (dest)); 1458 gcc_assert (mode == GET_MODE (dest));
1523 orig_regno = REGNO (dest); 1459 orig_regno = REGNO (dest);
1524 1460
1525 if (!REGNO_REG_SET_P (used_regs, orig_regno)) 1461 /* Check that nothing in used_regs intersects with orig_regno. When
1526 { 1462 we have a hard reg here, still loop over hard_regno_nregs. */
1527 if (orig_regno < FIRST_PSEUDO_REGISTER) 1463 if (HARD_REGISTER_NUM_P (orig_regno))
1528 { 1464 {
1529 gcc_assert (df_regs_ever_live_p (orig_regno)); 1465 int j, n;
1530 1466 for (j = 0, n = REG_NREGS (dest); j < n; j++)
1531 /* For hard registers, we have to check hardware imposed 1467 if (REGNO_REG_SET_P (used_regs, orig_regno + j))
1532 limitations (frame/stack registers, calls crossed). */ 1468 break;
1533 if (!TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs, 1469 if (j < n)
1534 orig_regno)) 1470 continue;
1535 { 1471 }
1536 /* Don't let register cross a call if it doesn't already 1472 else
1537 cross one. This condition is written in accordance with 1473 {
1538 that in sched-deps.c sched_analyze_reg(). */ 1474 if (REGNO_REG_SET_P (used_regs, orig_regno))
1539 if (!reg_rename_p->crosses_call 1475 continue;
1540 || REG_N_CALLS_CROSSED (orig_regno) > 0) 1476 }
1541 return gen_rtx_REG (mode, orig_regno); 1477 if (HARD_REGISTER_NUM_P (orig_regno))
1542 } 1478 {
1543 1479 gcc_assert (df_regs_ever_live_p (orig_regno));
1544 bad_hard_regs = true; 1480
1545 } 1481 /* For hard registers, we have to check hardware imposed
1546 else 1482 limitations (frame/stack registers, calls crossed). */
1547 return dest; 1483 if (!TEST_HARD_REG_BIT (reg_rename_p->unavailable_hard_regs,
1548 } 1484 orig_regno))
1549 } 1485 {
1486 /* Don't let register cross a call if it doesn't already
1487 cross one. This condition is written in accordance with
1488 that in sched-deps.c sched_analyze_reg(). */
1489 if (!reg_rename_p->crosses_call
1490 || REG_N_CALLS_CROSSED (orig_regno) > 0)
1491 return gen_rtx_REG (mode, orig_regno);
1492 }
1493
1494 bad_hard_regs = true;
1495 }
1496 else
1497 return dest;
1498 }
1550 1499
1551 *is_orig_reg_p_ptr = false; 1500 *is_orig_reg_p_ptr = false;
1552 1501
1553 /* We had some original hard registers that couldn't be used. 1502 /* We had some original hard registers that couldn't be used.
1554 Those were likely special. Don't try to create a pseudo. */ 1503 Those were likely special. Don't try to create a pseudo. */
1575 static void 1524 static void
1576 verify_target_availability (expr_t expr, regset used_regs, 1525 verify_target_availability (expr_t expr, regset used_regs,
1577 struct reg_rename *reg_rename_p) 1526 struct reg_rename *reg_rename_p)
1578 { 1527 {
1579 unsigned n, i, regno; 1528 unsigned n, i, regno;
1580 enum machine_mode mode; 1529 machine_mode mode;
1581 bool target_available, live_available, hard_available; 1530 bool target_available, live_available, hard_available;
1582 1531
1583 if (!REG_P (EXPR_LHS (expr)) || EXPR_TARGET_AVAILABLE (expr) < 0) 1532 if (!REG_P (EXPR_LHS (expr)) || EXPR_TARGET_AVAILABLE (expr) < 0)
1584 return; 1533 return;
1585 1534
1586 regno = expr_dest_regno (expr); 1535 regno = expr_dest_regno (expr);
1587 mode = GET_MODE (EXPR_LHS (expr)); 1536 mode = GET_MODE (EXPR_LHS (expr));
1588 target_available = EXPR_TARGET_AVAILABLE (expr) == 1; 1537 target_available = EXPR_TARGET_AVAILABLE (expr) == 1;
1589 n = reload_completed ? hard_regno_nregs[regno][mode] : 1; 1538 n = HARD_REGISTER_NUM_P (regno) ? hard_regno_nregs (regno, mode) : 1;
1590 1539
1591 live_available = hard_available = true; 1540 live_available = hard_available = true;
1592 for (i = 0; i < n; i++) 1541 for (i = 0; i < n; i++)
1593 { 1542 {
1594 if (bitmap_bit_p (used_regs, regno + i)) 1543 if (bitmap_bit_p (used_regs, regno + i))
1710 CLEAR_HARD_REG_SET (reg_rename_data.unavailable_hard_regs); 1659 CLEAR_HARD_REG_SET (reg_rename_data.unavailable_hard_regs);
1711 1660
1712 collect_unavailable_regs_from_bnds (expr, bnds, used_regs, &reg_rename_data, 1661 collect_unavailable_regs_from_bnds (expr, bnds, used_regs, &reg_rename_data,
1713 &original_insns); 1662 &original_insns);
1714 1663
1715 #ifdef ENABLE_CHECKING
1716 /* If after reload, make sure we're working with hard regs here. */ 1664 /* If after reload, make sure we're working with hard regs here. */
1717 if (reload_completed) 1665 if (flag_checking && reload_completed)
1718 { 1666 {
1719 reg_set_iterator rsi; 1667 reg_set_iterator rsi;
1720 unsigned i; 1668 unsigned i;
1721 1669
1722 EXECUTE_IF_SET_IN_REG_SET (used_regs, FIRST_PSEUDO_REGISTER, i, rsi) 1670 EXECUTE_IF_SET_IN_REG_SET (used_regs, FIRST_PSEUDO_REGISTER, i, rsi)
1723 gcc_unreachable (); 1671 gcc_unreachable ();
1724 } 1672 }
1725 #endif
1726 1673
1727 if (EXPR_SEPARABLE_P (expr)) 1674 if (EXPR_SEPARABLE_P (expr))
1728 { 1675 {
1729 rtx best_reg = NULL_RTX; 1676 rtx best_reg = NULL_RTX;
1730 /* Check that we have computed availability of a target register 1677 /* Check that we have computed availability of a target register
1825 ORIG_INSN is the original non-speculative insn in the stream. */ 1772 ORIG_INSN is the original non-speculative insn in the stream. */
1826 static insn_t 1773 static insn_t
1827 create_speculation_check (expr_t c_expr, ds_t check_ds, insn_t orig_insn) 1774 create_speculation_check (expr_t c_expr, ds_t check_ds, insn_t orig_insn)
1828 { 1775 {
1829 rtx check_pattern; 1776 rtx check_pattern;
1830 rtx insn_rtx; 1777 rtx_insn *insn_rtx;
1831 insn_t insn; 1778 insn_t insn;
1832 basic_block recovery_block; 1779 basic_block recovery_block;
1833 rtx label; 1780 rtx_insn *label;
1834 1781
1835 /* Create a recovery block if target is going to emit branchy check, or if 1782 /* Create a recovery block if target is going to emit branchy check, or if
1836 ORIG_INSN was speculative already. */ 1783 ORIG_INSN was speculative already. */
1837 if (targetm.sched.needs_block_p (check_ds) 1784 if (targetm.sched.needs_block_p (check_ds)
1838 || EXPR_SPEC_DONE_DS (INSN_EXPR (orig_insn)) != 0) 1785 || EXPR_SPEC_DONE_DS (INSN_EXPR (orig_insn)) != 0)
1841 label = BB_HEAD (recovery_block); 1788 label = BB_HEAD (recovery_block);
1842 } 1789 }
1843 else 1790 else
1844 { 1791 {
1845 recovery_block = NULL; 1792 recovery_block = NULL;
1846 label = NULL_RTX; 1793 label = NULL;
1847 } 1794 }
1848 1795
1849 /* Get pattern of the check. */ 1796 /* Get pattern of the check. */
1850 check_pattern = targetm.sched.gen_spec_check (EXPR_INSN_RTX (c_expr), label, 1797 check_pattern = targetm.sched.gen_spec_check (EXPR_INSN_RTX (c_expr), label,
1851 check_ds); 1798 check_ds);
1894 return insn; 1841 return insn;
1895 } 1842 }
1896 1843
1897 /* True when INSN is a "regN = regN" copy. */ 1844 /* True when INSN is a "regN = regN" copy. */
1898 static bool 1845 static bool
1899 identical_copy_p (rtx insn) 1846 identical_copy_p (rtx_insn *insn)
1900 { 1847 {
1901 rtx lhs, rhs, pat; 1848 rtx lhs, rhs, pat;
1902 1849
1903 pat = PATTERN (insn); 1850 pat = PATTERN (insn);
1904 1851
1917 } 1864 }
1918 1865
1919 /* Undo all transformations on *AV_PTR that were done when 1866 /* Undo all transformations on *AV_PTR that were done when
1920 moving through INSN. */ 1867 moving through INSN. */
1921 static void 1868 static void
1922 undo_transformations (av_set_t *av_ptr, rtx insn) 1869 undo_transformations (av_set_t *av_ptr, rtx_insn *insn)
1923 { 1870 {
1924 av_set_iterator av_iter; 1871 av_set_iterator av_iter;
1925 expr_t expr; 1872 expr_t expr;
1926 av_set_t new_set = NULL; 1873 av_set_t new_set = NULL;
1927 1874
1950 1897
1951 if (index >= 0) 1898 if (index >= 0)
1952 { 1899 {
1953 expr_history_def *phist; 1900 expr_history_def *phist;
1954 1901
1955 phist = VEC_index (expr_history_def, 1902 phist = &EXPR_HISTORY_OF_CHANGES (expr)[index];
1956 EXPR_HISTORY_OF_CHANGES (expr),
1957 index);
1958 1903
1959 switch (phist->type) 1904 switch (phist->type)
1960 { 1905 {
1961 case TRANS_SPECULATION: 1906 case TRANS_SPECULATION:
1962 { 1907 {
2122 sel_print ("would create bookkeeping block: "); 2067 sel_print ("would create bookkeeping block: ");
2123 2068
2124 return TRUE; 2069 return TRUE;
2125 } 2070 }
2126 2071
2072 /* Return true when the conflict with newly created implicit clobbers
2073 between EXPR and THROUGH_INSN is found because of renaming. */
2074 static bool
2075 implicit_clobber_conflict_p (insn_t through_insn, expr_t expr)
2076 {
2077 HARD_REG_SET temp;
2078 rtx_insn *insn;
2079 rtx reg, rhs, pat;
2080 hard_reg_set_iterator hrsi;
2081 unsigned regno;
2082 bool valid;
2083
2084 /* Make a new pseudo register. */
2085 reg = gen_reg_rtx (GET_MODE (EXPR_LHS (expr)));
2086 max_regno = max_reg_num ();
2087 maybe_extend_reg_info_p ();
2088
2089 /* Validate a change and bail out early. */
2090 insn = EXPR_INSN_RTX (expr);
2091 validate_change (insn, &SET_DEST (PATTERN (insn)), reg, true);
2092 valid = verify_changes (0);
2093 cancel_changes (0);
2094 if (!valid)
2095 {
2096 if (sched_verbose >= 6)
2097 sel_print ("implicit clobbers failed validation, ");
2098 return true;
2099 }
2100
2101 /* Make a new insn with it. */
2102 rhs = copy_rtx (VINSN_RHS (EXPR_VINSN (expr)));
2103 pat = gen_rtx_SET (reg, rhs);
2104 start_sequence ();
2105 insn = emit_insn (pat);
2106 end_sequence ();
2107
2108 /* Calculate implicit clobbers. */
2109 extract_insn (insn);
2110 preprocess_constraints (insn);
2111 alternative_mask prefrred = get_preferred_alternatives (insn);
2112 ira_implicitly_set_insn_hard_regs (&temp, prefrred);
2113 AND_COMPL_HARD_REG_SET (temp, ira_no_alloc_regs);
2114
2115 /* If any implicit clobber registers intersect with regular ones in
2116 through_insn, we have a dependency and thus bail out. */
2117 EXECUTE_IF_SET_IN_HARD_REG_SET (temp, 0, regno, hrsi)
2118 {
2119 vinsn_t vi = INSN_VINSN (through_insn);
2120 if (bitmap_bit_p (VINSN_REG_SETS (vi), regno)
2121 || bitmap_bit_p (VINSN_REG_CLOBBERS (vi), regno)
2122 || bitmap_bit_p (VINSN_REG_USES (vi), regno))
2123 return true;
2124 }
2125
2126 return false;
2127 }
2128
2127 /* Modifies EXPR so it can be moved through the THROUGH_INSN, 2129 /* Modifies EXPR so it can be moved through the THROUGH_INSN,
2128 performing necessary transformations. Record the type of transformation 2130 performing necessary transformations. Record the type of transformation
2129 made in PTRANS_TYPE, when it is not NULL. When INSIDE_INSN_GROUP, 2131 made in PTRANS_TYPE, when it is not NULL. When INSIDE_INSN_GROUP,
2130 permit all dependencies except true ones, and try to remove those 2132 permit all dependencies except true ones, and try to remove those
2131 too via forward substitution. All cases when a non-eliminable 2133 too via forward substitution. All cases when a non-eliminable
2254 Anyways, we should mark that the original register is 2256 Anyways, we should mark that the original register is
2255 unavailable. */ 2257 unavailable. */
2256 if (!enable_schedule_as_rhs_p || !EXPR_SEPARABLE_P (expr)) 2258 if (!enable_schedule_as_rhs_p || !EXPR_SEPARABLE_P (expr))
2257 return MOVEUP_EXPR_NULL; 2259 return MOVEUP_EXPR_NULL;
2258 2260
2261 /* When renaming a hard register to a pseudo before reload, extra
2262 dependencies can occur from the implicit clobbers of the insn.
2263 Filter out such cases here. */
2264 if (!reload_completed && REG_P (EXPR_LHS (expr))
2265 && HARD_REGISTER_P (EXPR_LHS (expr))
2266 && implicit_clobber_conflict_p (through_insn, expr))
2267 {
2268 if (sched_verbose >= 6)
2269 sel_print ("implicit clobbers conflict detected, ");
2270 return MOVEUP_EXPR_NULL;
2271 }
2259 EXPR_TARGET_AVAILABLE (expr) = false; 2272 EXPR_TARGET_AVAILABLE (expr) = false;
2260 was_target_conflict = true; 2273 was_target_conflict = true;
2261 as_rhs = true; 2274 as_rhs = true;
2262 } 2275 }
2263 2276
2514 dump_expr (expr); 2527 dump_expr (expr);
2515 sel_print (" through %d: ", INSN_UID (insn)); 2528 sel_print (" through %d: ", INSN_UID (insn));
2516 } 2529 }
2517 2530
2518 if (DEBUG_INSN_P (EXPR_INSN_RTX (expr)) 2531 if (DEBUG_INSN_P (EXPR_INSN_RTX (expr))
2532 && BLOCK_FOR_INSN (EXPR_INSN_RTX (expr))
2519 && (sel_bb_head (BLOCK_FOR_INSN (EXPR_INSN_RTX (expr))) 2533 && (sel_bb_head (BLOCK_FOR_INSN (EXPR_INSN_RTX (expr)))
2520 == EXPR_INSN_RTX (expr))) 2534 == EXPR_INSN_RTX (expr)))
2521 /* Don't use cached information for debug insns that are heads of 2535 /* Don't use cached information for debug insns that are heads of
2522 basic blocks. */; 2536 basic blocks. */;
2523 else if (try_bitmap_cache (expr, insn, inside_insn_group, &res)) 2537 else if (try_bitmap_cache (expr, insn, inside_insn_group, &res))
2744 sel_print ("\n"); 2758 sel_print ("\n");
2745 if (sinfo->succs_ok_n != sinfo->all_succs_n) 2759 if (sinfo->succs_ok_n != sinfo->all_succs_n)
2746 sel_print ("real successors num: %d\n", sinfo->all_succs_n); 2760 sel_print ("real successors num: %d\n", sinfo->all_succs_n);
2747 } 2761 }
2748 2762
2749 /* Add insn to to the tail of current path. */ 2763 /* Add insn to the tail of current path. */
2750 ilist_add (&p, insn); 2764 ilist_add (&p, insn);
2751 2765
2752 FOR_EACH_VEC_ELT (rtx, sinfo->succs_ok, is, succ) 2766 FOR_EACH_VEC_ELT (sinfo->succs_ok, is, succ)
2753 { 2767 {
2754 av_set_t succ_set; 2768 av_set_t succ_set;
2755 2769
2756 /* We will edit SUCC_SET and EXPR_SPEC field of its elements. */ 2770 /* We will edit SUCC_SET and EXPR_SPEC field of its elements. */
2757 succ_set = compute_av_set_inside_bb (succ, p, ws, true); 2771 succ_set = compute_av_set_inside_bb (succ, p, ws, true);
2758 2772
2759 av_set_split_usefulness (succ_set, 2773 av_set_split_usefulness (succ_set,
2760 VEC_index (int, sinfo->probs_ok, is), 2774 sinfo->probs_ok[is],
2761 sinfo->all_prob); 2775 sinfo->all_prob);
2762 2776
2763 if (sinfo->all_succs_n > 1) 2777 if (sinfo->all_succs_n > 1)
2764 { 2778 {
2765 /* Find EXPR'es that came from *all* successors and save them 2779 /* Find EXPR'es that came from *all* successors and save them
2801 } 2815 }
2802 2816
2803 /* Check liveness restrictions via hard way when there are more than 2817 /* Check liveness restrictions via hard way when there are more than
2804 two successors. */ 2818 two successors. */
2805 if (sinfo->succs_ok_n > 2) 2819 if (sinfo->succs_ok_n > 2)
2806 FOR_EACH_VEC_ELT (rtx, sinfo->succs_ok, is, succ) 2820 FOR_EACH_VEC_ELT (sinfo->succs_ok, is, succ)
2807 { 2821 {
2808 basic_block succ_bb = BLOCK_FOR_INSN (succ); 2822 basic_block succ_bb = BLOCK_FOR_INSN (succ);
2809 2823
2810 gcc_assert (BB_LV_SET_VALID_P (succ_bb)); 2824 gcc_assert (BB_LV_SET_VALID_P (succ_bb));
2811 mark_unavailable_targets (av1, BB_AV_SET (succ_bb), 2825 mark_unavailable_targets (av1, BB_AV_SET (succ_bb),
2812 BB_LV_SET (succ_bb)); 2826 BB_LV_SET (succ_bb));
2813 } 2827 }
2814 2828
2815 /* Finally, check liveness restrictions on paths leaving the region. */ 2829 /* Finally, check liveness restrictions on paths leaving the region. */
2816 if (sinfo->all_succs_n > sinfo->succs_ok_n) 2830 if (sinfo->all_succs_n > sinfo->succs_ok_n)
2817 FOR_EACH_VEC_ELT (rtx, sinfo->succs_other, is, succ) 2831 FOR_EACH_VEC_ELT (sinfo->succs_other, is, succ)
2818 mark_unavailable_targets 2832 mark_unavailable_targets
2819 (av1, NULL, BB_LV_SET (BLOCK_FOR_INSN (succ))); 2833 (av1, NULL, BB_LV_SET (BLOCK_FOR_INSN (succ)));
2820 2834
2821 if (sinfo->all_succs_n > 1) 2835 if (sinfo->all_succs_n > 1)
2822 { 2836 {
3147 return lv; 3161 return lv;
3148 } 3162 }
3149 3163
3150 /* Update liveness sets for INSN. */ 3164 /* Update liveness sets for INSN. */
3151 static inline void 3165 static inline void
3152 update_liveness_on_insn (rtx insn) 3166 update_liveness_on_insn (rtx_insn *insn)
3153 { 3167 {
3154 ignore_first = true; 3168 ignore_first = true;
3155 compute_live (insn); 3169 compute_live (insn);
3156 } 3170 }
3157 3171
3158 /* Compute liveness below INSN and write it into REGS. */ 3172 /* Compute liveness below INSN and write it into REGS. */
3159 static inline void 3173 static inline void
3160 compute_live_below_insn (rtx insn, regset regs) 3174 compute_live_below_insn (rtx_insn *insn, regset regs)
3161 { 3175 {
3162 rtx succ; 3176 rtx_insn *succ;
3163 succ_iterator si; 3177 succ_iterator si;
3164 3178
3165 FOR_EACH_SUCC_1 (succ, si, insn, SUCCS_ALL) 3179 FOR_EACH_SUCC_1 (succ, si, insn, SUCCS_ALL)
3166 IOR_REG_SET (regs, compute_live (succ)); 3180 IOR_REG_SET (regs, compute_live (succ));
3167 } 3181 }
3168 3182
3169 /* Update the data gathered in av and lv sets starting from INSN. */ 3183 /* Update the data gathered in av and lv sets starting from INSN. */
3170 static void 3184 static void
3171 update_data_sets (rtx insn) 3185 update_data_sets (rtx_insn *insn)
3172 { 3186 {
3173 update_liveness_on_insn (insn); 3187 update_liveness_on_insn (insn);
3174 if (sel_bb_head_p (insn)) 3188 if (sel_bb_head_p (insn))
3175 { 3189 {
3176 gcc_assert (AV_LEVEL (insn) != 0); 3190 gcc_assert (AV_LEVEL (insn) != 0);
3454 3468
3455 /* Filter speculative insns from AV_PTR if we don't want them. */ 3469 /* Filter speculative insns from AV_PTR if we don't want them. */
3456 static void 3470 static void
3457 process_spec_exprs (av_set_t *av_ptr) 3471 process_spec_exprs (av_set_t *av_ptr)
3458 { 3472 {
3459 bool try_data_p = true;
3460 bool try_control_p = true;
3461 expr_t expr; 3473 expr_t expr;
3462 av_set_iterator si; 3474 av_set_iterator si;
3463 3475
3464 if (spec_info == NULL) 3476 if (spec_info == NULL)
3465 return; 3477 return;
3480 && (ds & DATA_SPEC) 3492 && (ds & DATA_SPEC)
3481 && (ds & CONTROL_SPEC)))) 3493 && (ds & CONTROL_SPEC))))
3482 { 3494 {
3483 av_set_iter_remove (&si); 3495 av_set_iter_remove (&si);
3484 continue; 3496 continue;
3485 }
3486
3487 if ((spec_info->flags & PREFER_NON_DATA_SPEC)
3488 && !(ds & BEGIN_DATA))
3489 try_data_p = false;
3490
3491 if ((spec_info->flags & PREFER_NON_CONTROL_SPEC)
3492 && !(ds & BEGIN_CONTROL))
3493 try_control_p = false;
3494 }
3495
3496 FOR_EACH_EXPR_1 (expr, si, av_ptr)
3497 {
3498 ds_t ds;
3499
3500 ds = EXPR_SPEC_DONE_DS (expr);
3501
3502 if (ds & SPECULATIVE)
3503 {
3504 if ((ds & BEGIN_DATA) && !try_data_p)
3505 /* We don't want any data speculative instructions right
3506 now. */
3507 av_set_iter_remove (&si);
3508
3509 if ((ds & BEGIN_CONTROL) && !try_control_p)
3510 /* We don't want any control speculative instructions right
3511 now. */
3512 av_set_iter_remove (&si);
3513 } 3497 }
3514 } 3498 }
3515 } 3499 }
3516 3500
3517 /* Search for any use-like insns in AV_PTR and decide on scheduling 3501 /* Search for any use-like insns in AV_PTR and decide on scheduling
3576 } 3560 }
3577 3561
3578 return NULL; 3562 return NULL;
3579 } 3563 }
3580 3564
3581 /* Lookup EXPR in VINSN_VEC and return TRUE if found. */ 3565 /* Lookup EXPR in VINSN_VEC and return TRUE if found. Also check patterns from
3566 EXPR's history of changes. */
3582 static bool 3567 static bool
3583 vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr) 3568 vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr)
3584 { 3569 {
3585 vinsn_t vinsn; 3570 vinsn_t vinsn, expr_vinsn;
3586 int n; 3571 int n;
3587 3572 unsigned i;
3588 FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) 3573
3589 if (VINSN_SEPARABLE_P (vinsn)) 3574 /* Start with checking expr itself and then proceed with all the old forms
3590 { 3575 of expr taken from its history vector. */
3591 if (vinsn_equal_p (vinsn, EXPR_VINSN (expr))) 3576 for (i = 0, expr_vinsn = EXPR_VINSN (expr);
3592 return true; 3577 expr_vinsn;
3593 } 3578 expr_vinsn = (i < EXPR_HISTORY_OF_CHANGES (expr).length ()
3594 else 3579 ? EXPR_HISTORY_OF_CHANGES (expr)[i++].old_expr_vinsn
3595 { 3580 : NULL))
3596 /* For non-separable instructions, the blocking insn can have 3581 FOR_EACH_VEC_ELT (vinsn_vec, n, vinsn)
3597 another pattern due to substitution, and we can't choose 3582 if (VINSN_SEPARABLE_P (vinsn))
3598 different register as in the above case. Check all registers 3583 {
3599 being written instead. */ 3584 if (vinsn_equal_p (vinsn, expr_vinsn))
3600 if (bitmap_intersect_p (VINSN_REG_SETS (vinsn), 3585 return true;
3601 VINSN_REG_SETS (EXPR_VINSN (expr)))) 3586 }
3602 return true; 3587 else
3603 } 3588 {
3589 /* For non-separable instructions, the blocking insn can have
3590 another pattern due to substitution, and we can't choose
3591 different register as in the above case. Check all registers
3592 being written instead. */
3593 if (bitmap_intersect_p (VINSN_REG_SETS (vinsn),
3594 VINSN_REG_SETS (expr_vinsn)))
3595 return true;
3596 }
3604 3597
3605 return false; 3598 return false;
3606 } 3599 }
3607 3600
3608 #ifdef ENABLE_CHECKING
3609 /* Return true if either of expressions from ORIG_OPS can be blocked 3601 /* Return true if either of expressions from ORIG_OPS can be blocked
3610 by previously created bookkeeping code. STATIC_PARAMS points to static 3602 by previously created bookkeeping code. STATIC_PARAMS points to static
3611 parameters of move_op. */ 3603 parameters of move_op. */
3612 static bool 3604 static bool
3613 av_set_could_be_blocked_by_bookkeeping_p (av_set_t orig_ops, void *static_params) 3605 av_set_could_be_blocked_by_bookkeeping_p (av_set_t orig_ops, void *static_params)
3634 3626
3635 /* Expressions in ORIG_OPS may have wrong destination register due to 3627 /* Expressions in ORIG_OPS may have wrong destination register due to
3636 renaming. Check with the right register instead. */ 3628 renaming. Check with the right register instead. */
3637 if (sparams->dest && REG_P (sparams->dest)) 3629 if (sparams->dest && REG_P (sparams->dest))
3638 { 3630 {
3639 unsigned regno = REGNO (sparams->dest); 3631 rtx reg = sparams->dest;
3640 vinsn_t failed_vinsn = INSN_VINSN (sparams->failed_insn); 3632 vinsn_t failed_vinsn = INSN_VINSN (sparams->failed_insn);
3641 3633
3642 if (bitmap_bit_p (VINSN_REG_SETS (failed_vinsn), regno) 3634 if (register_unavailable_p (VINSN_REG_SETS (failed_vinsn), reg)
3643 || bitmap_bit_p (VINSN_REG_USES (failed_vinsn), regno) 3635 || register_unavailable_p (VINSN_REG_USES (failed_vinsn), reg)
3644 || bitmap_bit_p (VINSN_REG_CLOBBERS (failed_vinsn), regno)) 3636 || register_unavailable_p (VINSN_REG_CLOBBERS (failed_vinsn), reg))
3645 return true; 3637 return true;
3646 } 3638 }
3647 3639
3648 return false; 3640 return false;
3649 } 3641 }
3650 #endif
3651 3642
3652 /* Clear VINSN_VEC and detach vinsns. */ 3643 /* Clear VINSN_VEC and detach vinsns. */
3653 static void 3644 static void
3654 vinsn_vec_clear (vinsn_vec_t *vinsn_vec) 3645 vinsn_vec_clear (vinsn_vec_t *vinsn_vec)
3655 { 3646 {
3656 unsigned len = VEC_length (vinsn_t, *vinsn_vec); 3647 unsigned len = vinsn_vec->length ();
3657 if (len > 0) 3648 if (len > 0)
3658 { 3649 {
3659 vinsn_t vinsn; 3650 vinsn_t vinsn;
3660 int n; 3651 int n;
3661 3652
3662 FOR_EACH_VEC_ELT (vinsn_t, *vinsn_vec, n, vinsn) 3653 FOR_EACH_VEC_ELT (*vinsn_vec, n, vinsn)
3663 vinsn_detach (vinsn); 3654 vinsn_detach (vinsn);
3664 VEC_block_remove (vinsn_t, *vinsn_vec, 0, len); 3655 vinsn_vec->block_remove (0, len);
3665 } 3656 }
3666 } 3657 }
3667 3658
3668 /* Add the vinsn of EXPR to the VINSN_VEC. */ 3659 /* Add the vinsn of EXPR to the VINSN_VEC. */
3669 static void 3660 static void
3670 vinsn_vec_add (vinsn_vec_t *vinsn_vec, expr_t expr) 3661 vinsn_vec_add (vinsn_vec_t *vinsn_vec, expr_t expr)
3671 { 3662 {
3672 vinsn_attach (EXPR_VINSN (expr)); 3663 vinsn_attach (EXPR_VINSN (expr));
3673 VEC_safe_push (vinsn_t, heap, *vinsn_vec, EXPR_VINSN (expr)); 3664 vinsn_vec->safe_push (EXPR_VINSN (expr));
3674 } 3665 }
3675 3666
3676 /* Free the vector representing blocked expressions. */ 3667 /* Free the vector representing blocked expressions. */
3677 static void 3668 static void
3678 vinsn_vec_free (vinsn_vec_t *vinsn_vec) 3669 vinsn_vec_free (vinsn_vec_t &vinsn_vec)
3679 { 3670 {
3680 if (*vinsn_vec) 3671 vinsn_vec.release ();
3681 VEC_free (vinsn_t, heap, *vinsn_vec);
3682 } 3672 }
3683 3673
3684 /* Increase EXPR_PRIORITY_ADJ for INSN by AMOUNT. */ 3674 /* Increase EXPR_PRIORITY_ADJ for INSN by AMOUNT. */
3685 3675
3686 void sel_add_to_insn_priority (rtx insn, int amount) 3676 void sel_add_to_insn_priority (rtx insn, int amount)
3713 already scheduled. */ 3703 already scheduled. */
3714 if (av == NULL) 3704 if (av == NULL)
3715 return false; 3705 return false;
3716 3706
3717 /* Empty vector from the previous stuff. */ 3707 /* Empty vector from the previous stuff. */
3718 if (VEC_length (expr_t, vec_av_set) > 0) 3708 if (vec_av_set.length () > 0)
3719 VEC_block_remove (expr_t, vec_av_set, 0, VEC_length (expr_t, vec_av_set)); 3709 vec_av_set.block_remove (0, vec_av_set.length ());
3720 3710
3721 /* Turn the set into a vector for sorting and call sel_target_adjust_priority 3711 /* Turn the set into a vector for sorting and call sel_target_adjust_priority
3722 for each insn. */ 3712 for each insn. */
3723 gcc_assert (VEC_empty (expr_t, vec_av_set)); 3713 gcc_assert (vec_av_set.is_empty ());
3724 FOR_EACH_EXPR (expr, si, av) 3714 FOR_EACH_EXPR (expr, si, av)
3725 { 3715 {
3726 VEC_safe_push (expr_t, heap, vec_av_set, expr); 3716 vec_av_set.safe_push (expr);
3727 3717
3728 gcc_assert (EXPR_PRIORITY_ADJ (expr) == 0 || *pneed_stall); 3718 gcc_assert (EXPR_PRIORITY_ADJ (expr) == 0 || *pneed_stall);
3729 3719
3730 /* Adjust priority using target backend hook. */ 3720 /* Adjust priority using target backend hook. */
3731 sel_target_adjust_priority (expr); 3721 sel_target_adjust_priority (expr);
3732 } 3722 }
3733 3723
3734 /* Sort the vector. */ 3724 /* Sort the vector. */
3735 VEC_qsort (expr_t, vec_av_set, sel_rank_for_schedule); 3725 vec_av_set.qsort (sel_rank_for_schedule);
3736 3726
3737 /* We record maximal priority of insns in av set for current instruction 3727 /* We record maximal priority of insns in av set for current instruction
3738 group. */ 3728 group. */
3739 if (FENCE_STARTS_CYCLE_P (fence)) 3729 if (FENCE_STARTS_CYCLE_P (fence))
3740 av_max_prio = est_ticks_till_branch = INT_MIN; 3730 av_max_prio = est_ticks_till_branch = INT_MIN;
3741 3731
3742 /* Filter out inappropriate expressions. Loop's direction is reversed to 3732 /* Filter out inappropriate expressions. Loop's direction is reversed to
3743 visit "best" instructions first. We assume that VEC_unordered_remove 3733 visit "best" instructions first. We assume that vec::unordered_remove
3744 moves last element in place of one being deleted. */ 3734 moves last element in place of one being deleted. */
3745 for (n = VEC_length (expr_t, vec_av_set) - 1, stalled = 0; n >= 0; n--) 3735 for (n = vec_av_set.length () - 1, stalled = 0; n >= 0; n--)
3746 { 3736 {
3747 expr_t expr = VEC_index (expr_t, vec_av_set, n); 3737 expr_t expr = vec_av_set[n];
3748 insn_t insn = EXPR_INSN_RTX (expr); 3738 insn_t insn = EXPR_INSN_RTX (expr);
3749 signed char target_available; 3739 signed char target_available;
3750 bool is_orig_reg_p = true; 3740 bool is_orig_reg_p = true;
3751 int need_cycles, new_prio; 3741 int need_cycles, new_prio;
3742 bool fence_insn_p = INSN_UID (insn) == INSN_UID (FENCE_INSN (fence));
3752 3743
3753 /* Don't allow any insns other than from SCHED_GROUP if we have one. */ 3744 /* Don't allow any insns other than from SCHED_GROUP if we have one. */
3754 if (FENCE_SCHED_NEXT (fence) && insn != FENCE_SCHED_NEXT (fence)) 3745 if (FENCE_SCHED_NEXT (fence) && insn != FENCE_SCHED_NEXT (fence))
3755 { 3746 {
3756 VEC_unordered_remove (expr_t, vec_av_set, n); 3747 vec_av_set.unordered_remove (n);
3757 continue; 3748 continue;
3758 } 3749 }
3759 3750
3760 /* Set number of sched_next insns (just in case there 3751 /* Set number of sched_next insns (just in case there
3761 could be several). */ 3752 could be several). */
3766 FIXME: try to minimize calls to this. */ 3757 FIXME: try to minimize calls to this. */
3767 target_available = EXPR_TARGET_AVAILABLE (expr); 3758 target_available = EXPR_TARGET_AVAILABLE (expr);
3768 3759
3769 /* If insn was already scheduled on the current fence, 3760 /* If insn was already scheduled on the current fence,
3770 set TARGET_AVAILABLE to -1 no matter what expr's attribute says. */ 3761 set TARGET_AVAILABLE to -1 no matter what expr's attribute says. */
3771 if (vinsn_vec_has_expr_p (vec_target_unavailable_vinsns, expr)) 3762 if (vinsn_vec_has_expr_p (vec_target_unavailable_vinsns, expr)
3763 && !fence_insn_p)
3772 target_available = -1; 3764 target_available = -1;
3773 3765
3774 /* If the availability of the EXPR is invalidated by the insertion of 3766 /* If the availability of the EXPR is invalidated by the insertion of
3775 bookkeeping earlier, make sure that we won't choose this expr for 3767 bookkeeping earlier, make sure that we won't choose this expr for
3776 scheduling if it's not separable, and if it is separable, then 3768 scheduling if it's not separable, and if it is separable, then
3777 we have to recompute the set of available registers for it. */ 3769 we have to recompute the set of available registers for it. */
3778 if (vinsn_vec_has_expr_p (vec_bookkeeping_blocked_vinsns, expr)) 3770 if (vinsn_vec_has_expr_p (vec_bookkeeping_blocked_vinsns, expr))
3779 { 3771 {
3780 VEC_unordered_remove (expr_t, vec_av_set, n); 3772 vec_av_set.unordered_remove (n);
3781 if (sched_verbose >= 4) 3773 if (sched_verbose >= 4)
3782 sel_print ("Expr %d is blocked by bookkeeping inserted earlier\n", 3774 sel_print ("Expr %d is blocked by bookkeeping inserted earlier\n",
3783 INSN_UID (insn)); 3775 INSN_UID (insn));
3784 continue; 3776 continue;
3785 } 3777 }
3792 else if (/* Non-separable instruction will never 3784 else if (/* Non-separable instruction will never
3793 get another register. */ 3785 get another register. */
3794 (target_available == false 3786 (target_available == false
3795 && !EXPR_SEPARABLE_P (expr)) 3787 && !EXPR_SEPARABLE_P (expr))
3796 /* Don't try to find a register for low-priority expression. */ 3788 /* Don't try to find a register for low-priority expression. */
3797 || (int) VEC_length (expr_t, vec_av_set) - 1 - n >= max_insns_to_rename 3789 || (int) vec_av_set.length () - 1 - n >= max_insns_to_rename
3798 /* ??? FIXME: Don't try to rename data speculation. */ 3790 /* ??? FIXME: Don't try to rename data speculation. */
3799 || (EXPR_SPEC_DONE_DS (expr) & BEGIN_DATA) 3791 || (EXPR_SPEC_DONE_DS (expr) & BEGIN_DATA)
3800 || ! find_best_reg_for_expr (expr, bnds, &is_orig_reg_p)) 3792 || ! find_best_reg_for_expr (expr, bnds, &is_orig_reg_p))
3801 { 3793 {
3802 VEC_unordered_remove (expr_t, vec_av_set, n); 3794 vec_av_set.unordered_remove (n);
3803 if (sched_verbose >= 4) 3795 if (sched_verbose >= 4)
3804 sel_print ("Expr %d has no suitable target register\n", 3796 sel_print ("Expr %d has no suitable target register\n",
3805 INSN_UID (insn)); 3797 INSN_UID (insn));
3806 continue; 3798
3799 /* A fence insn should not get here. */
3800 gcc_assert (!fence_insn_p);
3801 continue;
3807 } 3802 }
3803
3804 /* At this point a fence insn should always be available. */
3805 gcc_assert (!fence_insn_p
3806 || INSN_UID (FENCE_INSN (fence)) == INSN_UID (EXPR_INSN_RTX (expr)));
3808 3807
3809 /* Filter expressions that need to be renamed or speculated when 3808 /* Filter expressions that need to be renamed or speculated when
3810 pipelining, because compensating register copies or speculation 3809 pipelining, because compensating register copies or speculation
3811 checks are likely to be placed near the beginning of the loop, 3810 checks are likely to be placed near the beginning of the loop,
3812 causing a stall. */ 3811 causing a stall. */
3817 renaming/speculation to be successful. */ 3816 renaming/speculation to be successful. */
3818 int need_n_ticks_till_branch = sel_vinsn_cost (EXPR_VINSN (expr)); 3817 int need_n_ticks_till_branch = sel_vinsn_cost (EXPR_VINSN (expr));
3819 3818
3820 if ((int) current_loop_nest->ninsns < 9) 3819 if ((int) current_loop_nest->ninsns < 9)
3821 { 3820 {
3822 VEC_unordered_remove (expr_t, vec_av_set, n); 3821 vec_av_set.unordered_remove (n);
3823 if (sched_verbose >= 4) 3822 if (sched_verbose >= 4)
3824 sel_print ("Pipelining expr %d will likely cause stall\n", 3823 sel_print ("Pipelining expr %d will likely cause stall\n",
3825 INSN_UID (insn)); 3824 INSN_UID (insn));
3826 continue; 3825 continue;
3827 } 3826 }
3828 3827
3829 if ((int) current_loop_nest->ninsns - num_insns_scheduled 3828 if ((int) current_loop_nest->ninsns - num_insns_scheduled
3830 < need_n_ticks_till_branch * issue_rate / 2 3829 < need_n_ticks_till_branch * issue_rate / 2
3831 && est_ticks_till_branch < need_n_ticks_till_branch) 3830 && est_ticks_till_branch < need_n_ticks_till_branch)
3832 { 3831 {
3833 VEC_unordered_remove (expr_t, vec_av_set, n); 3832 vec_av_set.unordered_remove (n);
3834 if (sched_verbose >= 4) 3833 if (sched_verbose >= 4)
3835 sel_print ("Pipelining expr %d will likely cause stall\n", 3834 sel_print ("Pipelining expr %d will likely cause stall\n",
3836 INSN_UID (insn)); 3835 INSN_UID (insn));
3837 continue; 3836 continue;
3838 } 3837 }
3843 if (sel_insn_is_speculation_check (insn) 3842 if (sel_insn_is_speculation_check (insn)
3844 && EXPR_PRIORITY (expr) < av_max_prio) 3843 && EXPR_PRIORITY (expr) < av_max_prio)
3845 { 3844 {
3846 stalled++; 3845 stalled++;
3847 min_need_stall = min_need_stall < 0 ? 1 : MIN (min_need_stall, 1); 3846 min_need_stall = min_need_stall < 0 ? 1 : MIN (min_need_stall, 1);
3848 VEC_unordered_remove (expr_t, vec_av_set, n); 3847 vec_av_set.unordered_remove (n);
3849 if (sched_verbose >= 4) 3848 if (sched_verbose >= 4)
3850 sel_print ("Delaying speculation check %d until its first use\n", 3849 sel_print ("Delaying speculation check %d until its first use\n",
3851 INSN_UID (insn)); 3850 INSN_UID (insn));
3852 continue; 3851 continue;
3853 } 3852 }
3870 { 3869 {
3871 stalled++; 3870 stalled++;
3872 min_need_stall = (min_need_stall < 0 3871 min_need_stall = (min_need_stall < 0
3873 ? need_cycles 3872 ? need_cycles
3874 : MIN (min_need_stall, need_cycles)); 3873 : MIN (min_need_stall, need_cycles));
3875 VEC_unordered_remove (expr_t, vec_av_set, n); 3874 vec_av_set.unordered_remove (n);
3876 3875
3877 if (sched_verbose >= 4) 3876 if (sched_verbose >= 4)
3878 sel_print ("Expr %d is not ready until cycle %d (cached)\n", 3877 sel_print ("Expr %d is not ready until cycle %d (cached)\n",
3879 INSN_UID (insn), 3878 INSN_UID (insn),
3880 FENCE_READY_TICKS (fence)[INSN_UID (insn)]); 3879 FENCE_READY_TICKS (fence)[INSN_UID (insn)]);
3908 stalled++; 3907 stalled++;
3909 min_need_stall = (min_need_stall < 0 3908 min_need_stall = (min_need_stall < 0
3910 ? need_cycles 3909 ? need_cycles
3911 : MIN (min_need_stall, need_cycles)); 3910 : MIN (min_need_stall, need_cycles));
3912 3911
3913 VEC_unordered_remove (expr_t, vec_av_set, n); 3912 vec_av_set.unordered_remove (n);
3914 3913
3915 if (sched_verbose >= 4) 3914 if (sched_verbose >= 4)
3916 sel_print ("Expr %d is not ready yet until cycle %d\n", 3915 sel_print ("Expr %d is not ready yet until cycle %d\n",
3917 INSN_UID (insn), 3916 INSN_UID (insn),
3918 FENCE_READY_TICKS (fence)[INSN_UID (insn)]); 3917 FENCE_READY_TICKS (fence)[INSN_UID (insn)]);
3926 3925
3927 /* Clear SCHED_NEXT. */ 3926 /* Clear SCHED_NEXT. */
3928 if (FENCE_SCHED_NEXT (fence)) 3927 if (FENCE_SCHED_NEXT (fence))
3929 { 3928 {
3930 gcc_assert (sched_next_worked == 1); 3929 gcc_assert (sched_next_worked == 1);
3931 FENCE_SCHED_NEXT (fence) = NULL_RTX; 3930 FENCE_SCHED_NEXT (fence) = NULL;
3932 } 3931 }
3933 3932
3934 /* No need to stall if this variable was not initialized. */ 3933 /* No need to stall if this variable was not initialized. */
3935 if (min_need_stall < 0) 3934 if (min_need_stall < 0)
3936 min_need_stall = 0; 3935 min_need_stall = 0;
3937 3936
3938 if (VEC_empty (expr_t, vec_av_set)) 3937 if (vec_av_set.is_empty ())
3939 { 3938 {
3940 /* We need to set *pneed_stall here, because later we skip this code 3939 /* We need to set *pneed_stall here, because later we skip this code
3941 when ready list is empty. */ 3940 when ready list is empty. */
3942 *pneed_stall = min_need_stall; 3941 *pneed_stall = min_need_stall;
3943 return false; 3942 return false;
3944 } 3943 }
3945 else 3944 else
3946 gcc_assert (min_need_stall == 0); 3945 gcc_assert (min_need_stall == 0);
3947 3946
3948 /* Sort the vector. */ 3947 /* Sort the vector. */
3949 VEC_qsort (expr_t, vec_av_set, sel_rank_for_schedule); 3948 vec_av_set.qsort (sel_rank_for_schedule);
3950 3949
3951 if (sched_verbose >= 4) 3950 if (sched_verbose >= 4)
3952 { 3951 {
3953 sel_print ("Total ready exprs: %d, stalled: %d\n", 3952 sel_print ("Total ready exprs: %d, stalled: %d\n",
3954 VEC_length (expr_t, vec_av_set), stalled); 3953 vec_av_set.length (), stalled);
3955 sel_print ("Sorted av set (%d): ", VEC_length (expr_t, vec_av_set)); 3954 sel_print ("Sorted av set (%d): ", vec_av_set.length ());
3956 FOR_EACH_VEC_ELT (expr_t, vec_av_set, n, expr) 3955 FOR_EACH_VEC_ELT (vec_av_set, n, expr)
3957 dump_expr (expr); 3956 dump_expr (expr);
3958 sel_print ("\n"); 3957 sel_print ("\n");
3959 } 3958 }
3960 3959
3961 *pneed_stall = 0; 3960 *pneed_stall = 0;
3969 { 3968 {
3970 int n; 3969 int n;
3971 expr_t expr; 3970 expr_t expr;
3972 3971
3973 /* Allocate and fill the ready list from the sorted vector. */ 3972 /* Allocate and fill the ready list from the sorted vector. */
3974 ready.n_ready = VEC_length (expr_t, vec_av_set); 3973 ready.n_ready = vec_av_set.length ();
3975 ready.first = ready.n_ready - 1; 3974 ready.first = ready.n_ready - 1;
3976 3975
3977 gcc_assert (ready.n_ready > 0); 3976 gcc_assert (ready.n_ready > 0);
3978 3977
3979 if (ready.n_ready > max_issue_size) 3978 if (ready.n_ready > max_issue_size)
3980 { 3979 {
3981 max_issue_size = ready.n_ready; 3980 max_issue_size = ready.n_ready;
3982 sched_extend_ready_list (ready.n_ready); 3981 sched_extend_ready_list (ready.n_ready);
3983 } 3982 }
3984 3983
3985 FOR_EACH_VEC_ELT (expr_t, vec_av_set, n, expr) 3984 FOR_EACH_VEC_ELT (vec_av_set, n, expr)
3986 { 3985 {
3987 vinsn_t vi = EXPR_VINSN (expr); 3986 vinsn_t vi = EXPR_VINSN (expr);
3988 insn_t insn = VINSN_INSN_RTX (vi); 3987 insn_t insn = VINSN_INSN_RTX (vi);
3989 3988
3990 ready_try[n] = 0; 3989 ready_try[n] = 0;
4125 /* Ensure that ready list and vec_av_set are in line with each other, 4124 /* Ensure that ready list and vec_av_set are in line with each other,
4126 i.e. vec_av_set[i] == ready_element (&ready, i). */ 4125 i.e. vec_av_set[i] == ready_element (&ready, i). */
4127 if (issue_more && ran_hook) 4126 if (issue_more && ran_hook)
4128 { 4127 {
4129 int i, j, n; 4128 int i, j, n;
4130 rtx *arr = ready.vec; 4129 rtx_insn **arr = ready.vec;
4131 expr_t *vec = VEC_address (expr_t, vec_av_set); 4130 expr_t *vec = vec_av_set.address ();
4132 4131
4133 for (i = 0, n = ready.n_ready; i < n; i++) 4132 for (i = 0, n = ready.n_ready; i < n; i++)
4134 if (EXPR_INSN_RTX (vec[i]) != arr[i]) 4133 if (EXPR_INSN_RTX (vec[i]) != arr[i])
4135 { 4134 {
4136 expr_t tmp;
4137
4138 for (j = i; j < n; j++) 4135 for (j = i; j < n; j++)
4139 if (EXPR_INSN_RTX (vec[j]) == arr[i]) 4136 if (EXPR_INSN_RTX (vec[j]) == arr[i])
4140 break; 4137 break;
4141 gcc_assert (j < n); 4138 gcc_assert (j < n);
4142 4139
4143 tmp = vec[i]; 4140 std::swap (vec[i], vec[j]);
4144 vec[i] = vec[j];
4145 vec[j] = tmp;
4146 } 4141 }
4147 } 4142 }
4148 4143
4149 return issue_more; 4144 return issue_more;
4150 } 4145 }
4151 4146
4152 /* Return an EXPR correponding to INDEX element of ready list, if 4147 /* Return an EXPR corresponding to INDEX element of ready list, if
4153 FOLLOW_READY_ELEMENT is true (i.e., an expr of 4148 FOLLOW_READY_ELEMENT is true (i.e., an expr of
4154 ready_element (&ready, INDEX) will be returned), and to INDEX element of 4149 ready_element (&ready, INDEX) will be returned), and to INDEX element of
4155 ready.vec otherwise. */ 4150 ready.vec otherwise. */
4156 static inline expr_t 4151 static inline expr_t
4157 find_expr_for_ready (int index, bool follow_ready_element) 4152 find_expr_for_ready (int index, bool follow_ready_element)
4159 expr_t expr; 4154 expr_t expr;
4160 int real_index; 4155 int real_index;
4161 4156
4162 real_index = follow_ready_element ? ready.first - index : index; 4157 real_index = follow_ready_element ? ready.first - index : index;
4163 4158
4164 expr = VEC_index (expr_t, vec_av_set, real_index); 4159 expr = vec_av_set[real_index];
4165 gcc_assert (ready.vec[real_index] == EXPR_INSN_RTX (expr)); 4160 gcc_assert (ready.vec[real_index] == EXPR_INSN_RTX (expr));
4166 4161
4167 return expr; 4162 return expr;
4168 } 4163 }
4169 4164
4190 insn = ready_element (&ready, i); 4185 insn = ready_element (&ready, i);
4191 4186
4192 if (! have_hook || i == 0) 4187 if (! have_hook || i == 0)
4193 r = 0; 4188 r = 0;
4194 else 4189 else
4195 r = !targetm.sched.first_cycle_multipass_dfa_lookahead_guard (insn); 4190 r = targetm.sched.first_cycle_multipass_dfa_lookahead_guard (insn, i);
4196 4191
4197 gcc_assert (INSN_CODE (insn) >= 0); 4192 gcc_assert (INSN_CODE (insn) >= 0);
4198 4193
4199 /* Only insns with ready_try = 0 can get here 4194 /* Only insns with ready_try = 0 can get here
4200 from fill_ready_list. */ 4195 from fill_ready_list. */
4252 /* Call the rest of the hooks after the choice was made. Return 4247 /* Call the rest of the hooks after the choice was made. Return
4253 the number of insns that still can be issued given that the current 4248 the number of insns that still can be issued given that the current
4254 number is ISSUE_MORE. FENCE and BEST_INSN are the current fence 4249 number is ISSUE_MORE. FENCE and BEST_INSN are the current fence
4255 and the insn chosen for scheduling, respectively. */ 4250 and the insn chosen for scheduling, respectively. */
4256 static int 4251 static int
4257 invoke_aftermath_hooks (fence_t fence, rtx best_insn, int issue_more) 4252 invoke_aftermath_hooks (fence_t fence, rtx_insn *best_insn, int issue_more)
4258 { 4253 {
4259 gcc_assert (INSN_P (best_insn)); 4254 gcc_assert (INSN_P (best_insn));
4260 4255
4261 /* First, call dfa_new_cycle, and then variable_issue, if available. */ 4256 /* First, call dfa_new_cycle, and then variable_issue, if available. */
4262 sel_dfa_new_cycle (best_insn, fence); 4257 sel_dfa_new_cycle (best_insn, fence);
4267 issue_more = 4262 issue_more =
4268 targetm.sched.variable_issue (sched_dump, sched_verbose, best_insn, 4263 targetm.sched.variable_issue (sched_dump, sched_verbose, best_insn,
4269 issue_more); 4264 issue_more);
4270 memcpy (FENCE_STATE (fence), curr_state, dfa_state_size); 4265 memcpy (FENCE_STATE (fence), curr_state, dfa_state_size);
4271 } 4266 }
4272 else if (GET_CODE (PATTERN (best_insn)) != USE 4267 else if (!DEBUG_INSN_P (best_insn)
4273 && GET_CODE (PATTERN (best_insn)) != CLOBBER) 4268 && GET_CODE (PATTERN (best_insn)) != USE
4269 && GET_CODE (PATTERN (best_insn)) != CLOBBER)
4274 issue_more--; 4270 issue_more--;
4275 4271
4276 return issue_more; 4272 return issue_more;
4277 } 4273 }
4278 4274
4279 /* Estimate the cost of issuing INSN on DFA state STATE. */ 4275 /* Estimate the cost of issuing INSN on DFA state STATE. */
4280 static int 4276 static int
4281 estimate_insn_cost (rtx insn, state_t state) 4277 estimate_insn_cost (rtx_insn *insn, state_t state)
4282 { 4278 {
4283 static state_t temp = NULL; 4279 static state_t temp = NULL;
4284 int cost; 4280 int cost;
4285 4281
4286 if (!temp) 4282 if (!temp)
4299 /* Return the cost of issuing EXPR on the FENCE as estimated by DFA. 4295 /* Return the cost of issuing EXPR on the FENCE as estimated by DFA.
4300 This function properly handles ASMs, USEs etc. */ 4296 This function properly handles ASMs, USEs etc. */
4301 static int 4297 static int
4302 get_expr_cost (expr_t expr, fence_t fence) 4298 get_expr_cost (expr_t expr, fence_t fence)
4303 { 4299 {
4304 rtx insn = EXPR_INSN_RTX (expr); 4300 rtx_insn *insn = EXPR_INSN_RTX (expr);
4305 4301
4306 if (recog_memoized (insn) < 0) 4302 if (recog_memoized (insn) < 0)
4307 { 4303 {
4308 if (!FENCE_STARTS_CYCLE_P (fence) 4304 if (!FENCE_STARTS_CYCLE_P (fence)
4309 && INSN_ASM_P (insn)) 4305 && INSN_ASM_P (insn))
4497 { 4493 {
4498 basic_block candidate_block = NULL; 4494 basic_block candidate_block = NULL;
4499 edge e; 4495 edge e;
4500 4496
4501 /* Loop over edges from E1 to E2, inclusive. */ 4497 /* Loop over edges from E1 to E2, inclusive. */
4502 for (e = e1; !lax || e->dest != EXIT_BLOCK_PTR; e = EDGE_SUCC (e->dest, 0)) 4498 for (e = e1; !lax || e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun); e =
4499 EDGE_SUCC (e->dest, 0))
4503 { 4500 {
4504 if (EDGE_COUNT (e->dest->preds) == 2) 4501 if (EDGE_COUNT (e->dest->preds) == 2)
4505 { 4502 {
4506 if (candidate_block == NULL) 4503 if (candidate_block == NULL)
4507 candidate_block = (EDGE_PRED (e->dest, 0) == e 4504 candidate_block = (EDGE_PRED (e->dest, 0) == e
4557 new_bb = sched_split_block (bb, NULL); 4554 new_bb = sched_split_block (bb, NULL);
4558 4555
4559 /* Move note_list from the upper bb. */ 4556 /* Move note_list from the upper bb. */
4560 gcc_assert (BB_NOTE_LIST (new_bb) == NULL_RTX); 4557 gcc_assert (BB_NOTE_LIST (new_bb) == NULL_RTX);
4561 BB_NOTE_LIST (new_bb) = BB_NOTE_LIST (bb); 4558 BB_NOTE_LIST (new_bb) = BB_NOTE_LIST (bb);
4562 BB_NOTE_LIST (bb) = NULL_RTX; 4559 BB_NOTE_LIST (bb) = NULL;
4563 4560
4564 gcc_assert (e2->dest == bb); 4561 gcc_assert (e2->dest == bb);
4565 4562
4566 /* Skip block for bookkeeping copy when leaving E1->src. */ 4563 /* Skip block for bookkeeping copy when leaving E1->src. */
4567 if (e1->flags & EDGE_FALLTHRU) 4564 if (e1->flags & EDGE_FALLTHRU)
4588 insn_t last; 4585 insn_t last;
4589 4586
4590 if (DEBUG_INSN_P (insn) 4587 if (DEBUG_INSN_P (insn)
4591 && single_succ_p (new_bb) 4588 && single_succ_p (new_bb)
4592 && (succ = single_succ (new_bb)) 4589 && (succ = single_succ (new_bb))
4593 && succ != EXIT_BLOCK_PTR 4590 && succ != EXIT_BLOCK_PTR_FOR_FN (cfun)
4594 && DEBUG_INSN_P ((last = sel_bb_end (new_bb)))) 4591 && DEBUG_INSN_P ((last = sel_bb_end (new_bb))))
4595 { 4592 {
4596 while (insn != last && (DEBUG_INSN_P (insn) || NOTE_P (insn))) 4593 while (insn != last && (DEBUG_INSN_P (insn) || NOTE_P (insn)))
4597 insn = NEXT_INSN (insn); 4594 insn = NEXT_INSN (insn);
4598 4595
4599 if (insn == last) 4596 if (insn == last)
4600 { 4597 {
4601 sel_global_bb_info_def gbi; 4598 sel_global_bb_info_def gbi;
4602 sel_region_bb_info_def rbi; 4599 sel_region_bb_info_def rbi;
4603 int i;
4604 4600
4605 if (sched_verbose >= 2) 4601 if (sched_verbose >= 2)
4606 sel_print ("Swapping block ids %i and %i\n", 4602 sel_print ("Swapping block ids %i and %i\n",
4607 new_bb->index, succ->index); 4603 new_bb->index, succ->index);
4608 4604
4609 i = new_bb->index; 4605 std::swap (new_bb->index, succ->index);
4610 new_bb->index = succ->index; 4606
4611 succ->index = i; 4607 SET_BASIC_BLOCK_FOR_FN (cfun, new_bb->index, new_bb);
4612 4608 SET_BASIC_BLOCK_FOR_FN (cfun, succ->index, succ);
4613 SET_BASIC_BLOCK (new_bb->index, new_bb);
4614 SET_BASIC_BLOCK (succ->index, succ);
4615 4609
4616 memcpy (&gbi, SEL_GLOBAL_BB_INFO (new_bb), sizeof (gbi)); 4610 memcpy (&gbi, SEL_GLOBAL_BB_INFO (new_bb), sizeof (gbi));
4617 memcpy (SEL_GLOBAL_BB_INFO (new_bb), SEL_GLOBAL_BB_INFO (succ), 4611 memcpy (SEL_GLOBAL_BB_INFO (new_bb), SEL_GLOBAL_BB_INFO (succ),
4618 sizeof (gbi)); 4612 sizeof (gbi));
4619 memcpy (SEL_GLOBAL_BB_INFO (succ), &gbi, sizeof (gbi)); 4613 memcpy (SEL_GLOBAL_BB_INFO (succ), &gbi, sizeof (gbi));
4621 memcpy (&rbi, SEL_REGION_BB_INFO (new_bb), sizeof (rbi)); 4615 memcpy (&rbi, SEL_REGION_BB_INFO (new_bb), sizeof (rbi));
4622 memcpy (SEL_REGION_BB_INFO (new_bb), SEL_REGION_BB_INFO (succ), 4616 memcpy (SEL_REGION_BB_INFO (new_bb), SEL_REGION_BB_INFO (succ),
4623 sizeof (rbi)); 4617 sizeof (rbi));
4624 memcpy (SEL_REGION_BB_INFO (succ), &rbi, sizeof (rbi)); 4618 memcpy (SEL_REGION_BB_INFO (succ), &rbi, sizeof (rbi));
4625 4619
4626 i = BLOCK_TO_BB (new_bb->index); 4620 std::swap (BLOCK_TO_BB (new_bb->index),
4627 BLOCK_TO_BB (new_bb->index) = BLOCK_TO_BB (succ->index); 4621 BLOCK_TO_BB (succ->index));
4628 BLOCK_TO_BB (succ->index) = i; 4622
4629 4623 std::swap (CONTAINING_RGN (new_bb->index),
4630 i = CONTAINING_RGN (new_bb->index); 4624 CONTAINING_RGN (succ->index));
4631 CONTAINING_RGN (new_bb->index) = CONTAINING_RGN (succ->index); 4625
4632 CONTAINING_RGN (succ->index) = i; 4626 for (int i = 0; i < current_nr_blocks; i++)
4633
4634 for (i = 0; i < current_nr_blocks; i++)
4635 if (BB_TO_BLOCK (i) == succ->index) 4627 if (BB_TO_BLOCK (i) == succ->index)
4636 BB_TO_BLOCK (i) = new_bb->index; 4628 BB_TO_BLOCK (i) = new_bb->index;
4637 else if (BB_TO_BLOCK (i) == new_bb->index) 4629 else if (BB_TO_BLOCK (i) == new_bb->index)
4638 BB_TO_BLOCK (i) = succ->index; 4630 BB_TO_BLOCK (i) = succ->index;
4639 4631
4654 if (sched_verbose >= 4) 4646 if (sched_verbose >= 4)
4655 sel_print ("Swapping code labels %i and %i\n", 4647 sel_print ("Swapping code labels %i and %i\n",
4656 CODE_LABEL_NUMBER (BB_HEAD (new_bb)), 4648 CODE_LABEL_NUMBER (BB_HEAD (new_bb)),
4657 CODE_LABEL_NUMBER (BB_HEAD (succ))); 4649 CODE_LABEL_NUMBER (BB_HEAD (succ)));
4658 4650
4659 i = CODE_LABEL_NUMBER (BB_HEAD (new_bb)); 4651 std::swap (CODE_LABEL_NUMBER (BB_HEAD (new_bb)),
4660 CODE_LABEL_NUMBER (BB_HEAD (new_bb)) 4652 CODE_LABEL_NUMBER (BB_HEAD (succ)));
4661 = CODE_LABEL_NUMBER (BB_HEAD (succ));
4662 CODE_LABEL_NUMBER (BB_HEAD (succ)) = i;
4663 } 4653 }
4664 } 4654 }
4665 } 4655 }
4666 4656
4667 return bb; 4657 return bb;
4668 } 4658 }
4669 4659
4670 /* Return insn after which we must insert bookkeeping code for path(s) incoming 4660 /* Return insn after which we must insert bookkeeping code for path(s) incoming
4671 into E2->dest, except from E1->src. */ 4661 into E2->dest, except from E1->src. If the returned insn immediately
4662 precedes a fence, assign that fence to *FENCE_TO_REWIND. */
4672 static insn_t 4663 static insn_t
4673 find_place_for_bookkeeping (edge e1, edge e2) 4664 find_place_for_bookkeeping (edge e1, edge e2, fence_t *fence_to_rewind)
4674 { 4665 {
4675 insn_t place_to_insert; 4666 insn_t place_to_insert;
4676 /* Find a basic block that can hold bookkeeping. If it can be found, do not 4667 /* Find a basic block that can hold bookkeeping. If it can be found, do not
4677 create new basic block, but insert bookkeeping there. */ 4668 create new basic block, but insert bookkeeping there. */
4678 basic_block book_block = find_block_for_bookkeeping (e1, e2, FALSE); 4669 basic_block book_block = find_block_for_bookkeeping (e1, e2, FALSE);
4685 bookkeeping, this causes scheduling differences between debug 4676 bookkeeping, this causes scheduling differences between debug
4686 and non-debug compilations, for the block would have been 4677 and non-debug compilations, for the block would have been
4687 removed already. */ 4678 removed already. */
4688 if (DEBUG_INSN_P (place_to_insert)) 4679 if (DEBUG_INSN_P (place_to_insert))
4689 { 4680 {
4690 rtx insn = sel_bb_head (book_block); 4681 rtx_insn *insn = sel_bb_head (book_block);
4691 4682
4692 while (insn != place_to_insert && 4683 while (insn != place_to_insert &&
4693 (DEBUG_INSN_P (insn) || NOTE_P (insn))) 4684 (DEBUG_INSN_P (insn) || NOTE_P (insn)))
4694 insn = NEXT_INSN (insn); 4685 insn = NEXT_INSN (insn);
4695 4686
4710 { 4701 {
4711 if (sched_verbose >= 9) 4702 if (sched_verbose >= 9)
4712 sel_print ("Pre-existing bookkeeping block is %i\n", book_block->index); 4703 sel_print ("Pre-existing bookkeeping block is %i\n", book_block->index);
4713 } 4704 }
4714 4705
4715 /* If basic block ends with a jump, insert bookkeeping code right before it. */ 4706 *fence_to_rewind = NULL;
4707 /* If basic block ends with a jump, insert bookkeeping code right before it.
4708 Notice if we are crossing a fence when taking PREV_INSN. */
4716 if (INSN_P (place_to_insert) && control_flow_insn_p (place_to_insert)) 4709 if (INSN_P (place_to_insert) && control_flow_insn_p (place_to_insert))
4717 place_to_insert = PREV_INSN (place_to_insert); 4710 {
4711 *fence_to_rewind = flist_lookup (fences, place_to_insert);
4712 place_to_insert = PREV_INSN (place_to_insert);
4713 }
4718 4714
4719 return place_to_insert; 4715 return place_to_insert;
4720 } 4716 }
4721 4717
4722 /* Find a proper seqno for bookkeeing insn inserted at PLACE_TO_INSERT 4718 /* Find a proper seqno for bookkeeing insn inserted at PLACE_TO_INSERT
4723 for JOIN_POINT. */ 4719 for JOIN_POINT. */
4724 static int 4720 static int
4725 find_seqno_for_bookkeeping (insn_t place_to_insert, insn_t join_point) 4721 find_seqno_for_bookkeeping (insn_t place_to_insert, insn_t join_point)
4726 { 4722 {
4727 int seqno; 4723 int seqno;
4728 rtx next;
4729 4724
4730 /* Check if we are about to insert bookkeeping copy before a jump, and use 4725 /* Check if we are about to insert bookkeeping copy before a jump, and use
4731 jump's seqno for the copy; otherwise, use JOIN_POINT's seqno. */ 4726 jump's seqno for the copy; otherwise, use JOIN_POINT's seqno. */
4732 next = NEXT_INSN (place_to_insert); 4727 rtx_insn *next = NEXT_INSN (place_to_insert);
4733 if (INSN_P (next) 4728 if (INSN_P (next)
4734 && JUMP_P (next) 4729 && JUMP_P (next)
4735 && BLOCK_FOR_INSN (next) == BLOCK_FOR_INSN (place_to_insert)) 4730 && BLOCK_FOR_INSN (next) == BLOCK_FOR_INSN (place_to_insert))
4736 { 4731 {
4737 gcc_assert (INSN_SCHED_TIMES (next) == 0); 4732 gcc_assert (INSN_SCHED_TIMES (next) == 0);
4762 /* Insert bookkeeping copy of C_EXPS's insn after PLACE_TO_INSERT, assigning 4757 /* Insert bookkeeping copy of C_EXPS's insn after PLACE_TO_INSERT, assigning
4763 NEW_SEQNO to it. Return created insn. */ 4758 NEW_SEQNO to it. Return created insn. */
4764 static insn_t 4759 static insn_t
4765 emit_bookkeeping_insn (insn_t place_to_insert, expr_t c_expr, int new_seqno) 4760 emit_bookkeeping_insn (insn_t place_to_insert, expr_t c_expr, int new_seqno)
4766 { 4761 {
4767 rtx new_insn_rtx = create_copy_of_insn_rtx (EXPR_INSN_RTX (c_expr)); 4762 rtx_insn *new_insn_rtx = create_copy_of_insn_rtx (EXPR_INSN_RTX (c_expr));
4768 4763
4769 vinsn_t new_vinsn 4764 vinsn_t new_vinsn
4770 = create_vinsn_from_insn_rtx (new_insn_rtx, 4765 = create_vinsn_from_insn_rtx (new_insn_rtx,
4771 VINSN_UNIQUE_P (EXPR_VINSN (c_expr))); 4766 VINSN_UNIQUE_P (EXPR_VINSN (c_expr)));
4772 4767
4787 generate_bookkeeping_insn (expr_t c_expr, edge e1, edge e2) 4782 generate_bookkeeping_insn (expr_t c_expr, edge e1, edge e2)
4788 { 4783 {
4789 insn_t join_point, place_to_insert, new_insn; 4784 insn_t join_point, place_to_insert, new_insn;
4790 int new_seqno; 4785 int new_seqno;
4791 bool need_to_exchange_data_sets; 4786 bool need_to_exchange_data_sets;
4787 fence_t fence_to_rewind;
4792 4788
4793 if (sched_verbose >= 4) 4789 if (sched_verbose >= 4)
4794 sel_print ("Generating bookkeeping insn (%d->%d)\n", e1->src->index, 4790 sel_print ("Generating bookkeeping insn (%d->%d)\n", e1->src->index,
4795 e2->dest->index); 4791 e2->dest->index);
4796 4792
4797 join_point = sel_bb_head (e2->dest); 4793 join_point = sel_bb_head (e2->dest);
4798 place_to_insert = find_place_for_bookkeeping (e1, e2); 4794 place_to_insert = find_place_for_bookkeeping (e1, e2, &fence_to_rewind);
4799 if (!place_to_insert)
4800 return NULL;
4801 new_seqno = find_seqno_for_bookkeeping (place_to_insert, join_point); 4795 new_seqno = find_seqno_for_bookkeeping (place_to_insert, join_point);
4802 need_to_exchange_data_sets 4796 need_to_exchange_data_sets
4803 = sel_bb_empty_p (BLOCK_FOR_INSN (place_to_insert)); 4797 = sel_bb_empty_p (BLOCK_FOR_INSN (place_to_insert));
4804 4798
4805 new_insn = emit_bookkeeping_insn (place_to_insert, c_expr, new_seqno); 4799 new_insn = emit_bookkeeping_insn (place_to_insert, c_expr, new_seqno);
4800
4801 if (fence_to_rewind)
4802 FENCE_INSN (fence_to_rewind) = new_insn;
4806 4803
4807 /* When inserting bookkeeping insn in new block, av sets should be 4804 /* When inserting bookkeeping insn in new block, av sets should be
4808 following: old basic block (that now holds bookkeeping) data sets are 4805 following: old basic block (that now holds bookkeeping) data sets are
4809 the same as was before generation of bookkeeping, and new basic block 4806 the same as was before generation of bookkeeping, and new basic block
4810 (that now hold all other insns of old basic block) data sets are 4807 (that now hold all other insns of old basic block) data sets are
4840 if (!control_flow_insn_p (EXPR_INSN_RTX (expr)) 4837 if (!control_flow_insn_p (EXPR_INSN_RTX (expr))
4841 && (!bookkeeping_p || VINSN_UNIQUE_P (EXPR_VINSN (expr))) 4838 && (!bookkeeping_p || VINSN_UNIQUE_P (EXPR_VINSN (expr)))
4842 && (EXPR_SPEC (expr) 4839 && (EXPR_SPEC (expr)
4843 || !EXPR_ORIG_BB_INDEX (expr) 4840 || !EXPR_ORIG_BB_INDEX (expr)
4844 || !dominated_by_p (CDI_DOMINATORS, 4841 || !dominated_by_p (CDI_DOMINATORS,
4845 BASIC_BLOCK (EXPR_ORIG_BB_INDEX (expr)), 4842 BASIC_BLOCK_FOR_FN (cfun,
4843 EXPR_ORIG_BB_INDEX (expr)),
4846 BLOCK_FOR_INSN (FENCE_INSN (fence))))) 4844 BLOCK_FOR_INSN (FENCE_INSN (fence)))))
4847 { 4845 {
4848 if (sched_verbose >= 4) 4846 if (sched_verbose >= 4)
4849 sel_print ("Expr %d removed because it would need bookkeeping, which " 4847 sel_print ("Expr %d removed because it would need bookkeeping, which "
4850 "cannot be created\n", INSN_UID (EXPR_INSN_RTX (expr))); 4848 "cannot be created\n", INSN_UID (EXPR_INSN_RTX (expr)));
4883 (p8) mov [r14]=r23 4881 (p8) mov [r14]=r23
4884 NOTE BASIC BLOCK: 4882 NOTE BASIC BLOCK:
4885 ... 4883 ...
4886 */ 4884 */
4887 static void 4885 static void
4888 move_cond_jump (rtx insn, bnd_t bnd) 4886 move_cond_jump (rtx_insn *insn, bnd_t bnd)
4889 { 4887 {
4890 edge ft_edge; 4888 edge ft_edge;
4891 basic_block block_from, block_next, block_new, block_bnd, bb; 4889 basic_block block_from, block_next, block_new, block_bnd, bb;
4892 rtx next, prev, link, head; 4890 rtx_insn *next, *prev, *link, *head;
4893 4891
4894 block_from = BLOCK_FOR_INSN (insn); 4892 block_from = BLOCK_FOR_INSN (insn);
4895 block_bnd = BLOCK_FOR_INSN (BND_TO (bnd)); 4893 block_bnd = BLOCK_FOR_INSN (BND_TO (bnd));
4896 prev = BND_TO (bnd); 4894 prev = BND_TO (bnd);
4897 4895
4898 #ifdef ENABLE_CHECKING
4899 /* Moving of jump should not cross any other jumps or beginnings of new 4896 /* Moving of jump should not cross any other jumps or beginnings of new
4900 basic blocks. The only exception is when we move a jump through 4897 basic blocks. The only exception is when we move a jump through
4901 mutually exclusive insns along fallthru edges. */ 4898 mutually exclusive insns along fallthru edges. */
4902 if (block_from != block_bnd) 4899 if (flag_checking && block_from != block_bnd)
4903 { 4900 {
4904 bb = block_from; 4901 bb = block_from;
4905 for (link = PREV_INSN (insn); link != PREV_INSN (prev); 4902 for (link = PREV_INSN (insn); link != PREV_INSN (prev);
4906 link = PREV_INSN (link)) 4903 link = PREV_INSN (link))
4907 { 4904 {
4912 gcc_assert (single_pred (bb) == BLOCK_FOR_INSN (link)); 4909 gcc_assert (single_pred (bb) == BLOCK_FOR_INSN (link));
4913 bb = BLOCK_FOR_INSN (link); 4910 bb = BLOCK_FOR_INSN (link);
4914 } 4911 }
4915 } 4912 }
4916 } 4913 }
4917 #endif
4918 4914
4919 /* Jump is moved to the boundary. */ 4915 /* Jump is moved to the boundary. */
4920 next = PREV_INSN (insn); 4916 next = PREV_INSN (insn);
4921 BND_TO (bnd) = insn; 4917 BND_TO (bnd) = insn;
4922 4918
4934 /* Move all instructions except INSN to BLOCK_NEW. */ 4930 /* Move all instructions except INSN to BLOCK_NEW. */
4935 bb = block_bnd; 4931 bb = block_bnd;
4936 head = BB_HEAD (block_new); 4932 head = BB_HEAD (block_new);
4937 while (bb != block_from->next_bb) 4933 while (bb != block_from->next_bb)
4938 { 4934 {
4939 rtx from, to; 4935 rtx_insn *from, *to;
4940 from = bb == block_bnd ? prev : sel_bb_head (bb); 4936 from = bb == block_bnd ? prev : sel_bb_head (bb);
4941 to = bb == block_from ? next : sel_bb_end (bb); 4937 to = bb == block_from ? next : sel_bb_end (bb);
4942 4938
4943 /* The jump being moved can be the first insn in the block. 4939 /* The jump being moved can be the first insn in the block.
4944 In this case we don't have to move anything in this block. */ 4940 In this case we don't have to move anything in this block. */
4986 remove_temp_moveop_nops (bool full_tidying) 4982 remove_temp_moveop_nops (bool full_tidying)
4987 { 4983 {
4988 int i; 4984 int i;
4989 insn_t insn; 4985 insn_t insn;
4990 4986
4991 FOR_EACH_VEC_ELT (insn_t, vec_temp_moveop_nops, i, insn) 4987 FOR_EACH_VEC_ELT (vec_temp_moveop_nops, i, insn)
4992 { 4988 {
4993 gcc_assert (INSN_NOP_P (insn)); 4989 gcc_assert (INSN_NOP_P (insn));
4994 return_nop_to_pool (insn, full_tidying); 4990 return_nop_to_pool (insn, full_tidying);
4995 } 4991 }
4996 4992
4997 /* Empty the vector. */ 4993 /* Empty the vector. */
4998 if (VEC_length (insn_t, vec_temp_moveop_nops) > 0) 4994 if (vec_temp_moveop_nops.length () > 0)
4999 VEC_block_remove (insn_t, vec_temp_moveop_nops, 0, 4995 vec_temp_moveop_nops.block_remove (0, vec_temp_moveop_nops.length ());
5000 VEC_length (insn_t, vec_temp_moveop_nops));
5001 } 4996 }
5002 4997
5003 /* Records the maximal UID before moving up an instruction. Used for 4998 /* Records the maximal UID before moving up an instruction. Used for
5004 distinguishing between bookkeeping copies and original insns. */ 4999 distinguishing between bookkeeping copies and original insns. */
5005 static int max_uid_before_move_op = 0; 5000 static int max_uid_before_move_op = 0;
5146 5141
5147 /* Move nop to previous block. */ 5142 /* Move nop to previous block. */
5148 static void ATTRIBUTE_UNUSED 5143 static void ATTRIBUTE_UNUSED
5149 move_nop_to_previous_block (insn_t nop, basic_block prev_bb) 5144 move_nop_to_previous_block (insn_t nop, basic_block prev_bb)
5150 { 5145 {
5151 insn_t prev_insn, next_insn, note; 5146 insn_t prev_insn, next_insn;
5152 5147
5153 gcc_assert (sel_bb_head_p (nop) 5148 gcc_assert (sel_bb_head_p (nop)
5154 && prev_bb == BLOCK_FOR_INSN (nop)->prev_bb); 5149 && prev_bb == BLOCK_FOR_INSN (nop)->prev_bb);
5155 note = bb_note (BLOCK_FOR_INSN (nop)); 5150 rtx_note *note = bb_note (BLOCK_FOR_INSN (nop));
5156 prev_insn = sel_bb_end (prev_bb); 5151 prev_insn = sel_bb_end (prev_bb);
5157 next_insn = NEXT_INSN (nop); 5152 next_insn = NEXT_INSN (nop);
5158 gcc_assert (prev_insn != NULL_RTX 5153 gcc_assert (prev_insn != NULL_RTX
5159 && PREV_INSN (note) == prev_insn); 5154 && PREV_INSN (note) == prev_insn);
5160 5155
5161 NEXT_INSN (prev_insn) = nop; 5156 SET_NEXT_INSN (prev_insn) = nop;
5162 PREV_INSN (nop) = prev_insn; 5157 SET_PREV_INSN (nop) = prev_insn;
5163 5158
5164 PREV_INSN (note) = nop; 5159 SET_PREV_INSN (note) = nop;
5165 NEXT_INSN (note) = next_insn; 5160 SET_NEXT_INSN (note) = next_insn;
5166 5161
5167 NEXT_INSN (nop) = note; 5162 SET_NEXT_INSN (nop) = note;
5168 PREV_INSN (next_insn) = note; 5163 SET_PREV_INSN (next_insn) = note;
5169 5164
5170 BB_END (prev_bb) = nop; 5165 BB_END (prev_bb) = nop;
5171 BLOCK_FOR_INSN (nop) = prev_bb; 5166 BLOCK_FOR_INSN (nop) = prev_bb;
5172 } 5167 }
5173 5168
5328 bool asm_p; 5323 bool asm_p;
5329 5324
5330 /* First, reflect that something is scheduled on this fence. */ 5325 /* First, reflect that something is scheduled on this fence. */
5331 asm_p = advance_state_on_fence (fence, insn); 5326 asm_p = advance_state_on_fence (fence, insn);
5332 FENCE_LAST_SCHEDULED_INSN (fence) = insn; 5327 FENCE_LAST_SCHEDULED_INSN (fence) = insn;
5333 VEC_safe_push (rtx, gc, FENCE_EXECUTING_INSNS (fence), insn); 5328 vec_safe_push (FENCE_EXECUTING_INSNS (fence), insn);
5334 if (SCHED_GROUP_P (insn)) 5329 if (SCHED_GROUP_P (insn))
5335 { 5330 {
5336 FENCE_SCHED_NEXT (fence) = INSN_SCHED_NEXT (insn); 5331 FENCE_SCHED_NEXT (fence) = INSN_SCHED_NEXT (insn);
5337 SCHED_GROUP_P (insn) = 0; 5332 SCHED_GROUP_P (insn) = 0;
5338 } 5333 }
5339 else 5334 else
5340 FENCE_SCHED_NEXT (fence) = NULL_RTX; 5335 FENCE_SCHED_NEXT (fence) = NULL;
5341 if (INSN_UID (insn) < FENCE_READY_TICKS_SIZE (fence)) 5336 if (INSN_UID (insn) < FENCE_READY_TICKS_SIZE (fence))
5342 FENCE_READY_TICKS (fence) [INSN_UID (insn)] = 0; 5337 FENCE_READY_TICKS (fence) [INSN_UID (insn)] = 0;
5343 5338
5344 /* Set instruction scheduling info. This will be used in bundling, 5339 /* Set instruction scheduling info. This will be used in bundling,
5345 pipelining, tick computations etc. */ 5340 pipelining, tick computations etc. */
5520 /* Do while we can add any operation to the current group. */ 5515 /* Do while we can add any operation to the current group. */
5521 do 5516 do
5522 { 5517 {
5523 blist_t *bnds_tailp1, *bndsp; 5518 blist_t *bnds_tailp1, *bndsp;
5524 expr_t expr_vliw; 5519 expr_t expr_vliw;
5525 int need_stall; 5520 int need_stall = false;
5526 int was_stall = 0, scheduled_insns = 0; 5521 int was_stall = 0, scheduled_insns = 0;
5527 int max_insns = pipelining_p ? issue_rate : 2 * issue_rate; 5522 int max_insns = pipelining_p ? issue_rate : 2 * issue_rate;
5528 int max_stall = pipelining_p ? 1 : 3; 5523 int max_stall = pipelining_p ? 1 : 3;
5529 bool last_insn_was_debug = false; 5524 bool last_insn_was_debug = false;
5530 bool was_debug_bb_end_p = false; 5525 bool was_debug_bb_end_p = false;
5669 update_and_record_unavailable_insns (basic_block book_block) 5664 update_and_record_unavailable_insns (basic_block book_block)
5670 { 5665 {
5671 av_set_iterator i; 5666 av_set_iterator i;
5672 av_set_t old_av_set = NULL; 5667 av_set_t old_av_set = NULL;
5673 expr_t cur_expr; 5668 expr_t cur_expr;
5674 rtx bb_end = sel_bb_end (book_block); 5669 rtx_insn *bb_end = sel_bb_end (book_block);
5675 5670
5676 /* First, get correct liveness in the bookkeeping block. The problem is 5671 /* First, get correct liveness in the bookkeeping block. The problem is
5677 the range between the bookeeping insn and the end of block. */ 5672 the range between the bookeeping insn and the end of block. */
5678 update_liveness_on_insn (bb_end); 5673 update_liveness_on_insn (bb_end);
5679 if (control_flow_insn_p (bb_end)) 5674 if (control_flow_insn_p (bb_end))
5698 /* In this case, we can just turn off the E_T_A bit, but we can't 5693 /* In this case, we can just turn off the E_T_A bit, but we can't
5699 represent this information with the current vector. */ 5694 represent this information with the current vector. */
5700 || EXPR_TARGET_AVAILABLE (new_expr) 5695 || EXPR_TARGET_AVAILABLE (new_expr)
5701 != EXPR_TARGET_AVAILABLE (cur_expr)) 5696 != EXPR_TARGET_AVAILABLE (cur_expr))
5702 /* Unfortunately, the below code could be also fired up on 5697 /* Unfortunately, the below code could be also fired up on
5703 separable insns. 5698 separable insns, e.g. when moving insns through the new
5704 FIXME: add an example of how this could happen. */ 5699 speculation check as in PR 53701. */
5705 vinsn_vec_add (&vec_bookkeeping_blocked_vinsns, cur_expr); 5700 vinsn_vec_add (&vec_bookkeeping_blocked_vinsns, cur_expr);
5706 } 5701 }
5707 5702
5708 av_set_clear (&old_av_set); 5703 av_set_clear (&old_av_set);
5709 } 5704 }
5810 } 5805 }
5811 5806
5812 /* Track bookkeeping copies created, insns scheduled, and blocks for 5807 /* Track bookkeeping copies created, insns scheduled, and blocks for
5813 rescheduling when INSN is found by move_op. */ 5808 rescheduling when INSN is found by move_op. */
5814 static void 5809 static void
5815 track_scheduled_insns_and_blocks (rtx insn) 5810 track_scheduled_insns_and_blocks (rtx_insn *insn)
5816 { 5811 {
5817 /* Even if this insn can be a copy that will be removed during current move_op, 5812 /* Even if this insn can be a copy that will be removed during current move_op,
5818 we still need to count it as an originator. */ 5813 we still need to count it as an originator. */
5819 bitmap_set_bit (current_originators, INSN_UID (insn)); 5814 bitmap_set_bit (current_originators, INSN_UID (insn));
5820 5815
5837 } 5832 }
5838 5833
5839 /* Emit a register-register copy for INSN if needed. Return true if 5834 /* Emit a register-register copy for INSN if needed. Return true if
5840 emitted one. PARAMS is the move_op static parameters. */ 5835 emitted one. PARAMS is the move_op static parameters. */
5841 static bool 5836 static bool
5842 maybe_emit_renaming_copy (rtx insn, 5837 maybe_emit_renaming_copy (rtx_insn *insn,
5843 moveop_static_params_p params) 5838 moveop_static_params_p params)
5844 { 5839 {
5845 bool insn_emitted = false; 5840 bool insn_emitted = false;
5846 rtx cur_reg; 5841 rtx cur_reg;
5847 5842
5877 5872
5878 /* Emit a speculative check for INSN speculated as EXPR if needed. 5873 /* Emit a speculative check for INSN speculated as EXPR if needed.
5879 Return true if we've emitted one. PARAMS is the move_op static 5874 Return true if we've emitted one. PARAMS is the move_op static
5880 parameters. */ 5875 parameters. */
5881 static bool 5876 static bool
5882 maybe_emit_speculative_check (rtx insn, expr_t expr, 5877 maybe_emit_speculative_check (rtx_insn *insn, expr_t expr,
5883 moveop_static_params_p params) 5878 moveop_static_params_p params)
5884 { 5879 {
5885 bool insn_emitted = false; 5880 bool insn_emitted = false;
5886 insn_t x; 5881 insn_t x;
5887 ds_t check_ds; 5882 ds_t check_ds;
5906 5901
5907 /* Handle transformations that leave an insn in place of original 5902 /* Handle transformations that leave an insn in place of original
5908 insn such as renaming/speculation. Return true if one of such 5903 insn such as renaming/speculation. Return true if one of such
5909 transformations actually happened, and we have emitted this insn. */ 5904 transformations actually happened, and we have emitted this insn. */
5910 static bool 5905 static bool
5911 handle_emitting_transformations (rtx insn, expr_t expr, 5906 handle_emitting_transformations (rtx_insn *insn, expr_t expr,
5912 moveop_static_params_p params) 5907 moveop_static_params_p params)
5913 { 5908 {
5914 bool insn_emitted = false; 5909 bool insn_emitted = false;
5915 5910
5916 insn_emitted = maybe_emit_renaming_copy (insn, params); 5911 insn_emitted = maybe_emit_renaming_copy (insn, params);
5922 /* If INSN is the only insn in the basic block (not counting JUMP, 5917 /* If INSN is the only insn in the basic block (not counting JUMP,
5923 which may be a jump to next insn, and DEBUG_INSNs), we want to 5918 which may be a jump to next insn, and DEBUG_INSNs), we want to
5924 leave a NOP there till the return to fill_insns. */ 5919 leave a NOP there till the return to fill_insns. */
5925 5920
5926 static bool 5921 static bool
5927 need_nop_to_preserve_insn_bb (rtx insn) 5922 need_nop_to_preserve_insn_bb (rtx_insn *insn)
5928 { 5923 {
5929 insn_t bb_head, bb_end, bb_next, in_next; 5924 insn_t bb_head, bb_end, bb_next, in_next;
5930 basic_block bb = BLOCK_FOR_INSN (insn); 5925 basic_block bb = BLOCK_FOR_INSN (insn);
5931 5926
5932 bb_head = sel_bb_head (bb); 5927 bb_head = sel_bb_head (bb);
5965 } 5960 }
5966 5961
5967 /* Remove INSN from stream. When ONLY_DISCONNECT is true, its data 5962 /* Remove INSN from stream. When ONLY_DISCONNECT is true, its data
5968 is not removed but reused when INSN is re-emitted. */ 5963 is not removed but reused when INSN is re-emitted. */
5969 static void 5964 static void
5970 remove_insn_from_stream (rtx insn, bool only_disconnect) 5965 remove_insn_from_stream (rtx_insn *insn, bool only_disconnect)
5971 { 5966 {
5972 /* If there's only one insn in the BB, make sure that a nop is 5967 /* If there's only one insn in the BB, make sure that a nop is
5973 inserted into it, so the basic block won't disappear when we'll 5968 inserted into it, so the basic block won't disappear when we'll
5974 delete INSN below with sel_remove_insn. It should also survive 5969 delete INSN below with sel_remove_insn. It should also survive
5975 till the return to fill_insns. */ 5970 till the return to fill_insns. */
5976 if (need_nop_to_preserve_insn_bb (insn)) 5971 if (need_nop_to_preserve_insn_bb (insn))
5977 { 5972 {
5978 insn_t nop = get_nop_from_pool (insn); 5973 insn_t nop = get_nop_from_pool (insn);
5979 gcc_assert (INSN_NOP_P (nop)); 5974 gcc_assert (INSN_NOP_P (nop));
5980 VEC_safe_push (insn_t, heap, vec_temp_moveop_nops, nop); 5975 vec_temp_moveop_nops.safe_push (nop);
5981 } 5976 }
5982 5977
5983 sel_remove_insn (insn, only_disconnect, false); 5978 sel_remove_insn (insn, only_disconnect, false);
5984 } 5979 }
5985 5980
5990 static void 5985 static void
5991 move_op_orig_expr_found (insn_t insn, expr_t expr, 5986 move_op_orig_expr_found (insn_t insn, expr_t expr,
5992 cmpd_local_params_p lparams ATTRIBUTE_UNUSED, 5987 cmpd_local_params_p lparams ATTRIBUTE_UNUSED,
5993 void *static_params) 5988 void *static_params)
5994 { 5989 {
5995 bool only_disconnect, insn_emitted; 5990 bool only_disconnect;
5996 moveop_static_params_p params = (moveop_static_params_p) static_params; 5991 moveop_static_params_p params = (moveop_static_params_p) static_params;
5997 5992
5998 copy_expr_onside (params->c_expr, INSN_EXPR (insn)); 5993 copy_expr_onside (params->c_expr, INSN_EXPR (insn));
5999 track_scheduled_insns_and_blocks (insn); 5994 track_scheduled_insns_and_blocks (insn);
6000 insn_emitted = handle_emitting_transformations (insn, expr, params); 5995 handle_emitting_transformations (insn, expr, params);
6001 only_disconnect = (params->uid == INSN_UID (insn) 5996 only_disconnect = params->uid == INSN_UID (insn);
6002 && ! insn_emitted && ! EXPR_WAS_CHANGED (expr));
6003 5997
6004 /* Mark that we've disconnected an insn. */ 5998 /* Mark that we've disconnected an insn. */
6005 if (only_disconnect) 5999 if (only_disconnect)
6006 params->uid = -1; 6000 params->uid = -1;
6007 remove_insn_from_stream (insn, only_disconnect); 6001 remove_insn_from_stream (insn, only_disconnect);
6211 move_op_orig_expr_not_found (insn_t insn, av_set_t orig_ops ATTRIBUTE_UNUSED, 6205 move_op_orig_expr_not_found (insn_t insn, av_set_t orig_ops ATTRIBUTE_UNUSED,
6212 void *static_params) 6206 void *static_params)
6213 { 6207 {
6214 moveop_static_params_p sparams = (moveop_static_params_p) static_params; 6208 moveop_static_params_p sparams = (moveop_static_params_p) static_params;
6215 6209
6216 #ifdef ENABLE_CHECKING
6217 sparams->failed_insn = insn; 6210 sparams->failed_insn = insn;
6218 #endif
6219 6211
6220 /* If we're scheduling separate expr, in order to generate correct code 6212 /* If we're scheduling separate expr, in order to generate correct code
6221 we need to stop the search at bookkeeping code generated with the 6213 we need to stop the search at bookkeeping code generated with the
6222 same destination register or memory. */ 6214 same destination register or memory. */
6223 if (lhs_of_insn_equals_to_dest_p (insn, sparams->dest)) 6215 if (lhs_of_insn_equals_to_dest_p (insn, sparams->dest))
6314 code_motion_process_successors (insn_t insn, av_set_t orig_ops, 6306 code_motion_process_successors (insn_t insn, av_set_t orig_ops,
6315 ilist_t path, void *static_params) 6307 ilist_t path, void *static_params)
6316 { 6308 {
6317 int res = 0; 6309 int res = 0;
6318 succ_iterator succ_i; 6310 succ_iterator succ_i;
6319 rtx succ; 6311 insn_t succ;
6320 basic_block bb; 6312 basic_block bb;
6321 int old_index; 6313 int old_index;
6322 unsigned old_succs; 6314 unsigned old_succs;
6323 6315
6324 struct cmpd_local_params lparams; 6316 struct cmpd_local_params lparams;
6364 res = b; 6356 res = b;
6365 else if (b == -1 && res != 1) 6357 else if (b == -1 && res != 1)
6366 res = b; 6358 res = b;
6367 6359
6368 /* We have simplified the control flow below this point. In this case, 6360 /* We have simplified the control flow below this point. In this case,
6369 the iterator becomes invalid. We need to try again. */ 6361 the iterator becomes invalid. We need to try again.
6362 If we have removed the insn itself, it could be only an
6363 unconditional jump. Thus, do not rescan but break immediately --
6364 we have already visited the only successor block. */
6365 if (!BLOCK_FOR_INSN (insn))
6366 {
6367 if (sched_verbose >= 6)
6368 sel_print ("Not doing rescan: already visited the only successor"
6369 " of block %d\n", old_index);
6370 break;
6371 }
6370 if (BLOCK_FOR_INSN (insn)->index != old_index 6372 if (BLOCK_FOR_INSN (insn)->index != old_index
6371 || EDGE_COUNT (bb->succs) != old_succs) 6373 || EDGE_COUNT (bb->succs) != old_succs)
6372 goto rescan; 6374 {
6373 } 6375 if (sched_verbose >= 6)
6374 6376 sel_print ("Rescan: CFG was simplified below insn %d, block %d\n",
6375 #ifdef ENABLE_CHECKING 6377 INSN_UID (insn), BLOCK_FOR_INSN (insn)->index);
6378 insn = sel_bb_end (BLOCK_FOR_INSN (insn));
6379 goto rescan;
6380 }
6381 }
6382
6376 /* Here, RES==1 if original expr was found at least for one of the 6383 /* Here, RES==1 if original expr was found at least for one of the
6377 successors. After the loop, RES may happen to have zero value 6384 successors. After the loop, RES may happen to have zero value
6378 only if at some point the expr searched is present in av_set, but is 6385 only if at some point the expr searched is present in av_set, but is
6379 not found below. In most cases, this situation is an error. 6386 not found below. In most cases, this situation is an error.
6380 The exception is when the original operation is blocked by 6387 The exception is when the original operation is blocked by
6381 bookkeeping generated for another fence or for another path in current 6388 bookkeeping generated for another fence or for another path in current
6382 move_op. */ 6389 move_op. */
6383 gcc_assert (res == 1 6390 gcc_checking_assert (res == 1
6384 || (res == 0 6391 || (res == 0
6385 && av_set_could_be_blocked_by_bookkeeping_p (orig_ops, 6392 && av_set_could_be_blocked_by_bookkeeping_p (orig_ops, static_params))
6386 static_params)) 6393 || res == -1);
6387 || res == -1);
6388 #endif
6389 6394
6390 /* Merge data, clean up, etc. */ 6395 /* Merge data, clean up, etc. */
6391 if (res != -1 && code_motion_path_driver_info->after_merge_succs) 6396 if (res != -1 && code_motion_path_driver_info->after_merge_succs)
6392 code_motion_path_driver_info->after_merge_succs (&lparams, static_params); 6397 code_motion_path_driver_info->after_merge_succs (&lparams, static_params);
6393 6398
6459 6464
6460 if (bitmap_bit_p (code_motion_visited_blocks, bb->index)) 6465 if (bitmap_bit_p (code_motion_visited_blocks, bb->index))
6461 { 6466 {
6462 /* We have already found an original operation on this branch, do not 6467 /* We have already found an original operation on this branch, do not
6463 go any further and just return TRUE here. If we don't stop here, 6468 go any further and just return TRUE here. If we don't stop here,
6464 function can have exponential behaviour even on the small code 6469 function can have exponential behavior even on the small code
6465 with many different paths (e.g. with data speculation and 6470 with many different paths (e.g. with data speculation and
6466 recovery blocks). */ 6471 recovery blocks). */
6467 if (sched_verbose >= 6) 6472 if (sched_verbose >= 6)
6468 sel_print ("Block %d already visited in this traversal\n", bb->index); 6473 sel_print ("Block %d already visited in this traversal\n", bb->index);
6469 if (code_motion_path_driver_info->on_enter) 6474 if (code_motion_path_driver_info->on_enter)
6479 static_params, false); 6484 static_params, false);
6480 orig_ops = av_set_copy (orig_ops); 6485 orig_ops = av_set_copy (orig_ops);
6481 6486
6482 /* Filter the orig_ops set. */ 6487 /* Filter the orig_ops set. */
6483 if (AV_SET_VALID_P (insn)) 6488 if (AV_SET_VALID_P (insn))
6484 av_set_intersect (&orig_ops, AV_SET (insn)); 6489 av_set_code_motion_filter (&orig_ops, AV_SET (insn));
6485 6490
6486 /* If no more original ops, return immediately. */ 6491 /* If no more original ops, return immediately. */
6487 if (!orig_ops) 6492 if (!orig_ops)
6488 { 6493 {
6489 if (sched_verbose >= 6) 6494 if (sched_verbose >= 6)
6585 /* Here INSN either points to the insn before the original insn (may be 6590 /* Here INSN either points to the insn before the original insn (may be
6586 bb_note, if original insn was a bb_head) or to the bb_end. */ 6591 bb_note, if original insn was a bb_head) or to the bb_end. */
6587 if (!expr) 6592 if (!expr)
6588 { 6593 {
6589 int res; 6594 int res;
6595 rtx_insn *last_insn = PREV_INSN (insn);
6596 bool added_to_path;
6590 6597
6591 gcc_assert (insn == sel_bb_end (bb)); 6598 gcc_assert (insn == sel_bb_end (bb));
6592 6599
6593 /* Add bb tail to PATH (but it doesn't make any sense if it's a bb_head - 6600 /* Add bb tail to PATH (but it doesn't make any sense if it's a bb_head -
6594 it's already in PATH then). */ 6601 it's already in PATH then). */
6595 if (insn != first_insn) 6602 if (insn != first_insn)
6596 ilist_add (&path, insn); 6603 {
6604 ilist_add (&path, insn);
6605 added_to_path = true;
6606 }
6607 else
6608 added_to_path = false;
6597 6609
6598 /* Process_successors should be able to find at least one 6610 /* Process_successors should be able to find at least one
6599 successor for which code_motion_path_driver returns TRUE. */ 6611 successor for which code_motion_path_driver returns TRUE. */
6600 res = code_motion_process_successors (insn, orig_ops, 6612 res = code_motion_process_successors (insn, orig_ops,
6601 path, static_params); 6613 path, static_params);
6602 6614
6615 /* Jump in the end of basic block could have been removed or replaced
6616 during code_motion_process_successors, so recompute insn as the
6617 last insn in bb. */
6618 if (NEXT_INSN (last_insn) != insn)
6619 {
6620 insn = sel_bb_end (bb);
6621 first_insn = sel_bb_head (bb);
6622 }
6623
6603 /* Remove bb tail from path. */ 6624 /* Remove bb tail from path. */
6604 if (insn != first_insn) 6625 if (added_to_path)
6605 ilist_remove (&path); 6626 ilist_remove (&path);
6606 6627
6607 if (res != 1) 6628 if (res != 1)
6608 { 6629 {
6609 /* This is the case when one of the original expr is no longer available 6630 /* This is the case when one of the original expr is no longer available
6639 6660
6640 /* This should be the very last operation as at bb head we could change 6661 /* This should be the very last operation as at bb head we could change
6641 the numbering by creating bookkeeping blocks. */ 6662 the numbering by creating bookkeeping blocks. */
6642 if (removed_last_insn) 6663 if (removed_last_insn)
6643 insn = PREV_INSN (insn); 6664 insn = PREV_INSN (insn);
6644 bitmap_set_bit (code_motion_visited_blocks, BLOCK_FOR_INSN (insn)->index); 6665
6666 /* If we have simplified the control flow and removed the first jump insn,
6667 there's no point in marking this block in the visited blocks bitmap. */
6668 if (BLOCK_FOR_INSN (insn))
6669 bitmap_set_bit (code_motion_visited_blocks, BLOCK_FOR_INSN (insn)->index);
6645 return true; 6670 return true;
6646 } 6671 }
6647 6672
6648 /* Move up the operations from ORIG_OPS set traversing the dag starting 6673 /* Move up the operations from ORIG_OPS set traversing the dag starting
6649 from INSN. PATH represents the edges traversed so far. 6674 from INSN. PATH represents the edges traversed so far.
6659 move_op (insn_t insn, av_set_t orig_ops, expr_t expr_vliw, 6684 move_op (insn_t insn, av_set_t orig_ops, expr_t expr_vliw,
6660 rtx dest, expr_t c_expr, bool *should_move) 6685 rtx dest, expr_t c_expr, bool *should_move)
6661 { 6686 {
6662 struct moveop_static_params sparams; 6687 struct moveop_static_params sparams;
6663 struct cmpd_local_params lparams; 6688 struct cmpd_local_params lparams;
6664 bool res; 6689 int res;
6665 6690
6666 /* Init params for code_motion_path_driver. */ 6691 /* Init params for code_motion_path_driver. */
6667 sparams.dest = dest; 6692 sparams.dest = dest;
6668 sparams.c_expr = c_expr; 6693 sparams.c_expr = c_expr;
6669 sparams.uid = INSN_UID (EXPR_INSN_RTX (expr_vliw)); 6694 sparams.uid = INSN_UID (EXPR_INSN_RTX (expr_vliw));
6670 #ifdef ENABLE_CHECKING
6671 sparams.failed_insn = NULL; 6695 sparams.failed_insn = NULL;
6672 #endif
6673 sparams.was_renamed = false; 6696 sparams.was_renamed = false;
6674 lparams.e1 = NULL; 6697 lparams.e1 = NULL;
6675 6698
6676 /* We haven't visited any blocks yet. */ 6699 /* We haven't visited any blocks yet. */
6677 bitmap_clear (code_motion_visited_blocks); 6700 bitmap_clear (code_motion_visited_blocks);
6678 6701
6679 /* Set appropriate hooks and data. */ 6702 /* Set appropriate hooks and data. */
6680 code_motion_path_driver_info = &move_op_hooks; 6703 code_motion_path_driver_info = &move_op_hooks;
6681 res = code_motion_path_driver (insn, orig_ops, NULL, &lparams, &sparams); 6704 res = code_motion_path_driver (insn, orig_ops, NULL, &lparams, &sparams);
6705
6706 gcc_assert (res != -1);
6682 6707
6683 if (sparams.was_renamed) 6708 if (sparams.was_renamed)
6684 EXPR_WAS_RENAMED (expr_vliw) = true; 6709 EXPR_WAS_RENAMED (expr_vliw) = true;
6685 6710
6686 *should_move = (sparams.uid == -1); 6711 *should_move = (sparams.uid == -1);
6699 Clear visited blocks from BLOCKS_TO_RESCHEDULE. */ 6724 Clear visited blocks from BLOCKS_TO_RESCHEDULE. */
6700 static void 6725 static void
6701 init_seqno_1 (basic_block bb, sbitmap visited_bbs, bitmap blocks_to_reschedule) 6726 init_seqno_1 (basic_block bb, sbitmap visited_bbs, bitmap blocks_to_reschedule)
6702 { 6727 {
6703 int bbi = BLOCK_TO_BB (bb->index); 6728 int bbi = BLOCK_TO_BB (bb->index);
6704 insn_t insn, note = bb_note (bb); 6729 insn_t insn;
6705 insn_t succ_insn; 6730 insn_t succ_insn;
6706 succ_iterator si; 6731 succ_iterator si;
6707 6732
6708 SET_BIT (visited_bbs, bbi); 6733 rtx_note *note = bb_note (bb);
6734 bitmap_set_bit (visited_bbs, bbi);
6709 if (blocks_to_reschedule) 6735 if (blocks_to_reschedule)
6710 bitmap_clear_bit (blocks_to_reschedule, bb->index); 6736 bitmap_clear_bit (blocks_to_reschedule, bb->index);
6711 6737
6712 FOR_EACH_SUCC_1 (succ_insn, si, BB_END (bb), 6738 FOR_EACH_SUCC_1 (succ_insn, si, BB_END (bb),
6713 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS) 6739 SUCCS_NORMAL | SUCCS_SKIP_TO_LOOP_EXITS)
6715 basic_block succ = BLOCK_FOR_INSN (succ_insn); 6741 basic_block succ = BLOCK_FOR_INSN (succ_insn);
6716 int succ_bbi = BLOCK_TO_BB (succ->index); 6742 int succ_bbi = BLOCK_TO_BB (succ->index);
6717 6743
6718 gcc_assert (in_current_region_p (succ)); 6744 gcc_assert (in_current_region_p (succ));
6719 6745
6720 if (!TEST_BIT (visited_bbs, succ_bbi)) 6746 if (!bitmap_bit_p (visited_bbs, succ_bbi))
6721 { 6747 {
6722 gcc_assert (succ_bbi > bbi); 6748 gcc_assert (succ_bbi > bbi);
6723 6749
6724 init_seqno_1 (succ, visited_bbs, blocks_to_reschedule); 6750 init_seqno_1 (succ, visited_bbs, blocks_to_reschedule);
6725 } 6751 }
6729 6755
6730 for (insn = BB_END (bb); insn != note; insn = PREV_INSN (insn)) 6756 for (insn = BB_END (bb); insn != note; insn = PREV_INSN (insn))
6731 INSN_SEQNO (insn) = cur_seqno--; 6757 INSN_SEQNO (insn) = cur_seqno--;
6732 } 6758 }
6733 6759
6734 /* Initialize seqnos for the current region. NUMBER_OF_INSNS is the number 6760 /* Initialize seqnos for the current region. BLOCKS_TO_RESCHEDULE contains
6735 of instructions in the region, BLOCKS_TO_RESCHEDULE contains blocks on 6761 blocks on which we're rescheduling when pipelining, FROM is the block where
6736 which we're rescheduling when pipelining, FROM is the block where
6737 traversing region begins (it may not be the head of the region when 6762 traversing region begins (it may not be the head of the region when
6738 pipelining, but the head of the loop instead). 6763 pipelining, but the head of the loop instead).
6739 6764
6740 Returns the maximal seqno found. */ 6765 Returns the maximal seqno found. */
6741 static int 6766 static int
6742 init_seqno (int number_of_insns, bitmap blocks_to_reschedule, basic_block from) 6767 init_seqno (bitmap blocks_to_reschedule, basic_block from)
6743 { 6768 {
6744 sbitmap visited_bbs;
6745 bitmap_iterator bi; 6769 bitmap_iterator bi;
6746 unsigned bbi; 6770 unsigned bbi;
6747 6771
6748 visited_bbs = sbitmap_alloc (current_nr_blocks); 6772 auto_sbitmap visited_bbs (current_nr_blocks);
6749 6773
6750 if (blocks_to_reschedule) 6774 if (blocks_to_reschedule)
6751 { 6775 {
6752 sbitmap_ones (visited_bbs); 6776 bitmap_ones (visited_bbs);
6753 EXECUTE_IF_SET_IN_BITMAP (blocks_to_reschedule, 0, bbi, bi) 6777 EXECUTE_IF_SET_IN_BITMAP (blocks_to_reschedule, 0, bbi, bi)
6754 { 6778 {
6755 gcc_assert (BLOCK_TO_BB (bbi) < current_nr_blocks); 6779 gcc_assert (BLOCK_TO_BB (bbi) < current_nr_blocks);
6756 RESET_BIT (visited_bbs, BLOCK_TO_BB (bbi)); 6780 bitmap_clear_bit (visited_bbs, BLOCK_TO_BB (bbi));
6757 } 6781 }
6758 } 6782 }
6759 else 6783 else
6760 { 6784 {
6761 sbitmap_zero (visited_bbs); 6785 bitmap_clear (visited_bbs);
6762 from = EBB_FIRST_BB (0); 6786 from = EBB_FIRST_BB (0);
6763 } 6787 }
6764 6788
6765 cur_seqno = number_of_insns > 0 ? number_of_insns : sched_max_luid - 1; 6789 cur_seqno = sched_max_luid - 1;
6766 init_seqno_1 (from, visited_bbs, blocks_to_reschedule); 6790 init_seqno_1 (from, visited_bbs, blocks_to_reschedule);
6767 gcc_assert (cur_seqno == 0 || number_of_insns == 0); 6791
6768 6792 /* cur_seqno may be positive if the number of instructions is less than
6769 sbitmap_free (visited_bbs); 6793 sched_max_luid - 1 (when rescheduling or if some instructions have been
6794 removed by the call to purge_empty_blocks in sel_sched_region_1). */
6795 gcc_assert (cur_seqno >= 0);
6796
6770 return sched_max_luid - 1; 6797 return sched_max_luid - 1;
6771 } 6798 }
6772 6799
6773 /* Initialize scheduling parameters for current region. */ 6800 /* Initialize scheduling parameters for current region. */
6774 static void 6801 static void
6776 { 6803 {
6777 enable_schedule_as_rhs_p = 1; 6804 enable_schedule_as_rhs_p = 1;
6778 bookkeeping_p = 1; 6805 bookkeeping_p = 1;
6779 pipelining_p = (bookkeeping_p 6806 pipelining_p = (bookkeeping_p
6780 && (flag_sel_sched_pipelining != 0) 6807 && (flag_sel_sched_pipelining != 0)
6781 && current_loop_nest != NULL); 6808 && current_loop_nest != NULL
6809 && loop_has_exit_edges (current_loop_nest));
6782 max_insns_to_rename = PARAM_VALUE (PARAM_SELSCHED_INSNS_TO_RENAME); 6810 max_insns_to_rename = PARAM_VALUE (PARAM_SELSCHED_INSNS_TO_RENAME);
6783 max_ws = MAX_WS; 6811 max_ws = MAX_WS;
6784 } 6812 }
6785 6813
6786 /* Return true if all basic blocks of current region are empty. */ 6814 /* Return true if all basic blocks of current region are empty. */
6787 static bool 6815 static bool
6788 current_region_empty_p (void) 6816 current_region_empty_p (void)
6789 { 6817 {
6790 int i; 6818 int i;
6791 for (i = 0; i < current_nr_blocks; i++) 6819 for (i = 0; i < current_nr_blocks; i++)
6792 if (! sel_bb_empty_p (BASIC_BLOCK (BB_TO_BLOCK (i)))) 6820 if (! sel_bb_empty_p (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (i))))
6793 return false; 6821 return false;
6794 6822
6795 return true; 6823 return true;
6796 } 6824 }
6797 6825
6798 /* Prepare and verify loop nest for pipelining. */ 6826 /* Prepare and verify loop nest for pipelining. */
6799 static void 6827 static void
6800 setup_current_loop_nest (int rgn) 6828 setup_current_loop_nest (int rgn, bb_vec_t *bbs)
6801 { 6829 {
6802 current_loop_nest = get_loop_nest_for_rgn (rgn); 6830 current_loop_nest = get_loop_nest_for_rgn (rgn);
6803 6831
6804 if (!current_loop_nest) 6832 if (!current_loop_nest)
6805 return; 6833 return;
6806 6834
6807 /* If this loop has any saved loop preheaders from nested loops, 6835 /* If this loop has any saved loop preheaders from nested loops,
6808 add these basic blocks to the current region. */ 6836 add these basic blocks to the current region. */
6809 sel_add_loop_preheaders (); 6837 sel_add_loop_preheaders (bbs);
6810 6838
6811 /* Check that we're starting with a valid information. */ 6839 /* Check that we're starting with a valid information. */
6812 gcc_assert (loop_latch_edge (current_loop_nest)); 6840 gcc_assert (loop_latch_edge (current_loop_nest));
6813 gcc_assert (LOOP_MARKED_FOR_PIPELINING_P (current_loop_nest)); 6841 gcc_assert (LOOP_MARKED_FOR_PIPELINING_P (current_loop_nest));
6814 } 6842 }
6843 do region initialization here so the region can be bundled correctly, 6871 do region initialization here so the region can be bundled correctly,
6844 but we'll skip the scheduling in sel_sched_region (). */ 6872 but we'll skip the scheduling in sel_sched_region (). */
6845 if (current_region_empty_p ()) 6873 if (current_region_empty_p ())
6846 return true; 6874 return true;
6847 6875
6876 bbs.create (current_nr_blocks);
6877
6878 for (i = 0; i < current_nr_blocks; i++)
6879 bbs.quick_push (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (i)));
6880
6881 sel_init_bbs (bbs);
6882
6848 if (flag_sel_sched_pipelining) 6883 if (flag_sel_sched_pipelining)
6849 setup_current_loop_nest (rgn); 6884 setup_current_loop_nest (rgn, &bbs);
6850 6885
6851 sel_setup_region_sched_flags (); 6886 sel_setup_region_sched_flags ();
6852
6853 bbs = VEC_alloc (basic_block, heap, current_nr_blocks);
6854
6855 for (i = 0; i < current_nr_blocks; i++)
6856 VEC_quick_push (basic_block, bbs, BASIC_BLOCK (BB_TO_BLOCK (i)));
6857
6858 sel_init_bbs (bbs, NULL);
6859 6887
6860 /* Initialize luids and dependence analysis which both sel-sched and haifa 6888 /* Initialize luids and dependence analysis which both sel-sched and haifa
6861 need. */ 6889 need. */
6862 sched_init_luids (bbs, NULL, NULL, NULL); 6890 sched_init_luids (bbs);
6863 sched_deps_init (false); 6891 sched_deps_init (false);
6864 6892
6865 /* Initialize haifa data. */ 6893 /* Initialize haifa data. */
6866 rgn_setup_sched_infos (); 6894 rgn_setup_sched_infos ();
6867 sel_set_sched_flags (); 6895 sel_set_sched_flags ();
6868 haifa_init_h_i_d (bbs, NULL, NULL, NULL); 6896 haifa_init_h_i_d (bbs);
6869 6897
6870 sel_compute_priorities (rgn); 6898 sel_compute_priorities (rgn);
6871 init_deps_global (); 6899 init_deps_global ();
6872 6900
6873 /* Main initialization. */ 6901 /* Main initialization. */
6874 sel_setup_sched_infos (); 6902 sel_setup_sched_infos ();
6875 sel_init_global_and_expr (bbs); 6903 sel_init_global_and_expr (bbs);
6876 6904
6877 VEC_free (basic_block, heap, bbs); 6905 bbs.release ();
6878 6906
6879 blocks_to_reschedule = BITMAP_ALLOC (NULL); 6907 blocks_to_reschedule = BITMAP_ALLOC (NULL);
6880 6908
6881 /* Init correct liveness sets on each instruction of a single-block loop. 6909 /* Init correct liveness sets on each instruction of a single-block loop.
6882 This is the only situation when we can't update liveness when calling 6910 This is the only situation when we can't update liveness when calling
6883 compute_live for the first insn of the loop. */ 6911 compute_live for the first insn of the loop. */
6884 if (current_loop_nest) 6912 if (current_loop_nest)
6885 { 6913 {
6886 int header = (sel_is_loop_preheader_p (BASIC_BLOCK (BB_TO_BLOCK (0))) 6914 int header =
6887 ? 1 6915 (sel_is_loop_preheader_p (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (0)))
6888 : 0); 6916 ? 1
6917 : 0);
6889 6918
6890 if (current_nr_blocks == header + 1) 6919 if (current_nr_blocks == header + 1)
6891 update_liveness_on_insn 6920 update_liveness_on_insn
6892 (sel_bb_head (BASIC_BLOCK (BB_TO_BLOCK (header)))); 6921 (sel_bb_head (BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (header))));
6893 } 6922 }
6894 6923
6895 /* Set hooks so that no newly generated insn will go out unnoticed. */ 6924 /* Set hooks so that no newly generated insn will go out unnoticed. */
6896 sel_register_cfg_hooks (); 6925 sel_register_cfg_hooks ();
6897 6926
6925 { 6954 {
6926 int i; 6955 int i;
6927 6956
6928 for (i = 0; i < current_nr_blocks; i++) 6957 for (i = 0; i < current_nr_blocks; i++)
6929 { 6958 {
6930 basic_block bb = BASIC_BLOCK (BB_TO_BLOCK (i)); 6959 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, BB_TO_BLOCK (i));
6931 rtx insn; 6960 rtx_insn *insn;
6932 6961
6933 FOR_BB_INSNS (bb, insn) 6962 FOR_BB_INSNS (bb, insn)
6934 if (INSN_P (insn)) 6963 if (INSN_P (insn))
6935 { 6964 {
6936 expr_t expr = INSN_EXPR (insn); 6965 expr_t expr = INSN_EXPR (insn);
6945 this EBB in SCHEDULED_BLOCKS and appropriately filling in HEAD, TAIL, 6974 this EBB in SCHEDULED_BLOCKS and appropriately filling in HEAD, TAIL,
6946 PREV_HEAD, and NEXT_TAIL fields of CURRENT_SCHED_INFO structure. */ 6975 PREV_HEAD, and NEXT_TAIL fields of CURRENT_SCHED_INFO structure. */
6947 static void 6976 static void
6948 find_ebb_boundaries (basic_block bb, bitmap scheduled_blocks) 6977 find_ebb_boundaries (basic_block bb, bitmap scheduled_blocks)
6949 { 6978 {
6950 insn_t head, tail; 6979 rtx_insn *head, *tail;
6951 basic_block bb1 = bb; 6980 basic_block bb1 = bb;
6952 if (sched_verbose >= 2) 6981 if (sched_verbose >= 2)
6953 sel_print ("Finishing schedule in bbs: "); 6982 sel_print ("Finishing schedule in bbs: ");
6954 6983
6955 do 6984 do
7100 } 7129 }
7101 } 7130 }
7102 7131
7103 if (real_insn) 7132 if (real_insn)
7104 { 7133 {
7134 static state_t temp = NULL;
7135
7136 if (!temp)
7137 temp = xmalloc (dfa_state_size);
7138 memcpy (temp, curr_state, dfa_state_size);
7139
7105 cost = state_transition (curr_state, insn); 7140 cost = state_transition (curr_state, insn);
7106 issued_insns++; 7141 if (memcmp (temp, curr_state, dfa_state_size))
7142 issued_insns++;
7107 7143
7108 if (sched_verbose >= 2) 7144 if (sched_verbose >= 2)
7109 { 7145 {
7110 sel_print ("scheduled insn %d, clock %d\n", INSN_UID (insn), 7146 sel_print ("scheduled insn %d, clock %d\n", INSN_UID (insn),
7111 haifa_clock + 1); 7147 haifa_clock + 1);
7195 { 7231 {
7196 targetm.sched.finish (sched_dump, sched_verbose); 7232 targetm.sched.finish (sched_dump, sched_verbose);
7197 7233
7198 /* Extend luids so that insns generated by the target will 7234 /* Extend luids so that insns generated by the target will
7199 get zero luid. */ 7235 get zero luid. */
7200 sched_init_luids (NULL, NULL, NULL, NULL); 7236 sched_extend_luids ();
7201 } 7237 }
7202 } 7238 }
7203 7239
7204 BITMAP_FREE (scheduled_blocks); 7240 BITMAP_FREE (scheduled_blocks);
7205 } 7241 }
7213 simplify_changed_insns (); 7249 simplify_changed_insns ();
7214 sched_finish_ready_list (); 7250 sched_finish_ready_list ();
7215 free_nop_pool (); 7251 free_nop_pool ();
7216 7252
7217 /* Free the vectors. */ 7253 /* Free the vectors. */
7218 if (vec_av_set) 7254 vec_av_set.release ();
7219 VEC_free (expr_t, heap, vec_av_set);
7220 BITMAP_FREE (current_copies); 7255 BITMAP_FREE (current_copies);
7221 BITMAP_FREE (current_originators); 7256 BITMAP_FREE (current_originators);
7222 BITMAP_FREE (code_motion_visited_blocks); 7257 BITMAP_FREE (code_motion_visited_blocks);
7223 vinsn_vec_free (&vec_bookkeeping_blocked_vinsns); 7258 vinsn_vec_free (vec_bookkeeping_blocked_vinsns);
7224 vinsn_vec_free (&vec_target_unavailable_vinsns); 7259 vinsn_vec_free (vec_target_unavailable_vinsns);
7225 7260
7226 /* If LV_SET of the region head should be updated, do it now because 7261 /* If LV_SET of the region head should be updated, do it now because
7227 there will be no other chance. */ 7262 there will be no other chance. */
7228 { 7263 {
7229 succ_iterator si; 7264 succ_iterator si;
7249 7284
7250 free_nop_vinsn (); 7285 free_nop_vinsn ();
7251 7286
7252 finish_deps_global (); 7287 finish_deps_global ();
7253 sched_finish_luids (); 7288 sched_finish_luids ();
7289 h_d_i_d.release ();
7254 7290
7255 sel_finish_bbs (); 7291 sel_finish_bbs ();
7256 BITMAP_FREE (blocks_to_reschedule); 7292 BITMAP_FREE (blocks_to_reschedule);
7257 7293
7258 sel_unregister_cfg_hooks (); 7294 sel_unregister_cfg_hooks ();
7344 else if (*max_seqno < seqno) 7380 else if (*max_seqno < seqno)
7345 *max_seqno = seqno; 7381 *max_seqno = seqno;
7346 } 7382 }
7347 } 7383 }
7348 7384
7349 /* Calculate new fences from FENCES. */ 7385 /* Calculate new fences from FENCES. Write the current time to PTIME. */
7350 static flist_t 7386 static flist_t
7351 calculate_new_fences (flist_t fences, int orig_max_seqno) 7387 calculate_new_fences (flist_t fences, int orig_max_seqno, int *ptime)
7352 { 7388 {
7353 flist_t old_fences = fences; 7389 flist_t old_fences = fences;
7354 struct flist_tail_def _new_fences, *new_fences = &_new_fences; 7390 struct flist_tail_def _new_fences, *new_fences = &_new_fences;
7391 int max_time = 0;
7355 7392
7356 flist_tail_init (new_fences); 7393 flist_tail_init (new_fences);
7357 for (; fences; fences = FLIST_NEXT (fences)) 7394 for (; fences; fences = FLIST_NEXT (fences))
7358 { 7395 {
7359 fence_t fence = FLIST_FENCE (fences); 7396 fence_t fence = FLIST_FENCE (fences);
7378 move_fence_to_fences (fences, new_fences); 7415 move_fence_to_fences (fences, new_fences);
7379 } 7416 }
7380 } 7417 }
7381 else 7418 else
7382 extract_new_fences_from (fences, new_fences, orig_max_seqno); 7419 extract_new_fences_from (fences, new_fences, orig_max_seqno);
7420 max_time = MAX (max_time, FENCE_CYCLE (fence));
7383 } 7421 }
7384 7422
7385 flist_clear (&old_fences); 7423 flist_clear (&old_fences);
7424 *ptime = max_time;
7386 return FLIST_TAIL_HEAD (new_fences); 7425 return FLIST_TAIL_HEAD (new_fences);
7387 } 7426 }
7388 7427
7389 /* Update seqnos of insns given by PSCHEDULED_INSNS. MIN_SEQNO and MAX_SEQNO 7428 /* Update seqnos of insns given by PSCHEDULED_INSNS. MIN_SEQNO and MAX_SEQNO
7390 are the miminum and maximum seqnos of the group, HIGHEST_SEQNO_IN_USE is 7429 are the miminum and maximum seqnos of the group, HIGHEST_SEQNO_IN_USE is
7435 of scheduling. */ 7474 of scheduling. */
7436 static void 7475 static void
7437 sel_sched_region_2 (int orig_max_seqno) 7476 sel_sched_region_2 (int orig_max_seqno)
7438 { 7477 {
7439 int highest_seqno_in_use = orig_max_seqno; 7478 int highest_seqno_in_use = orig_max_seqno;
7479 int max_time = 0;
7440 7480
7441 stat_bookkeeping_copies = 0; 7481 stat_bookkeeping_copies = 0;
7442 stat_insns_needed_bookkeeping = 0; 7482 stat_insns_needed_bookkeeping = 0;
7443 stat_renamed_scheduled = 0; 7483 stat_renamed_scheduled = 0;
7444 stat_substitutions_total = 0; 7484 stat_substitutions_total = 0;
7450 ilist_t scheduled_insns = NULL; 7490 ilist_t scheduled_insns = NULL;
7451 ilist_t *scheduled_insns_tailp = &scheduled_insns; 7491 ilist_t *scheduled_insns_tailp = &scheduled_insns;
7452 7492
7453 find_min_max_seqno (fences, &min_seqno, &max_seqno); 7493 find_min_max_seqno (fences, &min_seqno, &max_seqno);
7454 schedule_on_fences (fences, max_seqno, &scheduled_insns_tailp); 7494 schedule_on_fences (fences, max_seqno, &scheduled_insns_tailp);
7455 fences = calculate_new_fences (fences, orig_max_seqno); 7495 fences = calculate_new_fences (fences, orig_max_seqno, &max_time);
7456 highest_seqno_in_use = update_seqnos_and_stage (min_seqno, max_seqno, 7496 highest_seqno_in_use = update_seqnos_and_stage (min_seqno, max_seqno,
7457 highest_seqno_in_use, 7497 highest_seqno_in_use,
7458 &scheduled_insns); 7498 &scheduled_insns);
7459 } 7499 }
7460 7500
7461 if (sched_verbose >= 1) 7501 if (sched_verbose >= 1)
7462 sel_print ("Scheduled %d bookkeeping copies, %d insns needed " 7502 {
7463 "bookkeeping, %d insns renamed, %d insns substituted\n", 7503 sel_print ("Total scheduling time: %d cycles\n", max_time);
7464 stat_bookkeeping_copies, 7504 sel_print ("Scheduled %d bookkeeping copies, %d insns needed "
7465 stat_insns_needed_bookkeeping, 7505 "bookkeeping, %d insns renamed, %d insns substituted\n",
7466 stat_renamed_scheduled, 7506 stat_bookkeeping_copies,
7467 stat_substitutions_total); 7507 stat_insns_needed_bookkeeping,
7508 stat_renamed_scheduled,
7509 stat_substitutions_total);
7510 }
7468 } 7511 }
7469 7512
7470 /* Schedule a region. When pipelining, search for possibly never scheduled 7513 /* Schedule a region. When pipelining, search for possibly never scheduled
7471 bookkeeping code and schedule it. Reschedule pipelined code without 7514 bookkeeping code and schedule it. Reschedule pipelined code without
7472 pipelining after. */ 7515 pipelining after. */
7473 static void 7516 static void
7474 sel_sched_region_1 (void) 7517 sel_sched_region_1 (void)
7475 { 7518 {
7476 int number_of_insns;
7477 int orig_max_seqno; 7519 int orig_max_seqno;
7478 7520
7479 /* Remove empty blocks that might be in the region from the beginning. 7521 /* Remove empty blocks that might be in the region from the beginning. */
7480 We need to do save sched_max_luid before that, as it actually shows
7481 the number of insns in the region, and purge_empty_blocks can
7482 alter it. */
7483 number_of_insns = sched_max_luid - 1;
7484 purge_empty_blocks (); 7522 purge_empty_blocks ();
7485 7523
7486 orig_max_seqno = init_seqno (number_of_insns, NULL, NULL); 7524 orig_max_seqno = init_seqno (NULL, NULL);
7487 gcc_assert (orig_max_seqno >= 1); 7525 gcc_assert (orig_max_seqno >= 1);
7488 7526
7489 /* When pipelining outer loops, create fences on the loop header, 7527 /* When pipelining outer loops, create fences on the loop header,
7490 not preheader. */ 7528 not preheader. */
7491 fences = NULL; 7529 fences = NULL;
7558 7596
7559 if (bitmap_bit_p (blocks_to_reschedule, bb->index)) 7597 if (bitmap_bit_p (blocks_to_reschedule, bb->index))
7560 { 7598 {
7561 flist_tail_init (new_fences); 7599 flist_tail_init (new_fences);
7562 7600
7563 orig_max_seqno = init_seqno (0, blocks_to_reschedule, bb); 7601 orig_max_seqno = init_seqno (blocks_to_reschedule, bb);
7564 7602
7565 /* Mark BB as head of the new ebb. */ 7603 /* Mark BB as head of the new ebb. */
7566 bitmap_set_bit (forced_ebb_heads, bb->index); 7604 bitmap_set_bit (forced_ebb_heads, bb->index);
7567 7605
7568 gcc_assert (fences == NULL); 7606 gcc_assert (fences == NULL);
7664 void 7702 void
7665 run_selective_scheduling (void) 7703 run_selective_scheduling (void)
7666 { 7704 {
7667 int rgn; 7705 int rgn;
7668 7706
7669 if (n_basic_blocks == NUM_FIXED_BLOCKS) 7707 if (n_basic_blocks_for_fn (cfun) == NUM_FIXED_BLOCKS)
7670 return; 7708 return;
7671 7709
7672 sel_global_init (); 7710 sel_global_init ();
7673 7711
7674 for (rgn = 0; rgn < nr_regions; rgn++) 7712 for (rgn = 0; rgn < nr_regions; rgn++)