Mercurial > hg > CbC > CbC_gcc
comparison gcc/lower-subreg.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Decompose multiword subregs. | 1 /* Decompose multiword subregs. |
2 Copyright (C) 2007-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2007-2018 Free Software Foundation, Inc. |
3 Contributed by Richard Henderson <rth@redhat.com> | 3 Contributed by Richard Henderson <rth@redhat.com> |
4 Ian Lance Taylor <iant@google.com> | 4 Ian Lance Taylor <iant@google.com> |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
101 #define twice_word_mode \ | 101 #define twice_word_mode \ |
102 this_target_lower_subreg->x_twice_word_mode | 102 this_target_lower_subreg->x_twice_word_mode |
103 #define choices \ | 103 #define choices \ |
104 this_target_lower_subreg->x_choices | 104 this_target_lower_subreg->x_choices |
105 | 105 |
106 /* Return true if MODE is a mode we know how to lower. When returning true, | |
107 store its byte size in *BYTES and its word size in *WORDS. */ | |
108 | |
109 static inline bool | |
110 interesting_mode_p (machine_mode mode, unsigned int *bytes, | |
111 unsigned int *words) | |
112 { | |
113 if (!GET_MODE_SIZE (mode).is_constant (bytes)) | |
114 return false; | |
115 *words = CEIL (*bytes, UNITS_PER_WORD); | |
116 return true; | |
117 } | |
118 | |
106 /* RTXes used while computing costs. */ | 119 /* RTXes used while computing costs. */ |
107 struct cost_rtxes { | 120 struct cost_rtxes { |
108 /* Source and target registers. */ | 121 /* Source and target registers. */ |
109 rtx source; | 122 rtx source; |
110 rtx target; | 123 rtx target; |
127 machine_mode mode, int op1) | 140 machine_mode mode, int op1) |
128 { | 141 { |
129 PUT_CODE (rtxes->shift, code); | 142 PUT_CODE (rtxes->shift, code); |
130 PUT_MODE (rtxes->shift, mode); | 143 PUT_MODE (rtxes->shift, mode); |
131 PUT_MODE (rtxes->source, mode); | 144 PUT_MODE (rtxes->source, mode); |
132 XEXP (rtxes->shift, 1) = GEN_INT (op1); | 145 XEXP (rtxes->shift, 1) = gen_int_shift_amount (mode, op1); |
133 return set_src_cost (rtxes->shift, mode, speed_p); | 146 return set_src_cost (rtxes->shift, mode, speed_p); |
134 } | 147 } |
135 | 148 |
136 /* For each X in the range [0, BITS_PER_WORD), set SPLITTING[X] | 149 /* For each X in the range [0, BITS_PER_WORD), set SPLITTING[X] |
137 to true if it is profitable to split a double-word CODE shift | 150 to true if it is profitable to split a double-word CODE shift |
197 GET_MODE_NAME (word_mode), word_move_zero_cost, word_move_cost); | 210 GET_MODE_NAME (word_mode), word_move_zero_cost, word_move_cost); |
198 | 211 |
199 for (i = 0; i < MAX_MACHINE_MODE; i++) | 212 for (i = 0; i < MAX_MACHINE_MODE; i++) |
200 { | 213 { |
201 machine_mode mode = (machine_mode) i; | 214 machine_mode mode = (machine_mode) i; |
202 int factor = GET_MODE_SIZE (mode) / UNITS_PER_WORD; | 215 unsigned int size, factor; |
203 if (factor > 1) | 216 if (interesting_mode_p (mode, &size, &factor) && factor > 1) |
204 { | 217 { |
205 int mode_move_cost; | 218 unsigned int mode_move_cost; |
206 | 219 |
207 PUT_MODE (rtxes->target, mode); | 220 PUT_MODE (rtxes->target, mode); |
208 PUT_MODE (rtxes->source, mode); | 221 PUT_MODE (rtxes->source, mode); |
209 mode_move_cost = set_rtx_cost (rtxes->set, speed_p); | 222 mode_move_cost = set_rtx_cost (rtxes->set, speed_p); |
210 | 223 |
467 { | 480 { |
468 iter.skip_subrtxes (); | 481 iter.skip_subrtxes (); |
469 continue; | 482 continue; |
470 } | 483 } |
471 | 484 |
472 outer_size = GET_MODE_SIZE (GET_MODE (x)); | 485 if (!interesting_mode_p (GET_MODE (x), &outer_size, &outer_words) |
473 inner_size = GET_MODE_SIZE (GET_MODE (inner)); | 486 || !interesting_mode_p (GET_MODE (inner), &inner_size, |
474 outer_words = (outer_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | 487 &inner_words)) |
475 inner_words = (inner_size + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | 488 continue; |
476 | 489 |
477 /* We only try to decompose single word subregs of multi-word | 490 /* We only try to decompose single word subregs of multi-word |
478 registers. When we find one, we return -1 to avoid iterating | 491 registers. When we find one, we return -1 to avoid iterating |
479 over the inner register. | 492 over the inner register. |
480 | 493 |
482 on 32-bit targets. We would need to record the way the | 495 on 32-bit targets. We would need to record the way the |
483 pseudo-register was used, and only decompose if all the uses | 496 pseudo-register was used, and only decompose if all the uses |
484 were the same number and size of pieces. Hopefully this | 497 were the same number and size of pieces. Hopefully this |
485 doesn't happen much. */ | 498 doesn't happen much. */ |
486 | 499 |
487 if (outer_words == 1 && inner_words > 1) | 500 if (outer_words == 1 |
501 && inner_words > 1 | |
502 /* Don't allow to decompose floating point subregs of | |
503 multi-word pseudos if the floating point mode does | |
504 not have word size, because otherwise we'd generate | |
505 a subreg with that floating mode from a different | |
506 sized integral pseudo which is not allowed by | |
507 validate_subreg. */ | |
508 && (!FLOAT_MODE_P (GET_MODE (x)) | |
509 || outer_size == UNITS_PER_WORD)) | |
488 { | 510 { |
489 bitmap_set_bit (decomposable_context, regno); | 511 bitmap_set_bit (decomposable_context, regno); |
490 iter.skip_subrtxes (); | 512 iter.skip_subrtxes (); |
491 continue; | 513 continue; |
492 } | 514 } |
505 continue; | 527 continue; |
506 } | 528 } |
507 } | 529 } |
508 else if (REG_P (x)) | 530 else if (REG_P (x)) |
509 { | 531 { |
510 unsigned int regno; | 532 unsigned int regno, size, words; |
511 | 533 |
512 /* We will see an outer SUBREG before we see the inner REG, so | 534 /* We will see an outer SUBREG before we see the inner REG, so |
513 when we see a plain REG here it means a direct reference to | 535 when we see a plain REG here it means a direct reference to |
514 the register. | 536 the register. |
515 | 537 |
525 pseudo-registers, since those are the only ones we care about | 547 pseudo-registers, since those are the only ones we care about |
526 and it keeps the size of the bitmaps down. */ | 548 and it keeps the size of the bitmaps down. */ |
527 | 549 |
528 regno = REGNO (x); | 550 regno = REGNO (x); |
529 if (!HARD_REGISTER_NUM_P (regno) | 551 if (!HARD_REGISTER_NUM_P (regno) |
530 && GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD) | 552 && interesting_mode_p (GET_MODE (x), &size, &words) |
553 && words > 1) | |
531 { | 554 { |
532 switch (*pcmi) | 555 switch (*pcmi) |
533 { | 556 { |
534 case NOT_SIMPLE_MOVE: | 557 case NOT_SIMPLE_MOVE: |
535 bitmap_set_bit (non_decomposable_context, regno); | 558 bitmap_set_bit (non_decomposable_context, regno); |
565 | 588 |
566 static void | 589 static void |
567 decompose_register (unsigned int regno) | 590 decompose_register (unsigned int regno) |
568 { | 591 { |
569 rtx reg; | 592 rtx reg; |
570 unsigned int words, i; | 593 unsigned int size, words, i; |
571 rtvec v; | 594 rtvec v; |
572 | 595 |
573 reg = regno_reg_rtx[regno]; | 596 reg = regno_reg_rtx[regno]; |
574 | 597 |
575 regno_reg_rtx[regno] = NULL_RTX; | 598 regno_reg_rtx[regno] = NULL_RTX; |
576 | 599 |
577 words = GET_MODE_SIZE (GET_MODE (reg)); | 600 if (!interesting_mode_p (GET_MODE (reg), &size, &words)) |
578 words = (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | 601 gcc_unreachable (); |
579 | 602 |
580 v = rtvec_alloc (words); | 603 v = rtvec_alloc (words); |
581 for (i = 0; i < words; ++i) | 604 for (i = 0; i < words; ++i) |
582 RTVEC_ELT (v, i) = gen_reg_rtx_offset (reg, word_mode, i * UNITS_PER_WORD); | 605 RTVEC_ELT (v, i) = gen_reg_rtx_offset (reg, word_mode, i * UNITS_PER_WORD); |
583 | 606 |
594 } | 617 } |
595 | 618 |
596 /* Get a SUBREG of a CONCATN. */ | 619 /* Get a SUBREG of a CONCATN. */ |
597 | 620 |
598 static rtx | 621 static rtx |
599 simplify_subreg_concatn (machine_mode outermode, rtx op, | 622 simplify_subreg_concatn (machine_mode outermode, rtx op, poly_uint64 orig_byte) |
600 unsigned int byte) | 623 { |
601 { | 624 unsigned int outer_size, outer_words, inner_size, inner_words; |
602 unsigned int inner_size; | |
603 machine_mode innermode, partmode; | 625 machine_mode innermode, partmode; |
604 rtx part; | 626 rtx part; |
605 unsigned int final_offset; | 627 unsigned int final_offset; |
606 | 628 unsigned int byte; |
629 | |
630 innermode = GET_MODE (op); | |
631 if (!interesting_mode_p (outermode, &outer_size, &outer_words) | |
632 || !interesting_mode_p (innermode, &inner_size, &inner_words)) | |
633 gcc_unreachable (); | |
634 | |
635 /* Must be constant if interesting_mode_p passes. */ | |
636 byte = orig_byte.to_constant (); | |
607 gcc_assert (GET_CODE (op) == CONCATN); | 637 gcc_assert (GET_CODE (op) == CONCATN); |
608 gcc_assert (byte % GET_MODE_SIZE (outermode) == 0); | 638 gcc_assert (byte % outer_size == 0); |
609 | 639 |
610 innermode = GET_MODE (op); | 640 gcc_assert (byte < inner_size); |
611 gcc_assert (byte < GET_MODE_SIZE (innermode)); | 641 if (outer_size > inner_size) |
612 if (GET_MODE_SIZE (outermode) > GET_MODE_SIZE (innermode)) | |
613 return NULL_RTX; | 642 return NULL_RTX; |
614 | 643 |
615 inner_size = GET_MODE_SIZE (innermode) / XVECLEN (op, 0); | 644 inner_size /= XVECLEN (op, 0); |
616 part = XVECEXP (op, 0, byte / inner_size); | 645 part = XVECEXP (op, 0, byte / inner_size); |
617 partmode = GET_MODE (part); | 646 partmode = GET_MODE (part); |
618 | 647 |
619 final_offset = byte % inner_size; | 648 final_offset = byte % inner_size; |
620 if (final_offset + GET_MODE_SIZE (outermode) > inner_size) | 649 if (final_offset + outer_size > inner_size) |
621 return NULL_RTX; | 650 return NULL_RTX; |
622 | 651 |
623 /* VECTOR_CSTs in debug expressions are expanded into CONCATN instead of | 652 /* VECTOR_CSTs in debug expressions are expanded into CONCATN instead of |
624 regular CONST_VECTORs. They have vector or integer modes, depending | 653 regular CONST_VECTORs. They have vector or integer modes, depending |
625 on the capabilities of the target. Cope with them. */ | 654 on the capabilities of the target. Cope with them. */ |
646 part. We shouldn't see anything else here. */ | 675 part. We shouldn't see anything else here. */ |
647 if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == CONCATN) | 676 if (GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == CONCATN) |
648 { | 677 { |
649 rtx op2; | 678 rtx op2; |
650 | 679 |
651 if ((GET_MODE_SIZE (GET_MODE (op)) | 680 if (known_eq (GET_MODE_SIZE (GET_MODE (op)), |
652 == GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))) | 681 GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))) |
653 && SUBREG_BYTE (op) == 0) | 682 && known_eq (SUBREG_BYTE (op), 0)) |
654 return simplify_gen_subreg_concatn (outermode, SUBREG_REG (op), | 683 return simplify_gen_subreg_concatn (outermode, SUBREG_REG (op), |
655 GET_MODE (SUBREG_REG (op)), byte); | 684 GET_MODE (SUBREG_REG (op)), byte); |
656 | 685 |
657 op2 = simplify_subreg_concatn (GET_MODE (op), SUBREG_REG (op), | 686 op2 = simplify_subreg_concatn (GET_MODE (op), SUBREG_REG (op), |
658 SUBREG_BYTE (op)); | 687 SUBREG_BYTE (op)); |
799 { | 828 { |
800 unsigned int regno = REGNO (x); | 829 unsigned int regno = REGNO (x); |
801 | 830 |
802 if (HARD_REGISTER_NUM_P (regno)) | 831 if (HARD_REGISTER_NUM_P (regno)) |
803 { | 832 { |
804 unsigned int byte, num_bytes; | 833 unsigned int byte, num_bytes, num_words; |
805 | 834 |
806 num_bytes = GET_MODE_SIZE (GET_MODE (x)); | 835 if (!interesting_mode_p (GET_MODE (x), &num_bytes, &num_words)) |
836 return false; | |
807 for (byte = 0; byte < num_bytes; byte += UNITS_PER_WORD) | 837 for (byte = 0; byte < num_bytes; byte += UNITS_PER_WORD) |
808 if (simplify_subreg_regno (regno, GET_MODE (x), byte, word_mode) < 0) | 838 if (simplify_subreg_regno (regno, GET_MODE (x), byte, word_mode) < 0) |
809 return false; | 839 return false; |
810 return true; | 840 return true; |
811 } | 841 } |
824 resolve_simple_move (rtx set, rtx_insn *insn) | 854 resolve_simple_move (rtx set, rtx_insn *insn) |
825 { | 855 { |
826 rtx src, dest, real_dest; | 856 rtx src, dest, real_dest; |
827 rtx_insn *insns; | 857 rtx_insn *insns; |
828 machine_mode orig_mode, dest_mode; | 858 machine_mode orig_mode, dest_mode; |
829 unsigned int words; | 859 unsigned int orig_size, words; |
830 bool pushing; | 860 bool pushing; |
831 | 861 |
832 src = SET_SRC (set); | 862 src = SET_SRC (set); |
833 dest = SET_DEST (set); | 863 dest = SET_DEST (set); |
834 orig_mode = GET_MODE (dest); | 864 orig_mode = GET_MODE (dest); |
835 | 865 |
836 words = (GET_MODE_SIZE (orig_mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | 866 if (!interesting_mode_p (orig_mode, &orig_size, &words)) |
867 gcc_unreachable (); | |
837 gcc_assert (words > 1); | 868 gcc_assert (words > 1); |
838 | 869 |
839 start_sequence (); | 870 start_sequence (); |
840 | 871 |
841 /* We have to handle copying from a SUBREG of a decomposed reg where | 872 /* We have to handle copying from a SUBREG of a decomposed reg where |
845 | 876 |
846 real_dest = NULL_RTX; | 877 real_dest = NULL_RTX; |
847 | 878 |
848 if (GET_CODE (src) == SUBREG | 879 if (GET_CODE (src) == SUBREG |
849 && resolve_reg_p (SUBREG_REG (src)) | 880 && resolve_reg_p (SUBREG_REG (src)) |
850 && (SUBREG_BYTE (src) != 0 | 881 && (maybe_ne (SUBREG_BYTE (src), 0) |
851 || (GET_MODE_SIZE (orig_mode) | 882 || maybe_ne (orig_size, GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))) |
852 != GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))) | |
853 { | 883 { |
854 real_dest = dest; | 884 real_dest = dest; |
855 dest = gen_reg_rtx (orig_mode); | 885 dest = gen_reg_rtx (orig_mode); |
856 if (REG_P (real_dest)) | 886 if (REG_P (real_dest)) |
857 REG_ATTRS (dest) = REG_ATTRS (real_dest); | 887 REG_ATTRS (dest) = REG_ATTRS (real_dest); |
860 /* Similarly if we are copying to a SUBREG of a decomposed reg where | 890 /* Similarly if we are copying to a SUBREG of a decomposed reg where |
861 the SUBREG is larger than word size. */ | 891 the SUBREG is larger than word size. */ |
862 | 892 |
863 if (GET_CODE (dest) == SUBREG | 893 if (GET_CODE (dest) == SUBREG |
864 && resolve_reg_p (SUBREG_REG (dest)) | 894 && resolve_reg_p (SUBREG_REG (dest)) |
865 && (SUBREG_BYTE (dest) != 0 | 895 && (maybe_ne (SUBREG_BYTE (dest), 0) |
866 || (GET_MODE_SIZE (orig_mode) | 896 || maybe_ne (orig_size, |
867 != GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))))) | 897 GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))))) |
868 { | 898 { |
869 rtx reg, smove; | 899 rtx reg, smove; |
870 rtx_insn *minsn; | 900 rtx_insn *minsn; |
871 | 901 |
872 reg = gen_reg_rtx (orig_mode); | 902 reg = gen_reg_rtx (orig_mode); |
962 | 992 |
963 if (pushing) | 993 if (pushing) |
964 { | 994 { |
965 unsigned int i, j, jinc; | 995 unsigned int i, j, jinc; |
966 | 996 |
967 gcc_assert (GET_MODE_SIZE (orig_mode) % UNITS_PER_WORD == 0); | 997 gcc_assert (orig_size % UNITS_PER_WORD == 0); |
968 gcc_assert (GET_CODE (XEXP (dest, 0)) != PRE_MODIFY); | 998 gcc_assert (GET_CODE (XEXP (dest, 0)) != PRE_MODIFY); |
969 gcc_assert (GET_CODE (XEXP (dest, 0)) != POST_MODIFY); | 999 gcc_assert (GET_CODE (XEXP (dest, 0)) != POST_MODIFY); |
970 | 1000 |
971 if (WORDS_BIG_ENDIAN == STACK_GROWS_DOWNWARD) | 1001 if (WORDS_BIG_ENDIAN == STACK_GROWS_DOWNWARD) |
972 { | 1002 { |
1057 static bool | 1087 static bool |
1058 resolve_clobber (rtx pat, rtx_insn *insn) | 1088 resolve_clobber (rtx pat, rtx_insn *insn) |
1059 { | 1089 { |
1060 rtx reg; | 1090 rtx reg; |
1061 machine_mode orig_mode; | 1091 machine_mode orig_mode; |
1062 unsigned int words, i; | 1092 unsigned int orig_size, words, i; |
1063 int ret; | 1093 int ret; |
1064 | 1094 |
1065 reg = XEXP (pat, 0); | 1095 reg = XEXP (pat, 0); |
1066 if (!resolve_reg_p (reg) && !resolve_subreg_p (reg)) | 1096 if (!resolve_reg_p (reg) && !resolve_subreg_p (reg)) |
1067 return false; | 1097 return false; |
1068 | 1098 |
1069 orig_mode = GET_MODE (reg); | 1099 orig_mode = GET_MODE (reg); |
1070 words = GET_MODE_SIZE (orig_mode); | 1100 if (!interesting_mode_p (orig_mode, &orig_size, &words)) |
1071 words = (words + UNITS_PER_WORD - 1) / UNITS_PER_WORD; | 1101 gcc_unreachable (); |
1072 | 1102 |
1073 ret = validate_change (NULL_RTX, &XEXP (pat, 0), | 1103 ret = validate_change (NULL_RTX, &XEXP (pat, 0), |
1074 simplify_gen_subreg_concatn (word_mode, reg, | 1104 simplify_gen_subreg_concatn (word_mode, reg, |
1075 orig_mode, 0), | 1105 orig_mode, 0), |
1076 0); | 1106 0); |
1330 of the SPEED_P choice. */ | 1360 of the SPEED_P choice. */ |
1331 | 1361 |
1332 static void | 1362 static void |
1333 dump_choices (bool speed_p, const char *description) | 1363 dump_choices (bool speed_p, const char *description) |
1334 { | 1364 { |
1335 unsigned int i; | 1365 unsigned int size, factor, i; |
1336 | 1366 |
1337 fprintf (dump_file, "Choices when optimizing for %s:\n", description); | 1367 fprintf (dump_file, "Choices when optimizing for %s:\n", description); |
1338 | 1368 |
1339 for (i = 0; i < MAX_MACHINE_MODE; i++) | 1369 for (i = 0; i < MAX_MACHINE_MODE; i++) |
1340 if (GET_MODE_SIZE ((machine_mode) i) > UNITS_PER_WORD) | 1370 if (interesting_mode_p ((machine_mode) i, &size, &factor) |
1371 && factor > 1) | |
1341 fprintf (dump_file, " %s mode %s for copy lowering.\n", | 1372 fprintf (dump_file, " %s mode %s for copy lowering.\n", |
1342 choices[speed_p].move_modes_to_split[i] | 1373 choices[speed_p].move_modes_to_split[i] |
1343 ? "Splitting" | 1374 ? "Splitting" |
1344 : "Skipping", | 1375 : "Skipping", |
1345 GET_MODE_NAME ((machine_mode) i)); | 1376 GET_MODE_NAME ((machine_mode) i)); |