source: trunk/src/gcc/gcc/ifcvt.c@ 2

Last change on this file since 2 was 2, checked in by bird, 23 years ago

Initial revision

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