comparison gcc/dojump.c @ 132:d34655255c78

update gcc-8.2
author mir3636
date Thu, 25 Oct 2018 10:21:07 +0900
parents 84e7813d76e9
children 1830386684a0
comparison
equal deleted inserted replaced
130:e108057fa461 132:d34655255c78
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));