Mercurial > hg > CbC > CbC_gcc
comparison gcc/reginfo.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
99 #else | 99 #else |
100 #define CALL_REALLY_USED_REGNO_P(X) call_used_regs[X] | 100 #define CALL_REALLY_USED_REGNO_P(X) call_used_regs[X] |
101 #endif | 101 #endif |
102 | 102 |
103 | 103 |
104 /* Indexed by hard register number, contains 1 for registers that are | 104 /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- or |
105 fixed use or call used registers that cannot hold quantities across | 105 a function value return register or TARGET_STRUCT_VALUE_RTX or |
106 calls even if we are willing to save and restore them. call fixed | 106 STATIC_CHAIN_REGNUM. These are the registers that cannot hold quantities |
107 registers are a subset of call used registers. */ | 107 across calls even if we are willing to save and restore them. */ |
108 char call_fixed_regs[FIRST_PSEUDO_REGISTER]; | 108 |
109 | |
110 /* The same info as a HARD_REG_SET. */ | |
111 HARD_REG_SET call_fixed_reg_set; | 109 HARD_REG_SET call_fixed_reg_set; |
112 | 110 |
113 /* Indexed by hard register number, contains 1 for registers | 111 /* Indexed by hard register number, contains 1 for registers |
114 that are being used for global register decls. | 112 that are being used for global register decls. |
115 These must be exempt from ordinary flow analysis | 113 These must be exempt from ordinary flow analysis |
275 int cost; | 273 int cost; |
276 if (!contains_reg_of_mode[j][m]) | 274 if (!contains_reg_of_mode[j][m]) |
277 cost = 65535; | 275 cost = 65535; |
278 else | 276 else |
279 { | 277 { |
280 cost = REGISTER_MOVE_COST (m, i, j); | 278 cost = REGISTER_MOVE_COST (m, (enum reg_class) i, |
279 (enum reg_class) j); | |
281 gcc_assert (cost < 65535); | 280 gcc_assert (cost < 65535); |
282 } | 281 } |
283 all_match &= (last_move_cost[i][j] == cost); | 282 all_match &= (last_move_cost[i][j] == cost); |
284 last_move_cost[i][j] = cost; | 283 last_move_cost[i][j] = cost; |
285 } | 284 } |
325 cost = MAX (cost, move_cost[m][*p1][j]); | 324 cost = MAX (cost, move_cost[m][*p1][j]); |
326 | 325 |
327 gcc_assert (cost <= 65535); | 326 gcc_assert (cost <= 65535); |
328 move_cost[m][i][j] = cost; | 327 move_cost[m][i][j] = cost; |
329 | 328 |
330 if (reg_class_subset_p (i, j)) | 329 if (reg_class_subset_p ((enum reg_class) i, (enum reg_class) j)) |
331 may_move_in_cost[m][i][j] = 0; | 330 may_move_in_cost[m][i][j] = 0; |
332 else | 331 else |
333 may_move_in_cost[m][i][j] = cost; | 332 may_move_in_cost[m][i][j] = cost; |
334 | 333 |
335 if (reg_class_subset_p (j, i)) | 334 if (reg_class_subset_p ((enum reg_class) j, (enum reg_class) i)) |
336 may_move_out_cost[m][i][j] = 0; | 335 may_move_out_cost[m][i][j] = 0; |
337 else | 336 else |
338 may_move_out_cost[m][i][j] = cost; | 337 may_move_out_cost[m][i][j] = cost; |
339 } | 338 } |
340 } | 339 } |
512 regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack); | 511 regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack); |
513 } | 512 } |
514 else | 513 else |
515 CLEAR_REG_SET (regs_invalidated_by_call_regset); | 514 CLEAR_REG_SET (regs_invalidated_by_call_regset); |
516 | 515 |
517 memcpy (call_fixed_regs, fixed_regs, sizeof call_fixed_regs); | |
518 | |
519 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | 516 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
520 { | 517 { |
521 /* call_used_regs must include fixed_regs. */ | 518 /* call_used_regs must include fixed_regs. */ |
522 gcc_assert (!fixed_regs[i] || call_used_regs[i]); | 519 gcc_assert (!fixed_regs[i] || call_used_regs[i]); |
523 #ifdef CALL_REALLY_USED_REGISTERS | 520 #ifdef CALL_REALLY_USED_REGISTERS |
528 if (fixed_regs[i]) | 525 if (fixed_regs[i]) |
529 SET_HARD_REG_BIT (fixed_reg_set, i); | 526 SET_HARD_REG_BIT (fixed_reg_set, i); |
530 | 527 |
531 if (call_used_regs[i]) | 528 if (call_used_regs[i]) |
532 SET_HARD_REG_BIT (call_used_reg_set, i); | 529 SET_HARD_REG_BIT (call_used_reg_set, i); |
533 if (call_fixed_regs[i]) | |
534 SET_HARD_REG_BIT (call_fixed_reg_set, i); | |
535 | 530 |
536 /* There are a couple of fixed registers that we know are safe to | 531 /* There are a couple of fixed registers that we know are safe to |
537 exclude from being clobbered by calls: | 532 exclude from being clobbered by calls: |
538 | 533 |
539 The frame pointer is always preserved across calls. The arg pointer | 534 The frame pointer is always preserved across calls. The arg pointer |
568 SET_HARD_REG_BIT (regs_invalidated_by_call, i); | 563 SET_HARD_REG_BIT (regs_invalidated_by_call, i); |
569 SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); | 564 SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i); |
570 } | 565 } |
571 } | 566 } |
572 | 567 |
568 COPY_HARD_REG_SET(call_fixed_reg_set, fixed_reg_set); | |
569 | |
573 /* Preserve global registers if called more than once. */ | 570 /* Preserve global registers if called more than once. */ |
574 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | 571 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) |
575 { | 572 { |
576 if (global_regs[i]) | 573 if (global_regs[i]) |
577 { | 574 { |
578 fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1; | 575 fixed_regs[i] = call_used_regs[i] = 1; |
579 SET_HARD_REG_BIT (fixed_reg_set, i); | 576 SET_HARD_REG_BIT (fixed_reg_set, i); |
580 SET_HARD_REG_BIT (call_used_reg_set, i); | 577 SET_HARD_REG_BIT (call_used_reg_set, i); |
581 SET_HARD_REG_BIT (call_fixed_reg_set, i); | 578 SET_HARD_REG_BIT (call_fixed_reg_set, i); |
582 } | 579 } |
583 } | 580 } |
587 for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++) | 584 for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++) |
588 { | 585 { |
589 HARD_REG_SET ok_regs; | 586 HARD_REG_SET ok_regs; |
590 CLEAR_HARD_REG_SET (ok_regs); | 587 CLEAR_HARD_REG_SET (ok_regs); |
591 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++) | 588 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++) |
592 if (!fixed_regs [j] && HARD_REGNO_MODE_OK (j, m)) | 589 if (!fixed_regs [j] && HARD_REGNO_MODE_OK (j, (enum machine_mode) m)) |
593 SET_HARD_REG_BIT (ok_regs, j); | 590 SET_HARD_REG_BIT (ok_regs, j); |
594 | 591 |
595 for (i = 0; i < N_REG_CLASSES; i++) | 592 for (i = 0; i < N_REG_CLASSES; i++) |
596 if ((unsigned) CLASS_MAX_NREGS (i, m) <= reg_class_size[i] | 593 if (((unsigned) CLASS_MAX_NREGS ((enum reg_class) i, |
594 (enum machine_mode) m) | |
595 <= reg_class_size[i]) | |
597 && hard_reg_set_intersect_p (ok_regs, reg_class_contents[i])) | 596 && hard_reg_set_intersect_p (ok_regs, reg_class_contents[i])) |
598 { | 597 { |
599 contains_reg_of_mode [i][m] = 1; | 598 contains_reg_of_mode [i][m] = 1; |
600 have_regs_of_mode [m] = 1; | 599 have_regs_of_mode [m] = 1; |
601 } | 600 } |
674 memory_move_secondary_cost. */ | 673 memory_move_secondary_cost. */ |
675 void | 674 void |
676 init_fake_stack_mems (void) | 675 init_fake_stack_mems (void) |
677 { | 676 { |
678 int i; | 677 int i; |
679 | 678 |
680 for (i = 0; i < MAX_MACHINE_MODE; i++) | 679 for (i = 0; i < MAX_MACHINE_MODE; i++) |
681 top_of_stack[i] = gen_rtx_MEM (i, stack_pointer_rtx); | 680 top_of_stack[i] = gen_rtx_MEM ((enum machine_mode) i, stack_pointer_rtx); |
682 } | 681 } |
683 | 682 |
684 | 683 |
685 /* Compute extra cost of moving registers to/from memory due to reloads. | 684 /* Compute extra cost of moving registers to/from memory due to reloads. |
686 Only needed if secondary reloads are required for memory moves. */ | 685 Only needed if secondary reloads are required for memory moves. */ |
865 | 864 |
866 /* If already fixed, nothing else to do. */ | 865 /* If already fixed, nothing else to do. */ |
867 if (fixed_regs[i]) | 866 if (fixed_regs[i]) |
868 return; | 867 return; |
869 | 868 |
870 fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1; | 869 fixed_regs[i] = call_used_regs[i] = 1; |
871 #ifdef CALL_REALLY_USED_REGISTERS | 870 #ifdef CALL_REALLY_USED_REGISTERS |
872 call_really_used_regs[i] = 1; | 871 call_really_used_regs[i] = 1; |
873 #endif | 872 #endif |
874 | 873 |
875 SET_HARD_REG_BIT (fixed_reg_set, i); | 874 SET_HARD_REG_BIT (fixed_reg_set, i); |
893 | 892 |
894 It might appear to be more general to have a bitmask of classes here, | 893 It might appear to be more general to have a bitmask of classes here, |
895 but since it is recommended that there be a class corresponding to the | 894 but since it is recommended that there be a class corresponding to the |
896 union of most major pair of classes, that generality is not required. */ | 895 union of most major pair of classes, that generality is not required. */ |
897 char altclass; | 896 char altclass; |
897 | |
898 /* coverclass is a register class that IRA uses for allocating | |
899 the pseudo. */ | |
900 char coverclass; | |
898 }; | 901 }; |
899 | 902 |
900 /* Record preferences of each pseudo. This is available after RA is | 903 /* Record preferences of each pseudo. This is available after RA is |
901 run. */ | 904 run. */ |
902 static struct reg_pref *reg_pref; | 905 static struct reg_pref *reg_pref; |
906 | |
907 /* Current size of reg_info. */ | |
908 static int reg_info_size; | |
903 | 909 |
904 /* Return the reg_class in which pseudo reg number REGNO is best allocated. | 910 /* Return the reg_class in which pseudo reg number REGNO is best allocated. |
905 This function is sometimes called before the info has been computed. | 911 This function is sometimes called before the info has been computed. |
906 When that happens, just return GENERAL_REGS, which is innocuous. */ | 912 When that happens, just return GENERAL_REGS, which is innocuous. */ |
907 enum reg_class | 913 enum reg_class |
920 return ALL_REGS; | 926 return ALL_REGS; |
921 | 927 |
922 return (enum reg_class) reg_pref[regno].altclass; | 928 return (enum reg_class) reg_pref[regno].altclass; |
923 } | 929 } |
924 | 930 |
931 /* Return the reg_class which is used by IRA for its allocation. */ | |
932 enum reg_class | |
933 reg_cover_class (int regno) | |
934 { | |
935 if (reg_pref == 0) | |
936 return NO_REGS; | |
937 | |
938 return (enum reg_class) reg_pref[regno].coverclass; | |
939 } | |
940 | |
941 | |
942 | |
943 /* Allocate space for reg info. */ | |
944 static void | |
945 allocate_reg_info (void) | |
946 { | |
947 reg_info_size = max_reg_num (); | |
948 gcc_assert (! reg_pref && ! reg_renumber); | |
949 reg_renumber = XNEWVEC (short, reg_info_size); | |
950 reg_pref = XCNEWVEC (struct reg_pref, reg_info_size); | |
951 memset (reg_renumber, -1, reg_info_size * sizeof (short)); | |
952 } | |
953 | |
954 | |
955 /* Resize reg info. The new elements will be uninitialized. Return | |
956 TRUE if new elements (for new pseudos) were added. */ | |
957 bool | |
958 resize_reg_info (void) | |
959 { | |
960 int old; | |
961 | |
962 if (reg_pref == NULL) | |
963 { | |
964 allocate_reg_info (); | |
965 return true; | |
966 } | |
967 if (reg_info_size == max_reg_num ()) | |
968 return false; | |
969 old = reg_info_size; | |
970 reg_info_size = max_reg_num (); | |
971 gcc_assert (reg_pref && reg_renumber); | |
972 reg_renumber = XRESIZEVEC (short, reg_renumber, reg_info_size); | |
973 reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, reg_info_size); | |
974 memset (reg_pref + old, -1, | |
975 (reg_info_size - old) * sizeof (struct reg_pref)); | |
976 memset (reg_renumber + old, -1, (reg_info_size - old) * sizeof (short)); | |
977 return true; | |
978 } | |
979 | |
980 | |
981 /* Free up the space allocated by allocate_reg_info. */ | |
982 void | |
983 free_reg_info (void) | |
984 { | |
985 if (reg_pref) | |
986 { | |
987 free (reg_pref); | |
988 reg_pref = NULL; | |
989 } | |
990 | |
991 if (reg_renumber) | |
992 { | |
993 free (reg_renumber); | |
994 reg_renumber = NULL; | |
995 } | |
996 } | |
997 | |
925 /* Initialize some global data for this pass. */ | 998 /* Initialize some global data for this pass. */ |
926 static unsigned int | 999 static unsigned int |
927 reginfo_init (void) | 1000 reginfo_init (void) |
928 { | 1001 { |
929 if (df) | 1002 if (df) |
930 df_compute_regs_ever_live (true); | 1003 df_compute_regs_ever_live (true); |
931 | 1004 |
932 /* This prevents dump_flow_info from losing if called | 1005 /* This prevents dump_flow_info from losing if called |
933 before reginfo is run. */ | 1006 before reginfo is run. */ |
934 reg_pref = NULL; | 1007 reg_pref = NULL; |
935 | |
936 /* No more global register variables may be declared. */ | 1008 /* No more global register variables may be declared. */ |
937 no_global_reg_vars = 1; | 1009 no_global_reg_vars = 1; |
938 return 1; | 1010 return 1; |
939 } | 1011 } |
940 | 1012 |
946 NULL, /* gate */ | 1018 NULL, /* gate */ |
947 reginfo_init, /* execute */ | 1019 reginfo_init, /* execute */ |
948 NULL, /* sub */ | 1020 NULL, /* sub */ |
949 NULL, /* next */ | 1021 NULL, /* next */ |
950 0, /* static_pass_number */ | 1022 0, /* static_pass_number */ |
951 0, /* tv_id */ | 1023 TV_NONE, /* tv_id */ |
952 0, /* properties_required */ | 1024 0, /* properties_required */ |
953 0, /* properties_provided */ | 1025 0, /* properties_provided */ |
954 0, /* properties_destroyed */ | 1026 0, /* properties_destroyed */ |
955 0, /* todo_flags_start */ | 1027 0, /* todo_flags_start */ |
956 0 /* todo_flags_finish */ | 1028 0 /* todo_flags_finish */ |
957 } | 1029 } |
958 }; | 1030 }; |
959 | 1031 |
960 | 1032 |
961 | 1033 |
962 /* Allocate space for reg info. */ | 1034 /* Set up preferred, alternate, and cover classes for REGNO as |
963 void | 1035 PREFCLASS, ALTCLASS, and COVERCLASS. */ |
964 allocate_reg_info (void) | |
965 { | |
966 int size = max_reg_num (); | |
967 | |
968 gcc_assert (! reg_pref && ! reg_renumber); | |
969 reg_renumber = XNEWVEC (short, size); | |
970 reg_pref = XCNEWVEC (struct reg_pref, size); | |
971 memset (reg_renumber, -1, size * sizeof (short)); | |
972 } | |
973 | |
974 | |
975 /* Resize reg info. The new elements will be uninitialized. */ | |
976 void | |
977 resize_reg_info (void) | |
978 { | |
979 int size = max_reg_num (); | |
980 | |
981 gcc_assert (reg_pref && reg_renumber); | |
982 reg_renumber = XRESIZEVEC (short, reg_renumber, size); | |
983 reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, size); | |
984 } | |
985 | |
986 | |
987 /* Free up the space allocated by allocate_reg_info. */ | |
988 void | |
989 free_reg_info (void) | |
990 { | |
991 if (reg_pref) | |
992 { | |
993 free (reg_pref); | |
994 reg_pref = NULL; | |
995 } | |
996 | |
997 if (reg_renumber) | |
998 { | |
999 free (reg_renumber); | |
1000 reg_renumber = NULL; | |
1001 } | |
1002 } | |
1003 | |
1004 | |
1005 | |
1006 | |
1007 /* Set up preferred and alternate classes for REGNO as PREFCLASS and | |
1008 ALTCLASS. */ | |
1009 void | 1036 void |
1010 setup_reg_classes (int regno, | 1037 setup_reg_classes (int regno, |
1011 enum reg_class prefclass, enum reg_class altclass) | 1038 enum reg_class prefclass, enum reg_class altclass, |
1039 enum reg_class coverclass) | |
1012 { | 1040 { |
1013 if (reg_pref == NULL) | 1041 if (reg_pref == NULL) |
1014 return; | 1042 return; |
1043 gcc_assert (reg_info_size == max_reg_num ()); | |
1015 reg_pref[regno].prefclass = prefclass; | 1044 reg_pref[regno].prefclass = prefclass; |
1016 reg_pref[regno].altclass = altclass; | 1045 reg_pref[regno].altclass = altclass; |
1046 reg_pref[regno].coverclass = coverclass; | |
1017 } | 1047 } |
1018 | 1048 |
1019 | 1049 |
1020 /* This is the `regscan' pass of the compiler, run just before cse and | 1050 /* This is the `regscan' pass of the compiler, run just before cse and |
1021 again just before loop. It finds the first and last use of each | 1051 again just before loop. It finds the first and last use of each |
1121 && ! REG_POINTER (SET_DEST (x)) | 1151 && ! REG_POINTER (SET_DEST (x)) |
1122 && ((REG_P (SET_SRC (x)) | 1152 && ((REG_P (SET_SRC (x)) |
1123 && REG_POINTER (SET_SRC (x))) | 1153 && REG_POINTER (SET_SRC (x))) |
1124 || ((GET_CODE (SET_SRC (x)) == PLUS | 1154 || ((GET_CODE (SET_SRC (x)) == PLUS |
1125 || GET_CODE (SET_SRC (x)) == LO_SUM) | 1155 || GET_CODE (SET_SRC (x)) == LO_SUM) |
1126 && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT | 1156 && CONST_INT_P (XEXP (SET_SRC (x), 1)) |
1127 && REG_P (XEXP (SET_SRC (x), 0)) | 1157 && REG_P (XEXP (SET_SRC (x), 0)) |
1128 && REG_POINTER (XEXP (SET_SRC (x), 0))) | 1158 && REG_POINTER (XEXP (SET_SRC (x), 0))) |
1129 || GET_CODE (SET_SRC (x)) == CONST | 1159 || GET_CODE (SET_SRC (x)) == CONST |
1130 || GET_CODE (SET_SRC (x)) == SYMBOL_REF | 1160 || GET_CODE (SET_SRC (x)) == SYMBOL_REF |
1131 || GET_CODE (SET_SRC (x)) == LABEL_REF | 1161 || GET_CODE (SET_SRC (x)) == LABEL_REF |
1266 | 1296 |
1267 node->modes[mode] |= 1 << (regno & 7); | 1297 node->modes[mode] |= 1 << (regno & 7); |
1268 } | 1298 } |
1269 | 1299 |
1270 /* Call record_subregs_of_mode for all the subregs in X. */ | 1300 /* Call record_subregs_of_mode for all the subregs in X. */ |
1271 static void | 1301 static void |
1272 find_subregs_of_mode (rtx x) | 1302 find_subregs_of_mode (rtx x) |
1273 { | 1303 { |
1274 enum rtx_code code = GET_CODE (x); | 1304 enum rtx_code code = GET_CODE (x); |
1275 const char * const fmt = GET_RTX_FORMAT (code); | 1305 const char * const fmt = GET_RTX_FORMAT (code); |
1276 int i; | 1306 int i; |
1277 | 1307 |
1278 if (code == SUBREG) | 1308 if (code == SUBREG) |
1279 record_subregs_of_mode (x); | 1309 record_subregs_of_mode (x); |
1280 | 1310 |
1281 /* Time for some deep diving. */ | 1311 /* Time for some deep diving. */ |
1282 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) | 1312 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) |
1283 { | 1313 { |
1284 if (fmt[i] == 'e') | 1314 if (fmt[i] == 'e') |
1285 find_subregs_of_mode (XEXP (x, i)); | 1315 find_subregs_of_mode (XEXP (x, i)); |
1290 find_subregs_of_mode (XVECEXP (x, i, j)); | 1320 find_subregs_of_mode (XVECEXP (x, i, j)); |
1291 } | 1321 } |
1292 } | 1322 } |
1293 } | 1323 } |
1294 | 1324 |
1295 static unsigned int | 1325 void |
1296 init_subregs_of_mode (void) | 1326 init_subregs_of_mode (void) |
1297 { | 1327 { |
1298 basic_block bb; | 1328 basic_block bb; |
1299 rtx insn; | 1329 rtx insn; |
1300 | 1330 |
1305 | 1335 |
1306 FOR_EACH_BB (bb) | 1336 FOR_EACH_BB (bb) |
1307 FOR_BB_INSNS (bb, insn) | 1337 FOR_BB_INSNS (bb, insn) |
1308 if (INSN_P (insn)) | 1338 if (INSN_P (insn)) |
1309 find_subregs_of_mode (PATTERN (insn)); | 1339 find_subregs_of_mode (PATTERN (insn)); |
1310 | |
1311 return 0; | |
1312 } | |
1313 | |
1314 /* Set bits in *USED which correspond to registers which can't change | |
1315 their mode from FROM to any mode in which REGNO was | |
1316 encountered. */ | |
1317 void | |
1318 cannot_change_mode_set_regs (HARD_REG_SET *used, enum machine_mode from, | |
1319 unsigned int regno) | |
1320 { | |
1321 struct subregs_of_mode_node dummy, *node; | |
1322 enum machine_mode to; | |
1323 unsigned char mask; | |
1324 unsigned int i; | |
1325 | |
1326 gcc_assert (subregs_of_mode); | |
1327 dummy.block = regno & -8; | |
1328 node = (struct subregs_of_mode_node *) | |
1329 htab_find_with_hash (subregs_of_mode, &dummy, dummy.block); | |
1330 if (node == NULL) | |
1331 return; | |
1332 | |
1333 mask = 1 << (regno & 7); | |
1334 for (to = VOIDmode; to < NUM_MACHINE_MODES; to++) | |
1335 if (node->modes[to] & mask) | |
1336 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) | |
1337 if (!TEST_HARD_REG_BIT (*used, i) | |
1338 && REG_CANNOT_CHANGE_MODE_P (i, from, to)) | |
1339 SET_HARD_REG_BIT (*used, i); | |
1340 } | 1340 } |
1341 | 1341 |
1342 /* Return 1 if REGNO has had an invalid mode change in CLASS from FROM | 1342 /* Return 1 if REGNO has had an invalid mode change in CLASS from FROM |
1343 mode. */ | 1343 mode. */ |
1344 bool | 1344 bool |
1345 invalid_mode_change_p (unsigned int regno, | 1345 invalid_mode_change_p (unsigned int regno, |
1346 enum reg_class rclass ATTRIBUTE_UNUSED, | 1346 enum reg_class rclass ATTRIBUTE_UNUSED, |
1347 enum machine_mode from) | 1347 enum machine_mode from) |
1348 { | 1348 { |
1349 struct subregs_of_mode_node dummy, *node; | 1349 struct subregs_of_mode_node dummy, *node; |
1350 enum machine_mode to; | 1350 unsigned int to; |
1351 unsigned char mask; | 1351 unsigned char mask; |
1352 | 1352 |
1353 gcc_assert (subregs_of_mode); | 1353 gcc_assert (subregs_of_mode); |
1354 dummy.block = regno & -8; | 1354 dummy.block = regno & -8; |
1355 node = (struct subregs_of_mode_node *) | 1355 node = (struct subregs_of_mode_node *) |
1358 return false; | 1358 return false; |
1359 | 1359 |
1360 mask = 1 << (regno & 7); | 1360 mask = 1 << (regno & 7); |
1361 for (to = VOIDmode; to < NUM_MACHINE_MODES; to++) | 1361 for (to = VOIDmode; to < NUM_MACHINE_MODES; to++) |
1362 if (node->modes[to] & mask) | 1362 if (node->modes[to] & mask) |
1363 if (CANNOT_CHANGE_MODE_CLASS (from, to, rclass)) | 1363 if (CANNOT_CHANGE_MODE_CLASS (from, (enum machine_mode) to, rclass)) |
1364 return true; | 1364 return true; |
1365 | 1365 |
1366 return false; | 1366 return false; |
1367 } | 1367 } |
1368 | 1368 |
1369 static unsigned int | 1369 void |
1370 finish_subregs_of_mode (void) | 1370 finish_subregs_of_mode (void) |
1371 { | 1371 { |
1372 htab_delete (subregs_of_mode); | 1372 htab_delete (subregs_of_mode); |
1373 subregs_of_mode = 0; | 1373 subregs_of_mode = 0; |
1374 return 0; | |
1375 } | 1374 } |
1376 #else | 1375 #else |
1377 static unsigned int | 1376 void |
1378 init_subregs_of_mode (void) | 1377 init_subregs_of_mode (void) |
1379 { | 1378 { |
1380 return 0; | 1379 } |
1381 } | 1380 void |
1382 static unsigned int | |
1383 finish_subregs_of_mode (void) | 1381 finish_subregs_of_mode (void) |
1384 { | 1382 { |
1385 return 0; | |
1386 } | 1383 } |
1387 | 1384 |
1388 #endif /* CANNOT_CHANGE_MODE_CLASS */ | 1385 #endif /* CANNOT_CHANGE_MODE_CLASS */ |
1389 | 1386 |
1390 static bool | |
1391 gate_subregs_of_mode_init (void) | |
1392 { | |
1393 #ifdef CANNOT_CHANGE_MODE_CLASS | |
1394 return true; | |
1395 #else | |
1396 return false; | |
1397 #endif | |
1398 } | |
1399 | |
1400 struct rtl_opt_pass pass_subregs_of_mode_init = | |
1401 { | |
1402 { | |
1403 RTL_PASS, | |
1404 "subregs_of_mode_init", /* name */ | |
1405 gate_subregs_of_mode_init, /* gate */ | |
1406 init_subregs_of_mode, /* execute */ | |
1407 NULL, /* sub */ | |
1408 NULL, /* next */ | |
1409 0, /* static_pass_number */ | |
1410 0, /* tv_id */ | |
1411 0, /* properties_required */ | |
1412 0, /* properties_provided */ | |
1413 0, /* properties_destroyed */ | |
1414 0, /* todo_flags_start */ | |
1415 0 /* todo_flags_finish */ | |
1416 } | |
1417 }; | |
1418 | |
1419 struct rtl_opt_pass pass_subregs_of_mode_finish = | |
1420 { | |
1421 { | |
1422 RTL_PASS, | |
1423 "subregs_of_mode_finish", /* name */ | |
1424 gate_subregs_of_mode_init, /* gate */ | |
1425 finish_subregs_of_mode, /* execute */ | |
1426 NULL, /* sub */ | |
1427 NULL, /* next */ | |
1428 0, /* static_pass_number */ | |
1429 0, /* tv_id */ | |
1430 0, /* properties_required */ | |
1431 0, /* properties_provided */ | |
1432 0, /* properties_destroyed */ | |
1433 0, /* todo_flags_start */ | |
1434 0 /* todo_flags_finish */ | |
1435 } | |
1436 }; | |
1437 | |
1438 | |
1439 #include "gt-reginfo.h" | 1387 #include "gt-reginfo.h" |