Mercurial > hg > CbC > CbC_gcc
comparison gcc/dojump.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 /* Convert tree expression to rtl instructions, for GNU compiler. | 1 /* Convert tree expression to rtl instructions, for GNU compiler. |
2 Copyright (C) 1988-2017 Free Software Foundation, Inc. | 2 Copyright (C) 1988-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
36 #include "explow.h" | 36 #include "explow.h" |
37 #include "expr.h" | 37 #include "expr.h" |
38 #include "langhooks.h" | 38 #include "langhooks.h" |
39 | 39 |
40 static bool prefer_and_bit_test (scalar_int_mode, int); | 40 static bool prefer_and_bit_test (scalar_int_mode, int); |
41 static void do_jump (tree, rtx_code_label *, rtx_code_label *, | |
42 profile_probability); | |
41 static void do_jump_by_parts_greater (scalar_int_mode, tree, tree, int, | 43 static void do_jump_by_parts_greater (scalar_int_mode, tree, tree, int, |
42 rtx_code_label *, rtx_code_label *, | 44 rtx_code_label *, rtx_code_label *, |
43 profile_probability); | 45 profile_probability); |
44 static void do_jump_by_parts_equality (scalar_int_mode, tree, tree, | 46 static void do_jump_by_parts_equality (scalar_int_mode, tree, tree, |
45 rtx_code_label *, rtx_code_label *, | 47 rtx_code_label *, rtx_code_label *, |
87 void | 89 void |
88 do_pending_stack_adjust (void) | 90 do_pending_stack_adjust (void) |
89 { | 91 { |
90 if (inhibit_defer_pop == 0) | 92 if (inhibit_defer_pop == 0) |
91 { | 93 { |
92 if (pending_stack_adjust != 0) | 94 if (maybe_ne (pending_stack_adjust, 0)) |
93 adjust_stack (GEN_INT (pending_stack_adjust)); | 95 adjust_stack (gen_int_mode (pending_stack_adjust, Pmode)); |
94 pending_stack_adjust = 0; | 96 pending_stack_adjust = 0; |
95 } | 97 } |
96 } | 98 } |
97 | 99 |
98 /* Remember pending_stack_adjust/stack_pointer_delta. | 100 /* Remember pending_stack_adjust/stack_pointer_delta. |
116 pending_stack_adjust = save->x_pending_stack_adjust; | 118 pending_stack_adjust = save->x_pending_stack_adjust; |
117 stack_pointer_delta = save->x_stack_pointer_delta; | 119 stack_pointer_delta = save->x_stack_pointer_delta; |
118 } | 120 } |
119 } | 121 } |
120 | 122 |
121 /* Expand conditional expressions. */ | |
122 | |
123 /* Generate code to evaluate EXP and jump to LABEL if the value is zero. */ | |
124 | |
125 void | |
126 jumpifnot (tree exp, rtx_code_label *label, profile_probability prob) | |
127 { | |
128 do_jump (exp, label, NULL, prob.invert ()); | |
129 } | |
130 | |
131 void | |
132 jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label, | |
133 profile_probability prob) | |
134 { | |
135 do_jump_1 (code, op0, op1, label, NULL, prob.invert ()); | |
136 } | |
137 | |
138 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */ | |
139 | |
140 void | |
141 jumpif (tree exp, rtx_code_label *label, profile_probability prob) | |
142 { | |
143 do_jump (exp, NULL, label, prob); | |
144 } | |
145 | |
146 void | |
147 jumpif_1 (enum tree_code code, tree op0, tree op1, | |
148 rtx_code_label *label, profile_probability prob) | |
149 { | |
150 do_jump_1 (code, op0, op1, NULL, label, prob); | |
151 } | |
152 | |
153 /* Used internally by prefer_and_bit_test. */ | 123 /* Used internally by prefer_and_bit_test. */ |
154 | 124 |
155 static GTY(()) rtx and_reg; | 125 static GTY(()) rtx and_reg; |
156 static GTY(()) rtx and_test; | 126 static GTY(()) rtx and_test; |
157 static GTY(()) rtx shift_test; | 127 static GTY(()) rtx shift_test; |
195 | 165 |
196 /* Subroutine of do_jump, dealing with exploded comparisons of the type | 166 /* Subroutine of do_jump, dealing with exploded comparisons of the type |
197 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump. | 167 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump. |
198 PROB is probability of jump to if_true_label. */ | 168 PROB is probability of jump to if_true_label. */ |
199 | 169 |
200 void | 170 static void |
201 do_jump_1 (enum tree_code code, tree op0, tree op1, | 171 do_jump_1 (enum tree_code code, tree op0, tree op1, |
202 rtx_code_label *if_false_label, rtx_code_label *if_true_label, | 172 rtx_code_label *if_false_label, rtx_code_label *if_true_label, |
203 profile_probability prob) | 173 profile_probability prob) |
204 { | 174 { |
205 machine_mode mode; | 175 machine_mode mode; |
345 reached it (i.e. the first condition was true). */ | 315 reached it (i.e. the first condition was true). */ |
346 profile_probability op0_prob = profile_probability::uninitialized (); | 316 profile_probability op0_prob = profile_probability::uninitialized (); |
347 profile_probability op1_prob = profile_probability::uninitialized (); | 317 profile_probability op1_prob = profile_probability::uninitialized (); |
348 if (prob.initialized_p ()) | 318 if (prob.initialized_p ()) |
349 { | 319 { |
350 profile_probability false_prob = prob.invert (); | 320 op1_prob = prob.invert (); |
351 profile_probability op0_false_prob = false_prob.apply_scale (1, 2); | 321 op0_prob = op1_prob.split (profile_probability::even ()); |
352 profile_probability op1_false_prob = false_prob.apply_scale (1, 2) | |
353 / op0_false_prob.invert (); | |
354 /* Get the probability that each jump below is true. */ | 322 /* Get the probability that each jump below is true. */ |
355 op0_prob = op0_false_prob.invert (); | 323 op0_prob = op0_prob.invert (); |
356 op1_prob = op1_false_prob.invert (); | 324 op1_prob = op1_prob.invert (); |
357 } | 325 } |
358 if (if_false_label == NULL) | 326 if (if_false_label == NULL) |
359 { | 327 { |
360 drop_through_label = gen_label_rtx (); | 328 drop_through_label = gen_label_rtx (); |
361 do_jump (op0, drop_through_label, NULL, op0_prob); | 329 do_jump (op0, drop_through_label, NULL, op0_prob); |
378 the probability we reached it (i.e. the first condition was false). */ | 346 the probability we reached it (i.e. the first condition was false). */ |
379 profile_probability op0_prob = profile_probability::uninitialized (); | 347 profile_probability op0_prob = profile_probability::uninitialized (); |
380 profile_probability op1_prob = profile_probability::uninitialized (); | 348 profile_probability op1_prob = profile_probability::uninitialized (); |
381 if (prob.initialized_p ()) | 349 if (prob.initialized_p ()) |
382 { | 350 { |
383 op0_prob = prob.apply_scale (1, 2); | 351 op1_prob = prob; |
384 op1_prob = prob.apply_scale (1, 2) / op0_prob.invert (); | 352 op0_prob = op1_prob.split (profile_probability::even ()); |
385 } | 353 } |
386 if (if_true_label == NULL) | 354 if (if_true_label == NULL) |
387 { | 355 { |
388 drop_through_label = gen_label_rtx (); | 356 drop_through_label = gen_label_rtx (); |
389 do_jump (op0, NULL, drop_through_label, op0_prob); | 357 do_jump (op0, NULL, drop_through_label, op0_prob); |
417 actually perform a jump. An example where there is no jump | 385 actually perform a jump. An example where there is no jump |
418 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null. | 386 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null. |
419 | 387 |
420 PROB is probability of jump to if_true_label. */ | 388 PROB is probability of jump to if_true_label. */ |
421 | 389 |
422 void | 390 static void |
423 do_jump (tree exp, rtx_code_label *if_false_label, | 391 do_jump (tree exp, rtx_code_label *if_false_label, |
424 rtx_code_label *if_true_label, profile_probability prob) | 392 rtx_code_label *if_true_label, profile_probability prob) |
425 { | 393 { |
426 enum tree_code code = TREE_CODE (exp); | 394 enum tree_code code = TREE_CODE (exp); |
427 rtx temp; | 395 rtx temp; |
467 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))) | 435 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))) |
468 goto normal; | 436 goto normal; |
469 /* FALLTHRU */ | 437 /* FALLTHRU */ |
470 case NON_LVALUE_EXPR: | 438 case NON_LVALUE_EXPR: |
471 case ABS_EXPR: | 439 case ABS_EXPR: |
440 case ABSU_EXPR: | |
472 case NEGATE_EXPR: | 441 case NEGATE_EXPR: |
473 case LROTATE_EXPR: | 442 case LROTATE_EXPR: |
474 case RROTATE_EXPR: | 443 case RROTATE_EXPR: |
475 /* These cannot change zero->nonzero or vice versa. */ | 444 /* These cannot change zero->nonzero or vice versa. */ |
476 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob); | 445 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob); |
945 default: | 914 default: |
946 gcc_unreachable (); | 915 gcc_unreachable (); |
947 } | 916 } |
948 } | 917 } |
949 | 918 |
919 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. | |
920 PROB is probability of jump to LABEL. */ | |
921 | |
922 void | |
923 jumpif (tree exp, rtx_code_label *label, profile_probability prob) | |
924 { | |
925 do_jump (exp, NULL, label, prob); | |
926 } | |
927 | |
928 /* Similar to jumpif but dealing with exploded comparisons of the type | |
929 OP0 CODE OP1 . LABEL and PROB are like in jumpif. */ | |
930 | |
931 void | |
932 jumpif_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label, | |
933 profile_probability prob) | |
934 { | |
935 do_jump_1 (code, op0, op1, NULL, label, prob); | |
936 } | |
937 | |
938 /* Generate code to evaluate EXP and jump to LABEL if the value is zero. | |
939 PROB is probability of jump to LABEL. */ | |
940 | |
941 void | |
942 jumpifnot (tree exp, rtx_code_label *label, profile_probability prob) | |
943 { | |
944 do_jump (exp, label, NULL, prob.invert ()); | |
945 } | |
946 | |
947 /* Similar to jumpifnot but dealing with exploded comparisons of the type | |
948 OP0 CODE OP1 . LABEL and PROB are like in jumpifnot. */ | |
949 | |
950 void | |
951 jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label, | |
952 profile_probability prob) | |
953 { | |
954 do_jump_1 (code, op0, op1, label, NULL, prob.invert ()); | |
955 } | |
950 | 956 |
951 /* Like do_compare_and_jump but expects the values to compare as two rtx's. | 957 /* Like do_compare_and_jump but expects the values to compare as two rtx's. |
952 The decision as to signed or unsigned comparison must be made by the caller. | 958 The decision as to signed or unsigned comparison must be made by the caller. |
953 | 959 |
954 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being | 960 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being |
1000 } | 1006 } |
1001 | 1007 |
1002 do_pending_stack_adjust (); | 1008 do_pending_stack_adjust (); |
1003 | 1009 |
1004 code = unsignedp ? unsigned_condition (code) : code; | 1010 code = unsignedp ? unsigned_condition (code) : code; |
1005 if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode, | 1011 if ((tem = simplify_relational_operation (code, mode, VOIDmode, |
1006 op0, op1))) | 1012 op0, op1)) != 0) |
1007 { | 1013 { |
1008 if (CONSTANT_P (tem)) | 1014 if (CONSTANT_P (tem)) |
1009 { | 1015 { |
1010 rtx_code_label *label = (tem == const0_rtx | 1016 rtx_code_label *label = (tem == const0_rtx |
1011 || tem == CONST0_RTX (mode)) | 1017 || tem == CONST0_RTX (mode)) |
1118 if (!HONOR_NANS (mode)) | 1124 if (!HONOR_NANS (mode)) |
1119 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED)); | 1125 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED)); |
1120 | 1126 |
1121 else | 1127 else |
1122 { | 1128 { |
1123 profile_probability first_prob = prob; | 1129 profile_probability cprob |
1130 = profile_probability::guessed_always (); | |
1124 if (first_code == UNORDERED) | 1131 if (first_code == UNORDERED) |
1125 first_prob = profile_probability::guessed_always ().apply_scale | 1132 cprob = cprob.apply_scale (1, 100); |
1126 (1, 100); | |
1127 else if (first_code == ORDERED) | 1133 else if (first_code == ORDERED) |
1128 first_prob = profile_probability::guessed_always ().apply_scale | 1134 cprob = cprob.apply_scale (99, 100); |
1129 (99, 100); | 1135 else |
1136 cprob = profile_probability::even (); | |
1137 /* We want to split: | |
1138 if (x) goto t; // prob; | |
1139 into | |
1140 if (a) goto t; // first_prob; | |
1141 if (b) goto t; // prob; | |
1142 such that the overall probability of jumping to t | |
1143 remains the same and first_prob is prob * cprob. */ | |
1130 if (and_them) | 1144 if (and_them) |
1131 { | 1145 { |
1132 rtx_code_label *dest_label; | 1146 rtx_code_label *dest_label; |
1147 prob = prob.invert (); | |
1148 profile_probability first_prob = prob.split (cprob).invert (); | |
1149 prob = prob.invert (); | |
1133 /* If we only jump if true, just bypass the second jump. */ | 1150 /* If we only jump if true, just bypass the second jump. */ |
1134 if (! if_false_label) | 1151 if (! if_false_label) |
1135 { | 1152 { |
1136 if (! dummy_label) | 1153 if (! dummy_label) |
1137 dummy_label = gen_label_rtx (); | 1154 dummy_label = gen_label_rtx (); |
1141 dest_label = if_false_label; | 1158 dest_label = if_false_label; |
1142 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, | 1159 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, |
1143 size, dest_label, NULL, first_prob); | 1160 size, dest_label, NULL, first_prob); |
1144 } | 1161 } |
1145 else | 1162 else |
1146 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, | 1163 { |
1147 size, NULL, if_true_label, first_prob); | 1164 profile_probability first_prob = prob.split (cprob); |
1165 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, | |
1166 size, NULL, if_true_label, first_prob); | |
1167 } | |
1148 } | 1168 } |
1149 } | 1169 } |
1150 | 1170 |
1151 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, | 1171 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, |
1152 if_true_label, prob); | 1172 if_true_label, prob); |
1200 mode = TYPE_MODE (type); | 1220 mode = TYPE_MODE (type); |
1201 unsignedp = TYPE_UNSIGNED (type); | 1221 unsignedp = TYPE_UNSIGNED (type); |
1202 code = unsignedp ? unsigned_code : signed_code; | 1222 code = unsignedp ? unsigned_code : signed_code; |
1203 | 1223 |
1204 /* If function pointers need to be "canonicalized" before they can | 1224 /* If function pointers need to be "canonicalized" before they can |
1205 be reliably compared, then canonicalize them. | 1225 be reliably compared, then canonicalize them. Canonicalize the |
1206 Only do this if *both* sides of the comparison are function pointers. | 1226 expression when one of the operands is a function pointer. This |
1207 If one side isn't, we want a noncanonicalized comparison. See PR | 1227 handles the case where the other operand is a void pointer. See |
1208 middle-end/17564. */ | 1228 PR middle-end/17564. */ |
1209 if (targetm.have_canonicalize_funcptr_for_compare () | 1229 if (targetm.have_canonicalize_funcptr_for_compare () |
1210 && POINTER_TYPE_P (TREE_TYPE (treeop0)) | 1230 && ((POINTER_TYPE_P (TREE_TYPE (treeop0)) |
1211 && POINTER_TYPE_P (TREE_TYPE (treeop1)) | 1231 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0)))) |
1212 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0))) | 1232 || (POINTER_TYPE_P (TREE_TYPE (treeop1)) |
1213 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1)))) | 1233 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1)))))) |
1214 { | 1234 { |
1215 rtx new_op0 = gen_reg_rtx (mode); | 1235 rtx new_op0 = gen_reg_rtx (mode); |
1216 rtx new_op1 = gen_reg_rtx (mode); | 1236 rtx new_op1 = gen_reg_rtx (mode); |
1217 | 1237 |
1218 emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op0, op0)); | 1238 emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op0, op0)); |