]> gcc.gnu.org Git - gcc.git/blob - gcc/ifcvt.c
ifcvt.c (merge_if_block): Use any_uncondjump_p...
[gcc.git] / gcc / ifcvt.c
1 /* If-conversion support.
2 Copyright (C) 2000 Free Software Foundation, Inc.
3
4 This file is part of GNU CC.
5
6 GNU CC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU CC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU CC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
20
21 #include "config.h"
22 #include "system.h"
23
24 #include "rtl.h"
25 #include "regs.h"
26 #include "function.h"
27 #include "flags.h"
28 #include "insn-config.h"
29 #include "recog.h"
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
32 #include "expr.h"
33 #include "real.h"
34 #include "output.h"
35 #include "toplev.h"
36 #include "tm_p.h"
37
38
39 #ifndef HAVE_conditional_execution
40 #define HAVE_conditional_execution 0
41 #endif
42 #ifndef HAVE_conditional_move
43 #define HAVE_conditional_move 0
44 #endif
45 #ifndef HAVE_incscc
46 #define HAVE_incscc 0
47 #endif
48 #ifndef HAVE_decscc
49 #define HAVE_decscc 0
50 #endif
51
52 #ifndef MAX_CONDITIONAL_EXECUTE
53 #define MAX_CONDITIONAL_EXECUTE (BRANCH_COST + 1)
54 #endif
55
56 #define NULL_EDGE ((struct edge_def *)NULL)
57 #define NULL_BLOCK ((struct basic_block_def *)NULL)
58
59 /* # of IF-THEN or IF-THEN-ELSE blocks we looked at */
60 static int num_possible_if_blocks;
61
62 /* # of IF-THEN or IF-THEN-ELSE blocks were converted to conditional
63 execution. */
64 static int num_updated_if_blocks;
65
66 /* # of basic blocks that were removed. */
67 static int num_removed_blocks;
68
69 /* The post-dominator relation on the original block numbers. */
70 static sbitmap *post_dominators;
71
72 /* Forward references. */
73 static int count_bb_insns PARAMS ((basic_block));
74 static rtx first_active_insn PARAMS ((basic_block));
75 static int last_active_insn_p PARAMS ((basic_block, rtx));
76 static int seq_contains_jump PARAMS ((rtx));
77
78 static int cond_exec_process_insns PARAMS ((rtx, rtx, rtx, rtx, int));
79 static rtx cond_exec_get_condition PARAMS ((rtx));
80 static int cond_exec_process_if_block PARAMS ((basic_block, basic_block,
81 basic_block, basic_block));
82
83 static rtx noce_get_condition PARAMS ((rtx, rtx *));
84 static int noce_operand_ok PARAMS ((rtx));
85 static int noce_process_if_block PARAMS ((basic_block, basic_block,
86 basic_block, basic_block));
87
88 static int process_if_block PARAMS ((basic_block, basic_block,
89 basic_block, basic_block));
90 static void merge_if_block PARAMS ((basic_block, basic_block,
91 basic_block, basic_block));
92
93 static int find_if_header PARAMS ((basic_block));
94 static int find_if_block PARAMS ((basic_block, edge, edge));
95 static int find_if_case_1 PARAMS ((basic_block, edge, edge));
96 static int find_if_case_2 PARAMS ((basic_block, edge, edge));
97 static int find_memory PARAMS ((rtx *, void *));
98 static int dead_or_predicable PARAMS ((basic_block, basic_block,
99 basic_block, rtx, int));
100 static void noce_emit_move_insn PARAMS ((rtx, rtx));
101 \f
102 /* Abuse the basic_block AUX field to store the original block index,
103 as well as a flag indicating that the block should be rescaned for
104 life analysis. */
105
106 #define SET_ORIG_INDEX(BB,I) ((BB)->aux = (void *)((size_t)(I) << 1))
107 #define ORIG_INDEX(BB) ((size_t)(BB)->aux >> 1)
108 #define SET_UPDATE_LIFE(BB) ((BB)->aux = (void *)((size_t)(BB)->aux | 1))
109 #define UPDATE_LIFE(BB) ((size_t)(BB)->aux & 1)
110
111 \f
112 /* Count the number of non-jump active insns in BB. */
113
114 static int
115 count_bb_insns (bb)
116 basic_block bb;
117 {
118 int count = 0;
119 rtx insn = bb->head;
120
121 while (1)
122 {
123 if (GET_CODE (insn) == CALL_INSN || GET_CODE (insn) == INSN)
124 count++;
125
126 if (insn == bb->end)
127 break;
128 insn = NEXT_INSN (insn);
129 }
130
131 return count;
132 }
133
134 /* Return the first non-jump active insn in the basic block. */
135
136 static rtx
137 first_active_insn (bb)
138 basic_block bb;
139 {
140 rtx insn = bb->head;
141
142 if (GET_CODE (insn) == CODE_LABEL)
143 {
144 if (insn == bb->end)
145 return NULL_RTX;
146 insn = NEXT_INSN (insn);
147 }
148
149 while (GET_CODE (insn) == NOTE)
150 {
151 if (insn == bb->end)
152 return NULL_RTX;
153 insn = NEXT_INSN (insn);
154 }
155
156 if (GET_CODE (insn) == JUMP_INSN)
157 return NULL_RTX;
158
159 return insn;
160 }
161
162 /* Return true if INSN is the last active non-jump insn in BB. */
163
164 static int
165 last_active_insn_p (bb, insn)
166 basic_block bb;
167 rtx insn;
168 {
169 do
170 {
171 if (insn == bb->end)
172 return TRUE;
173 insn = NEXT_INSN (insn);
174 }
175 while (GET_CODE (insn) == NOTE);
176
177 return GET_CODE (insn) == JUMP_INSN;
178 }
179
180 /* It is possible, especially when having dealt with multi-word
181 arithmetic, for the expanders to have emitted jumps. Search
182 through the sequence and return TRUE if a jump exists so that
183 we can abort the conversion. */
184
185 static int
186 seq_contains_jump (insn)
187 rtx insn;
188 {
189 while (insn)
190 {
191 if (GET_CODE (insn) == JUMP_INSN)
192 return 1;
193 insn = NEXT_INSN (insn);
194 }
195 return 0;
196 }
197 \f
198 /* Go through a bunch of insns, converting them to conditional
199 execution format if possible. Return TRUE if all of the non-note
200 insns were processed. */
201
202 static int
203 cond_exec_process_insns (start, end, test, prob_val, mod_ok)
204 rtx start; /* first insn to look at */
205 rtx end; /* last insn to look at */
206 rtx test; /* conditional execution test */
207 rtx prob_val; /* probability of branch taken. */
208 int mod_ok; /* true if modifications ok last insn. */
209 {
210 int must_be_last = FALSE;
211 rtx insn;
212 rtx pattern;
213
214 for (insn = start; ; insn = NEXT_INSN (insn))
215 {
216 if (GET_CODE (insn) == NOTE)
217 goto insn_done;
218
219 if (GET_CODE (insn) != INSN && GET_CODE (insn) != CALL_INSN)
220 abort ();
221
222 /* Remove USE insns that get in the way. */
223 if (reload_completed && GET_CODE (PATTERN (insn)) == USE)
224 {
225 /* ??? Ug. Actually unlinking the thing is problematic,
226 given what we'd have to coordinate with our callers. */
227 PUT_CODE (insn, NOTE);
228 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
229 NOTE_SOURCE_FILE (insn) = 0;
230 goto insn_done;
231 }
232
233 /* Last insn wasn't last? */
234 if (must_be_last)
235 return FALSE;
236
237 if (modified_in_p (test, insn))
238 {
239 if (!mod_ok)
240 return FALSE;
241 must_be_last = TRUE;
242 }
243
244 /* Now build the conditional form of the instruction. */
245 pattern = PATTERN (insn);
246
247 /* If the machine needs to modify the insn being conditionally executed,
248 say for example to force a constant integer operand into a temp
249 register, do so here. */
250 #ifdef IFCVT_MODIFY_INSN
251 IFCVT_MODIFY_INSN (pattern, insn);
252 if (! pattern)
253 return FALSE;
254 #endif
255
256 validate_change (insn, &PATTERN (insn),
257 gen_rtx_COND_EXEC (VOIDmode, copy_rtx (test),
258 pattern), 1);
259
260 if (GET_CODE (insn) == CALL_INSN && prob_val)
261 validate_change (insn, &REG_NOTES (insn),
262 alloc_EXPR_LIST (REG_BR_PROB, prob_val,
263 REG_NOTES (insn)), 1);
264
265 insn_done:
266 if (insn == end)
267 break;
268 }
269
270 return TRUE;
271 }
272
273 /* Return the condition for a jump. Do not do any special processing. */
274
275 static rtx
276 cond_exec_get_condition (jump)
277 rtx jump;
278 {
279 rtx test_if, cond;
280
281 if (any_condjump_p (jump))
282 test_if = SET_SRC (pc_set (jump));
283 else
284 return NULL_RTX;
285 cond = XEXP (test_if, 0);
286
287 /* If this branches to JUMP_LABEL when the condition is false,
288 reverse the condition. */
289 if (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
290 && XEXP (XEXP (test_if, 2), 0) == JUMP_LABEL (jump))
291 cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
292 GET_MODE (cond), XEXP (cond, 0),
293 XEXP (cond, 1));
294
295 return cond;
296 }
297
298 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
299 to conditional execution. Return TRUE if we were successful at
300 converting the the block. */
301
302 static int
303 cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb)
304 basic_block test_bb; /* Basic block test is in */
305 basic_block then_bb; /* Basic block for THEN block */
306 basic_block else_bb; /* Basic block for ELSE block */
307 basic_block join_bb; /* Basic block the join label is in */
308 {
309 rtx test_expr; /* expression in IF_THEN_ELSE that is tested */
310 rtx then_start; /* first insn in THEN block */
311 rtx then_end; /* last insn + 1 in THEN block */
312 rtx else_start = NULL_RTX; /* first insn in ELSE block or NULL */
313 rtx else_end = NULL_RTX; /* last insn + 1 in ELSE block */
314 int max; /* max # of insns to convert. */
315 int then_mod_ok; /* whether conditional mods are ok in THEN */
316 rtx true_expr; /* test for else block insns */
317 rtx false_expr; /* test for then block insns */
318 rtx true_prob_val; /* probability of else block */
319 rtx false_prob_val; /* probability of then block */
320 int n_insns;
321
322 /* Find the conditional jump to the ELSE or JOIN part, and isolate
323 the test. */
324 test_expr = cond_exec_get_condition (test_bb->end);
325 if (! test_expr)
326 return FALSE;
327
328 /* If the conditional jump is more than just a conditional jump,
329 then we can not do conditional execution conversion on this block. */
330 if (!onlyjump_p (test_bb->end))
331 return FALSE;
332
333 /* Collect the bounds of where we're to search. */
334
335 then_start = then_bb->head;
336 then_end = then_bb->end;
337
338 /* Skip a label heading THEN block. */
339 if (GET_CODE (then_start) == CODE_LABEL)
340 then_start = NEXT_INSN (then_start);
341
342 /* Skip a (use (const_int 0)) or branch as the final insn. */
343 if (GET_CODE (then_end) == INSN
344 && GET_CODE (PATTERN (then_end)) == USE
345 && GET_CODE (XEXP (PATTERN (then_end), 0)) == CONST_INT)
346 then_end = PREV_INSN (then_end);
347 else if (GET_CODE (then_end) == JUMP_INSN)
348 then_end = PREV_INSN (then_end);
349
350 if (else_bb)
351 {
352 /* Skip the ELSE block's label. */
353 else_start = NEXT_INSN (else_bb->head);
354 else_end = else_bb->end;
355
356 /* Skip a (use (const_int 0)) or branch as the final insn. */
357 if (GET_CODE (else_end) == INSN
358 && GET_CODE (PATTERN (else_end)) == USE
359 && GET_CODE (XEXP (PATTERN (else_end), 0)) == CONST_INT)
360 else_end = PREV_INSN (else_end);
361 else if (GET_CODE (else_end) == JUMP_INSN)
362 else_end = PREV_INSN (else_end);
363 }
364
365 /* How many instructions should we convert in total? */
366 n_insns = 0;
367 if (else_bb)
368 {
369 max = 2 * MAX_CONDITIONAL_EXECUTE;
370 n_insns = count_bb_insns (else_bb);
371 }
372 else
373 max = MAX_CONDITIONAL_EXECUTE;
374 n_insns += count_bb_insns (then_bb);
375 if (n_insns > max)
376 return FALSE;
377
378 /* Map test_expr/test_jump into the appropriate MD tests to use on
379 the conditionally executed code. */
380
381 true_expr = test_expr;
382 false_expr = gen_rtx_fmt_ee (reverse_condition (GET_CODE (true_expr)),
383 GET_MODE (true_expr), XEXP (true_expr, 0),
384 XEXP (true_expr, 1));
385
386 #ifdef IFCVT_MODIFY_TESTS
387 /* If the machine description needs to modify the tests, such as setting a
388 conditional execution register from a comparison, it can do so here. */
389 IFCVT_MODIFY_TESTS (true_expr, false_expr, test_bb, then_bb, else_bb,
390 join_bb);
391
392 /* See if the conversion failed */
393 if (!true_expr || !false_expr)
394 goto fail;
395 #endif
396
397 true_prob_val = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
398 if (true_prob_val)
399 {
400 true_prob_val = XEXP (true_prob_val, 0);
401 false_prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (true_prob_val));
402 }
403 else
404 false_prob_val = NULL_RTX;
405
406 /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
407 on then THEN block. */
408 then_mod_ok = (else_bb == NULL_BLOCK);
409
410 /* Go through the THEN and ELSE blocks converting the insns if possible
411 to conditional execution. */
412
413 if (then_end
414 && ! cond_exec_process_insns (then_start, then_end,
415 false_expr, false_prob_val, then_mod_ok))
416 goto fail;
417
418 if (else_bb
419 && ! cond_exec_process_insns (else_start, else_end,
420 true_expr, true_prob_val, TRUE))
421 goto fail;
422
423 if (! apply_change_group ())
424 return FALSE;
425
426 #ifdef IFCVT_MODIFY_FINAL
427 /* Do any machine dependent final modifications */
428 IFCVT_MODIFY_FINAL (test_bb, then_bb, else_bb, join_bb);
429 #endif
430
431 /* Conversion succeeded. */
432 if (rtl_dump_file)
433 fprintf (rtl_dump_file, "%d insn%s converted to conditional execution.\n",
434 n_insns, (n_insns == 1) ? " was" : "s were");
435
436 /* Merge the blocks! */
437 merge_if_block (test_bb, then_bb, else_bb, join_bb);
438 return TRUE;
439
440 fail:
441 #ifdef IFCVT_MODIFY_CANCEL
442 /* Cancel any machine dependent changes. */
443 IFCVT_MODIFY_CANCEL (test_bb, then_bb, else_bb, join_bb);
444 #endif
445
446 cancel_changes (0);
447 return FALSE;
448 }
449 \f
450 /* Used by noce_process_if_block to communicate with its subroutines.
451
452 The subroutines know that A and B may be evaluated freely. They
453 know that X is a register. They should insert new instructions
454 before cond_earliest. */
455
456 struct noce_if_info
457 {
458 basic_block test_bb;
459 rtx insn_a, insn_b;
460 rtx x, a, b;
461 rtx jump, cond, cond_earliest;
462 };
463
464 static rtx noce_emit_store_flag PARAMS ((struct noce_if_info *,
465 rtx, int, int));
466 static int noce_try_store_flag PARAMS ((struct noce_if_info *));
467 static int noce_try_store_flag_inc PARAMS ((struct noce_if_info *));
468 static int noce_try_store_flag_constants PARAMS ((struct noce_if_info *));
469 static int noce_try_store_flag_mask PARAMS ((struct noce_if_info *));
470 static rtx noce_emit_cmove PARAMS ((struct noce_if_info *,
471 rtx, enum rtx_code, rtx,
472 rtx, rtx, rtx));
473 static int noce_try_cmove PARAMS ((struct noce_if_info *));
474 static int noce_try_cmove_arith PARAMS ((struct noce_if_info *));
475 static rtx noce_get_alt_condition PARAMS ((struct noce_if_info *,
476 rtx, rtx *));
477 static int noce_try_minmax PARAMS ((struct noce_if_info *));
478 static int noce_try_abs PARAMS ((struct noce_if_info *));
479
480 /* Helper function for noce_try_store_flag*. */
481
482 static rtx
483 noce_emit_store_flag (if_info, x, reversep, normalize)
484 struct noce_if_info *if_info;
485 rtx x;
486 int reversep, normalize;
487 {
488 rtx cond = if_info->cond;
489 int cond_complex;
490 enum rtx_code code;
491
492 cond_complex = (! general_operand (XEXP (cond, 0), VOIDmode)
493 || ! general_operand (XEXP (cond, 1), VOIDmode));
494
495 /* If earliest == jump, or when the condition is complex, try to
496 build the store_flag insn directly. */
497
498 if (cond_complex)
499 cond = XEXP (SET_SRC (pc_set (if_info->jump)), 0);
500
501 if (reversep)
502 code = reversed_comparison_code (cond, if_info->jump);
503 else
504 code = GET_CODE (cond);
505
506 if ((if_info->cond_earliest == if_info->jump || cond_complex)
507 && (normalize == 0 || STORE_FLAG_VALUE == normalize))
508 {
509 rtx tmp;
510
511 tmp = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0),
512 XEXP (cond, 1));
513 tmp = gen_rtx_SET (VOIDmode, x, tmp);
514
515 start_sequence ();
516 tmp = emit_insn (tmp);
517
518 if (recog_memoized (tmp) >= 0)
519 {
520 tmp = get_insns ();
521 end_sequence ();
522 emit_insns (tmp);
523
524 if_info->cond_earliest = if_info->jump;
525
526 return x;
527 }
528
529 end_sequence ();
530 }
531
532 /* Don't even try if the comparison operands are weird. */
533 if (cond_complex)
534 return NULL_RTX;
535
536 return emit_store_flag (x, code, XEXP (cond, 0),
537 XEXP (cond, 1), VOIDmode,
538 (code == LTU || code == LEU
539 || code == GEU || code == GTU), normalize);
540 }
541
542 /* Emit instruction to move a rtx into STRICT_LOW_PART. */
543 static void
544 noce_emit_move_insn (x, y)
545 rtx x, y;
546 {
547 enum machine_mode outmode, inmode;
548 rtx outer, inner;
549 int bitpos;
550
551 if (GET_CODE (x) != STRICT_LOW_PART)
552 {
553 emit_move_insn (x, y);
554 return;
555 }
556
557 outer = XEXP (x, 0);
558 inner = XEXP (outer, 0);
559 outmode = GET_MODE (outer);
560 inmode = GET_MODE (inner);
561 bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
562 store_bit_field (inner, GET_MODE_BITSIZE (outmode),
563 bitpos, outmode, y, GET_MODE_BITSIZE (inmode),
564 GET_MODE_BITSIZE (inmode));
565 }
566
567 /* Convert "if (test) x = 1; else x = 0".
568
569 Only try 0 and STORE_FLAG_VALUE here. Other combinations will be
570 tried in noce_try_store_flag_constants after noce_try_cmove has had
571 a go at the conversion. */
572
573 static int
574 noce_try_store_flag (if_info)
575 struct noce_if_info *if_info;
576 {
577 int reversep;
578 rtx target, seq;
579
580 if (GET_CODE (if_info->b) == CONST_INT
581 && INTVAL (if_info->b) == STORE_FLAG_VALUE
582 && if_info->a == const0_rtx)
583 reversep = 0;
584 else if (if_info->b == const0_rtx
585 && GET_CODE (if_info->a) == CONST_INT
586 && INTVAL (if_info->a) == STORE_FLAG_VALUE
587 && (reversed_comparison_code (if_info->cond, if_info->jump)
588 != UNKNOWN))
589 reversep = 1;
590 else
591 return FALSE;
592
593 start_sequence ();
594
595 target = noce_emit_store_flag (if_info, if_info->x, reversep, 0);
596 if (target)
597 {
598 if (target != if_info->x)
599 noce_emit_move_insn (if_info->x, target);
600
601 seq = get_insns ();
602 end_sequence ();
603 emit_insns_before (seq, if_info->cond_earliest);
604
605 return TRUE;
606 }
607 else
608 {
609 end_sequence ();
610 return FALSE;
611 }
612 }
613
614 /* Convert "if (test) x = a; else x = b", for A and B constant. */
615
616 static int
617 noce_try_store_flag_constants (if_info)
618 struct noce_if_info *if_info;
619 {
620 rtx target, seq;
621 int reversep;
622 HOST_WIDE_INT itrue, ifalse, diff, tmp;
623 int normalize, can_reverse;
624
625 if (! no_new_pseudos
626 && GET_CODE (if_info->a) == CONST_INT
627 && GET_CODE (if_info->b) == CONST_INT)
628 {
629 ifalse = INTVAL (if_info->a);
630 itrue = INTVAL (if_info->b);
631 diff = itrue - ifalse;
632
633 can_reverse = (reversed_comparison_code (if_info->cond, if_info->jump)
634 != UNKNOWN);
635
636 reversep = 0;
637 if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
638 normalize = 0;
639 else if (ifalse == 0 && exact_log2 (itrue) >= 0
640 && (STORE_FLAG_VALUE == 1
641 || BRANCH_COST >= 2))
642 normalize = 1;
643 else if (itrue == 0 && exact_log2 (ifalse) >= 0 && can_reverse
644 && (STORE_FLAG_VALUE == 1 || BRANCH_COST >= 2))
645 normalize = 1, reversep = 1;
646 else if (itrue == -1
647 && (STORE_FLAG_VALUE == -1
648 || BRANCH_COST >= 2))
649 normalize = -1;
650 else if (ifalse == -1 && can_reverse
651 && (STORE_FLAG_VALUE == -1 || BRANCH_COST >= 2))
652 normalize = -1, reversep = 1;
653 else if ((BRANCH_COST >= 2 && STORE_FLAG_VALUE == -1)
654 || BRANCH_COST >= 3)
655 normalize = -1;
656 else
657 return FALSE;
658
659 if (reversep)
660 {
661 tmp = itrue; itrue = ifalse; ifalse = tmp;
662 diff = -diff;
663 }
664
665 start_sequence ();
666 target = noce_emit_store_flag (if_info, if_info->x, reversep, normalize);
667 if (! target)
668 {
669 end_sequence ();
670 return FALSE;
671 }
672
673 /* if (test) x = 3; else x = 4;
674 => x = 3 + (test == 0); */
675 if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
676 {
677 target = expand_binop (GET_MODE (if_info->x),
678 (diff == STORE_FLAG_VALUE
679 ? add_optab : sub_optab),
680 GEN_INT (ifalse), target, if_info->x, 0,
681 OPTAB_WIDEN);
682 }
683
684 /* if (test) x = 8; else x = 0;
685 => x = (test != 0) << 3; */
686 else if (ifalse == 0 && (tmp = exact_log2 (itrue)) >= 0)
687 {
688 target = expand_binop (GET_MODE (if_info->x), ashl_optab,
689 target, GEN_INT (tmp), if_info->x, 0,
690 OPTAB_WIDEN);
691 }
692
693 /* if (test) x = -1; else x = b;
694 => x = -(test != 0) | b; */
695 else if (itrue == -1)
696 {
697 target = expand_binop (GET_MODE (if_info->x), ior_optab,
698 target, GEN_INT (ifalse), if_info->x, 0,
699 OPTAB_WIDEN);
700 }
701
702 /* if (test) x = a; else x = b;
703 => x = (-(test != 0) & (b - a)) + a; */
704 else
705 {
706 target = expand_binop (GET_MODE (if_info->x), and_optab,
707 target, GEN_INT (diff), if_info->x, 0,
708 OPTAB_WIDEN);
709 if (target)
710 target = expand_binop (GET_MODE (if_info->x), add_optab,
711 target, GEN_INT (ifalse), if_info->x, 0,
712 OPTAB_WIDEN);
713 }
714
715 if (! target)
716 {
717 end_sequence ();
718 return FALSE;
719 }
720
721 if (target != if_info->x)
722 noce_emit_move_insn (if_info->x, target);
723
724 seq = get_insns ();
725 end_sequence ();
726
727 if (seq_contains_jump (seq))
728 return FALSE;
729
730 emit_insns_before (seq, if_info->cond_earliest);
731
732 return TRUE;
733 }
734
735 return FALSE;
736 }
737
738 /* Convert "if (test) foo++" into "foo += (test != 0)", and
739 similarly for "foo--". */
740
741 static int
742 noce_try_store_flag_inc (if_info)
743 struct noce_if_info *if_info;
744 {
745 rtx target, seq;
746 int subtract, normalize;
747
748 if (! no_new_pseudos
749 && (BRANCH_COST >= 2
750 || HAVE_incscc
751 || HAVE_decscc)
752 /* Should be no `else' case to worry about. */
753 && if_info->b == if_info->x
754 && GET_CODE (if_info->a) == PLUS
755 && (XEXP (if_info->a, 1) == const1_rtx
756 || XEXP (if_info->a, 1) == constm1_rtx)
757 && rtx_equal_p (XEXP (if_info->a, 0), if_info->x)
758 && (reversed_comparison_code (if_info->cond, if_info->jump)
759 != UNKNOWN))
760 {
761 if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
762 subtract = 0, normalize = 0;
763 else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
764 subtract = 1, normalize = 0;
765 else
766 subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
767
768 start_sequence ();
769
770 target = noce_emit_store_flag (if_info,
771 gen_reg_rtx (GET_MODE (if_info->x)),
772 1, normalize);
773
774 if (target)
775 target = expand_binop (GET_MODE (if_info->x),
776 subtract ? sub_optab : add_optab,
777 if_info->x, target, if_info->x, 0, OPTAB_WIDEN);
778 if (target)
779 {
780 if (target != if_info->x)
781 noce_emit_move_insn (if_info->x, target);
782
783 seq = get_insns ();
784 end_sequence ();
785
786 if (seq_contains_jump (seq))
787 return FALSE;
788
789 emit_insns_before (seq, if_info->cond_earliest);
790
791 return TRUE;
792 }
793
794 end_sequence ();
795 }
796
797 return FALSE;
798 }
799
800 /* Convert "if (test) x = 0;" to "x &= -(test == 0);" */
801
802 static int
803 noce_try_store_flag_mask (if_info)
804 struct noce_if_info *if_info;
805 {
806 rtx target, seq;
807 int reversep;
808
809 reversep = 0;
810 if (! no_new_pseudos
811 && (BRANCH_COST >= 2
812 || STORE_FLAG_VALUE == -1)
813 && ((if_info->a == const0_rtx
814 && rtx_equal_p (if_info->b, if_info->x))
815 || ((reversep = (reversed_comparison_code (if_info->cond,
816 if_info->jump)
817 != UNKNOWN))
818 && if_info->b == const0_rtx
819 && rtx_equal_p (if_info->a, if_info->x))))
820 {
821 start_sequence ();
822 target = noce_emit_store_flag (if_info,
823 gen_reg_rtx (GET_MODE (if_info->x)),
824 reversep, -1);
825 if (target)
826 target = expand_binop (GET_MODE (if_info->x), and_optab,
827 if_info->x, target, if_info->x, 0,
828 OPTAB_WIDEN);
829
830 if (target)
831 {
832 if (target != if_info->x)
833 noce_emit_move_insn (if_info->x, target);
834
835 seq = get_insns ();
836 end_sequence ();
837
838 if (seq_contains_jump (seq))
839 return FALSE;
840
841 emit_insns_before (seq, if_info->cond_earliest);
842
843 return TRUE;
844 }
845
846 end_sequence ();
847 }
848
849 return FALSE;
850 }
851
852 /* Helper function for noce_try_cmove and noce_try_cmove_arith. */
853
854 static rtx
855 noce_emit_cmove (if_info, x, code, cmp_a, cmp_b, vfalse, vtrue)
856 struct noce_if_info *if_info;
857 rtx x, cmp_a, cmp_b, vfalse, vtrue;
858 enum rtx_code code;
859 {
860 /* If earliest == jump, try to build the cmove insn directly.
861 This is helpful when combine has created some complex condition
862 (like for alpha's cmovlbs) that we can't hope to regenerate
863 through the normal interface. */
864
865 if (if_info->cond_earliest == if_info->jump)
866 {
867 rtx tmp;
868
869 tmp = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
870 tmp = gen_rtx_IF_THEN_ELSE (GET_MODE (x), tmp, vtrue, vfalse);
871 tmp = gen_rtx_SET (VOIDmode, x, tmp);
872
873 start_sequence ();
874 tmp = emit_insn (tmp);
875
876 if (recog_memoized (tmp) >= 0)
877 {
878 tmp = get_insns ();
879 end_sequence ();
880 emit_insns (tmp);
881
882 return x;
883 }
884
885 end_sequence ();
886 }
887
888 /* Don't even try if the comparison operands are weird. */
889 if (! general_operand (cmp_a, GET_MODE (cmp_a))
890 || ! general_operand (cmp_b, GET_MODE (cmp_b)))
891 return NULL_RTX;
892
893 #if HAVE_conditional_move
894 return emit_conditional_move (x, code, cmp_a, cmp_b, VOIDmode,
895 vtrue, vfalse, GET_MODE (x),
896 (code == LTU || code == GEU
897 || code == LEU || code == GTU));
898 #else
899 /* We'll never get here, as noce_process_if_block doesn't call the
900 functions involved. Ifdef code, however, should be discouraged
901 because it leads to typos in the code not selected. However,
902 emit_conditional_move won't exist either. */
903 return NULL_RTX;
904 #endif
905 }
906
907 /* Try only simple constants and registers here. More complex cases
908 are handled in noce_try_cmove_arith after noce_try_store_flag_arith
909 has had a go at it. */
910
911 static int
912 noce_try_cmove (if_info)
913 struct noce_if_info *if_info;
914 {
915 enum rtx_code code;
916 rtx target, seq;
917
918 if ((CONSTANT_P (if_info->a) || register_operand (if_info->a, VOIDmode))
919 && (CONSTANT_P (if_info->b) || register_operand (if_info->b, VOIDmode)))
920 {
921 start_sequence ();
922
923 code = GET_CODE (if_info->cond);
924 target = noce_emit_cmove (if_info, if_info->x, code,
925 XEXP (if_info->cond, 0),
926 XEXP (if_info->cond, 1),
927 if_info->a, if_info->b);
928
929 if (target)
930 {
931 if (target != if_info->x)
932 noce_emit_move_insn (if_info->x, target);
933
934 seq = get_insns ();
935 end_sequence ();
936 emit_insns_before (seq, if_info->cond_earliest);
937 return TRUE;
938 }
939 else
940 {
941 end_sequence ();
942 return FALSE;
943 }
944 }
945
946 return FALSE;
947 }
948
949 /* Try more complex cases involving conditional_move. */
950
951 static int
952 noce_try_cmove_arith (if_info)
953 struct noce_if_info *if_info;
954 {
955 rtx a = if_info->a;
956 rtx b = if_info->b;
957 rtx x = if_info->x;
958 rtx insn_a, insn_b;
959 rtx tmp, target;
960 int is_mem = 0;
961 enum rtx_code code;
962
963 /* A conditional move from two memory sources is equivalent to a
964 conditional on their addresses followed by a load. Don't do this
965 early because it'll screw alias analysis. Note that we've
966 already checked for no side effects. */
967 if (! no_new_pseudos && cse_not_expected
968 && GET_CODE (a) == MEM && GET_CODE (b) == MEM
969 && BRANCH_COST >= 5)
970 {
971 a = XEXP (a, 0);
972 b = XEXP (b, 0);
973 x = gen_reg_rtx (Pmode);
974 is_mem = 1;
975 }
976
977 /* ??? We could handle this if we knew that a load from A or B could
978 not fault. This is also true if we've already loaded
979 from the address along the path from ENTRY. */
980 else if (may_trap_p (a) || may_trap_p (b))
981 return FALSE;
982
983 /* if (test) x = a + b; else x = c - d;
984 => y = a + b;
985 x = c - d;
986 if (test)
987 x = y;
988 */
989
990 code = GET_CODE (if_info->cond);
991 insn_a = if_info->insn_a;
992 insn_b = if_info->insn_b;
993
994 /* Possibly rearrange operands to make things come out more natural. */
995 if (reversed_comparison_code (if_info->cond, if_info->jump) != UNKNOWN)
996 {
997 int reversep = 0;
998 if (rtx_equal_p (b, x))
999 reversep = 1;
1000 else if (general_operand (b, GET_MODE (b)))
1001 reversep = 1;
1002
1003 if (reversep)
1004 {
1005 code = reversed_comparison_code (if_info->cond, if_info->jump);
1006 tmp = a, a = b, b = tmp;
1007 tmp = insn_a, insn_a = insn_b, insn_b = tmp;
1008 }
1009 }
1010
1011 start_sequence ();
1012
1013 /* If either operand is complex, load it into a register first.
1014 The best way to do this is to copy the original insn. In this
1015 way we preserve any clobbers etc that the insn may have had.
1016 This is of course not possible in the IS_MEM case. */
1017 if (! general_operand (a, GET_MODE (a)))
1018 {
1019 rtx set;
1020
1021 if (no_new_pseudos)
1022 goto end_seq_and_fail;
1023
1024 if (is_mem)
1025 {
1026 tmp = gen_reg_rtx (GET_MODE (a));
1027 tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, a));
1028 }
1029 else if (! insn_a)
1030 goto end_seq_and_fail;
1031 else
1032 {
1033 a = gen_reg_rtx (GET_MODE (a));
1034 tmp = copy_rtx (insn_a);
1035 set = single_set (tmp);
1036 SET_DEST (set) = a;
1037 tmp = emit_insn (PATTERN (tmp));
1038 }
1039 if (recog_memoized (tmp) < 0)
1040 goto end_seq_and_fail;
1041 }
1042 if (! general_operand (b, GET_MODE (b)))
1043 {
1044 rtx set;
1045
1046 if (no_new_pseudos)
1047 goto end_seq_and_fail;
1048
1049 if (is_mem)
1050 {
1051 tmp = gen_reg_rtx (GET_MODE (b));
1052 tmp = emit_insn (gen_rtx_SET (VOIDmode, tmp, b));
1053 }
1054 else if (! insn_b)
1055 goto end_seq_and_fail;
1056 else
1057 {
1058 b = gen_reg_rtx (GET_MODE (b));
1059 tmp = copy_rtx (insn_b);
1060 set = single_set (tmp);
1061 SET_DEST (set) = b;
1062 tmp = emit_insn (PATTERN (tmp));
1063 }
1064 if (recog_memoized (tmp) < 0)
1065 goto end_seq_and_fail;
1066 }
1067
1068 target = noce_emit_cmove (if_info, x, code, XEXP (if_info->cond, 0),
1069 XEXP (if_info->cond, 1), a, b);
1070
1071 if (! target)
1072 goto end_seq_and_fail;
1073
1074 /* If we're handling a memory for above, emit the load now. */
1075 if (is_mem)
1076 {
1077 tmp = gen_rtx_MEM (GET_MODE (if_info->x), target);
1078
1079 /* Copy over flags as appropriate. */
1080 if (MEM_VOLATILE_P (if_info->a) || MEM_VOLATILE_P (if_info->b))
1081 MEM_VOLATILE_P (tmp) = 1;
1082 if (MEM_IN_STRUCT_P (if_info->a) && MEM_IN_STRUCT_P (if_info->b))
1083 MEM_IN_STRUCT_P (tmp) = 1;
1084 if (MEM_SCALAR_P (if_info->a) && MEM_SCALAR_P (if_info->b))
1085 MEM_SCALAR_P (tmp) = 1;
1086 if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b))
1087 MEM_ALIAS_SET (tmp) = MEM_ALIAS_SET (if_info->a);
1088
1089 noce_emit_move_insn (if_info->x, tmp);
1090 }
1091 else if (target != x)
1092 noce_emit_move_insn (x, target);
1093
1094 tmp = get_insns ();
1095 end_sequence ();
1096 emit_insns_before (tmp, if_info->cond_earliest);
1097 return TRUE;
1098
1099 end_seq_and_fail:
1100 end_sequence ();
1101 return FALSE;
1102 }
1103
1104 /* For most cases, the simplified condition we found is the best
1105 choice, but this is not the case for the min/max/abs transforms.
1106 For these we wish to know that it is A or B in the condition. */
1107
1108 static rtx
1109 noce_get_alt_condition (if_info, target, earliest)
1110 struct noce_if_info *if_info;
1111 rtx target;
1112 rtx *earliest;
1113 {
1114 rtx cond, set, insn;
1115 int reverse;
1116
1117 /* If target is already mentioned in the known condition, return it. */
1118 if (reg_mentioned_p (target, if_info->cond))
1119 {
1120 *earliest = if_info->cond_earliest;
1121 return if_info->cond;
1122 }
1123
1124 set = pc_set (if_info->jump);
1125 cond = XEXP (SET_SRC (set), 0);
1126 reverse
1127 = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
1128 && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (if_info->jump);
1129
1130 cond = canonicalize_condition (if_info->jump, cond, reverse,
1131 earliest, target);
1132 if (! cond || ! reg_mentioned_p (target, cond))
1133 return NULL;
1134
1135 /* We almost certainly searched back to a different place.
1136 Need to re-verify correct lifetimes. */
1137
1138 /* X may not be mentioned in the range (cond_earliest, jump]. */
1139 for (insn = if_info->jump; insn != *earliest; insn = PREV_INSN (insn))
1140 if (INSN_P (insn) && reg_mentioned_p (if_info->x, insn))
1141 return NULL;
1142
1143 /* A and B may not be modified in the range [cond_earliest, jump). */
1144 for (insn = *earliest; insn != if_info->jump; insn = NEXT_INSN (insn))
1145 if (INSN_P (insn)
1146 && (modified_in_p (if_info->a, insn)
1147 || modified_in_p (if_info->b, insn)))
1148 return NULL;
1149
1150 return cond;
1151 }
1152
1153 /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc. */
1154
1155 static int
1156 noce_try_minmax (if_info)
1157 struct noce_if_info *if_info;
1158 {
1159 rtx cond, earliest, target, seq;
1160 enum rtx_code code;
1161 int unsignedp;
1162 optab op;
1163
1164 /* ??? Can't guarantee that expand_binop won't create pseudos. */
1165 if (no_new_pseudos)
1166 return FALSE;
1167
1168 /* ??? Reject FP modes since we don't know how 0 vs -0 or NaNs
1169 will be resolved with an SMIN/SMAX. It wouldn't be too hard
1170 to get the target to tell us... */
1171 if (FLOAT_MODE_P (GET_MODE (if_info->x))
1172 && TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT
1173 && ! flag_unsafe_math_optimizations)
1174 return FALSE;
1175
1176 cond = noce_get_alt_condition (if_info, if_info->a, &earliest);
1177 if (!cond)
1178 return FALSE;
1179
1180 /* Verify the condition is of the form we expect, and canonicalize
1181 the comparison code. */
1182 code = GET_CODE (cond);
1183 if (rtx_equal_p (XEXP (cond, 0), if_info->a))
1184 {
1185 if (! rtx_equal_p (XEXP (cond, 1), if_info->b))
1186 return FALSE;
1187 }
1188 else if (rtx_equal_p (XEXP (cond, 1), if_info->a))
1189 {
1190 if (! rtx_equal_p (XEXP (cond, 0), if_info->b))
1191 return FALSE;
1192 code = swap_condition (code);
1193 }
1194 else
1195 return FALSE;
1196
1197 /* Determine what sort of operation this is. Note that the code is for
1198 a taken branch, so the code->operation mapping appears backwards. */
1199 switch (code)
1200 {
1201 case LT:
1202 case LE:
1203 case UNLT:
1204 case UNLE:
1205 op = smax_optab;
1206 unsignedp = 0;
1207 break;
1208 case GT:
1209 case GE:
1210 case UNGT:
1211 case UNGE:
1212 op = smin_optab;
1213 unsignedp = 0;
1214 break;
1215 case LTU:
1216 case LEU:
1217 op = umax_optab;
1218 unsignedp = 1;
1219 break;
1220 case GTU:
1221 case GEU:
1222 op = umin_optab;
1223 unsignedp = 1;
1224 break;
1225 default:
1226 return FALSE;
1227 }
1228
1229 start_sequence ();
1230
1231 target = expand_binop (GET_MODE (if_info->x), op, if_info->a, if_info->b,
1232 if_info->x, unsignedp, OPTAB_WIDEN);
1233 if (! target)
1234 {
1235 end_sequence ();
1236 return FALSE;
1237 }
1238 if (target != if_info->x)
1239 noce_emit_move_insn (if_info->x, target);
1240
1241 seq = get_insns ();
1242 end_sequence ();
1243
1244 if (seq_contains_jump (seq))
1245 return FALSE;
1246
1247 emit_insns_before (seq, earliest);
1248 if_info->cond = cond;
1249 if_info->cond_earliest = earliest;
1250
1251 return TRUE;
1252 }
1253
1254 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", etc. */
1255
1256 static int
1257 noce_try_abs (if_info)
1258 struct noce_if_info *if_info;
1259 {
1260 rtx cond, earliest, target, seq, a, b, c;
1261 int negate;
1262
1263 /* ??? Can't guarantee that expand_binop won't create pseudos. */
1264 if (no_new_pseudos)
1265 return FALSE;
1266
1267 /* Recognize A and B as constituting an ABS or NABS. */
1268 a = if_info->a;
1269 b = if_info->b;
1270 if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b))
1271 negate = 0;
1272 else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a))
1273 {
1274 c = a; a = b; b = c;
1275 negate = 1;
1276 }
1277 else
1278 return FALSE;
1279
1280 cond = noce_get_alt_condition (if_info, b, &earliest);
1281 if (!cond)
1282 return FALSE;
1283
1284 /* Verify the condition is of the form we expect. */
1285 if (rtx_equal_p (XEXP (cond, 0), b))
1286 c = XEXP (cond, 1);
1287 else if (rtx_equal_p (XEXP (cond, 1), b))
1288 c = XEXP (cond, 0);
1289 else
1290 return FALSE;
1291
1292 /* Verify that C is zero. Search backward through the block for
1293 a REG_EQUAL note if necessary. */
1294 if (REG_P (c))
1295 {
1296 rtx insn, note = NULL;
1297 for (insn = earliest;
1298 insn != if_info->test_bb->head;
1299 insn = PREV_INSN (insn))
1300 if (INSN_P (insn)
1301 && ((note = find_reg_note (insn, REG_EQUAL, c))
1302 || (note = find_reg_note (insn, REG_EQUIV, c))))
1303 break;
1304 if (! note)
1305 return FALSE;
1306 c = XEXP (note, 0);
1307 }
1308 if (GET_CODE (c) == MEM
1309 && GET_CODE (XEXP (c, 0)) == SYMBOL_REF
1310 && CONSTANT_POOL_ADDRESS_P (XEXP (c, 0)))
1311 c = get_pool_constant (XEXP (c, 0));
1312
1313 /* Work around funny ideas get_condition has wrt canonicalization.
1314 Note that these rtx constants are known to be CONST_INT, and
1315 therefore imply integer comparisons. */
1316 if (c == constm1_rtx && GET_CODE (cond) == GT)
1317 ;
1318 else if (c == const1_rtx && GET_CODE (cond) == LT)
1319 ;
1320 else if (c != CONST0_RTX (GET_MODE (b)))
1321 return FALSE;
1322
1323 /* Determine what sort of operation this is. */
1324 switch (GET_CODE (cond))
1325 {
1326 case LT:
1327 case LE:
1328 case UNLT:
1329 case UNLE:
1330 negate = !negate;
1331 break;
1332 case GT:
1333 case GE:
1334 case UNGT:
1335 case UNGE:
1336 break;
1337 default:
1338 return FALSE;
1339 }
1340
1341 start_sequence ();
1342
1343 target = expand_unop (GET_MODE (if_info->x), abs_optab, b, if_info->x, 0);
1344
1345 /* ??? It's a quandry whether cmove would be better here, especially
1346 for integers. Perhaps combine will clean things up. */
1347 if (target && negate)
1348 target = expand_unop (GET_MODE (target), neg_optab, target, if_info->x, 0);
1349
1350 if (! target)
1351 {
1352 end_sequence ();
1353 return FALSE;
1354 }
1355
1356 if (target != if_info->x)
1357 noce_emit_move_insn (if_info->x, target);
1358
1359 seq = get_insns ();
1360 end_sequence ();
1361
1362 if (seq_contains_jump (seq))
1363 return FALSE;
1364
1365 emit_insns_before (seq, earliest);
1366 if_info->cond = cond;
1367 if_info->cond_earliest = earliest;
1368
1369 return TRUE;
1370 }
1371
1372 /* Look for the condition for the jump first. We'd prefer to avoid
1373 get_condition if we can -- it tries to look back for the contents
1374 of an original compare. On targets that use normal integers for
1375 comparisons, e.g. alpha, this is wasteful. */
1376
1377 static rtx
1378 noce_get_condition (jump, earliest)
1379 rtx jump;
1380 rtx *earliest;
1381 {
1382 rtx cond;
1383 rtx set;
1384
1385 /* If the condition variable is a register and is MODE_INT, accept it.
1386 Otherwise, fall back on get_condition. */
1387
1388 if (! any_condjump_p (jump))
1389 return NULL_RTX;
1390
1391 set = pc_set (jump);
1392
1393 cond = XEXP (SET_SRC (set), 0);
1394 if (GET_CODE (XEXP (cond, 0)) == REG
1395 && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_INT)
1396 {
1397 *earliest = jump;
1398
1399 /* If this branches to JUMP_LABEL when the condition is false,
1400 reverse the condition. */
1401 if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
1402 && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump))
1403 cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
1404 GET_MODE (cond), XEXP (cond, 0),
1405 XEXP (cond, 1));
1406 }
1407 else
1408 cond = get_condition (jump, earliest);
1409
1410 return cond;
1411 }
1412
1413 /* Return true if OP is ok for if-then-else processing. */
1414
1415 static int
1416 noce_operand_ok (op)
1417 rtx op;
1418 {
1419 /* We special-case memories, so handle any of them with
1420 no address side effects. */
1421 if (GET_CODE (op) == MEM)
1422 return ! side_effects_p (XEXP (op, 0));
1423
1424 if (side_effects_p (op))
1425 return FALSE;
1426
1427 /* ??? Unfortuantely may_trap_p can't look at flag_trapping_math, due to
1428 being linked into the genfoo programs. This is probably a mistake.
1429 With finite operands, most fp operations don't trap. */
1430 if (!flag_trapping_math && FLOAT_MODE_P (GET_MODE (op)))
1431 switch (GET_CODE (op))
1432 {
1433 case DIV:
1434 case MOD:
1435 case UDIV:
1436 case UMOD:
1437 /* ??? This is kinda lame -- almost every target will have forced
1438 the constant into a register first. But given the expense of
1439 division, this is probably for the best. */
1440 return (CONSTANT_P (XEXP (op, 1))
1441 && XEXP (op, 1) != CONST0_RTX (GET_MODE (op))
1442 && ! may_trap_p (XEXP (op, 0)));
1443
1444 default:
1445 switch (GET_RTX_CLASS (GET_CODE (op)))
1446 {
1447 case '1':
1448 return ! may_trap_p (XEXP (op, 0));
1449 case 'c':
1450 case '2':
1451 return ! may_trap_p (XEXP (op, 0)) && ! may_trap_p (XEXP (op, 1));
1452 }
1453 break;
1454 }
1455
1456 return ! may_trap_p (op);
1457 }
1458
1459 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
1460 without using conditional execution. Return TRUE if we were
1461 successful at converting the the block. */
1462
1463 static int
1464 noce_process_if_block (test_bb, then_bb, else_bb, join_bb)
1465 basic_block test_bb; /* Basic block test is in */
1466 basic_block then_bb; /* Basic block for THEN block */
1467 basic_block else_bb; /* Basic block for ELSE block */
1468 basic_block join_bb; /* Basic block the join label is in */
1469 {
1470 /* We're looking for patterns of the form
1471
1472 (1) if (...) x = a; else x = b;
1473 (2) x = b; if (...) x = a;
1474 (3) if (...) x = a; // as if with an initial x = x.
1475
1476 The later patterns require jumps to be more expensive.
1477
1478 ??? For future expansion, look for multiple X in such patterns. */
1479
1480 struct noce_if_info if_info;
1481 rtx insn_a, insn_b;
1482 rtx set_a, set_b;
1483 rtx orig_x, x, a, b;
1484 rtx jump, cond, insn;
1485
1486 /* If this is not a standard conditional jump, we can't parse it. */
1487 jump = test_bb->end;
1488 cond = noce_get_condition (jump, &if_info.cond_earliest);
1489 if (! cond)
1490 return FALSE;
1491
1492 /* If the conditional jump is more than just a conditional jump,
1493 then we can not do if-conversion on this block. */
1494 if (! onlyjump_p (jump))
1495 return FALSE;
1496
1497 /* We must be comparing objects whose modes imply the size. */
1498 if (GET_MODE (XEXP (cond, 0)) == BLKmode)
1499 return FALSE;
1500
1501 /* Look for one of the potential sets. */
1502 insn_a = first_active_insn (then_bb);
1503 if (! insn_a
1504 || ! last_active_insn_p (then_bb, insn_a)
1505 || (set_a = single_set (insn_a)) == NULL_RTX)
1506 return FALSE;
1507
1508 x = SET_DEST (set_a);
1509 a = SET_SRC (set_a);
1510
1511 /* Look for the other potential set. Make sure we've got equivalent
1512 destinations. */
1513 /* ??? This is overconservative. Storing to two different mems is
1514 as easy as conditionally computing the address. Storing to a
1515 single mem merely requires a scratch memory to use as one of the
1516 destination addresses; often the memory immediately below the
1517 stack pointer is available for this. */
1518 set_b = NULL_RTX;
1519 if (else_bb)
1520 {
1521 insn_b = first_active_insn (else_bb);
1522 if (! insn_b
1523 || ! last_active_insn_p (else_bb, insn_b)
1524 || (set_b = single_set (insn_b)) == NULL_RTX
1525 || ! rtx_equal_p (x, SET_DEST (set_b)))
1526 return FALSE;
1527 }
1528 else
1529 {
1530 insn_b = prev_nonnote_insn (if_info.cond_earliest);
1531 if (! insn_b
1532 || GET_CODE (insn_b) != INSN
1533 || (set_b = single_set (insn_b)) == NULL_RTX
1534 || ! rtx_equal_p (x, SET_DEST (set_b))
1535 || reg_mentioned_p (x, cond)
1536 || reg_mentioned_p (x, a)
1537 || reg_mentioned_p (x, SET_SRC (set_b)))
1538 insn_b = set_b = NULL_RTX;
1539 }
1540 b = (set_b ? SET_SRC (set_b) : x);
1541
1542 /* X may not be mentioned in the range (cond_earliest, jump]. */
1543 for (insn = jump; insn != if_info.cond_earliest; insn = PREV_INSN (insn))
1544 if (INSN_P (insn) && reg_mentioned_p (x, insn))
1545 return FALSE;
1546
1547 /* A and B may not be modified in the range [cond_earliest, jump). */
1548 for (insn = if_info.cond_earliest; insn != jump; insn = NEXT_INSN (insn))
1549 if (INSN_P (insn)
1550 && (modified_in_p (a, insn) || modified_in_p (b, insn)))
1551 return FALSE;
1552
1553 /* Only operate on register destinations, and even then avoid extending
1554 the lifetime of hard registers on small register class machines. */
1555 orig_x = x;
1556 if (GET_CODE (x) != REG
1557 || (SMALL_REGISTER_CLASSES
1558 && REGNO (x) < FIRST_PSEUDO_REGISTER))
1559 {
1560 if (no_new_pseudos)
1561 return FALSE;
1562 x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART
1563 ? XEXP (x, 0) : x));
1564 }
1565
1566 /* Don't operate on sources that may trap or are volatile. */
1567 if (! noce_operand_ok (a) || ! noce_operand_ok (b))
1568 return FALSE;
1569
1570 /* Set up the info block for our subroutines. */
1571 if_info.test_bb = test_bb;
1572 if_info.cond = cond;
1573 if_info.jump = jump;
1574 if_info.insn_a = insn_a;
1575 if_info.insn_b = insn_b;
1576 if_info.x = x;
1577 if_info.a = a;
1578 if_info.b = b;
1579
1580 /* Try optimizations in some approximation of a useful order. */
1581 /* ??? Should first look to see if X is live incoming at all. If it
1582 isn't, we don't need anything but an unconditional set. */
1583
1584 /* Look and see if A and B are really the same. Avoid creating silly
1585 cmove constructs that no one will fix up later. */
1586 if (rtx_equal_p (a, b))
1587 {
1588 /* If we have an INSN_B, we don't have to create any new rtl. Just
1589 move the instruction that we already have. If we don't have an
1590 INSN_B, that means that A == X, and we've got a noop move. In
1591 that case don't do anything and let the code below delete INSN_A. */
1592 if (insn_b && else_bb)
1593 {
1594 rtx note;
1595
1596 if (else_bb && insn_b == else_bb->end)
1597 else_bb->end = PREV_INSN (insn_b);
1598 reorder_insns (insn_b, insn_b, PREV_INSN (if_info.cond_earliest));
1599
1600 /* If there was a REG_EQUAL note, delete it since it may have been
1601 true due to this insn being after a jump. */
1602 if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0)
1603 remove_note (insn_b, note);
1604
1605 insn_b = NULL_RTX;
1606 }
1607 /* If we have "x = b; if (...) x = a;", and x has side-effects, then
1608 x must be executed twice. */
1609 else if (insn_b && side_effects_p (orig_x))
1610 return FALSE;
1611
1612 x = orig_x;
1613 goto success;
1614 }
1615
1616 if (noce_try_store_flag (&if_info))
1617 goto success;
1618 if (noce_try_minmax (&if_info))
1619 goto success;
1620 if (noce_try_abs (&if_info))
1621 goto success;
1622 if (HAVE_conditional_move
1623 && noce_try_cmove (&if_info))
1624 goto success;
1625 if (! HAVE_conditional_execution)
1626 {
1627 if (noce_try_store_flag_constants (&if_info))
1628 goto success;
1629 if (noce_try_store_flag_inc (&if_info))
1630 goto success;
1631 if (noce_try_store_flag_mask (&if_info))
1632 goto success;
1633 if (HAVE_conditional_move
1634 && noce_try_cmove_arith (&if_info))
1635 goto success;
1636 }
1637
1638 return FALSE;
1639
1640 success:
1641 /* The original sets may now be killed. */
1642 if (insn_a == then_bb->end)
1643 then_bb->end = PREV_INSN (insn_a);
1644 flow_delete_insn (insn_a);
1645
1646 /* Several special cases here: First, we may have reused insn_b above,
1647 in which case insn_b is now NULL. Second, we want to delete insn_b
1648 if it came from the ELSE block, because follows the now correct
1649 write that appears in the TEST block. However, if we got insn_b from
1650 the TEST block, it may in fact be loading data needed for the comparison.
1651 We'll let life_analysis remove the insn if it's really dead. */
1652 if (insn_b && else_bb)
1653 {
1654 if (insn_b == else_bb->end)
1655 else_bb->end = PREV_INSN (insn_b);
1656 flow_delete_insn (insn_b);
1657 }
1658
1659 /* The new insns will have been inserted before cond_earliest. We should
1660 be able to remove the jump with impunity, but the condition itself may
1661 have been modified by gcse to be shared across basic blocks. */
1662 test_bb->end = PREV_INSN (jump);
1663 flow_delete_insn (jump);
1664
1665 /* If we used a temporary, fix it up now. */
1666 if (orig_x != x)
1667 {
1668 start_sequence ();
1669 noce_emit_move_insn (orig_x, x);
1670 insn_b = gen_sequence ();
1671 end_sequence ();
1672
1673 test_bb->end = emit_insn_after (insn_b, test_bb->end);
1674 }
1675
1676 /* Merge the blocks! */
1677 merge_if_block (test_bb, then_bb, else_bb, join_bb);
1678
1679 return TRUE;
1680 }
1681 \f
1682 /* Attempt to convert an IF-THEN or IF-THEN-ELSE block into
1683 straight line code. Return true if successful. */
1684
1685 static int
1686 process_if_block (test_bb, then_bb, else_bb, join_bb)
1687 basic_block test_bb; /* Basic block test is in */
1688 basic_block then_bb; /* Basic block for THEN block */
1689 basic_block else_bb; /* Basic block for ELSE block */
1690 basic_block join_bb; /* Basic block the join label is in */
1691 {
1692 if (! reload_completed
1693 && noce_process_if_block (test_bb, then_bb, else_bb, join_bb))
1694 return TRUE;
1695
1696 if (HAVE_conditional_execution
1697 && reload_completed
1698 && cond_exec_process_if_block (test_bb, then_bb, else_bb, join_bb))
1699 return TRUE;
1700
1701 return FALSE;
1702 }
1703
1704 /* Merge the blocks and mark for local life update. */
1705
1706 static void
1707 merge_if_block (test_bb, then_bb, else_bb, join_bb)
1708 basic_block test_bb; /* Basic block test is in */
1709 basic_block then_bb; /* Basic block for THEN block */
1710 basic_block else_bb; /* Basic block for ELSE block */
1711 basic_block join_bb; /* Basic block the join label is in */
1712 {
1713 basic_block combo_bb;
1714
1715 /* All block merging is done into the lower block numbers. */
1716
1717 combo_bb = test_bb;
1718
1719 /* First merge TEST block into THEN block. This is a no-brainer since
1720 the THEN block did not have a code label to begin with. */
1721
1722 if (combo_bb->global_live_at_end)
1723 COPY_REG_SET (combo_bb->global_live_at_end, then_bb->global_live_at_end);
1724 merge_blocks_nomove (combo_bb, then_bb);
1725 num_removed_blocks++;
1726
1727 /* The ELSE block, if it existed, had a label. That label count
1728 will almost always be zero, but odd things can happen when labels
1729 get their addresses taken. */
1730 if (else_bb)
1731 {
1732 merge_blocks_nomove (combo_bb, else_bb);
1733 num_removed_blocks++;
1734 }
1735
1736 /* If there was no join block reported, that means it was not adjacent
1737 to the others, and so we cannot merge them. */
1738
1739 if (! join_bb)
1740 {
1741 /* The outgoing edge for the current COMBO block should already
1742 be correct. Verify this. */
1743 if (combo_bb->succ == NULL_EDGE)
1744 abort ();
1745
1746 /* There should sill be a branch at the end of the THEN or ELSE
1747 blocks taking us to our final destination. */
1748 if (! any_uncondjump_p (combo_bb->end)
1749 && ! returnjump_p (combo_bb->end))
1750 abort ();
1751 }
1752
1753 /* The JOIN block may have had quite a number of other predecessors too.
1754 Since we've already merged the TEST, THEN and ELSE blocks, we should
1755 have only one remaining edge from our if-then-else diamond. If there
1756 is more than one remaining edge, it must come from elsewhere. There
1757 may be zero incoming edges if the THEN block didn't actually join
1758 back up (as with a call to abort). */
1759 else if (join_bb->pred == NULL || join_bb->pred->pred_next == NULL)
1760 {
1761 /* We can merge the JOIN. */
1762 if (combo_bb->global_live_at_end)
1763 COPY_REG_SET (combo_bb->global_live_at_end,
1764 join_bb->global_live_at_end);
1765 merge_blocks_nomove (combo_bb, join_bb);
1766 num_removed_blocks++;
1767 }
1768 else
1769 {
1770 /* We cannot merge the JOIN. */
1771
1772 /* The outgoing edge for the current COMBO block should already
1773 be correct. Verify this. */
1774 if (combo_bb->succ->succ_next != NULL_EDGE
1775 || combo_bb->succ->dest != join_bb)
1776 abort ();
1777
1778 /* Remove the jump and cruft from the end of the COMBO block. */
1779 tidy_fallthru_edge (combo_bb->succ, combo_bb, join_bb);
1780 }
1781
1782 /* Make sure we update life info properly. */
1783 SET_UPDATE_LIFE (combo_bb);
1784
1785 num_updated_if_blocks++;
1786 }
1787 \f
1788 /* Find a block ending in a simple IF condition. Return TRUE if
1789 we were able to transform it in some way. */
1790
1791 static int
1792 find_if_header (test_bb)
1793 basic_block test_bb;
1794 {
1795 edge then_edge;
1796 edge else_edge;
1797
1798 /* The kind of block we're looking for has exactly two successors. */
1799 if ((then_edge = test_bb->succ) == NULL_EDGE
1800 || (else_edge = then_edge->succ_next) == NULL_EDGE
1801 || else_edge->succ_next != NULL_EDGE)
1802 return FALSE;
1803
1804 /* Neither edge should be abnormal. */
1805 if ((then_edge->flags & EDGE_COMPLEX)
1806 || (else_edge->flags & EDGE_COMPLEX))
1807 return FALSE;
1808
1809 /* The THEN edge is canonically the one that falls through. */
1810 if (then_edge->flags & EDGE_FALLTHRU)
1811 ;
1812 else if (else_edge->flags & EDGE_FALLTHRU)
1813 {
1814 edge e = else_edge;
1815 else_edge = then_edge;
1816 then_edge = e;
1817 }
1818 else
1819 /* Otherwise this must be a multiway branch of some sort. */
1820 return FALSE;
1821
1822 if (find_if_block (test_bb, then_edge, else_edge))
1823 goto success;
1824 if (post_dominators
1825 && (! HAVE_conditional_execution || reload_completed))
1826 {
1827 if (find_if_case_1 (test_bb, then_edge, else_edge))
1828 goto success;
1829 if (find_if_case_2 (test_bb, then_edge, else_edge))
1830 goto success;
1831 }
1832
1833 return FALSE;
1834
1835 success:
1836 if (rtl_dump_file)
1837 fprintf (rtl_dump_file, "Conversion succeeded.\n");
1838 return TRUE;
1839 }
1840
1841 /* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
1842 block. If so, we'll try to convert the insns to not require the branch.
1843 Return TRUE if we were successful at converting the the block. */
1844
1845 static int
1846 find_if_block (test_bb, then_edge, else_edge)
1847 basic_block test_bb;
1848 edge then_edge, else_edge;
1849 {
1850 basic_block then_bb = then_edge->dest;
1851 basic_block else_bb = else_edge->dest;
1852 basic_block join_bb = NULL_BLOCK;
1853 edge then_succ = then_bb->succ;
1854 edge else_succ = else_bb->succ;
1855 int next_index;
1856
1857 /* The THEN block of an IF-THEN combo must have exactly one predecessor. */
1858 if (then_bb->pred->pred_next != NULL_EDGE)
1859 return FALSE;
1860
1861 /* The THEN block of an IF-THEN combo must have zero or one successors. */
1862 if (then_succ != NULL_EDGE
1863 && (then_succ->succ_next != NULL_EDGE
1864 || (then_succ->flags & EDGE_COMPLEX)))
1865 return FALSE;
1866
1867 /* If the THEN block has no successors, conditional execution can still
1868 make a conditional call. Don't do this unless the ELSE block has
1869 only one incoming edge -- the CFG manipulation is too ugly otherwise.
1870 Check for the last insn of the THEN block being an indirect jump, which
1871 is listed as not having any successors, but confuses the rest of the CE
1872 code processing. XXX we should fix this in the future. */
1873 if (then_succ == NULL)
1874 {
1875 if (else_bb->pred->pred_next == NULL_EDGE)
1876 {
1877 rtx last_insn = then_bb->end;
1878
1879 while (last_insn
1880 && GET_CODE (last_insn) == NOTE
1881 && last_insn != then_bb->head)
1882 last_insn = PREV_INSN (last_insn);
1883
1884 if (last_insn
1885 && GET_CODE (last_insn) == JUMP_INSN
1886 && ! simplejump_p (last_insn))
1887 return FALSE;
1888
1889 join_bb = else_bb;
1890 else_bb = NULL_BLOCK;
1891 }
1892 else
1893 return FALSE;
1894 }
1895
1896 /* If the THEN block's successor is the other edge out of the TEST block,
1897 then we have an IF-THEN combo without an ELSE. */
1898 else if (then_succ->dest == else_bb)
1899 {
1900 join_bb = else_bb;
1901 else_bb = NULL_BLOCK;
1902 }
1903
1904 /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
1905 has exactly one predecessor and one successor, and the outgoing edge
1906 is not complex, then we have an IF-THEN-ELSE combo. */
1907 else if (else_succ != NULL_EDGE
1908 && then_succ->dest == else_succ->dest
1909 && else_bb->pred->pred_next == NULL_EDGE
1910 && else_succ->succ_next == NULL_EDGE
1911 && ! (else_succ->flags & EDGE_COMPLEX))
1912 join_bb = else_succ->dest;
1913
1914 /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination. */
1915 else
1916 return FALSE;
1917
1918 num_possible_if_blocks++;
1919
1920 if (rtl_dump_file)
1921 {
1922 if (else_bb)
1923 fprintf (rtl_dump_file,
1924 "\nIF-THEN-ELSE block found, start %d, then %d, else %d, join %d\n",
1925 test_bb->index, then_bb->index, else_bb->index,
1926 join_bb->index);
1927 else
1928 fprintf (rtl_dump_file,
1929 "\nIF-THEN block found, start %d, then %d, join %d\n",
1930 test_bb->index, then_bb->index, join_bb->index);
1931 }
1932
1933 /* Make sure IF, THEN, and ELSE, blocks are adjacent. Actually, we
1934 get the first condition for free, since we've already asserted that
1935 there's a fallthru edge from IF to THEN. */
1936 /* ??? As an enhancement, move the ELSE block. Have to deal with
1937 BLOCK notes, if by no other means than aborting the merge if they
1938 exist. Sticky enough I don't want to think about it now. */
1939 next_index = then_bb->index;
1940 if (else_bb && ++next_index != else_bb->index)
1941 return FALSE;
1942 if (++next_index != join_bb->index)
1943 {
1944 if (else_bb)
1945 join_bb = NULL;
1946 else
1947 return FALSE;
1948 }
1949
1950 /* Do the real work. */
1951 return process_if_block (test_bb, then_bb, else_bb, join_bb);
1952 }
1953
1954 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
1955 transformable, but not necessarily the other. There need be no
1956 JOIN block.
1957
1958 Return TRUE if we were successful at converting the the block.
1959
1960 Cases we'd like to look at:
1961
1962 (1)
1963 if (test) goto over; // x not live
1964 x = a;
1965 goto label;
1966 over:
1967
1968 becomes
1969
1970 x = a;
1971 if (! test) goto label;
1972
1973 (2)
1974 if (test) goto E; // x not live
1975 x = big();
1976 goto L;
1977 E:
1978 x = b;
1979 goto M;
1980
1981 becomes
1982
1983 x = b;
1984 if (test) goto M;
1985 x = big();
1986 goto L;
1987
1988 (3) // This one's really only interesting for targets that can do
1989 // multiway branching, e.g. IA-64 BBB bundles. For other targets
1990 // it results in multiple branches on a cache line, which often
1991 // does not sit well with predictors.
1992
1993 if (test1) goto E; // predicted not taken
1994 x = a;
1995 if (test2) goto F;
1996 ...
1997 E:
1998 x = b;
1999 J:
2000
2001 becomes
2002
2003 x = a;
2004 if (test1) goto E;
2005 if (test2) goto F;
2006
2007 Notes:
2008
2009 (A) Don't do (2) if the branch is predicted against the block we're
2010 eliminating. Do it anyway if we can eliminate a branch; this requires
2011 that the sole successor of the eliminated block postdominate the other
2012 side of the if.
2013
2014 (B) With CE, on (3) we can steal from both sides of the if, creating
2015
2016 if (test1) x = a;
2017 if (!test1) x = b;
2018 if (test1) goto J;
2019 if (test2) goto F;
2020 ...
2021 J:
2022
2023 Again, this is most useful if J postdominates.
2024
2025 (C) CE substitutes for helpful life information.
2026
2027 (D) These heuristics need a lot of work. */
2028
2029 /* Tests for case 1 above. */
2030
2031 static int
2032 find_if_case_1 (test_bb, then_edge, else_edge)
2033 basic_block test_bb;
2034 edge then_edge, else_edge;
2035 {
2036 basic_block then_bb = then_edge->dest;
2037 basic_block else_bb = else_edge->dest;
2038 edge then_succ = then_bb->succ;
2039 rtx new_lab;
2040
2041 /* THEN has one successor. */
2042 if (!then_succ || then_succ->succ_next != NULL)
2043 return FALSE;
2044
2045 /* THEN does not fall through, but is not strange either. */
2046 if (then_succ->flags & (EDGE_COMPLEX | EDGE_FALLTHRU))
2047 return FALSE;
2048
2049 /* THEN has one predecessor. */
2050 if (then_bb->pred->pred_next != NULL)
2051 return FALSE;
2052
2053 /* ELSE follows THEN. (??? could be moved) */
2054 if (else_bb->index != then_bb->index + 1)
2055 return FALSE;
2056
2057 num_possible_if_blocks++;
2058 if (rtl_dump_file)
2059 fprintf (rtl_dump_file,
2060 "\nIF-CASE-1 found, start %d, then %d\n",
2061 test_bb->index, then_bb->index);
2062
2063 /* THEN is small. */
2064 if (count_bb_insns (then_bb) > BRANCH_COST)
2065 return FALSE;
2066
2067 /* Find the label for THEN's destination. */
2068 if (then_succ->dest == EXIT_BLOCK_PTR)
2069 new_lab = NULL_RTX;
2070 else
2071 {
2072 new_lab = JUMP_LABEL (then_bb->end);
2073 if (! new_lab)
2074 abort ();
2075 }
2076
2077 /* Registers set are dead, or are predicable. */
2078 if (! dead_or_predicable (test_bb, then_bb, else_bb, new_lab, 1))
2079 return FALSE;
2080
2081 /* Conversion went ok, including moving the insns and fixing up the
2082 jump. Adjust the CFG to match. */
2083
2084 SET_UPDATE_LIFE (test_bb);
2085 bitmap_operation (test_bb->global_live_at_end,
2086 else_bb->global_live_at_start,
2087 then_bb->global_live_at_end, BITMAP_IOR);
2088
2089 make_edge (NULL, test_bb, then_succ->dest, 0);
2090 flow_delete_block (then_bb);
2091 tidy_fallthru_edge (else_edge, test_bb, else_bb);
2092
2093 num_removed_blocks++;
2094 num_updated_if_blocks++;
2095
2096 return TRUE;
2097 }
2098
2099 /* Test for case 2 above. */
2100
2101 static int
2102 find_if_case_2 (test_bb, then_edge, else_edge)
2103 basic_block test_bb;
2104 edge then_edge, else_edge;
2105 {
2106 basic_block then_bb = then_edge->dest;
2107 basic_block else_bb = else_edge->dest;
2108 edge else_succ = else_bb->succ;
2109 rtx new_lab, note;
2110
2111 /* ELSE has one successor. */
2112 if (!else_succ || else_succ->succ_next != NULL)
2113 return FALSE;
2114
2115 /* ELSE outgoing edge is not complex. */
2116 if (else_succ->flags & EDGE_COMPLEX)
2117 return FALSE;
2118
2119 /* ELSE has one predecessor. */
2120 if (else_bb->pred->pred_next != NULL)
2121 return FALSE;
2122
2123 /* THEN is not EXIT. */
2124 if (then_bb->index < 0)
2125 return FALSE;
2126
2127 /* ELSE is predicted or SUCC(ELSE) postdominates THEN. */
2128 note = find_reg_note (test_bb->end, REG_BR_PROB, NULL_RTX);
2129 if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2)
2130 ;
2131 else if (else_succ->dest->index < 0
2132 || TEST_BIT (post_dominators[ORIG_INDEX (then_bb)],
2133 ORIG_INDEX (else_succ->dest)))
2134 ;
2135 else
2136 return FALSE;
2137
2138 num_possible_if_blocks++;
2139 if (rtl_dump_file)
2140 fprintf (rtl_dump_file,
2141 "\nIF-CASE-2 found, start %d, else %d\n",
2142 test_bb->index, else_bb->index);
2143
2144 /* ELSE is small. */
2145 if (count_bb_insns (then_bb) > BRANCH_COST)
2146 return FALSE;
2147
2148 /* Find the label for ELSE's destination. */
2149 if (else_succ->dest == EXIT_BLOCK_PTR)
2150 new_lab = NULL_RTX;
2151 else
2152 {
2153 if (else_succ->flags & EDGE_FALLTHRU)
2154 {
2155 new_lab = else_succ->dest->head;
2156 if (GET_CODE (new_lab) != CODE_LABEL)
2157 abort ();
2158 }
2159 else
2160 {
2161 new_lab = JUMP_LABEL (else_bb->end);
2162 if (! new_lab)
2163 abort ();
2164 }
2165 }
2166
2167 /* Registers set are dead, or are predicable. */
2168 if (! dead_or_predicable (test_bb, else_bb, then_bb, new_lab, 0))
2169 return FALSE;
2170
2171 /* Conversion went ok, including moving the insns and fixing up the
2172 jump. Adjust the CFG to match. */
2173
2174 SET_UPDATE_LIFE (test_bb);
2175 bitmap_operation (test_bb->global_live_at_end,
2176 then_bb->global_live_at_start,
2177 else_bb->global_live_at_end, BITMAP_IOR);
2178
2179 remove_edge (else_edge);
2180 make_edge (NULL, test_bb, else_succ->dest, 0);
2181 flow_delete_block (else_bb);
2182
2183 num_removed_blocks++;
2184 num_updated_if_blocks++;
2185
2186 /* ??? We may now fallthru from one of THEN's successors into a join
2187 block. Rerun cleanup_cfg? Examine things manually? Wait? */
2188
2189 return TRUE;
2190 }
2191
2192 /* A subroutine of dead_or_predicable called through for_each_rtx.
2193 Return 1 if a memory is found. */
2194
2195 static int
2196 find_memory (px, data)
2197 rtx *px;
2198 void *data ATTRIBUTE_UNUSED;
2199 {
2200 return GET_CODE (*px) == MEM;
2201 }
2202
2203 /* Used by the code above to perform the actual rtl transformations.
2204 Return TRUE if successful.
2205
2206 TEST_BB is the block containing the conditional branch. MERGE_BB
2207 is the block containing the code to manipulate. NEW_DEST is the
2208 label TEST_BB should be branching to after the conversion.
2209 REVERSEP is true if the sense of the branch should be reversed. */
2210
2211 static int
2212 dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
2213 basic_block test_bb, merge_bb, other_bb;
2214 rtx new_dest;
2215 int reversep;
2216 {
2217 rtx head, end, jump, earliest, old_dest;
2218
2219 jump = test_bb->end;
2220
2221 /* Find the extent of the real code in the merge block. */
2222 head = merge_bb->head;
2223 end = merge_bb->end;
2224
2225 if (GET_CODE (head) == CODE_LABEL)
2226 head = NEXT_INSN (head);
2227 if (GET_CODE (head) == NOTE)
2228 {
2229 if (head == end)
2230 {
2231 head = end = NULL_RTX;
2232 goto no_body;
2233 }
2234 head = NEXT_INSN (head);
2235 }
2236
2237 if (GET_CODE (end) == JUMP_INSN)
2238 {
2239 if (head == end)
2240 {
2241 head = end = NULL_RTX;
2242 goto no_body;
2243 }
2244 end = PREV_INSN (end);
2245 }
2246
2247 /* Disable handling dead code by conditional execution if the machine needs
2248 to do anything funny with the tests, etc. */
2249 #ifndef IFCVT_MODIFY_TESTS
2250 if (HAVE_conditional_execution)
2251 {
2252 /* In the conditional execution case, we have things easy. We know
2253 the condition is reversable. We don't have to check life info,
2254 becase we're going to conditionally execute the code anyway.
2255 All that's left is making sure the insns involved can actually
2256 be predicated. */
2257
2258 rtx cond, prob_val;
2259
2260 cond = cond_exec_get_condition (jump);
2261
2262 prob_val = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
2263 if (prob_val)
2264 prob_val = XEXP (prob_val, 0);
2265
2266 if (reversep)
2267 {
2268 cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
2269 GET_MODE (cond), XEXP (cond, 0),
2270 XEXP (cond, 1));
2271 if (prob_val)
2272 prob_val = GEN_INT (REG_BR_PROB_BASE - INTVAL (prob_val));
2273 }
2274
2275 if (! cond_exec_process_insns (head, end, cond, prob_val, 0))
2276 goto cancel;
2277
2278 earliest = jump;
2279 }
2280 else
2281 #endif
2282 {
2283 /* In the non-conditional execution case, we have to verify that there
2284 are no trapping operations, no calls, no references to memory, and
2285 that any registers modified are dead at the branch site. */
2286
2287 rtx insn, cond, prev;
2288 regset_head merge_set_head, tmp_head, test_live_head, test_set_head;
2289 regset merge_set, tmp, test_live, test_set;
2290 struct propagate_block_info *pbi;
2291 int i, fail = 0;
2292
2293 /* Check for no calls or trapping operations. */
2294 for (insn = head; ; insn = NEXT_INSN (insn))
2295 {
2296 if (GET_CODE (insn) == CALL_INSN)
2297 return FALSE;
2298 if (INSN_P (insn))
2299 {
2300 if (may_trap_p (PATTERN (insn)))
2301 return FALSE;
2302
2303 /* ??? Even non-trapping memories such as stack frame
2304 references must be avoided. For stores, we collect
2305 no lifetime info; for reads, we'd have to assert
2306 true_dependance false against every store in the
2307 TEST range. */
2308 if (for_each_rtx (&PATTERN (insn), find_memory, NULL))
2309 return FALSE;
2310 }
2311 if (insn == end)
2312 break;
2313 }
2314
2315 if (! any_condjump_p (jump))
2316 return FALSE;
2317
2318 /* Find the extent of the conditional. */
2319 cond = noce_get_condition (jump, &earliest);
2320 if (! cond)
2321 return FALSE;
2322
2323 /* Collect:
2324 MERGE_SET = set of registers set in MERGE_BB
2325 TEST_LIVE = set of registers live at EARLIEST
2326 TEST_SET = set of registers set between EARLIEST and the
2327 end of the block. */
2328
2329 tmp = INITIALIZE_REG_SET (tmp_head);
2330 merge_set = INITIALIZE_REG_SET (merge_set_head);
2331 test_live = INITIALIZE_REG_SET (test_live_head);
2332 test_set = INITIALIZE_REG_SET (test_set_head);
2333
2334 /* ??? bb->local_set is only valid during calculate_global_regs_live,
2335 so we must recompute usage for MERGE_BB. Not so bad, I suppose,
2336 since we've already asserted that MERGE_BB is small. */
2337 propagate_block (merge_bb, tmp, merge_set, merge_set, 0);
2338
2339 /* For small register class machines, don't lengthen lifetimes of
2340 hard registers before reload. */
2341 if (SMALL_REGISTER_CLASSES && ! reload_completed)
2342 {
2343 EXECUTE_IF_SET_IN_BITMAP
2344 (merge_set, 0, i,
2345 {
2346 if (i < FIRST_PSEUDO_REGISTER
2347 && ! fixed_regs[i]
2348 && ! global_regs[i])
2349 fail = 1;
2350 });
2351 }
2352
2353 /* For TEST, we're interested in a range of insns, not a whole block.
2354 Moreover, we're interested in the insns live from OTHER_BB. */
2355
2356 COPY_REG_SET (test_live, other_bb->global_live_at_start);
2357 pbi = init_propagate_block_info (test_bb, test_live, test_set, test_set,
2358 0);
2359
2360 for (insn = jump; ; insn = prev)
2361 {
2362 prev = propagate_one_insn (pbi, insn);
2363 if (insn == earliest)
2364 break;
2365 }
2366
2367 free_propagate_block_info (pbi);
2368
2369 /* We can perform the transformation if
2370 MERGE_SET & (TEST_SET | TEST_LIVE)
2371 and
2372 TEST_SET & merge_bb->global_live_at_start
2373 are empty. */
2374
2375 bitmap_operation (tmp, test_set, test_live, BITMAP_IOR);
2376 bitmap_operation (tmp, tmp, merge_set, BITMAP_AND);
2377 EXECUTE_IF_SET_IN_BITMAP(tmp, 0, i, fail = 1);
2378
2379 bitmap_operation (tmp, test_set, merge_bb->global_live_at_start,
2380 BITMAP_AND);
2381 EXECUTE_IF_SET_IN_BITMAP(tmp, 0, i, fail = 1);
2382
2383 FREE_REG_SET (tmp);
2384 FREE_REG_SET (merge_set);
2385 FREE_REG_SET (test_live);
2386 FREE_REG_SET (test_set);
2387
2388 if (fail)
2389 return FALSE;
2390 }
2391
2392 no_body:
2393 /* We don't want to use normal invert_jump or redirect_jump because
2394 we don't want to delete_insn called. Also, we want to do our own
2395 change group management. */
2396
2397 old_dest = JUMP_LABEL (jump);
2398 if (reversep
2399 ? ! invert_jump_1 (jump, new_dest)
2400 : ! redirect_jump_1 (jump, new_dest))
2401 goto cancel;
2402
2403 if (! apply_change_group ())
2404 return FALSE;
2405
2406 if (old_dest)
2407 LABEL_NUSES (old_dest) -= 1;
2408 if (new_dest)
2409 LABEL_NUSES (new_dest) += 1;
2410 JUMP_LABEL (jump) = new_dest;
2411
2412 if (reversep)
2413 {
2414 rtx note = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
2415 if (note)
2416 XEXP (note, 0) = GEN_INT (REG_BR_PROB_BASE - INTVAL (XEXP (note, 0)));
2417 }
2418
2419 /* Move the insns out of MERGE_BB to before the branch. */
2420 if (head != NULL)
2421 {
2422 if (end == merge_bb->end)
2423 merge_bb->end = PREV_INSN (head);
2424
2425 head = squeeze_notes (head, end);
2426 if (GET_CODE (end) == NOTE
2427 && (NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_END
2428 || NOTE_LINE_NUMBER (end) == NOTE_INSN_BLOCK_BEG
2429 || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_BEG
2430 || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_END
2431 || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_CONT
2432 || NOTE_LINE_NUMBER (end) == NOTE_INSN_LOOP_VTOP))
2433 {
2434 if (head == end)
2435 return TRUE;
2436 end = PREV_INSN (end);
2437 }
2438
2439 reorder_insns (head, end, PREV_INSN (earliest));
2440 }
2441 return TRUE;
2442
2443 cancel:
2444 cancel_changes (0);
2445 return FALSE;
2446 }
2447 \f
2448 /* Main entry point for all if-conversion. */
2449
2450 void
2451 if_convert (life_data_ok)
2452 int life_data_ok;
2453 {
2454 int block_num;
2455
2456 num_possible_if_blocks = 0;
2457 num_updated_if_blocks = 0;
2458 num_removed_blocks = 0;
2459
2460 /* Free up basic_block_for_insn so that we don't have to keep it
2461 up to date, either here or in merge_blocks_nomove. */
2462 free_basic_block_vars (1);
2463
2464 /* Compute postdominators if we think we'll use them. */
2465 post_dominators = NULL;
2466 if (HAVE_conditional_execution || life_data_ok)
2467 {
2468 post_dominators = sbitmap_vector_alloc (n_basic_blocks, n_basic_blocks);
2469 calculate_dominance_info (NULL, post_dominators, CDI_POST_DOMINATORS);
2470 }
2471
2472 /* Record initial block numbers. */
2473 for (block_num = 0; block_num < n_basic_blocks; block_num++)
2474 SET_ORIG_INDEX (BASIC_BLOCK (block_num), block_num);
2475
2476 /* Go through each of the basic blocks looking for things to convert. */
2477 for (block_num = 0; block_num < n_basic_blocks; )
2478 {
2479 basic_block bb = BASIC_BLOCK (block_num);
2480 if (find_if_header (bb))
2481 block_num = bb->index;
2482 else
2483 block_num++;
2484 }
2485
2486 if (post_dominators)
2487 sbitmap_vector_free (post_dominators);
2488
2489 if (rtl_dump_file)
2490 fflush (rtl_dump_file);
2491
2492 /* Rebuild basic_block_for_insn for update_life_info and for gcse. */
2493 compute_bb_for_insn (get_max_uid ());
2494
2495 /* Rebuild life info for basic blocks that require it. */
2496 if (num_removed_blocks && life_data_ok)
2497 {
2498 sbitmap update_life_blocks = sbitmap_alloc (n_basic_blocks);
2499 sbitmap_zero (update_life_blocks);
2500
2501 /* If we allocated new pseudos, we must resize the array for sched1. */
2502 if (max_regno < max_reg_num ())
2503 {
2504 max_regno = max_reg_num ();
2505 allocate_reg_info (max_regno, FALSE, FALSE);
2506 }
2507
2508 for (block_num = 0; block_num < n_basic_blocks; block_num++)
2509 if (UPDATE_LIFE (BASIC_BLOCK (block_num)))
2510 SET_BIT (update_life_blocks, block_num);
2511
2512 count_or_remove_death_notes (update_life_blocks, 1);
2513 /* ??? See about adding a mode that verifies that the initial
2514 set of blocks don't let registers come live. */
2515 update_life_info (update_life_blocks, UPDATE_LIFE_GLOBAL,
2516 PROP_DEATH_NOTES | PROP_SCAN_DEAD_CODE
2517 | PROP_KILL_DEAD_CODE);
2518
2519 sbitmap_free (update_life_blocks);
2520 }
2521
2522 /* Write the final stats. */
2523 if (rtl_dump_file && num_possible_if_blocks > 0)
2524 {
2525 fprintf (rtl_dump_file,
2526 "\n%d possible IF blocks searched.\n",
2527 num_possible_if_blocks);
2528 fprintf (rtl_dump_file,
2529 "%d IF blocks converted.\n",
2530 num_updated_if_blocks);
2531 fprintf (rtl_dump_file,
2532 "%d basic blocks deleted.\n\n\n",
2533 num_removed_blocks);
2534 }
2535
2536 #ifdef ENABLE_CHECKING
2537 verify_flow_info ();
2538 #endif
2539 }
This page took 0.14799 seconds and 6 git commands to generate.