Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-math-opts.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 | 3bfb6c00c1e0 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Global, SSA-based optimizations using mathematical identities. | 1 /* Global, SSA-based optimizations using mathematical identities. |
2 Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. | 2 Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it | 6 GCC is free software; you can redistribute it and/or modify it |
7 under the terms of the GNU General Public License as published by the | 7 under the terms of the GNU General Public License as published by the |
8 Free Software Foundation; either version 3, or (at your option) any | 8 Free Software Foundation; either version 3, or (at your option) any |
9 later version. | 9 later version. |
10 | 10 |
11 GCC is distributed in the hope that it will be useful, but WITHOUT | 11 GCC is distributed in the hope that it will be useful, but WITHOUT |
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 for more details. | 14 for more details. |
15 | 15 |
16 You should have received a copy of the GNU General Public License | 16 You should have received a copy of the GNU General Public License |
17 along with GCC; see the file COPYING3. If not see | 17 along with GCC; see the file COPYING3. If not see |
18 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
19 | 19 |
20 /* Currently, the only mini-pass in this file tries to CSE reciprocal | 20 /* Currently, the only mini-pass in this file tries to CSE reciprocal |
95 #include "timevar.h" | 95 #include "timevar.h" |
96 #include "tree-pass.h" | 96 #include "tree-pass.h" |
97 #include "alloc-pool.h" | 97 #include "alloc-pool.h" |
98 #include "basic-block.h" | 98 #include "basic-block.h" |
99 #include "target.h" | 99 #include "target.h" |
100 | 100 #include "diagnostic.h" |
101 #include "rtl.h" | |
102 #include "expr.h" | |
103 #include "optabs.h" | |
101 | 104 |
102 /* This structure represents one basic block that either computes a | 105 /* This structure represents one basic block that either computes a |
103 division, or is a common dominator for basic block that compute a | 106 division, or is a common dominator for basic block that compute a |
104 division. */ | 107 division. */ |
105 struct occurrence { | 108 struct occurrence { |
307 /* Make a variable with the replacement and substitute it. */ | 310 /* Make a variable with the replacement and substitute it. */ |
308 type = TREE_TYPE (def); | 311 type = TREE_TYPE (def); |
309 recip_def = make_rename_temp (type, "reciptmp"); | 312 recip_def = make_rename_temp (type, "reciptmp"); |
310 new_stmt = gimple_build_assign_with_ops (RDIV_EXPR, recip_def, | 313 new_stmt = gimple_build_assign_with_ops (RDIV_EXPR, recip_def, |
311 build_one_cst (type), def); | 314 build_one_cst (type), def); |
312 | 315 |
313 if (occ->bb_has_division) | 316 if (occ->bb_has_division) |
314 { | 317 { |
315 /* Case 1: insert before an existing division. */ | 318 /* Case 1: insert before an existing division. */ |
316 gsi = gsi_after_labels (occ->bb); | 319 gsi = gsi_after_labels (occ->bb); |
317 while (!gsi_end_p (gsi) && !is_division_by (gsi_stmt (gsi), def)) | 320 while (!gsi_end_p (gsi) && !is_division_by (gsi_stmt (gsi), def)) |
413 { | 416 { |
414 register_division_in (gimple_bb (use_stmt)); | 417 register_division_in (gimple_bb (use_stmt)); |
415 count++; | 418 count++; |
416 } | 419 } |
417 } | 420 } |
418 | 421 |
419 /* Do the expensive part only if we can hope to optimize something. */ | 422 /* Do the expensive part only if we can hope to optimize something. */ |
420 threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def))); | 423 threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def))); |
421 if (count >= threshold) | 424 if (count >= threshold) |
422 { | 425 { |
423 gimple use_stmt; | 426 gimple use_stmt; |
544 the wrong thing. */ | 547 the wrong thing. */ |
545 fail = false; | 548 fail = false; |
546 FOR_EACH_IMM_USE_FAST (use_p, ui, arg1) | 549 FOR_EACH_IMM_USE_FAST (use_p, ui, arg1) |
547 { | 550 { |
548 gimple stmt2 = USE_STMT (use_p); | 551 gimple stmt2 = USE_STMT (use_p); |
552 if (is_gimple_debug (stmt2)) | |
553 continue; | |
549 if (!is_gimple_assign (stmt2) | 554 if (!is_gimple_assign (stmt2) |
550 || gimple_assign_rhs_code (stmt2) != RDIV_EXPR | 555 || gimple_assign_rhs_code (stmt2) != RDIV_EXPR |
551 || gimple_assign_rhs1 (stmt2) == arg1 | 556 || gimple_assign_rhs1 (stmt2) == arg1 |
552 || gimple_assign_rhs2 (stmt2) != arg1) | 557 || gimple_assign_rhs2 (stmt2) != arg1) |
553 { | 558 { |
556 } | 561 } |
557 } | 562 } |
558 if (fail) | 563 if (fail) |
559 continue; | 564 continue; |
560 | 565 |
566 gimple_replace_lhs (stmt1, arg1); | |
561 gimple_call_set_fndecl (stmt1, fndecl); | 567 gimple_call_set_fndecl (stmt1, fndecl); |
562 update_stmt (stmt1); | 568 update_stmt (stmt1); |
563 | 569 |
564 FOR_EACH_IMM_USE_STMT (stmt, ui, arg1) | 570 FOR_EACH_IMM_USE_STMT (stmt, ui, arg1) |
565 { | 571 { |
586 gate_cse_reciprocals, /* gate */ | 592 gate_cse_reciprocals, /* gate */ |
587 execute_cse_reciprocals, /* execute */ | 593 execute_cse_reciprocals, /* execute */ |
588 NULL, /* sub */ | 594 NULL, /* sub */ |
589 NULL, /* next */ | 595 NULL, /* next */ |
590 0, /* static_pass_number */ | 596 0, /* static_pass_number */ |
591 0, /* tv_id */ | 597 TV_NONE, /* tv_id */ |
592 PROP_ssa, /* properties_required */ | 598 PROP_ssa, /* properties_required */ |
593 0, /* properties_provided */ | 599 0, /* properties_provided */ |
594 0, /* properties_destroyed */ | 600 0, /* properties_destroyed */ |
595 0, /* todo_flags_start */ | 601 0, /* todo_flags_start */ |
596 TODO_dump_func | TODO_update_ssa | TODO_verify_ssa | 602 TODO_dump_func | TODO_update_ssa | TODO_verify_ssa |
729 /* Replace call with a copy. */ | 735 /* Replace call with a copy. */ |
730 stmt = gimple_build_assign (gimple_call_lhs (use_stmt), rhs); | 736 stmt = gimple_build_assign (gimple_call_lhs (use_stmt), rhs); |
731 | 737 |
732 gsi = gsi_for_stmt (use_stmt); | 738 gsi = gsi_for_stmt (use_stmt); |
733 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT); | 739 gsi_insert_after (&gsi, stmt, GSI_SAME_STMT); |
734 gsi_remove (&gsi, true); | 740 gsi_remove (&gsi, true); |
735 } | 741 } |
736 | 742 |
737 VEC_free(gimple, heap, stmts); | 743 VEC_free(gimple, heap, stmts); |
738 } | 744 } |
739 | 745 |
800 gate_cse_sincos, /* gate */ | 806 gate_cse_sincos, /* gate */ |
801 execute_cse_sincos, /* execute */ | 807 execute_cse_sincos, /* execute */ |
802 NULL, /* sub */ | 808 NULL, /* sub */ |
803 NULL, /* next */ | 809 NULL, /* next */ |
804 0, /* static_pass_number */ | 810 0, /* static_pass_number */ |
805 0, /* tv_id */ | 811 TV_NONE, /* tv_id */ |
806 PROP_ssa, /* properties_required */ | 812 PROP_ssa, /* properties_required */ |
807 0, /* properties_provided */ | 813 0, /* properties_provided */ |
808 0, /* properties_destroyed */ | 814 0, /* properties_destroyed */ |
809 0, /* todo_flags_start */ | 815 0, /* todo_flags_start */ |
810 TODO_dump_func | TODO_update_ssa | TODO_verify_ssa | 816 TODO_dump_func | TODO_update_ssa | TODO_verify_ssa |
811 | TODO_verify_stmts /* todo_flags_finish */ | 817 | TODO_verify_stmts /* todo_flags_finish */ |
812 } | 818 } |
813 }; | 819 }; |
814 | 820 |
815 /* Find all expressions in the form of sqrt(a/b) and | 821 /* A symbolic number is used to detect byte permutation and selection |
816 convert them to rsqrt(b/a). */ | 822 patterns. Therefore the field N contains an artificial number |
823 consisting of byte size markers: | |
824 | |
825 0 - byte has the value 0 | |
826 1..size - byte contains the content of the byte | |
827 number indexed with that value minus one */ | |
828 | |
829 struct symbolic_number { | |
830 unsigned HOST_WIDEST_INT n; | |
831 int size; | |
832 }; | |
833 | |
834 /* Perform a SHIFT or ROTATE operation by COUNT bits on symbolic | |
835 number N. Return false if the requested operation is not permitted | |
836 on a symbolic number. */ | |
837 | |
838 static inline bool | |
839 do_shift_rotate (enum tree_code code, | |
840 struct symbolic_number *n, | |
841 int count) | |
842 { | |
843 if (count % 8 != 0) | |
844 return false; | |
845 | |
846 /* Zero out the extra bits of N in order to avoid them being shifted | |
847 into the significant bits. */ | |
848 if (n->size < (int)sizeof (HOST_WIDEST_INT)) | |
849 n->n &= ((unsigned HOST_WIDEST_INT)1 << (n->size * BITS_PER_UNIT)) - 1; | |
850 | |
851 switch (code) | |
852 { | |
853 case LSHIFT_EXPR: | |
854 n->n <<= count; | |
855 break; | |
856 case RSHIFT_EXPR: | |
857 n->n >>= count; | |
858 break; | |
859 case LROTATE_EXPR: | |
860 n->n = (n->n << count) | (n->n >> ((n->size * BITS_PER_UNIT) - count)); | |
861 break; | |
862 case RROTATE_EXPR: | |
863 n->n = (n->n >> count) | (n->n << ((n->size * BITS_PER_UNIT) - count)); | |
864 break; | |
865 default: | |
866 return false; | |
867 } | |
868 return true; | |
869 } | |
870 | |
871 /* Perform sanity checking for the symbolic number N and the gimple | |
872 statement STMT. */ | |
873 | |
874 static inline bool | |
875 verify_symbolic_number_p (struct symbolic_number *n, gimple stmt) | |
876 { | |
877 tree lhs_type; | |
878 | |
879 lhs_type = gimple_expr_type (stmt); | |
880 | |
881 if (TREE_CODE (lhs_type) != INTEGER_TYPE) | |
882 return false; | |
883 | |
884 if (TYPE_PRECISION (lhs_type) != n->size * BITS_PER_UNIT) | |
885 return false; | |
886 | |
887 return true; | |
888 } | |
889 | |
890 /* find_bswap_1 invokes itself recursively with N and tries to perform | |
891 the operation given by the rhs of STMT on the result. If the | |
892 operation could successfully be executed the function returns the | |
893 tree expression of the source operand and NULL otherwise. */ | |
894 | |
895 static tree | |
896 find_bswap_1 (gimple stmt, struct symbolic_number *n, int limit) | |
897 { | |
898 enum tree_code code; | |
899 tree rhs1, rhs2 = NULL; | |
900 gimple rhs1_stmt, rhs2_stmt; | |
901 tree source_expr1; | |
902 enum gimple_rhs_class rhs_class; | |
903 | |
904 if (!limit || !is_gimple_assign (stmt)) | |
905 return NULL_TREE; | |
906 | |
907 rhs1 = gimple_assign_rhs1 (stmt); | |
908 | |
909 if (TREE_CODE (rhs1) != SSA_NAME) | |
910 return NULL_TREE; | |
911 | |
912 code = gimple_assign_rhs_code (stmt); | |
913 rhs_class = gimple_assign_rhs_class (stmt); | |
914 rhs1_stmt = SSA_NAME_DEF_STMT (rhs1); | |
915 | |
916 if (rhs_class == GIMPLE_BINARY_RHS) | |
917 rhs2 = gimple_assign_rhs2 (stmt); | |
918 | |
919 /* Handle unary rhs and binary rhs with integer constants as second | |
920 operand. */ | |
921 | |
922 if (rhs_class == GIMPLE_UNARY_RHS | |
923 || (rhs_class == GIMPLE_BINARY_RHS | |
924 && TREE_CODE (rhs2) == INTEGER_CST)) | |
925 { | |
926 if (code != BIT_AND_EXPR | |
927 && code != LSHIFT_EXPR | |
928 && code != RSHIFT_EXPR | |
929 && code != LROTATE_EXPR | |
930 && code != RROTATE_EXPR | |
931 && code != NOP_EXPR | |
932 && code != CONVERT_EXPR) | |
933 return NULL_TREE; | |
934 | |
935 source_expr1 = find_bswap_1 (rhs1_stmt, n, limit - 1); | |
936 | |
937 /* If find_bswap_1 returned NULL STMT is a leaf node and we have | |
938 to initialize the symbolic number. */ | |
939 if (!source_expr1) | |
940 { | |
941 /* Set up the symbolic number N by setting each byte to a | |
942 value between 1 and the byte size of rhs1. The highest | |
943 order byte is set to 1 and the lowest order byte to | |
944 n.size. */ | |
945 n->size = TYPE_PRECISION (TREE_TYPE (rhs1)); | |
946 if (n->size % BITS_PER_UNIT != 0) | |
947 return NULL_TREE; | |
948 n->size /= BITS_PER_UNIT; | |
949 n->n = (sizeof (HOST_WIDEST_INT) < 8 ? 0 : | |
950 (unsigned HOST_WIDEST_INT)0x01020304 << 32 | 0x05060708); | |
951 n->n >>= (sizeof (HOST_WIDEST_INT) - n->size) * BITS_PER_UNIT; | |
952 | |
953 source_expr1 = rhs1; | |
954 } | |
955 | |
956 switch (code) | |
957 { | |
958 case BIT_AND_EXPR: | |
959 { | |
960 int i; | |
961 unsigned HOST_WIDEST_INT val = widest_int_cst_value (rhs2); | |
962 unsigned HOST_WIDEST_INT tmp = val; | |
963 | |
964 /* Only constants masking full bytes are allowed. */ | |
965 for (i = 0; i < n->size; i++, tmp >>= BITS_PER_UNIT) | |
966 if ((tmp & 0xff) != 0 && (tmp & 0xff) != 0xff) | |
967 return NULL_TREE; | |
968 | |
969 n->n &= val; | |
970 } | |
971 break; | |
972 case LSHIFT_EXPR: | |
973 case RSHIFT_EXPR: | |
974 case LROTATE_EXPR: | |
975 case RROTATE_EXPR: | |
976 if (!do_shift_rotate (code, n, (int)TREE_INT_CST_LOW (rhs2))) | |
977 return NULL_TREE; | |
978 break; | |
979 CASE_CONVERT: | |
980 { | |
981 int type_size; | |
982 | |
983 type_size = TYPE_PRECISION (gimple_expr_type (stmt)); | |
984 if (type_size % BITS_PER_UNIT != 0) | |
985 return NULL_TREE; | |
986 | |
987 if (type_size / BITS_PER_UNIT < (int)(sizeof (HOST_WIDEST_INT))) | |
988 { | |
989 /* If STMT casts to a smaller type mask out the bits not | |
990 belonging to the target type. */ | |
991 n->size = type_size / BITS_PER_UNIT; | |
992 n->n &= ((unsigned HOST_WIDEST_INT)1 << type_size) - 1; | |
993 } | |
994 } | |
995 break; | |
996 default: | |
997 return NULL_TREE; | |
998 }; | |
999 return verify_symbolic_number_p (n, stmt) ? source_expr1 : NULL; | |
1000 } | |
1001 | |
1002 /* Handle binary rhs. */ | |
1003 | |
1004 if (rhs_class == GIMPLE_BINARY_RHS) | |
1005 { | |
1006 struct symbolic_number n1, n2; | |
1007 tree source_expr2; | |
1008 | |
1009 if (code != BIT_IOR_EXPR) | |
1010 return NULL_TREE; | |
1011 | |
1012 if (TREE_CODE (rhs2) != SSA_NAME) | |
1013 return NULL_TREE; | |
1014 | |
1015 rhs2_stmt = SSA_NAME_DEF_STMT (rhs2); | |
1016 | |
1017 switch (code) | |
1018 { | |
1019 case BIT_IOR_EXPR: | |
1020 source_expr1 = find_bswap_1 (rhs1_stmt, &n1, limit - 1); | |
1021 | |
1022 if (!source_expr1) | |
1023 return NULL_TREE; | |
1024 | |
1025 source_expr2 = find_bswap_1 (rhs2_stmt, &n2, limit - 1); | |
1026 | |
1027 if (source_expr1 != source_expr2 | |
1028 || n1.size != n2.size) | |
1029 return NULL_TREE; | |
1030 | |
1031 n->size = n1.size; | |
1032 n->n = n1.n | n2.n; | |
1033 | |
1034 if (!verify_symbolic_number_p (n, stmt)) | |
1035 return NULL_TREE; | |
1036 | |
1037 break; | |
1038 default: | |
1039 return NULL_TREE; | |
1040 } | |
1041 return source_expr1; | |
1042 } | |
1043 return NULL_TREE; | |
1044 } | |
1045 | |
1046 /* Check if STMT completes a bswap implementation consisting of ORs, | |
1047 SHIFTs and ANDs. Return the source tree expression on which the | |
1048 byte swap is performed and NULL if no bswap was found. */ | |
1049 | |
1050 static tree | |
1051 find_bswap (gimple stmt) | |
1052 { | |
1053 /* The number which the find_bswap result should match in order to | |
1054 have a full byte swap. The insignificant bytes are masked out | |
1055 before using it. */ | |
1056 unsigned HOST_WIDEST_INT cmp = | |
1057 sizeof (HOST_WIDEST_INT) < 8 ? 0 : | |
1058 (unsigned HOST_WIDEST_INT)0x08070605 << 32 | 0x04030201; | |
1059 | |
1060 struct symbolic_number n; | |
1061 tree source_expr; | |
1062 | |
1063 /* The last parameter determines the depth search limit. It usually | |
1064 correlates directly to the number of bytes to be touched. We | |
1065 increase that number by one here in order to also cover signed -> | |
1066 unsigned conversions of the src operand as can be seen in | |
1067 libgcc. */ | |
1068 source_expr = find_bswap_1 (stmt, &n, | |
1069 TREE_INT_CST_LOW ( | |
1070 TYPE_SIZE_UNIT (gimple_expr_type (stmt))) + 1); | |
1071 | |
1072 if (!source_expr) | |
1073 return NULL_TREE; | |
1074 | |
1075 /* Zero out the extra bits of N and CMP. */ | |
1076 if (n.size < (int)sizeof (HOST_WIDEST_INT)) | |
1077 { | |
1078 unsigned HOST_WIDEST_INT mask = | |
1079 ((unsigned HOST_WIDEST_INT)1 << (n.size * BITS_PER_UNIT)) - 1; | |
1080 | |
1081 n.n &= mask; | |
1082 cmp &= mask; | |
1083 } | |
1084 | |
1085 /* A complete byte swap should make the symbolic number to start | |
1086 with the largest digit in the highest order byte. */ | |
1087 if (cmp != n.n) | |
1088 return NULL_TREE; | |
1089 | |
1090 return source_expr; | |
1091 } | |
1092 | |
1093 /* Find manual byte swap implementations and turn them into a bswap | |
1094 builtin invokation. */ | |
817 | 1095 |
818 static unsigned int | 1096 static unsigned int |
819 execute_convert_to_rsqrt (void) | 1097 execute_optimize_bswap (void) |
820 { | 1098 { |
821 basic_block bb; | 1099 basic_block bb; |
1100 bool bswap32_p, bswap64_p; | |
1101 bool changed = false; | |
1102 tree bswap32_type = NULL_TREE, bswap64_type = NULL_TREE; | |
1103 | |
1104 if (BITS_PER_UNIT != 8) | |
1105 return 0; | |
1106 | |
1107 if (sizeof (HOST_WIDEST_INT) < 8) | |
1108 return 0; | |
1109 | |
1110 bswap32_p = (built_in_decls[BUILT_IN_BSWAP32] | |
1111 && optab_handler (bswap_optab, SImode)->insn_code != | |
1112 CODE_FOR_nothing); | |
1113 bswap64_p = (built_in_decls[BUILT_IN_BSWAP64] | |
1114 && optab_handler (bswap_optab, DImode)->insn_code != | |
1115 CODE_FOR_nothing); | |
1116 | |
1117 if (!bswap32_p && !bswap64_p) | |
1118 return 0; | |
1119 | |
1120 /* Determine the argument type of the builtins. The code later on | |
1121 assumes that the return and argument type are the same. */ | |
1122 if (bswap32_p) | |
1123 { | |
1124 tree fndecl = built_in_decls[BUILT_IN_BSWAP32]; | |
1125 bswap32_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); | |
1126 } | |
1127 | |
1128 if (bswap64_p) | |
1129 { | |
1130 tree fndecl = built_in_decls[BUILT_IN_BSWAP64]; | |
1131 bswap64_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); | |
1132 } | |
822 | 1133 |
823 FOR_EACH_BB (bb) | 1134 FOR_EACH_BB (bb) |
824 { | 1135 { |
825 gimple_stmt_iterator gsi; | 1136 gimple_stmt_iterator gsi; |
826 | 1137 |
827 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) | 1138 for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi)) |
828 { | 1139 { |
829 gimple stmt = gsi_stmt (gsi); | 1140 gimple stmt = gsi_stmt (gsi); |
830 tree fndecl; | 1141 tree bswap_src, bswap_type; |
831 | 1142 tree bswap_tmp; |
832 if (is_gimple_call (stmt) | 1143 tree fndecl = NULL_TREE; |
833 && gimple_call_lhs (stmt) | 1144 int type_size; |
834 && (fndecl = gimple_call_fndecl (stmt)) | 1145 gimple call; |
835 && (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL | 1146 |
836 || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD)) | 1147 if (!is_gimple_assign (stmt) |
1148 || gimple_assign_rhs_code (stmt) != BIT_IOR_EXPR) | |
1149 continue; | |
1150 | |
1151 type_size = TYPE_PRECISION (gimple_expr_type (stmt)); | |
1152 | |
1153 switch (type_size) | |
837 { | 1154 { |
838 enum built_in_function code; | 1155 case 32: |
839 bool md_code; | 1156 if (bswap32_p) |
840 tree arg1; | |
841 gimple stmt1; | |
842 | |
843 code = DECL_FUNCTION_CODE (fndecl); | |
844 md_code = DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD; | |
845 | |
846 fndecl = targetm.builtin_reciprocal (code, md_code, true); | |
847 if (!fndecl) | |
848 continue; | |
849 | |
850 arg1 = gimple_call_arg (stmt, 0); | |
851 | |
852 if (TREE_CODE (arg1) != SSA_NAME) | |
853 continue; | |
854 | |
855 stmt1 = SSA_NAME_DEF_STMT (arg1); | |
856 | |
857 if (is_gimple_assign (stmt1) | |
858 && gimple_assign_rhs_code (stmt1) == RDIV_EXPR) | |
859 { | 1157 { |
860 tree arg10, arg11; | 1158 fndecl = built_in_decls[BUILT_IN_BSWAP32]; |
861 | 1159 bswap_type = bswap32_type; |
862 arg10 = gimple_assign_rhs1 (stmt1); | |
863 arg11 = gimple_assign_rhs2 (stmt1); | |
864 | |
865 /* Swap operands of RDIV_EXPR. */ | |
866 gimple_assign_set_rhs1 (stmt1, arg11); | |
867 gimple_assign_set_rhs2 (stmt1, arg10); | |
868 fold_stmt_inplace (stmt1); | |
869 update_stmt (stmt1); | |
870 | |
871 gimple_call_set_fndecl (stmt, fndecl); | |
872 update_stmt (stmt); | |
873 } | 1160 } |
1161 break; | |
1162 case 64: | |
1163 if (bswap64_p) | |
1164 { | |
1165 fndecl = built_in_decls[BUILT_IN_BSWAP64]; | |
1166 bswap_type = bswap64_type; | |
1167 } | |
1168 break; | |
1169 default: | |
1170 continue; | |
874 } | 1171 } |
875 } | 1172 |
876 } | 1173 if (!fndecl) |
877 | 1174 continue; |
878 return 0; | 1175 |
1176 bswap_src = find_bswap (stmt); | |
1177 | |
1178 if (!bswap_src) | |
1179 continue; | |
1180 | |
1181 changed = true; | |
1182 | |
1183 bswap_tmp = bswap_src; | |
1184 | |
1185 /* Convert the src expression if necessary. */ | |
1186 if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp), bswap_type)) | |
1187 { | |
1188 gimple convert_stmt; | |
1189 | |
1190 bswap_tmp = create_tmp_var (bswap_type, "bswapsrc"); | |
1191 add_referenced_var (bswap_tmp); | |
1192 bswap_tmp = make_ssa_name (bswap_tmp, NULL); | |
1193 | |
1194 convert_stmt = gimple_build_assign_with_ops ( | |
1195 CONVERT_EXPR, bswap_tmp, bswap_src, NULL); | |
1196 gsi_insert_before (&gsi, convert_stmt, GSI_SAME_STMT); | |
1197 } | |
1198 | |
1199 call = gimple_build_call (fndecl, 1, bswap_tmp); | |
1200 | |
1201 bswap_tmp = gimple_assign_lhs (stmt); | |
1202 | |
1203 /* Convert the result if necessary. */ | |
1204 if (!useless_type_conversion_p (TREE_TYPE (bswap_tmp), bswap_type)) | |
1205 { | |
1206 gimple convert_stmt; | |
1207 | |
1208 bswap_tmp = create_tmp_var (bswap_type, "bswapdst"); | |
1209 add_referenced_var (bswap_tmp); | |
1210 bswap_tmp = make_ssa_name (bswap_tmp, NULL); | |
1211 convert_stmt = gimple_build_assign_with_ops ( | |
1212 CONVERT_EXPR, gimple_assign_lhs (stmt), bswap_tmp, NULL); | |
1213 gsi_insert_after (&gsi, convert_stmt, GSI_SAME_STMT); | |
1214 } | |
1215 | |
1216 gimple_call_set_lhs (call, bswap_tmp); | |
1217 | |
1218 if (dump_file) | |
1219 { | |
1220 fprintf (dump_file, "%d bit bswap implementation found at: ", | |
1221 (int)type_size); | |
1222 print_gimple_stmt (dump_file, stmt, 0, 0); | |
1223 } | |
1224 | |
1225 gsi_insert_after (&gsi, call, GSI_SAME_STMT); | |
1226 gsi_remove (&gsi, true); | |
1227 } | |
1228 } | |
1229 | |
1230 return (changed ? TODO_dump_func | TODO_update_ssa | TODO_verify_ssa | |
1231 | TODO_verify_stmts : 0); | |
879 } | 1232 } |
880 | 1233 |
881 static bool | 1234 static bool |
882 gate_convert_to_rsqrt (void) | 1235 gate_optimize_bswap (void) |
883 { | 1236 { |
884 return flag_unsafe_math_optimizations && optimize; | 1237 return flag_expensive_optimizations && optimize; |
885 } | 1238 } |
886 | 1239 |
887 struct gimple_opt_pass pass_convert_to_rsqrt = | 1240 struct gimple_opt_pass pass_optimize_bswap = |
888 { | 1241 { |
889 { | 1242 { |
890 GIMPLE_PASS, | 1243 GIMPLE_PASS, |
891 "rsqrt", /* name */ | 1244 "bswap", /* name */ |
892 gate_convert_to_rsqrt, /* gate */ | 1245 gate_optimize_bswap, /* gate */ |
893 execute_convert_to_rsqrt, /* execute */ | 1246 execute_optimize_bswap, /* execute */ |
894 NULL, /* sub */ | 1247 NULL, /* sub */ |
895 NULL, /* next */ | 1248 NULL, /* next */ |
896 0, /* static_pass_number */ | 1249 0, /* static_pass_number */ |
897 0, /* tv_id */ | 1250 TV_NONE, /* tv_id */ |
898 PROP_ssa, /* properties_required */ | 1251 PROP_ssa, /* properties_required */ |
899 0, /* properties_provided */ | 1252 0, /* properties_provided */ |
900 0, /* properties_destroyed */ | 1253 0, /* properties_destroyed */ |
901 0, /* todo_flags_start */ | 1254 0, /* todo_flags_start */ |
902 TODO_dump_func | TODO_update_ssa | TODO_verify_ssa | 1255 0 /* todo_flags_finish */ |
903 | TODO_verify_stmts /* todo_flags_finish */ | |
904 } | 1256 } |
905 }; | 1257 }; |