Mercurial > hg > CbC > CbC_gcc
comparison gcc/dojump.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | b7f97abdc517 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Convert tree expression to rtl instructions, for GNU compiler. | 1 /* Convert tree expression to rtl instructions, for GNU compiler. |
2 Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, | 2 Copyright (C) 1988-2017 Free Software Foundation, Inc. |
3 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 | |
4 Free Software Foundation, Inc. | |
5 | 3 |
6 This file is part of GCC. | 4 This file is part of GCC. |
7 | 5 |
8 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 |
9 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 |
20 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
21 | 19 |
22 #include "config.h" | 20 #include "config.h" |
23 #include "system.h" | 21 #include "system.h" |
24 #include "coretypes.h" | 22 #include "coretypes.h" |
25 #include "tm.h" | 23 #include "backend.h" |
24 #include "target.h" | |
26 #include "rtl.h" | 25 #include "rtl.h" |
27 #include "tree.h" | 26 #include "tree.h" |
28 #include "flags.h" | 27 #include "predict.h" |
29 #include "function.h" | 28 #include "memmodel.h" |
30 #include "insn-config.h" | 29 #include "tm_p.h" |
31 #include "insn-attr.h" | 30 #include "optabs.h" |
31 #include "emit-rtl.h" | |
32 #include "fold-const.h" | |
33 #include "stor-layout.h" | |
32 /* Include expr.h after insn-config.h so we get HAVE_conditional_move. */ | 34 /* Include expr.h after insn-config.h so we get HAVE_conditional_move. */ |
35 #include "dojump.h" | |
36 #include "explow.h" | |
33 #include "expr.h" | 37 #include "expr.h" |
34 #include "optabs.h" | |
35 #include "langhooks.h" | 38 #include "langhooks.h" |
36 #include "ggc.h" | 39 |
37 #include "basic-block.h" | 40 static bool prefer_and_bit_test (scalar_int_mode, int); |
38 #include "output.h" | 41 static void do_jump_by_parts_greater (scalar_int_mode, tree, tree, int, |
39 | 42 rtx_code_label *, rtx_code_label *, |
40 static bool prefer_and_bit_test (enum machine_mode, int); | 43 profile_probability); |
41 static void do_jump_by_parts_greater (tree, tree, int, rtx, rtx, int); | 44 static void do_jump_by_parts_equality (scalar_int_mode, tree, tree, |
42 static void do_jump_by_parts_equality (tree, tree, rtx, rtx, int); | 45 rtx_code_label *, rtx_code_label *, |
43 static void do_compare_and_jump (tree, tree, enum rtx_code, enum rtx_code, rtx, | 46 profile_probability); |
44 rtx, int); | 47 static void do_compare_and_jump (tree, tree, enum rtx_code, enum rtx_code, |
45 | 48 rtx_code_label *, rtx_code_label *, |
46 /* Invert probability if there is any. -1 stands for unknown. */ | 49 profile_probability); |
47 | |
48 static inline int | |
49 inv (int prob) | |
50 { | |
51 return prob == -1 ? -1 : REG_BR_PROB_BASE - prob; | |
52 } | |
53 | 50 |
54 /* At the start of a function, record that we have no previously-pushed | 51 /* At the start of a function, record that we have no previously-pushed |
55 arguments waiting to be popped. */ | 52 arguments waiting to be popped. */ |
56 | 53 |
57 void | 54 void |
95 if (pending_stack_adjust != 0) | 92 if (pending_stack_adjust != 0) |
96 adjust_stack (GEN_INT (pending_stack_adjust)); | 93 adjust_stack (GEN_INT (pending_stack_adjust)); |
97 pending_stack_adjust = 0; | 94 pending_stack_adjust = 0; |
98 } | 95 } |
99 } | 96 } |
97 | |
98 /* Remember pending_stack_adjust/stack_pointer_delta. | |
99 To be used around code that may call do_pending_stack_adjust (), | |
100 but the generated code could be discarded e.g. using delete_insns_since. */ | |
101 | |
102 void | |
103 save_pending_stack_adjust (saved_pending_stack_adjust *save) | |
104 { | |
105 save->x_pending_stack_adjust = pending_stack_adjust; | |
106 save->x_stack_pointer_delta = stack_pointer_delta; | |
107 } | |
108 | |
109 /* Restore the saved pending_stack_adjust/stack_pointer_delta. */ | |
110 | |
111 void | |
112 restore_pending_stack_adjust (saved_pending_stack_adjust *save) | |
113 { | |
114 if (inhibit_defer_pop == 0) | |
115 { | |
116 pending_stack_adjust = save->x_pending_stack_adjust; | |
117 stack_pointer_delta = save->x_stack_pointer_delta; | |
118 } | |
119 } | |
100 | 120 |
101 /* Expand conditional expressions. */ | 121 /* Expand conditional expressions. */ |
102 | 122 |
103 /* Generate code to evaluate EXP and jump to LABEL if the value is zero. | 123 /* Generate code to evaluate EXP and jump to LABEL if the value is zero. */ |
104 LABEL is an rtx of code CODE_LABEL, in this function and all the | |
105 functions here. */ | |
106 | 124 |
107 void | 125 void |
108 jumpifnot (tree exp, rtx label, int prob) | 126 jumpifnot (tree exp, rtx_code_label *label, profile_probability prob) |
109 { | 127 { |
110 do_jump (exp, label, NULL_RTX, inv (prob)); | 128 do_jump (exp, label, NULL, prob.invert ()); |
111 } | 129 } |
112 | 130 |
113 void | 131 void |
114 jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx label, int prob) | 132 jumpifnot_1 (enum tree_code code, tree op0, tree op1, rtx_code_label *label, |
115 { | 133 profile_probability prob) |
116 do_jump_1 (code, op0, op1, label, NULL_RTX, inv (prob)); | 134 { |
135 do_jump_1 (code, op0, op1, label, NULL, prob.invert ()); | |
117 } | 136 } |
118 | 137 |
119 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */ | 138 /* Generate code to evaluate EXP and jump to LABEL if the value is nonzero. */ |
120 | 139 |
121 void | 140 void |
122 jumpif (tree exp, rtx label, int prob) | 141 jumpif (tree exp, rtx_code_label *label, profile_probability prob) |
123 { | 142 { |
124 do_jump (exp, NULL_RTX, label, prob); | 143 do_jump (exp, NULL, label, prob); |
125 } | 144 } |
126 | 145 |
127 void | 146 void |
128 jumpif_1 (enum tree_code code, tree op0, tree op1, rtx label, int prob) | 147 jumpif_1 (enum tree_code code, tree op0, tree op1, |
129 { | 148 rtx_code_label *label, profile_probability prob) |
130 do_jump_1 (code, op0, op1, NULL_RTX, label, prob); | 149 { |
150 do_jump_1 (code, op0, op1, NULL, label, prob); | |
131 } | 151 } |
132 | 152 |
133 /* Used internally by prefer_and_bit_test. */ | 153 /* Used internally by prefer_and_bit_test. */ |
134 | 154 |
135 static GTY(()) rtx and_reg; | 155 static GTY(()) rtx and_reg; |
139 /* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1", | 159 /* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1", |
140 where X is an arbitrary register of mode MODE. Return true if the former | 160 where X is an arbitrary register of mode MODE. Return true if the former |
141 is preferred. */ | 161 is preferred. */ |
142 | 162 |
143 static bool | 163 static bool |
144 prefer_and_bit_test (enum machine_mode mode, int bitnum) | 164 prefer_and_bit_test (scalar_int_mode mode, int bitnum) |
145 { | 165 { |
166 bool speed_p; | |
167 wide_int mask = wi::set_bit_in_zero (bitnum, GET_MODE_PRECISION (mode)); | |
168 | |
146 if (and_test == 0) | 169 if (and_test == 0) |
147 { | 170 { |
148 /* Set up rtxes for the two variations. Use NULL as a placeholder | 171 /* Set up rtxes for the two variations. Use NULL as a placeholder |
149 for the BITNUM-based constants. */ | 172 for the BITNUM-based constants. */ |
150 and_reg = gen_rtx_REG (mode, FIRST_PSEUDO_REGISTER); | 173 and_reg = gen_rtx_REG (mode, LAST_VIRTUAL_REGISTER + 1); |
151 and_test = gen_rtx_AND (mode, and_reg, NULL); | 174 and_test = gen_rtx_AND (mode, and_reg, NULL); |
152 shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL), | 175 shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL), |
153 const1_rtx); | 176 const1_rtx); |
154 } | 177 } |
155 else | 178 else |
160 PUT_MODE (shift_test, mode); | 183 PUT_MODE (shift_test, mode); |
161 PUT_MODE (XEXP (shift_test, 0), mode); | 184 PUT_MODE (XEXP (shift_test, 0), mode); |
162 } | 185 } |
163 | 186 |
164 /* Fill in the integers. */ | 187 /* Fill in the integers. */ |
165 XEXP (and_test, 1) | 188 XEXP (and_test, 1) = immed_wide_int_const (mask, mode); |
166 = immed_double_int_const (double_int_setbit (double_int_zero, bitnum), | |
167 mode); | |
168 XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum); | 189 XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum); |
169 | 190 |
170 return (rtx_cost (and_test, IF_THEN_ELSE, optimize_insn_for_speed_p ()) | 191 speed_p = optimize_insn_for_speed_p (); |
171 <= rtx_cost (shift_test, IF_THEN_ELSE, optimize_insn_for_speed_p ())); | 192 return (rtx_cost (and_test, mode, IF_THEN_ELSE, 0, speed_p) |
193 <= rtx_cost (shift_test, mode, IF_THEN_ELSE, 0, speed_p)); | |
172 } | 194 } |
173 | 195 |
174 /* Subroutine of do_jump, dealing with exploded comparisons of the type | 196 /* Subroutine of do_jump, dealing with exploded comparisons of the type |
175 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump. | 197 OP0 CODE OP1 . IF_FALSE_LABEL and IF_TRUE_LABEL like in do_jump. |
176 PROB is probability of jump to if_true_label, or -1 if unknown. */ | 198 PROB is probability of jump to if_true_label. */ |
177 | 199 |
178 void | 200 void |
179 do_jump_1 (enum tree_code code, tree op0, tree op1, | 201 do_jump_1 (enum tree_code code, tree op0, tree op1, |
180 rtx if_false_label, rtx if_true_label, int prob) | 202 rtx_code_label *if_false_label, rtx_code_label *if_true_label, |
181 { | 203 profile_probability prob) |
182 enum machine_mode mode; | 204 { |
183 rtx drop_through_label = 0; | 205 machine_mode mode; |
206 rtx_code_label *drop_through_label = 0; | |
207 scalar_int_mode int_mode; | |
184 | 208 |
185 switch (code) | 209 switch (code) |
186 { | 210 { |
187 case EQ_EXPR: | 211 case EQ_EXPR: |
188 { | 212 { |
192 != MODE_COMPLEX_FLOAT); | 216 != MODE_COMPLEX_FLOAT); |
193 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type)) | 217 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type)) |
194 != MODE_COMPLEX_INT); | 218 != MODE_COMPLEX_INT); |
195 | 219 |
196 if (integer_zerop (op1)) | 220 if (integer_zerop (op1)) |
197 do_jump (op0, if_true_label, if_false_label, inv (prob)); | 221 do_jump (op0, if_true_label, if_false_label, |
198 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT | 222 prob.invert ()); |
199 && !can_compare_p (EQ, TYPE_MODE (inner_type), ccp_jump)) | 223 else if (is_int_mode (TYPE_MODE (inner_type), &int_mode) |
200 do_jump_by_parts_equality (op0, op1, if_false_label, if_true_label, | 224 && !can_compare_p (EQ, int_mode, ccp_jump)) |
201 prob); | 225 do_jump_by_parts_equality (int_mode, op0, op1, if_false_label, |
226 if_true_label, prob); | |
202 else | 227 else |
203 do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label, | 228 do_compare_and_jump (op0, op1, EQ, EQ, if_false_label, if_true_label, |
204 prob); | 229 prob); |
205 break; | 230 break; |
206 } | 231 } |
214 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type)) | 239 gcc_assert (GET_MODE_CLASS (TYPE_MODE (inner_type)) |
215 != MODE_COMPLEX_INT); | 240 != MODE_COMPLEX_INT); |
216 | 241 |
217 if (integer_zerop (op1)) | 242 if (integer_zerop (op1)) |
218 do_jump (op0, if_false_label, if_true_label, prob); | 243 do_jump (op0, if_false_label, if_true_label, prob); |
219 else if (GET_MODE_CLASS (TYPE_MODE (inner_type)) == MODE_INT | 244 else if (is_int_mode (TYPE_MODE (inner_type), &int_mode) |
220 && !can_compare_p (NE, TYPE_MODE (inner_type), ccp_jump)) | 245 && !can_compare_p (NE, int_mode, ccp_jump)) |
221 do_jump_by_parts_equality (op0, op1, if_true_label, if_false_label, | 246 do_jump_by_parts_equality (int_mode, op0, op1, if_true_label, |
222 inv (prob)); | 247 if_false_label, prob.invert ()); |
223 else | 248 else |
224 do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label, | 249 do_compare_and_jump (op0, op1, NE, NE, if_false_label, if_true_label, |
225 prob); | 250 prob); |
226 break; | 251 break; |
227 } | 252 } |
228 | 253 |
229 case LT_EXPR: | 254 case LT_EXPR: |
230 mode = TYPE_MODE (TREE_TYPE (op0)); | 255 mode = TYPE_MODE (TREE_TYPE (op0)); |
231 if (GET_MODE_CLASS (mode) == MODE_INT | 256 if (is_int_mode (mode, &int_mode) |
232 && ! can_compare_p (LT, mode, ccp_jump)) | 257 && ! can_compare_p (LT, int_mode, ccp_jump)) |
233 do_jump_by_parts_greater (op0, op1, 1, if_false_label, if_true_label, | 258 do_jump_by_parts_greater (int_mode, op0, op1, 1, if_false_label, |
234 prob); | 259 if_true_label, prob); |
235 else | 260 else |
236 do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label, | 261 do_compare_and_jump (op0, op1, LT, LTU, if_false_label, if_true_label, |
237 prob); | 262 prob); |
238 break; | 263 break; |
239 | 264 |
240 case LE_EXPR: | 265 case LE_EXPR: |
241 mode = TYPE_MODE (TREE_TYPE (op0)); | 266 mode = TYPE_MODE (TREE_TYPE (op0)); |
242 if (GET_MODE_CLASS (mode) == MODE_INT | 267 if (is_int_mode (mode, &int_mode) |
243 && ! can_compare_p (LE, mode, ccp_jump)) | 268 && ! can_compare_p (LE, int_mode, ccp_jump)) |
244 do_jump_by_parts_greater (op0, op1, 0, if_true_label, if_false_label, | 269 do_jump_by_parts_greater (int_mode, op0, op1, 0, if_true_label, |
245 inv (prob)); | 270 if_false_label, prob.invert ()); |
246 else | 271 else |
247 do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label, | 272 do_compare_and_jump (op0, op1, LE, LEU, if_false_label, if_true_label, |
248 prob); | 273 prob); |
249 break; | 274 break; |
250 | 275 |
251 case GT_EXPR: | 276 case GT_EXPR: |
252 mode = TYPE_MODE (TREE_TYPE (op0)); | 277 mode = TYPE_MODE (TREE_TYPE (op0)); |
253 if (GET_MODE_CLASS (mode) == MODE_INT | 278 if (is_int_mode (mode, &int_mode) |
254 && ! can_compare_p (GT, mode, ccp_jump)) | 279 && ! can_compare_p (GT, int_mode, ccp_jump)) |
255 do_jump_by_parts_greater (op0, op1, 0, if_false_label, if_true_label, | 280 do_jump_by_parts_greater (int_mode, op0, op1, 0, if_false_label, |
256 prob); | 281 if_true_label, prob); |
257 else | 282 else |
258 do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label, | 283 do_compare_and_jump (op0, op1, GT, GTU, if_false_label, if_true_label, |
259 prob); | 284 prob); |
260 break; | 285 break; |
261 | 286 |
262 case GE_EXPR: | 287 case GE_EXPR: |
263 mode = TYPE_MODE (TREE_TYPE (op0)); | 288 mode = TYPE_MODE (TREE_TYPE (op0)); |
264 if (GET_MODE_CLASS (mode) == MODE_INT | 289 if (is_int_mode (mode, &int_mode) |
265 && ! can_compare_p (GE, mode, ccp_jump)) | 290 && ! can_compare_p (GE, int_mode, ccp_jump)) |
266 do_jump_by_parts_greater (op0, op1, 1, if_true_label, if_false_label, | 291 do_jump_by_parts_greater (int_mode, op0, op1, 1, if_true_label, |
267 inv (prob)); | 292 if_false_label, prob.invert ()); |
268 else | 293 else |
269 do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label, | 294 do_compare_and_jump (op0, op1, GE, GEU, if_false_label, if_true_label, |
270 prob); | 295 prob); |
271 break; | 296 break; |
272 | 297 |
309 do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label, | 334 do_compare_and_jump (op0, op1, LTGT, LTGT, if_false_label, if_true_label, |
310 prob); | 335 prob); |
311 break; | 336 break; |
312 | 337 |
313 case TRUTH_ANDIF_EXPR: | 338 case TRUTH_ANDIF_EXPR: |
314 if (if_false_label == NULL_RTX) | 339 { |
315 { | 340 /* Spread the probability that the expression is false evenly between |
316 drop_through_label = gen_label_rtx (); | 341 the two conditions. So the first condition is false half the total |
317 do_jump (op0, drop_through_label, NULL_RTX, prob); | 342 probability of being false. The second condition is false the other |
318 do_jump (op1, NULL_RTX, if_true_label, prob); | 343 half of the total probability of being false, so its jump has a false |
319 } | 344 probability of half the total, relative to the probability we |
320 else | 345 reached it (i.e. the first condition was true). */ |
321 { | 346 profile_probability op0_prob = profile_probability::uninitialized (); |
322 do_jump (op0, if_false_label, NULL_RTX, prob); | 347 profile_probability op1_prob = profile_probability::uninitialized (); |
323 do_jump (op1, if_false_label, if_true_label, prob); | 348 if (prob.initialized_p ()) |
324 } | 349 { |
325 break; | 350 profile_probability false_prob = prob.invert (); |
351 profile_probability op0_false_prob = false_prob.apply_scale (1, 2); | |
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. */ | |
355 op0_prob = op0_false_prob.invert (); | |
356 op1_prob = op1_false_prob.invert (); | |
357 } | |
358 if (if_false_label == NULL) | |
359 { | |
360 drop_through_label = gen_label_rtx (); | |
361 do_jump (op0, drop_through_label, NULL, op0_prob); | |
362 do_jump (op1, NULL, if_true_label, op1_prob); | |
363 } | |
364 else | |
365 { | |
366 do_jump (op0, if_false_label, NULL, op0_prob); | |
367 do_jump (op1, if_false_label, if_true_label, op1_prob); | |
368 } | |
369 break; | |
370 } | |
326 | 371 |
327 case TRUTH_ORIF_EXPR: | 372 case TRUTH_ORIF_EXPR: |
328 if (if_true_label == NULL_RTX) | 373 { |
329 { | 374 /* Spread the probability evenly between the two conditions. So |
330 drop_through_label = gen_label_rtx (); | 375 the first condition has half the total probability of being true. |
331 do_jump (op0, NULL_RTX, drop_through_label, prob); | 376 The second condition has the other half of the total probability, |
332 do_jump (op1, if_false_label, NULL_RTX, prob); | 377 so its jump has a probability of half the total, relative to |
333 } | 378 the probability we reached it (i.e. the first condition was false). */ |
334 else | 379 profile_probability op0_prob = profile_probability::uninitialized (); |
335 { | 380 profile_probability op1_prob = profile_probability::uninitialized (); |
336 do_jump (op0, NULL_RTX, if_true_label, prob); | 381 if (prob.initialized_p ()) |
337 do_jump (op1, if_false_label, if_true_label, prob); | 382 { |
338 } | 383 op0_prob = prob.apply_scale (1, 2); |
339 break; | 384 op1_prob = prob.apply_scale (1, 2) / op0_prob.invert (); |
385 } | |
386 if (if_true_label == NULL) | |
387 { | |
388 drop_through_label = gen_label_rtx (); | |
389 do_jump (op0, NULL, drop_through_label, op0_prob); | |
390 do_jump (op1, if_false_label, NULL, op1_prob); | |
391 } | |
392 else | |
393 { | |
394 do_jump (op0, NULL, if_true_label, op0_prob); | |
395 do_jump (op1, if_false_label, if_true_label, op1_prob); | |
396 } | |
397 break; | |
398 } | |
340 | 399 |
341 default: | 400 default: |
342 gcc_unreachable (); | 401 gcc_unreachable (); |
343 } | 402 } |
344 | 403 |
356 | 415 |
357 do_jump always does any pending stack adjust except when it does not | 416 do_jump always does any pending stack adjust except when it does not |
358 actually perform a jump. An example where there is no jump | 417 actually perform a jump. An example where there is no jump |
359 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null. | 418 is when EXP is `(foo (), 0)' and IF_FALSE_LABEL is null. |
360 | 419 |
361 PROB is probability of jump to if_true_label, or -1 if unknown. */ | 420 PROB is probability of jump to if_true_label. */ |
362 | 421 |
363 void | 422 void |
364 do_jump (tree exp, rtx if_false_label, rtx if_true_label, int prob) | 423 do_jump (tree exp, rtx_code_label *if_false_label, |
424 rtx_code_label *if_true_label, profile_probability prob) | |
365 { | 425 { |
366 enum tree_code code = TREE_CODE (exp); | 426 enum tree_code code = TREE_CODE (exp); |
367 rtx temp; | 427 rtx temp; |
368 int i; | 428 int i; |
369 tree type; | 429 tree type; |
370 enum machine_mode mode; | 430 scalar_int_mode mode; |
371 rtx drop_through_label = 0; | 431 rtx_code_label *drop_through_label = NULL; |
372 | 432 |
373 switch (code) | 433 switch (code) |
374 { | 434 { |
375 case ERROR_MARK: | 435 case ERROR_MARK: |
376 break; | 436 break; |
377 | 437 |
378 case INTEGER_CST: | 438 case INTEGER_CST: |
379 temp = integer_zerop (exp) ? if_false_label : if_true_label; | 439 { |
380 if (temp) | 440 rtx_code_label *lab = integer_zerop (exp) ? if_false_label |
381 emit_jump (temp); | 441 : if_true_label; |
382 break; | 442 if (lab) |
443 emit_jump (lab); | |
444 break; | |
445 } | |
383 | 446 |
384 #if 0 | 447 #if 0 |
385 /* This is not true with #pragma weak */ | 448 /* This is not true with #pragma weak */ |
386 case ADDR_EXPR: | 449 case ADDR_EXPR: |
387 /* The address of something can never be zero. */ | 450 /* The address of something can never be zero. */ |
394 if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF | 457 if (TREE_CODE (TREE_OPERAND (exp, 0)) == COMPONENT_REF |
395 || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF | 458 || TREE_CODE (TREE_OPERAND (exp, 0)) == BIT_FIELD_REF |
396 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF | 459 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_REF |
397 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF) | 460 || TREE_CODE (TREE_OPERAND (exp, 0)) == ARRAY_RANGE_REF) |
398 goto normal; | 461 goto normal; |
462 /* FALLTHRU */ | |
399 case CONVERT_EXPR: | 463 case CONVERT_EXPR: |
400 /* If we are narrowing the operand, we have to do the compare in the | 464 /* If we are narrowing the operand, we have to do the compare in the |
401 narrower mode. */ | 465 narrower mode. */ |
402 if ((TYPE_PRECISION (TREE_TYPE (exp)) | 466 if ((TYPE_PRECISION (TREE_TYPE (exp)) |
403 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))) | 467 < TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (exp, 0))))) |
404 goto normal; | 468 goto normal; |
469 /* FALLTHRU */ | |
405 case NON_LVALUE_EXPR: | 470 case NON_LVALUE_EXPR: |
406 case ABS_EXPR: | 471 case ABS_EXPR: |
407 case NEGATE_EXPR: | 472 case NEGATE_EXPR: |
408 case LROTATE_EXPR: | 473 case LROTATE_EXPR: |
409 case RROTATE_EXPR: | 474 case RROTATE_EXPR: |
411 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob); | 476 do_jump (TREE_OPERAND (exp, 0), if_false_label, if_true_label, prob); |
412 break; | 477 break; |
413 | 478 |
414 case TRUTH_NOT_EXPR: | 479 case TRUTH_NOT_EXPR: |
415 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label, | 480 do_jump (TREE_OPERAND (exp, 0), if_true_label, if_false_label, |
416 inv (prob)); | 481 prob.invert ()); |
417 break; | 482 break; |
418 | 483 |
419 case COND_EXPR: | 484 case COND_EXPR: |
420 { | 485 { |
421 rtx label1 = gen_label_rtx (); | 486 rtx_code_label *label1 = gen_label_rtx (); |
422 if (!if_true_label || !if_false_label) | 487 if (!if_true_label || !if_false_label) |
423 { | 488 { |
424 drop_through_label = gen_label_rtx (); | 489 drop_through_label = gen_label_rtx (); |
425 if (!if_true_label) | 490 if (!if_true_label) |
426 if_true_label = drop_through_label; | 491 if_true_label = drop_through_label; |
427 if (!if_false_label) | 492 if (!if_false_label) |
428 if_false_label = drop_through_label; | 493 if_false_label = drop_through_label; |
429 } | 494 } |
430 | 495 |
431 do_pending_stack_adjust (); | 496 do_pending_stack_adjust (); |
432 do_jump (TREE_OPERAND (exp, 0), label1, NULL_RTX, -1); | 497 do_jump (TREE_OPERAND (exp, 0), label1, NULL, |
498 profile_probability::uninitialized ()); | |
433 do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob); | 499 do_jump (TREE_OPERAND (exp, 1), if_false_label, if_true_label, prob); |
434 emit_label (label1); | 500 emit_label (label1); |
435 do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob); | 501 do_jump (TREE_OPERAND (exp, 2), if_false_label, if_true_label, prob); |
436 break; | 502 break; |
437 } | 503 } |
438 | 504 |
439 case COMPOUND_EXPR: | 505 case COMPOUND_EXPR: |
440 /* Lowered by gimplify.c. */ | 506 /* Lowered by gimplify.c. */ |
441 gcc_unreachable (); | 507 gcc_unreachable (); |
442 | |
443 case COMPONENT_REF: | |
444 case BIT_FIELD_REF: | |
445 case ARRAY_REF: | |
446 case ARRAY_RANGE_REF: | |
447 { | |
448 HOST_WIDE_INT bitsize, bitpos; | |
449 int unsignedp; | |
450 enum machine_mode mode; | |
451 tree type; | |
452 tree offset; | |
453 int volatilep = 0; | |
454 | |
455 /* Get description of this reference. We don't actually care | |
456 about the underlying object here. */ | |
457 get_inner_reference (exp, &bitsize, &bitpos, &offset, &mode, | |
458 &unsignedp, &volatilep, false); | |
459 | |
460 type = lang_hooks.types.type_for_size (bitsize, unsignedp); | |
461 if (! SLOW_BYTE_ACCESS | |
462 && type != 0 && bitsize >= 0 | |
463 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp)) | |
464 && have_insn_for (COMPARE, TYPE_MODE (type))) | |
465 { | |
466 do_jump (fold_convert (type, exp), if_false_label, if_true_label, | |
467 prob); | |
468 break; | |
469 } | |
470 goto normal; | |
471 } | |
472 | 508 |
473 case MINUS_EXPR: | 509 case MINUS_EXPR: |
474 /* Nonzero iff operands of minus differ. */ | 510 /* Nonzero iff operands of minus differ. */ |
475 code = NE_EXPR; | 511 code = NE_EXPR; |
476 | 512 |
501 See if the former is preferred for jump tests and restore it | 537 See if the former is preferred for jump tests and restore it |
502 if so. */ | 538 if so. */ |
503 if (integer_onep (TREE_OPERAND (exp, 1))) | 539 if (integer_onep (TREE_OPERAND (exp, 1))) |
504 { | 540 { |
505 tree exp0 = TREE_OPERAND (exp, 0); | 541 tree exp0 = TREE_OPERAND (exp, 0); |
506 rtx set_label, clr_label; | 542 rtx_code_label *set_label, *clr_label; |
507 int setclr_prob = prob; | 543 profile_probability setclr_prob = prob; |
508 | 544 |
509 /* Strip narrowing integral type conversions. */ | 545 /* Strip narrowing integral type conversions. */ |
510 while (CONVERT_EXPR_P (exp0) | 546 while (CONVERT_EXPR_P (exp0) |
511 && TREE_OPERAND (exp0, 0) != error_mark_node | 547 && TREE_OPERAND (exp0, 0) != error_mark_node |
512 && TYPE_PRECISION (TREE_TYPE (exp0)) | 548 && TYPE_PRECISION (TREE_TYPE (exp0)) |
518 && integer_onep (TREE_OPERAND (exp0, 1))) | 554 && integer_onep (TREE_OPERAND (exp0, 1))) |
519 { | 555 { |
520 exp0 = TREE_OPERAND (exp0, 0); | 556 exp0 = TREE_OPERAND (exp0, 0); |
521 clr_label = if_true_label; | 557 clr_label = if_true_label; |
522 set_label = if_false_label; | 558 set_label = if_false_label; |
523 setclr_prob = inv (prob); | 559 setclr_prob = prob.invert (); |
524 } | 560 } |
525 else | 561 else |
526 { | 562 { |
527 clr_label = if_false_label; | 563 clr_label = if_false_label; |
528 set_label = if_true_label; | 564 set_label = if_true_label; |
534 tree shift = TREE_OPERAND (exp0, 1); | 570 tree shift = TREE_OPERAND (exp0, 1); |
535 tree argtype = TREE_TYPE (arg); | 571 tree argtype = TREE_TYPE (arg); |
536 if (TREE_CODE (shift) == INTEGER_CST | 572 if (TREE_CODE (shift) == INTEGER_CST |
537 && compare_tree_int (shift, 0) >= 0 | 573 && compare_tree_int (shift, 0) >= 0 |
538 && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0 | 574 && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0 |
539 && prefer_and_bit_test (TYPE_MODE (argtype), | 575 && prefer_and_bit_test (SCALAR_INT_TYPE_MODE (argtype), |
540 TREE_INT_CST_LOW (shift))) | 576 TREE_INT_CST_LOW (shift))) |
541 { | 577 { |
542 unsigned HOST_WIDE_INT mask | 578 unsigned HOST_WIDE_INT mask |
543 = (unsigned HOST_WIDE_INT) 1 << TREE_INT_CST_LOW (shift); | 579 = HOST_WIDE_INT_1U << TREE_INT_CST_LOW (shift); |
544 do_jump (build2 (BIT_AND_EXPR, argtype, arg, | 580 do_jump (build2 (BIT_AND_EXPR, argtype, arg, |
545 build_int_cstu (argtype, mask)), | 581 build_int_cstu (argtype, mask)), |
546 clr_label, set_label, setclr_prob); | 582 clr_label, set_label, setclr_prob); |
547 break; | 583 break; |
548 } | 584 } |
558 | 594 |
559 if (! SLOW_BYTE_ACCESS | 595 if (! SLOW_BYTE_ACCESS |
560 && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST | 596 && TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST |
561 && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT | 597 && TYPE_PRECISION (TREE_TYPE (exp)) <= HOST_BITS_PER_WIDE_INT |
562 && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0 | 598 && (i = tree_floor_log2 (TREE_OPERAND (exp, 1))) >= 0 |
563 && (mode = mode_for_size (i + 1, MODE_INT, 0)) != BLKmode | 599 && int_mode_for_size (i + 1, 0).exists (&mode) |
564 && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0 | 600 && (type = lang_hooks.types.type_for_mode (mode, 1)) != 0 |
565 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp)) | 601 && TYPE_PRECISION (type) < TYPE_PRECISION (TREE_TYPE (exp)) |
566 && have_insn_for (COMPARE, TYPE_MODE (type))) | 602 && have_insn_for (COMPARE, TYPE_MODE (type))) |
567 { | 603 { |
568 do_jump (fold_convert (type, exp), if_false_label, if_true_label, | 604 do_jump (fold_convert (type, exp), if_false_label, if_true_label, |
573 if (TYPE_PRECISION (TREE_TYPE (exp)) > 1 | 609 if (TYPE_PRECISION (TREE_TYPE (exp)) > 1 |
574 || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) | 610 || TREE_CODE (TREE_OPERAND (exp, 1)) == INTEGER_CST) |
575 goto normal; | 611 goto normal; |
576 | 612 |
577 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */ | 613 /* Boolean comparisons can be compiled as TRUTH_AND_EXPR. */ |
614 /* FALLTHRU */ | |
578 | 615 |
579 case TRUTH_AND_EXPR: | 616 case TRUTH_AND_EXPR: |
580 /* High branch cost, expand as the bitwise AND of the conditions. | 617 /* High branch cost, expand as the bitwise AND of the conditions. |
581 Do the same if the RHS has side effects, because we're effectively | 618 Do the same if the RHS has side effects, because we're effectively |
582 turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR. */ | 619 turning a TRUTH_AND_EXPR into a TRUTH_ANDIF_EXPR. */ |
629 /* Compare OP0 with OP1, word at a time, in mode MODE. | 666 /* Compare OP0 with OP1, word at a time, in mode MODE. |
630 UNSIGNEDP says to do unsigned comparison. | 667 UNSIGNEDP says to do unsigned comparison. |
631 Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */ | 668 Jump to IF_TRUE_LABEL if OP0 is greater, IF_FALSE_LABEL otherwise. */ |
632 | 669 |
633 static void | 670 static void |
634 do_jump_by_parts_greater_rtx (enum machine_mode mode, int unsignedp, rtx op0, | 671 do_jump_by_parts_greater_rtx (scalar_int_mode mode, int unsignedp, rtx op0, |
635 rtx op1, rtx if_false_label, rtx if_true_label, | 672 rtx op1, rtx_code_label *if_false_label, |
636 int prob) | 673 rtx_code_label *if_true_label, |
674 profile_probability prob) | |
637 { | 675 { |
638 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); | 676 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); |
639 rtx drop_through_label = 0; | 677 rtx_code_label *drop_through_label = 0; |
678 bool drop_through_if_true = false, drop_through_if_false = false; | |
679 enum rtx_code code = GT; | |
640 int i; | 680 int i; |
641 | 681 |
642 if (! if_true_label || ! if_false_label) | 682 if (! if_true_label || ! if_false_label) |
643 drop_through_label = gen_label_rtx (); | 683 drop_through_label = gen_label_rtx (); |
644 if (! if_true_label) | 684 if (! if_true_label) |
645 if_true_label = drop_through_label; | 685 { |
686 if_true_label = drop_through_label; | |
687 drop_through_if_true = true; | |
688 } | |
646 if (! if_false_label) | 689 if (! if_false_label) |
647 if_false_label = drop_through_label; | 690 { |
691 if_false_label = drop_through_label; | |
692 drop_through_if_false = true; | |
693 } | |
694 | |
695 /* Deal with the special case 0 > x: only one comparison is necessary and | |
696 we reverse it to avoid jumping to the drop-through label. */ | |
697 if (op0 == const0_rtx && drop_through_if_true && !drop_through_if_false) | |
698 { | |
699 code = LE; | |
700 if_true_label = if_false_label; | |
701 if_false_label = drop_through_label; | |
702 drop_through_if_true = false; | |
703 drop_through_if_false = true; | |
704 prob = prob.invert (); | |
705 } | |
648 | 706 |
649 /* Compare a word at a time, high order first. */ | 707 /* Compare a word at a time, high order first. */ |
650 for (i = 0; i < nwords; i++) | 708 for (i = 0; i < nwords; i++) |
651 { | 709 { |
652 rtx op0_word, op1_word; | 710 rtx op0_word, op1_word; |
661 op0_word = operand_subword_force (op0, nwords - 1 - i, mode); | 719 op0_word = operand_subword_force (op0, nwords - 1 - i, mode); |
662 op1_word = operand_subword_force (op1, nwords - 1 - i, mode); | 720 op1_word = operand_subword_force (op1, nwords - 1 - i, mode); |
663 } | 721 } |
664 | 722 |
665 /* All but high-order word must be compared as unsigned. */ | 723 /* All but high-order word must be compared as unsigned. */ |
666 do_compare_rtx_and_jump (op0_word, op1_word, GT, | 724 do_compare_rtx_and_jump (op0_word, op1_word, code, (unsignedp || i > 0), |
667 (unsignedp || i > 0), word_mode, NULL_RTX, | 725 word_mode, NULL_RTX, NULL, if_true_label, |
668 NULL_RTX, if_true_label, prob); | 726 prob); |
727 | |
728 /* Emit only one comparison for 0. Do not emit the last cond jump. */ | |
729 if (op0 == const0_rtx || i == nwords - 1) | |
730 break; | |
669 | 731 |
670 /* Consider lower words only if these are equal. */ | 732 /* Consider lower words only if these are equal. */ |
671 do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode, | 733 do_compare_rtx_and_jump (op0_word, op1_word, NE, unsignedp, word_mode, |
672 NULL_RTX, NULL_RTX, if_false_label, | 734 NULL_RTX, NULL, if_false_label, |
673 inv (prob)); | 735 prob.invert ()); |
674 } | 736 } |
675 | 737 |
676 if (if_false_label) | 738 if (!drop_through_if_false) |
677 emit_jump (if_false_label); | 739 emit_jump (if_false_label); |
678 if (drop_through_label) | 740 if (drop_through_label) |
679 emit_label (drop_through_label); | 741 emit_label (drop_through_label); |
680 } | 742 } |
681 | 743 |
682 /* Given a comparison expression EXP for values too wide to be compared | 744 /* Given a comparison expression EXP for values too wide to be compared |
683 with one insn, test the comparison and jump to the appropriate label. | 745 with one insn, test the comparison and jump to the appropriate label. |
684 The code of EXP is ignored; we always test GT if SWAP is 0, | 746 The code of EXP is ignored; we always test GT if SWAP is 0, |
685 and LT if SWAP is 1. */ | 747 and LT if SWAP is 1. MODE is the mode of the two operands. */ |
686 | 748 |
687 static void | 749 static void |
688 do_jump_by_parts_greater (tree treeop0, tree treeop1, int swap, | 750 do_jump_by_parts_greater (scalar_int_mode mode, tree treeop0, tree treeop1, |
689 rtx if_false_label, rtx if_true_label, int prob) | 751 int swap, rtx_code_label *if_false_label, |
752 rtx_code_label *if_true_label, | |
753 profile_probability prob) | |
690 { | 754 { |
691 rtx op0 = expand_normal (swap ? treeop1 : treeop0); | 755 rtx op0 = expand_normal (swap ? treeop1 : treeop0); |
692 rtx op1 = expand_normal (swap ? treeop0 : treeop1); | 756 rtx op1 = expand_normal (swap ? treeop0 : treeop1); |
693 enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0)); | |
694 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0)); | 757 int unsignedp = TYPE_UNSIGNED (TREE_TYPE (treeop0)); |
695 | 758 |
696 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, | 759 do_jump_by_parts_greater_rtx (mode, unsignedp, op0, op1, if_false_label, |
697 if_true_label, prob); | 760 if_true_label, prob); |
698 } | 761 } |
699 | 762 |
700 /* Jump according to whether OP0 is 0. We assume that OP0 has an integer | 763 /* Jump according to whether OP0 is 0. We assume that OP0 has an integer |
701 mode, MODE, that is too wide for the available compare insns. Either | 764 mode, MODE, that is too wide for the available compare insns. Either |
702 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX | 765 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL |
703 to indicate drop through. */ | 766 to indicate drop through. */ |
704 | 767 |
705 static void | 768 static void |
706 do_jump_by_parts_zero_rtx (enum machine_mode mode, rtx op0, | 769 do_jump_by_parts_zero_rtx (scalar_int_mode mode, rtx op0, |
707 rtx if_false_label, rtx if_true_label, int prob) | 770 rtx_code_label *if_false_label, |
771 rtx_code_label *if_true_label, | |
772 profile_probability prob) | |
708 { | 773 { |
709 int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD; | 774 int nwords = GET_MODE_SIZE (mode) / UNITS_PER_WORD; |
710 rtx part; | 775 rtx part; |
711 int i; | 776 int i; |
712 rtx drop_through_label = 0; | 777 rtx_code_label *drop_through_label = NULL; |
713 | 778 |
714 /* The fastest way of doing this comparison on almost any machine is to | 779 /* The fastest way of doing this comparison on almost any machine is to |
715 "or" all the words and compare the result. If all have to be loaded | 780 "or" all the words and compare the result. If all have to be loaded |
716 from memory and this is a very wide item, it's possible this may | 781 from memory and this is a very wide item, it's possible this may |
717 be slower, but that's highly unlikely. */ | 782 be slower, but that's highly unlikely. */ |
730 return; | 795 return; |
731 } | 796 } |
732 | 797 |
733 /* If we couldn't do the "or" simply, do this with a series of compares. */ | 798 /* If we couldn't do the "or" simply, do this with a series of compares. */ |
734 if (! if_false_label) | 799 if (! if_false_label) |
735 drop_through_label = if_false_label = gen_label_rtx (); | 800 if_false_label = drop_through_label = gen_label_rtx (); |
736 | 801 |
737 for (i = 0; i < nwords; i++) | 802 for (i = 0; i < nwords; i++) |
738 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), | 803 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), |
739 const0_rtx, EQ, 1, word_mode, NULL_RTX, | 804 const0_rtx, EQ, 1, word_mode, NULL_RTX, |
740 if_false_label, NULL_RTX, prob); | 805 if_false_label, NULL, prob); |
741 | 806 |
742 if (if_true_label) | 807 if (if_true_label) |
743 emit_jump (if_true_label); | 808 emit_jump (if_true_label); |
744 | 809 |
745 if (drop_through_label) | 810 if (drop_through_label) |
750 where MODE is an integer mode too wide to be compared with one insn. | 815 where MODE is an integer mode too wide to be compared with one insn. |
751 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX | 816 Either (but not both) of IF_TRUE_LABEL and IF_FALSE_LABEL may be NULL_RTX |
752 to indicate drop through. */ | 817 to indicate drop through. */ |
753 | 818 |
754 static void | 819 static void |
755 do_jump_by_parts_equality_rtx (enum machine_mode mode, rtx op0, rtx op1, | 820 do_jump_by_parts_equality_rtx (scalar_int_mode mode, rtx op0, rtx op1, |
756 rtx if_false_label, rtx if_true_label, int prob) | 821 rtx_code_label *if_false_label, |
822 rtx_code_label *if_true_label, | |
823 profile_probability prob) | |
757 { | 824 { |
758 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); | 825 int nwords = (GET_MODE_SIZE (mode) / UNITS_PER_WORD); |
759 rtx drop_through_label = 0; | 826 rtx_code_label *drop_through_label = NULL; |
760 int i; | 827 int i; |
761 | 828 |
762 if (op1 == const0_rtx) | 829 if (op1 == const0_rtx) |
763 { | 830 { |
764 do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label, | 831 do_jump_by_parts_zero_rtx (mode, op0, if_false_label, if_true_label, |
777 | 844 |
778 for (i = 0; i < nwords; i++) | 845 for (i = 0; i < nwords; i++) |
779 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), | 846 do_compare_rtx_and_jump (operand_subword_force (op0, i, mode), |
780 operand_subword_force (op1, i, mode), | 847 operand_subword_force (op1, i, mode), |
781 EQ, 0, word_mode, NULL_RTX, | 848 EQ, 0, word_mode, NULL_RTX, |
782 if_false_label, NULL_RTX, prob); | 849 if_false_label, NULL, prob); |
783 | 850 |
784 if (if_true_label) | 851 if (if_true_label) |
785 emit_jump (if_true_label); | 852 emit_jump (if_true_label); |
786 if (drop_through_label) | 853 if (drop_through_label) |
787 emit_label (drop_through_label); | 854 emit_label (drop_through_label); |
788 } | 855 } |
789 | 856 |
790 /* Given an EQ_EXPR expression EXP for values too wide to be compared | 857 /* Given an EQ_EXPR expression EXP for values too wide to be compared |
791 with one insn, test the comparison and jump to the appropriate label. */ | 858 with one insn, test the comparison and jump to the appropriate label. |
859 MODE is the mode of the two operands. */ | |
792 | 860 |
793 static void | 861 static void |
794 do_jump_by_parts_equality (tree treeop0, tree treeop1, rtx if_false_label, | 862 do_jump_by_parts_equality (scalar_int_mode mode, tree treeop0, tree treeop1, |
795 rtx if_true_label, int prob) | 863 rtx_code_label *if_false_label, |
864 rtx_code_label *if_true_label, | |
865 profile_probability prob) | |
796 { | 866 { |
797 rtx op0 = expand_normal (treeop0); | 867 rtx op0 = expand_normal (treeop0); |
798 rtx op1 = expand_normal (treeop1); | 868 rtx op1 = expand_normal (treeop1); |
799 enum machine_mode mode = TYPE_MODE (TREE_TYPE (treeop0)); | |
800 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label, | 869 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label, |
801 if_true_label, prob); | 870 if_true_label, prob); |
802 } | 871 } |
803 | 872 |
804 /* Split a comparison into two others, the second of which has the other | 873 /* Split a comparison into two others, the second of which has the other |
808 | 877 |
809 The two conditions are written in *CODE1 and *CODE2. Return true if | 878 The two conditions are written in *CODE1 and *CODE2. Return true if |
810 the conditions must be ANDed, false if they must be ORed. */ | 879 the conditions must be ANDed, false if they must be ORed. */ |
811 | 880 |
812 bool | 881 bool |
813 split_comparison (enum rtx_code code, enum machine_mode mode, | 882 split_comparison (enum rtx_code code, machine_mode mode, |
814 enum rtx_code *code1, enum rtx_code *code2) | 883 enum rtx_code *code1, enum rtx_code *code2) |
815 { | 884 { |
816 switch (code) | 885 switch (code) |
817 { | 886 { |
818 case LT: | 887 case LT: |
885 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being | 954 If MODE is BLKmode, SIZE is an RTX giving the size of the objects being |
886 compared. */ | 955 compared. */ |
887 | 956 |
888 void | 957 void |
889 do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, | 958 do_compare_rtx_and_jump (rtx op0, rtx op1, enum rtx_code code, int unsignedp, |
890 enum machine_mode mode, rtx size, rtx if_false_label, | 959 machine_mode mode, rtx size, |
891 rtx if_true_label, int prob) | 960 rtx_code_label *if_false_label, |
961 rtx_code_label *if_true_label, | |
962 profile_probability prob) | |
892 { | 963 { |
893 rtx tem; | 964 rtx tem; |
894 rtx dummy_label = NULL_RTX; | 965 rtx_code_label *dummy_label = NULL; |
895 rtx last; | |
896 | 966 |
897 /* Reverse the comparison if that is safe and we want to jump if it is | 967 /* Reverse the comparison if that is safe and we want to jump if it is |
898 false. Also convert to the reverse comparison if the target can | 968 false. Also convert to the reverse comparison if the target can |
899 implement it. */ | 969 implement it. */ |
900 if ((! if_true_label | 970 if ((! if_true_label |
912 | 982 |
913 /* Canonicalize to UNORDERED for the libcall. */ | 983 /* Canonicalize to UNORDERED for the libcall. */ |
914 if (can_compare_p (rcode, mode, ccp_jump) | 984 if (can_compare_p (rcode, mode, ccp_jump) |
915 || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump))) | 985 || (code == ORDERED && ! can_compare_p (ORDERED, mode, ccp_jump))) |
916 { | 986 { |
917 tem = if_true_label; | 987 std::swap (if_true_label, if_false_label); |
918 if_true_label = if_false_label; | |
919 if_false_label = tem; | |
920 code = rcode; | 988 code = rcode; |
921 prob = inv (prob); | 989 prob = prob.invert (); |
922 } | 990 } |
923 } | 991 } |
924 | 992 |
925 /* If one operand is constant, make it the second one. Only do this | 993 /* If one operand is constant, make it the second one. Only do this |
926 if the other operand is not constant as well. */ | 994 if the other operand is not constant as well. */ |
927 | 995 |
928 if (swap_commutative_operands_p (op0, op1)) | 996 if (swap_commutative_operands_p (op0, op1)) |
929 { | 997 { |
930 tem = op0; | 998 std::swap (op0, op1); |
931 op0 = op1; | |
932 op1 = tem; | |
933 code = swap_condition (code); | 999 code = swap_condition (code); |
934 } | 1000 } |
935 | 1001 |
936 do_pending_stack_adjust (); | 1002 do_pending_stack_adjust (); |
937 | 1003 |
939 if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode, | 1005 if (0 != (tem = simplify_relational_operation (code, mode, VOIDmode, |
940 op0, op1))) | 1006 op0, op1))) |
941 { | 1007 { |
942 if (CONSTANT_P (tem)) | 1008 if (CONSTANT_P (tem)) |
943 { | 1009 { |
944 rtx label = (tem == const0_rtx || tem == CONST0_RTX (mode)) | 1010 rtx_code_label *label = (tem == const0_rtx |
945 ? if_false_label : if_true_label; | 1011 || tem == CONST0_RTX (mode)) |
1012 ? if_false_label : if_true_label; | |
946 if (label) | 1013 if (label) |
947 emit_jump (label); | 1014 emit_jump (label); |
948 return; | 1015 return; |
949 } | 1016 } |
950 | 1017 |
956 } | 1023 } |
957 | 1024 |
958 if (! if_true_label) | 1025 if (! if_true_label) |
959 dummy_label = if_true_label = gen_label_rtx (); | 1026 dummy_label = if_true_label = gen_label_rtx (); |
960 | 1027 |
961 if (GET_MODE_CLASS (mode) == MODE_INT | 1028 scalar_int_mode int_mode; |
962 && ! can_compare_p (code, mode, ccp_jump)) | 1029 if (is_int_mode (mode, &int_mode) |
1030 && ! can_compare_p (code, int_mode, ccp_jump)) | |
963 { | 1031 { |
964 switch (code) | 1032 switch (code) |
965 { | 1033 { |
966 case LTU: | 1034 case LTU: |
967 do_jump_by_parts_greater_rtx (mode, 1, op1, op0, | 1035 do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0, |
968 if_false_label, if_true_label, prob); | 1036 if_false_label, if_true_label, prob); |
969 break; | 1037 break; |
970 | 1038 |
971 case LEU: | 1039 case LEU: |
972 do_jump_by_parts_greater_rtx (mode, 1, op0, op1, | 1040 do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1, |
973 if_true_label, if_false_label, | 1041 if_true_label, if_false_label, |
974 inv (prob)); | 1042 prob.invert ()); |
975 break; | 1043 break; |
976 | 1044 |
977 case GTU: | 1045 case GTU: |
978 do_jump_by_parts_greater_rtx (mode, 1, op0, op1, | 1046 do_jump_by_parts_greater_rtx (int_mode, 1, op0, op1, |
979 if_false_label, if_true_label, prob); | 1047 if_false_label, if_true_label, prob); |
980 break; | 1048 break; |
981 | 1049 |
982 case GEU: | 1050 case GEU: |
983 do_jump_by_parts_greater_rtx (mode, 1, op1, op0, | 1051 do_jump_by_parts_greater_rtx (int_mode, 1, op1, op0, |
984 if_true_label, if_false_label, | 1052 if_true_label, if_false_label, |
985 inv (prob)); | 1053 prob.invert ()); |
986 break; | 1054 break; |
987 | 1055 |
988 case LT: | 1056 case LT: |
989 do_jump_by_parts_greater_rtx (mode, 0, op1, op0, | 1057 do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0, |
990 if_false_label, if_true_label, prob); | 1058 if_false_label, if_true_label, prob); |
991 break; | 1059 break; |
992 | 1060 |
993 case LE: | 1061 case LE: |
994 do_jump_by_parts_greater_rtx (mode, 0, op0, op1, | 1062 do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1, |
995 if_true_label, if_false_label, | 1063 if_true_label, if_false_label, |
996 inv (prob)); | 1064 prob.invert ()); |
997 break; | 1065 break; |
998 | 1066 |
999 case GT: | 1067 case GT: |
1000 do_jump_by_parts_greater_rtx (mode, 0, op0, op1, | 1068 do_jump_by_parts_greater_rtx (int_mode, 0, op0, op1, |
1001 if_false_label, if_true_label, prob); | 1069 if_false_label, if_true_label, prob); |
1002 break; | 1070 break; |
1003 | 1071 |
1004 case GE: | 1072 case GE: |
1005 do_jump_by_parts_greater_rtx (mode, 0, op1, op0, | 1073 do_jump_by_parts_greater_rtx (int_mode, 0, op1, op0, |
1006 if_true_label, if_false_label, | 1074 if_true_label, if_false_label, |
1007 inv (prob)); | 1075 prob.invert ()); |
1008 break; | 1076 break; |
1009 | 1077 |
1010 case EQ: | 1078 case EQ: |
1011 do_jump_by_parts_equality_rtx (mode, op0, op1, if_false_label, | 1079 do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_false_label, |
1012 if_true_label, prob); | 1080 if_true_label, prob); |
1013 break; | 1081 break; |
1014 | 1082 |
1015 case NE: | 1083 case NE: |
1016 do_jump_by_parts_equality_rtx (mode, op0, op1, if_true_label, | 1084 do_jump_by_parts_equality_rtx (int_mode, op0, op1, if_true_label, |
1017 if_false_label, inv (prob)); | 1085 if_false_label, |
1086 prob.invert ()); | |
1018 break; | 1087 break; |
1019 | 1088 |
1020 default: | 1089 default: |
1021 gcc_unreachable (); | 1090 gcc_unreachable (); |
1022 } | 1091 } |
1023 } | 1092 } |
1024 else | 1093 else |
1025 { | 1094 { |
1026 if (GET_MODE_CLASS (mode) == MODE_FLOAT | 1095 if (SCALAR_FLOAT_MODE_P (mode) |
1027 && ! can_compare_p (code, mode, ccp_jump) | 1096 && ! can_compare_p (code, mode, ccp_jump) |
1028 && can_compare_p (swap_condition (code), mode, ccp_jump)) | 1097 && can_compare_p (swap_condition (code), mode, ccp_jump)) |
1029 { | 1098 { |
1030 rtx tmp; | |
1031 code = swap_condition (code); | 1099 code = swap_condition (code); |
1032 tmp = op0; | 1100 std::swap (op0, op1); |
1033 op0 = op1; | |
1034 op1 = tmp; | |
1035 } | 1101 } |
1036 | 1102 else if (SCALAR_FLOAT_MODE_P (mode) |
1037 else if (GET_MODE_CLASS (mode) == MODE_FLOAT | |
1038 && ! can_compare_p (code, mode, ccp_jump) | 1103 && ! can_compare_p (code, mode, ccp_jump) |
1039 | 1104 /* Never split ORDERED and UNORDERED. |
1040 /* Never split ORDERED and UNORDERED. These must be implemented. */ | 1105 These must be implemented. */ |
1041 && (code != ORDERED && code != UNORDERED) | 1106 && (code != ORDERED && code != UNORDERED) |
1042 | 1107 /* Split a floating-point comparison if |
1043 /* Split a floating-point comparison if we can jump on other | 1108 we can jump on other conditions... */ |
1044 conditions... */ | |
1045 && (have_insn_for (COMPARE, mode) | 1109 && (have_insn_for (COMPARE, mode) |
1046 | |
1047 /* ... or if there is no libcall for it. */ | 1110 /* ... or if there is no libcall for it. */ |
1048 || code_to_optab[code] == NULL)) | 1111 || code_to_optab (code) == unknown_optab)) |
1049 { | 1112 { |
1050 enum rtx_code first_code; | 1113 enum rtx_code first_code; |
1051 bool and_them = split_comparison (code, mode, &first_code, &code); | 1114 bool and_them = split_comparison (code, mode, &first_code, &code); |
1052 | 1115 |
1053 /* If there are no NaNs, the first comparison should always fall | 1116 /* If there are no NaNs, the first comparison should always fall |
1055 if (!HONOR_NANS (mode)) | 1118 if (!HONOR_NANS (mode)) |
1056 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED)); | 1119 gcc_assert (first_code == (and_them ? ORDERED : UNORDERED)); |
1057 | 1120 |
1058 else | 1121 else |
1059 { | 1122 { |
1123 profile_probability first_prob = prob; | |
1124 if (first_code == UNORDERED) | |
1125 first_prob = profile_probability::guessed_always ().apply_scale | |
1126 (1, 100); | |
1127 else if (first_code == ORDERED) | |
1128 first_prob = profile_probability::guessed_always ().apply_scale | |
1129 (99, 100); | |
1060 if (and_them) | 1130 if (and_them) |
1061 { | 1131 { |
1062 rtx dest_label; | 1132 rtx_code_label *dest_label; |
1063 /* If we only jump if true, just bypass the second jump. */ | 1133 /* If we only jump if true, just bypass the second jump. */ |
1064 if (! if_false_label) | 1134 if (! if_false_label) |
1065 { | 1135 { |
1066 if (! dummy_label) | 1136 if (! dummy_label) |
1067 dummy_label = gen_label_rtx (); | 1137 dummy_label = gen_label_rtx (); |
1068 dest_label = dummy_label; | 1138 dest_label = dummy_label; |
1069 } | 1139 } |
1070 else | 1140 else |
1071 dest_label = if_false_label; | 1141 dest_label = if_false_label; |
1072 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, | 1142 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, |
1073 size, dest_label, NULL_RTX, prob); | 1143 size, dest_label, NULL, first_prob); |
1074 } | 1144 } |
1075 else | 1145 else |
1076 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, | 1146 do_compare_rtx_and_jump (op0, op1, first_code, unsignedp, mode, |
1077 size, NULL_RTX, if_true_label, prob); | 1147 size, NULL, if_true_label, first_prob); |
1078 } | 1148 } |
1079 } | 1149 } |
1080 | 1150 |
1081 last = get_last_insn (); | |
1082 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, | 1151 emit_cmp_and_jump_insns (op0, op1, code, size, mode, unsignedp, |
1083 if_true_label); | 1152 if_true_label, prob); |
1084 if (prob != -1 && profile_status != PROFILE_ABSENT) | |
1085 { | |
1086 for (last = NEXT_INSN (last); | |
1087 last && NEXT_INSN (last); | |
1088 last = NEXT_INSN (last)) | |
1089 if (JUMP_P (last)) | |
1090 break; | |
1091 if (!last | |
1092 || !JUMP_P (last) | |
1093 || NEXT_INSN (last) | |
1094 || !any_condjump_p (last)) | |
1095 { | |
1096 if (dump_file) | |
1097 fprintf (dump_file, "Failed to add probability note\n"); | |
1098 } | |
1099 else | |
1100 { | |
1101 gcc_assert (!find_reg_note (last, REG_BR_PROB, 0)); | |
1102 add_reg_note (last, REG_BR_PROB, GEN_INT (prob)); | |
1103 } | |
1104 } | |
1105 } | 1153 } |
1106 | 1154 |
1107 if (if_false_label) | 1155 if (if_false_label) |
1108 emit_jump (if_false_label); | 1156 emit_jump (if_false_label); |
1109 if (dummy_label) | 1157 if (dummy_label) |
1120 We force a stack adjustment unless there are currently | 1168 We force a stack adjustment unless there are currently |
1121 things pushed on the stack that aren't yet used. */ | 1169 things pushed on the stack that aren't yet used. */ |
1122 | 1170 |
1123 static void | 1171 static void |
1124 do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code, | 1172 do_compare_and_jump (tree treeop0, tree treeop1, enum rtx_code signed_code, |
1125 enum rtx_code unsigned_code, rtx if_false_label, | 1173 enum rtx_code unsigned_code, |
1126 rtx if_true_label, int prob) | 1174 rtx_code_label *if_false_label, |
1175 rtx_code_label *if_true_label, profile_probability prob) | |
1127 { | 1176 { |
1128 rtx op0, op1; | 1177 rtx op0, op1; |
1129 tree type; | 1178 tree type; |
1130 enum machine_mode mode; | 1179 machine_mode mode; |
1131 int unsignedp; | 1180 int unsignedp; |
1132 enum rtx_code code; | 1181 enum rtx_code code; |
1133 | 1182 |
1134 /* Don't crash if the comparison was erroneous. */ | 1183 /* Don't crash if the comparison was erroneous. */ |
1135 op0 = expand_normal (treeop0); | 1184 op0 = expand_normal (treeop0); |
1139 op1 = expand_normal (treeop1); | 1188 op1 = expand_normal (treeop1); |
1140 if (TREE_CODE (treeop1) == ERROR_MARK) | 1189 if (TREE_CODE (treeop1) == ERROR_MARK) |
1141 return; | 1190 return; |
1142 | 1191 |
1143 type = TREE_TYPE (treeop0); | 1192 type = TREE_TYPE (treeop0); |
1144 mode = TYPE_MODE (type); | |
1145 if (TREE_CODE (treeop0) == INTEGER_CST | 1193 if (TREE_CODE (treeop0) == INTEGER_CST |
1146 && (TREE_CODE (treeop1) != INTEGER_CST | 1194 && (TREE_CODE (treeop1) != INTEGER_CST |
1147 || (GET_MODE_BITSIZE (mode) | 1195 || (GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type)) |
1148 > GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (treeop1)))))) | 1196 > GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (treeop1)))))) |
1149 { | 1197 /* op0 might have been replaced by promoted constant, in which |
1150 /* op0 might have been replaced by promoted constant, in which | 1198 case the type of second argument should be used. */ |
1151 case the type of second argument should be used. */ | 1199 type = TREE_TYPE (treeop1); |
1152 type = TREE_TYPE (treeop1); | 1200 mode = TYPE_MODE (type); |
1153 mode = TYPE_MODE (type); | |
1154 } | |
1155 unsignedp = TYPE_UNSIGNED (type); | 1201 unsignedp = TYPE_UNSIGNED (type); |
1156 code = unsignedp ? unsigned_code : signed_code; | 1202 code = unsignedp ? unsigned_code : signed_code; |
1157 | 1203 |
1158 #ifdef HAVE_canonicalize_funcptr_for_compare | |
1159 /* If function pointers need to be "canonicalized" before they can | 1204 /* If function pointers need to be "canonicalized" before they can |
1160 be reliably compared, then canonicalize them. | 1205 be reliably compared, then canonicalize them. |
1161 Only do this if *both* sides of the comparison are function pointers. | 1206 Only do this if *both* sides of the comparison are function pointers. |
1162 If one side isn't, we want a noncanonicalized comparison. See PR | 1207 If one side isn't, we want a noncanonicalized comparison. See PR |
1163 middle-end/17564. */ | 1208 middle-end/17564. */ |
1164 if (HAVE_canonicalize_funcptr_for_compare | 1209 if (targetm.have_canonicalize_funcptr_for_compare () |
1165 && TREE_CODE (TREE_TYPE (treeop0)) == POINTER_TYPE | 1210 && POINTER_TYPE_P (TREE_TYPE (treeop0)) |
1166 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop0))) | 1211 && POINTER_TYPE_P (TREE_TYPE (treeop1)) |
1167 == FUNCTION_TYPE | 1212 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop0))) |
1168 && TREE_CODE (TREE_TYPE (treeop1)) == POINTER_TYPE | 1213 && FUNC_OR_METHOD_TYPE_P (TREE_TYPE (TREE_TYPE (treeop1)))) |
1169 && TREE_CODE (TREE_TYPE (TREE_TYPE (treeop1))) | |
1170 == FUNCTION_TYPE) | |
1171 { | 1214 { |
1172 rtx new_op0 = gen_reg_rtx (mode); | 1215 rtx new_op0 = gen_reg_rtx (mode); |
1173 rtx new_op1 = gen_reg_rtx (mode); | 1216 rtx new_op1 = gen_reg_rtx (mode); |
1174 | 1217 |
1175 emit_insn (gen_canonicalize_funcptr_for_compare (new_op0, op0)); | 1218 emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op0, op0)); |
1176 op0 = new_op0; | 1219 op0 = new_op0; |
1177 | 1220 |
1178 emit_insn (gen_canonicalize_funcptr_for_compare (new_op1, op1)); | 1221 emit_insn (targetm.gen_canonicalize_funcptr_for_compare (new_op1, op1)); |
1179 op1 = new_op1; | 1222 op1 = new_op1; |
1180 } | 1223 } |
1181 #endif | |
1182 | 1224 |
1183 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, | 1225 do_compare_rtx_and_jump (op0, op1, code, unsignedp, mode, |
1184 ((mode == BLKmode) | 1226 ((mode == BLKmode) |
1185 ? expr_size (treeop0) : NULL_RTX), | 1227 ? expr_size (treeop0) : NULL_RTX), |
1186 if_false_label, if_true_label, prob); | 1228 if_false_label, if_true_label, prob); |