1 /* If-conversion support.
2    Copyright (C) 2000-2022 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 3, 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 COPYING3.  If not see
18    <http://www.gnu.org/licenses/>.  */
19 
20 #include "config.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "backend.h"
24 #include "target.h"
25 #include "rtl.h"
26 #include "tree.h"
27 #include "cfghooks.h"
28 #include "df.h"
29 #include "memmodel.h"
30 #include "tm_p.h"
31 #include "expmed.h"
32 #include "optabs.h"
33 #include "regs.h"
34 #include "emit-rtl.h"
35 #include "recog.h"
36 
37 #include "cfgrtl.h"
38 #include "cfganal.h"
39 #include "cfgcleanup.h"
40 #include "expr.h"
41 #include "output.h"
42 #include "cfgloop.h"
43 #include "tree-pass.h"
44 #include "dbgcnt.h"
45 #include "shrink-wrap.h"
46 #include "rtl-iter.h"
47 #include "ifcvt.h"
48 
49 #ifndef MAX_CONDITIONAL_EXECUTE
50 #define MAX_CONDITIONAL_EXECUTE \
51   (BRANCH_COST (optimize_function_for_speed_p (cfun), false) \
52    + 1)
53 #endif
54 
55 #define IFCVT_MULTIPLE_DUMPS 1
56 
57 #define NULL_BLOCK  ((basic_block) NULL)
58 
59 /* True if after combine pass.  */
60 static bool ifcvt_after_combine;
61 
62 /* True if the target has the cbranchcc4 optab.  */
63 static bool have_cbranchcc4;
64 
65 /* # of IF-THEN or IF-THEN-ELSE blocks we looked at  */
66 static int num_possible_if_blocks;
67 
68 /* # of IF-THEN or IF-THEN-ELSE blocks were converted to conditional
69    execution.  */
70 static int num_updated_if_blocks;
71 
72 /* # of changes made.  */
73 static int num_true_changes;
74 
75 /* Whether conditional execution changes were made.  */
76 static int cond_exec_changed_p;
77 
78 /* Forward references.  */
79 static int count_bb_insns (const_basic_block);
80 static bool cheap_bb_rtx_cost_p (const_basic_block, profile_probability, int);
81 static rtx_insn *first_active_insn (basic_block);
82 static rtx_insn *last_active_insn (basic_block, int);
83 static rtx_insn *find_active_insn_before (basic_block, rtx_insn *);
84 static rtx_insn *find_active_insn_after (basic_block, rtx_insn *);
85 static basic_block block_fallthru (basic_block);
86 static rtx cond_exec_get_condition (rtx_insn *, bool);
87 static rtx noce_get_condition (rtx_insn *, rtx_insn **, bool);
88 static int noce_operand_ok (const_rtx);
89 static void merge_if_block (ce_if_block *);
90 static int find_cond_trap (basic_block, edge, edge);
91 static basic_block find_if_header (basic_block, int);
92 static int block_jumps_and_fallthru_p (basic_block, basic_block);
93 static int noce_find_if_block (basic_block, edge, edge, int);
94 static int cond_exec_find_if_block (ce_if_block *);
95 static int find_if_case_1 (basic_block, edge, edge);
96 static int find_if_case_2 (basic_block, edge, edge);
97 static int dead_or_predicable (basic_block, basic_block, basic_block,
98                                      edge, int);
99 static void noce_emit_move_insn (rtx, rtx);
100 static rtx_insn *block_has_only_trap (basic_block);
101 static void need_cmov_or_rewire (basic_block, hash_set<rtx_insn *> *,
102                                          hash_map<rtx_insn *, int> *);
103 static bool noce_convert_multiple_sets_1 (struct noce_if_info *,
104                                                     hash_set<rtx_insn *> *,
105                                                     hash_map<rtx_insn *, int> *,
106                                                     auto_vec<rtx> *,
107                                                     auto_vec<rtx> *,
108                                                     auto_vec<rtx_insn *> *, int *);
109 
110 /* Count the number of non-jump active insns in BB.  */
111 
112 static int
count_bb_insns(const_basic_block bb)113 count_bb_insns (const_basic_block bb)
114 {
115   int count = 0;
116   rtx_insn *insn = BB_HEAD (bb);
117 
118   while (1)
119     {
120       if (active_insn_p (insn) && !JUMP_P (insn))
121           count++;
122 
123       if (insn == BB_END (bb))
124           break;
125       insn = NEXT_INSN (insn);
126     }
127 
128   return count;
129 }
130 
131 /* Determine whether the total insn_cost on non-jump insns in
132    basic block BB is less than MAX_COST.  This function returns
133    false if the cost of any instruction could not be estimated.
134 
135    The cost of the non-jump insns in BB is scaled by REG_BR_PROB_BASE
136    as those insns are being speculated.  MAX_COST is scaled with SCALE
137    plus a small fudge factor.  */
138 
139 static bool
cheap_bb_rtx_cost_p(const_basic_block bb,profile_probability prob,int max_cost)140 cheap_bb_rtx_cost_p (const_basic_block bb,
141                          profile_probability prob, int max_cost)
142 {
143   int count = 0;
144   rtx_insn *insn = BB_HEAD (bb);
145   bool speed = optimize_bb_for_speed_p (bb);
146   int scale = prob.initialized_p () ? prob.to_reg_br_prob_base ()
147                 : REG_BR_PROB_BASE;
148 
149   /* Set scale to REG_BR_PROB_BASE to void the identical scaling
150      applied to insn_cost when optimizing for size.  Only do
151      this after combine because if-conversion might interfere with
152      passes before combine.
153 
154      Use optimize_function_for_speed_p instead of the pre-defined
155      variable speed to make sure it is set to same value for all
156      basic blocks in one if-conversion transformation.  */
157   if (!optimize_function_for_speed_p (cfun) && ifcvt_after_combine)
158     scale = REG_BR_PROB_BASE;
159   /* Our branch probability/scaling factors are just estimates and don't
160      account for cases where we can get speculation for free and other
161      secondary benefits.  So we fudge the scale factor to make speculating
162      appear a little more profitable when optimizing for performance.  */
163   else
164     scale += REG_BR_PROB_BASE / 8;
165 
166 
167   max_cost *= scale;
168 
169   while (1)
170     {
171       if (NONJUMP_INSN_P (insn))
172           {
173             int cost = insn_cost (insn, speed) * REG_BR_PROB_BASE;
174             if (cost == 0)
175               return false;
176 
177             /* If this instruction is the load or set of a "stack" register,
178                such as a floating point register on x87, then the cost of
179                speculatively executing this insn may need to include
180                the additional cost of popping its result off of the
181                register stack.  Unfortunately, correctly recognizing and
182                accounting for this additional overhead is tricky, so for
183                now we simply prohibit such speculative execution.  */
184 #ifdef STACK_REGS
185             {
186               rtx set = single_set (insn);
187               if (set && STACK_REG_P (SET_DEST (set)))
188                 return false;
189             }
190 #endif
191 
192             count += cost;
193             if (count >= max_cost)
194               return false;
195           }
196       else if (CALL_P (insn))
197           return false;
198 
199       if (insn == BB_END (bb))
200           break;
201       insn = NEXT_INSN (insn);
202     }
203 
204   return true;
205 }
206 
207 /* Return the first non-jump active insn in the basic block.  */
208 
209 static rtx_insn *
first_active_insn(basic_block bb)210 first_active_insn (basic_block bb)
211 {
212   rtx_insn *insn = BB_HEAD (bb);
213 
214   if (LABEL_P (insn))
215     {
216       if (insn == BB_END (bb))
217           return NULL;
218       insn = NEXT_INSN (insn);
219     }
220 
221   while (NOTE_P (insn) || DEBUG_INSN_P (insn))
222     {
223       if (insn == BB_END (bb))
224           return NULL;
225       insn = NEXT_INSN (insn);
226     }
227 
228   if (JUMP_P (insn))
229     return NULL;
230 
231   return insn;
232 }
233 
234 /* Return the last non-jump active (non-jump) insn in the basic block.  */
235 
236 static rtx_insn *
last_active_insn(basic_block bb,int skip_use_p)237 last_active_insn (basic_block bb, int skip_use_p)
238 {
239   rtx_insn *insn = BB_END (bb);
240   rtx_insn *head = BB_HEAD (bb);
241 
242   while (NOTE_P (insn)
243            || JUMP_P (insn)
244            || DEBUG_INSN_P (insn)
245            || (skip_use_p
246                && NONJUMP_INSN_P (insn)
247                && GET_CODE (PATTERN (insn)) == USE))
248     {
249       if (insn == head)
250           return NULL;
251       insn = PREV_INSN (insn);
252     }
253 
254   if (LABEL_P (insn))
255     return NULL;
256 
257   return insn;
258 }
259 
260 /* Return the active insn before INSN inside basic block CURR_BB. */
261 
262 static rtx_insn *
find_active_insn_before(basic_block curr_bb,rtx_insn * insn)263 find_active_insn_before (basic_block curr_bb, rtx_insn *insn)
264 {
265   if (!insn || insn == BB_HEAD (curr_bb))
266     return NULL;
267 
268   while ((insn = PREV_INSN (insn)) != NULL_RTX)
269     {
270       if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
271         break;
272 
273       /* No other active insn all the way to the start of the basic block. */
274       if (insn == BB_HEAD (curr_bb))
275         return NULL;
276     }
277 
278   return insn;
279 }
280 
281 /* Return the active insn after INSN inside basic block CURR_BB. */
282 
283 static rtx_insn *
find_active_insn_after(basic_block curr_bb,rtx_insn * insn)284 find_active_insn_after (basic_block curr_bb, rtx_insn *insn)
285 {
286   if (!insn || insn == BB_END (curr_bb))
287     return NULL;
288 
289   while ((insn = NEXT_INSN (insn)) != NULL_RTX)
290     {
291       if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
292         break;
293 
294       /* No other active insn all the way to the end of the basic block. */
295       if (insn == BB_END (curr_bb))
296         return NULL;
297     }
298 
299   return insn;
300 }
301 
302 /* Return the basic block reached by falling though the basic block BB.  */
303 
304 static basic_block
block_fallthru(basic_block bb)305 block_fallthru (basic_block bb)
306 {
307   edge e = find_fallthru_edge (bb->succs);
308 
309   return (e) ? e->dest : NULL_BLOCK;
310 }
311 
312 /* Return true if RTXs A and B can be safely interchanged.  */
313 
314 static bool
rtx_interchangeable_p(const_rtx a,const_rtx b)315 rtx_interchangeable_p (const_rtx a, const_rtx b)
316 {
317   if (!rtx_equal_p (a, b))
318     return false;
319 
320   if (GET_CODE (a) != MEM)
321     return true;
322 
323   /* A dead type-unsafe memory reference is legal, but a live type-unsafe memory
324      reference is not.  Interchanging a dead type-unsafe memory reference with
325      a live type-safe one creates a live type-unsafe memory reference, in other
326      words, it makes the program illegal.
327      We check here conservatively whether the two memory references have equal
328      memory attributes.  */
329 
330   return mem_attrs_eq_p (get_mem_attrs (a), get_mem_attrs (b));
331 }
332 
333 
334 /* Go through a bunch of insns, converting them to conditional
335    execution format if possible.  Return TRUE if all of the non-note
336    insns were processed.  */
337 
338 static int
cond_exec_process_insns(ce_if_block * ce_info ATTRIBUTE_UNUSED,rtx_insn * start,rtx end,rtx test,profile_probability prob_val,int mod_ok)339 cond_exec_process_insns (ce_if_block *ce_info ATTRIBUTE_UNUSED,
340                                /* if block information */rtx_insn *start,
341                                /* first insn to look at */rtx end,
342                                /* last insn to look at */rtx test,
343                                /* conditional execution test */profile_probability
344                                                                           prob_val,
345                                /* probability of branch taken. */int mod_ok)
346 {
347   int must_be_last = FALSE;
348   rtx_insn *insn;
349   rtx xtest;
350   rtx pattern;
351 
352   if (!start || !end)
353     return FALSE;
354 
355   for (insn = start; ; insn = NEXT_INSN (insn))
356     {
357       /* dwarf2out can't cope with conditional prologues.  */
358       if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
359           return FALSE;
360 
361       if (NOTE_P (insn) || DEBUG_INSN_P (insn))
362           goto insn_done;
363 
364       gcc_assert (NONJUMP_INSN_P (insn) || CALL_P (insn));
365 
366       /* dwarf2out can't cope with conditional unwind info.  */
367       if (RTX_FRAME_RELATED_P (insn))
368           return FALSE;
369 
370       /* Remove USE insns that get in the way.  */
371       if (reload_completed && GET_CODE (PATTERN (insn)) == USE)
372           {
373             /* ??? Ug.  Actually unlinking the thing is problematic,
374                given what we'd have to coordinate with our callers.  */
375             SET_INSN_DELETED (insn);
376             goto insn_done;
377           }
378 
379       /* Last insn wasn't last?  */
380       if (must_be_last)
381           return FALSE;
382 
383       if (modified_in_p (test, insn))
384           {
385             if (!mod_ok)
386               return FALSE;
387             must_be_last = TRUE;
388           }
389 
390       /* Now build the conditional form of the instruction.  */
391       pattern = PATTERN (insn);
392       xtest = copy_rtx (test);
393 
394       /* If this is already a COND_EXEC, rewrite the test to be an AND of the
395          two conditions.  */
396       if (GET_CODE (pattern) == COND_EXEC)
397           {
398             if (GET_MODE (xtest) != GET_MODE (COND_EXEC_TEST (pattern)))
399               return FALSE;
400 
401             xtest = gen_rtx_AND (GET_MODE (xtest), xtest,
402                                      COND_EXEC_TEST (pattern));
403             pattern = COND_EXEC_CODE (pattern);
404           }
405 
406       pattern = gen_rtx_COND_EXEC (VOIDmode, xtest, pattern);
407 
408       /* If the machine needs to modify the insn being conditionally executed,
409          say for example to force a constant integer operand into a temp
410          register, do so here.  */
411 #ifdef IFCVT_MODIFY_INSN
412       IFCVT_MODIFY_INSN (ce_info, pattern, insn);
413       if (! pattern)
414           return FALSE;
415 #endif
416 
417       validate_change (insn, &PATTERN (insn), pattern, 1);
418 
419       if (CALL_P (insn) && prob_val.initialized_p ())
420           validate_change (insn, &REG_NOTES (insn),
421                                gen_rtx_INT_LIST ((machine_mode) REG_BR_PROB,
422                                                      prob_val.to_reg_br_prob_note (),
423                                                      REG_NOTES (insn)), 1);
424 
425     insn_done:
426       if (insn == end)
427           break;
428     }
429 
430   return TRUE;
431 }
432 
433 /* Return the condition for a jump.  Do not do any special processing.  */
434 
435 static rtx
cond_exec_get_condition(rtx_insn * jump,bool get_reversed=false)436 cond_exec_get_condition (rtx_insn *jump, bool get_reversed = false)
437 {
438   rtx test_if, cond;
439 
440   if (any_condjump_p (jump))
441     test_if = SET_SRC (pc_set (jump));
442   else
443     return NULL_RTX;
444   cond = XEXP (test_if, 0);
445 
446   /* If this branches to JUMP_LABEL when the condition is false,
447      reverse the condition.  */
448   if (get_reversed
449       || (GET_CODE (XEXP (test_if, 2)) == LABEL_REF
450             && label_ref_label (XEXP (test_if, 2))
451             == JUMP_LABEL (jump)))
452     {
453       enum rtx_code rev = reversed_comparison_code (cond, jump);
454       if (rev == UNKNOWN)
455           return NULL_RTX;
456 
457       cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
458                                    XEXP (cond, 1));
459     }
460 
461   return cond;
462 }
463 
464 /* Given a simple IF-THEN or IF-THEN-ELSE block, attempt to convert it
465    to conditional execution.  Return TRUE if we were successful at
466    converting the block.  */
467 
468 static int
cond_exec_process_if_block(ce_if_block * ce_info,int do_multiple_p)469 cond_exec_process_if_block (ce_if_block * ce_info,
470                                   /* if block information */int do_multiple_p)
471 {
472   basic_block test_bb = ce_info->test_bb;         /* last test block */
473   basic_block then_bb = ce_info->then_bb;         /* THEN */
474   basic_block else_bb = ce_info->else_bb;         /* ELSE or NULL */
475   rtx test_expr;              /* expression in IF_THEN_ELSE that is tested */
476   rtx_insn *then_start;                 /* first insn in THEN block */
477   rtx_insn *then_end;                   /* last insn + 1 in THEN block */
478   rtx_insn *else_start = NULL;          /* first insn in ELSE block or NULL */
479   rtx_insn *else_end = NULL;  /* last insn + 1 in ELSE block */
480   int max;                              /* max # of insns to convert.  */
481   int then_mod_ok;            /* whether conditional mods are ok in THEN */
482   rtx true_expr;              /* test for else block insns */
483   rtx false_expr;             /* test for then block insns */
484   profile_probability true_prob_val;/* probability of else block */
485   profile_probability false_prob_val;/* probability of then block */
486   rtx_insn *then_last_head = NULL;      /* Last match at the head of THEN */
487   rtx_insn *else_last_head = NULL;      /* Last match at the head of ELSE */
488   rtx_insn *then_first_tail = NULL;     /* First match at the tail of THEN */
489   rtx_insn *else_first_tail = NULL;     /* First match at the tail of ELSE */
490   int then_n_insns, else_n_insns, n_insns;
491   enum rtx_code false_code;
492   rtx note;
493 
494   /* If test is comprised of && or || elements, and we've failed at handling
495      all of them together, just use the last test if it is the special case of
496      && elements without an ELSE block.  */
497   if (!do_multiple_p && ce_info->num_multiple_test_blocks)
498     {
499       if (else_bb || ! ce_info->and_and_p)
500           return FALSE;
501 
502       ce_info->test_bb = test_bb = ce_info->last_test_bb;
503       ce_info->num_multiple_test_blocks = 0;
504       ce_info->num_and_and_blocks = 0;
505       ce_info->num_or_or_blocks = 0;
506     }
507 
508   /* Find the conditional jump to the ELSE or JOIN part, and isolate
509      the test.  */
510   test_expr = cond_exec_get_condition (BB_END (test_bb));
511   if (! test_expr)
512     return FALSE;
513 
514   /* If the conditional jump is more than just a conditional jump,
515      then we cannot do conditional execution conversion on this block.  */
516   if (! onlyjump_p (BB_END (test_bb)))
517     return FALSE;
518 
519   /* Collect the bounds of where we're to search, skipping any labels, jumps
520      and notes at the beginning and end of the block.  Then count the total
521      number of insns and see if it is small enough to convert.  */
522   then_start = first_active_insn (then_bb);
523   then_end = last_active_insn (then_bb, TRUE);
524   then_n_insns = ce_info->num_then_insns = count_bb_insns (then_bb);
525   n_insns = then_n_insns;
526   max = MAX_CONDITIONAL_EXECUTE;
527 
528   if (else_bb)
529     {
530       int n_matching;
531 
532       max *= 2;
533       else_start = first_active_insn (else_bb);
534       else_end = last_active_insn (else_bb, TRUE);
535       else_n_insns = ce_info->num_else_insns = count_bb_insns (else_bb);
536       n_insns += else_n_insns;
537 
538       /* Look for matching sequences at the head and tail of the two blocks,
539            and limit the range of insns to be converted if possible.  */
540       n_matching = flow_find_cross_jump (then_bb, else_bb,
541                                                    &then_first_tail, &else_first_tail,
542                                                    NULL);
543       if (then_first_tail == BB_HEAD (then_bb))
544           then_start = then_end = NULL;
545       if (else_first_tail == BB_HEAD (else_bb))
546           else_start = else_end = NULL;
547 
548       if (n_matching > 0)
549           {
550             if (then_end)
551               then_end = find_active_insn_before (then_bb, then_first_tail);
552             if (else_end)
553               else_end = find_active_insn_before (else_bb, else_first_tail);
554             n_insns -= 2 * n_matching;
555           }
556 
557       if (then_start
558             && else_start
559             && then_n_insns > n_matching
560             && else_n_insns > n_matching)
561           {
562             int longest_match = MIN (then_n_insns - n_matching,
563                                            else_n_insns - n_matching);
564             n_matching
565               = flow_find_head_matching_sequence (then_bb, else_bb,
566                                                             &then_last_head,
567                                                             &else_last_head,
568                                                             longest_match);
569 
570             if (n_matching > 0)
571               {
572                 rtx_insn *insn;
573 
574                 /* We won't pass the insns in the head sequence to
575                      cond_exec_process_insns, so we need to test them here
576                      to make sure that they don't clobber the condition.  */
577                 for (insn = BB_HEAD (then_bb);
578                        insn != NEXT_INSN (then_last_head);
579                        insn = NEXT_INSN (insn))
580                     if (!LABEL_P (insn) && !NOTE_P (insn)
581                         && !DEBUG_INSN_P (insn)
582                         && modified_in_p (test_expr, insn))
583                       return FALSE;
584               }
585 
586             if (then_last_head == then_end)
587               then_start = then_end = NULL;
588             if (else_last_head == else_end)
589               else_start = else_end = NULL;
590 
591             if (n_matching > 0)
592               {
593                 if (then_start)
594                     then_start = find_active_insn_after (then_bb, then_last_head);
595                 if (else_start)
596                     else_start = find_active_insn_after (else_bb, else_last_head);
597                 n_insns -= 2 * n_matching;
598               }
599           }
600     }
601 
602   if (n_insns > max)
603     return FALSE;
604 
605   /* Map test_expr/test_jump into the appropriate MD tests to use on
606      the conditionally executed code.  */
607 
608   true_expr = test_expr;
609 
610   false_code = reversed_comparison_code (true_expr, BB_END (test_bb));
611   if (false_code != UNKNOWN)
612     false_expr = gen_rtx_fmt_ee (false_code, GET_MODE (true_expr),
613                                          XEXP (true_expr, 0), XEXP (true_expr, 1));
614   else
615     false_expr = NULL_RTX;
616 
617 #ifdef IFCVT_MODIFY_TESTS
618   /* If the machine description needs to modify the tests, such as setting a
619      conditional execution register from a comparison, it can do so here.  */
620   IFCVT_MODIFY_TESTS (ce_info, true_expr, false_expr);
621 
622   /* See if the conversion failed.  */
623   if (!true_expr || !false_expr)
624     goto fail;
625 #endif
626 
627   note = find_reg_note (BB_END (test_bb), REG_BR_PROB, NULL_RTX);
628   if (note)
629     {
630       true_prob_val = profile_probability::from_reg_br_prob_note (XINT (note, 0));
631       false_prob_val = true_prob_val.invert ();
632     }
633   else
634     {
635       true_prob_val = profile_probability::uninitialized ();
636       false_prob_val = profile_probability::uninitialized ();
637     }
638 
639   /* If we have && or || tests, do them here.  These tests are in the adjacent
640      blocks after the first block containing the test.  */
641   if (ce_info->num_multiple_test_blocks > 0)
642     {
643       basic_block bb = test_bb;
644       basic_block last_test_bb = ce_info->last_test_bb;
645 
646       if (! false_expr)
647           goto fail;
648 
649       do
650           {
651             rtx_insn *start, *end;
652             rtx t, f;
653             enum rtx_code f_code;
654 
655             bb = block_fallthru (bb);
656             start = first_active_insn (bb);
657             end = last_active_insn (bb, TRUE);
658             if (start
659                 && ! cond_exec_process_insns (ce_info, start, end, false_expr,
660                                                       false_prob_val, FALSE))
661               goto fail;
662 
663             /* If the conditional jump is more than just a conditional jump, then
664                we cannot do conditional execution conversion on this block.  */
665             if (! onlyjump_p (BB_END (bb)))
666               goto fail;
667 
668             /* Find the conditional jump and isolate the test.  */
669             t = cond_exec_get_condition (BB_END (bb));
670             if (! t)
671               goto fail;
672 
673             f_code = reversed_comparison_code (t, BB_END (bb));
674             if (f_code == UNKNOWN)
675               goto fail;
676 
677             f = gen_rtx_fmt_ee (f_code, GET_MODE (t), XEXP (t, 0), XEXP (t, 1));
678             if (ce_info->and_and_p)
679               {
680                 t = gen_rtx_AND (GET_MODE (t), true_expr, t);
681                 f = gen_rtx_IOR (GET_MODE (t), false_expr, f);
682               }
683             else
684               {
685                 t = gen_rtx_IOR (GET_MODE (t), true_expr, t);
686                 f = gen_rtx_AND (GET_MODE (t), false_expr, f);
687               }
688 
689             /* If the machine description needs to modify the tests, such as
690                setting a conditional execution register from a comparison, it can
691                do so here.  */
692 #ifdef IFCVT_MODIFY_MULTIPLE_TESTS
693             IFCVT_MODIFY_MULTIPLE_TESTS (ce_info, bb, t, f);
694 
695             /* See if the conversion failed.  */
696             if (!t || !f)
697               goto fail;
698 #endif
699 
700             true_expr = t;
701             false_expr = f;
702           }
703       while (bb != last_test_bb);
704     }
705 
706   /* For IF-THEN-ELSE blocks, we don't allow modifications of the test
707      on then THEN block.  */
708   then_mod_ok = (else_bb == NULL_BLOCK);
709 
710   /* Go through the THEN and ELSE blocks converting the insns if possible
711      to conditional execution.  */
712 
713   if (then_end
714       && (! false_expr
715             || ! cond_exec_process_insns (ce_info, then_start, then_end,
716                                                   false_expr, false_prob_val,
717                                                   then_mod_ok)))
718     goto fail;
719 
720   if (else_bb && else_end
721       && ! cond_exec_process_insns (ce_info, else_start, else_end,
722                                             true_expr, true_prob_val, TRUE))
723     goto fail;
724 
725   /* If we cannot apply the changes, fail.  Do not go through the normal fail
726      processing, since apply_change_group will call cancel_changes.  */
727   if (! apply_change_group ())
728     {
729 #ifdef IFCVT_MODIFY_CANCEL
730       /* Cancel any machine dependent changes.  */
731       IFCVT_MODIFY_CANCEL (ce_info);
732 #endif
733       return FALSE;
734     }
735 
736 #ifdef IFCVT_MODIFY_FINAL
737   /* Do any machine dependent final modifications.  */
738   IFCVT_MODIFY_FINAL (ce_info);
739 #endif
740 
741   /* Conversion succeeded.  */
742   if (dump_file)
743     fprintf (dump_file, "%d insn%s converted to conditional execution.\n",
744                n_insns, (n_insns == 1) ? " was" : "s were");
745 
746   /* Merge the blocks!  If we had matching sequences, make sure to delete one
747      copy at the appropriate location first: delete the copy in the THEN branch
748      for a tail sequence so that the remaining one is executed last for both
749      branches, and delete the copy in the ELSE branch for a head sequence so
750      that the remaining one is executed first for both branches.  */
751   if (then_first_tail)
752     {
753       rtx_insn *from = then_first_tail;
754       if (!INSN_P (from))
755           from = find_active_insn_after (then_bb, from);
756       delete_insn_chain (from, get_last_bb_insn (then_bb), false);
757     }
758   if (else_last_head)
759     delete_insn_chain (first_active_insn (else_bb), else_last_head, false);
760 
761   merge_if_block (ce_info);
762   cond_exec_changed_p = TRUE;
763   return TRUE;
764 
765  fail:
766 #ifdef IFCVT_MODIFY_CANCEL
767   /* Cancel any machine dependent changes.  */
768   IFCVT_MODIFY_CANCEL (ce_info);
769 #endif
770 
771   cancel_changes (0);
772   return FALSE;
773 }
774 
775 static rtx noce_emit_store_flag (struct noce_if_info *, rtx, int, int);
776 static int noce_try_move (struct noce_if_info *);
777 static int noce_try_ifelse_collapse (struct noce_if_info *);
778 static int noce_try_store_flag (struct noce_if_info *);
779 static int noce_try_addcc (struct noce_if_info *);
780 static int noce_try_store_flag_constants (struct noce_if_info *);
781 static int noce_try_store_flag_mask (struct noce_if_info *);
782 static rtx noce_emit_cmove (struct noce_if_info *, rtx, enum rtx_code, rtx,
783                                   rtx, rtx, rtx, rtx = NULL, rtx = NULL);
784 static int noce_try_cmove (struct noce_if_info *);
785 static int noce_try_cmove_arith (struct noce_if_info *);
786 static rtx noce_get_alt_condition (struct noce_if_info *, rtx, rtx_insn **);
787 static int noce_try_minmax (struct noce_if_info *);
788 static int noce_try_abs (struct noce_if_info *);
789 static int noce_try_sign_mask (struct noce_if_info *);
790 
791 /* Return the comparison code for reversed condition for IF_INFO,
792    or UNKNOWN if reversing the condition is not possible.  */
793 
794 static inline enum rtx_code
noce_reversed_cond_code(struct noce_if_info * if_info)795 noce_reversed_cond_code (struct noce_if_info *if_info)
796 {
797   if (if_info->rev_cond)
798     return GET_CODE (if_info->rev_cond);
799   return reversed_comparison_code (if_info->cond, if_info->jump);
800 }
801 
802 /* Return true if SEQ is a good candidate as a replacement for the
803    if-convertible sequence described in IF_INFO.
804    This is the default implementation that targets can override
805    through a target hook.  */
806 
807 bool
default_noce_conversion_profitable_p(rtx_insn * seq,struct noce_if_info * if_info)808 default_noce_conversion_profitable_p (rtx_insn *seq,
809                                               struct noce_if_info *if_info)
810 {
811   bool speed_p = if_info->speed_p;
812 
813   /* Cost up the new sequence.  */
814   unsigned int cost = seq_cost (seq, speed_p);
815 
816   if (cost <= if_info->original_cost)
817     return true;
818 
819   /* When compiling for size, we can make a reasonably accurately guess
820      at the size growth.  When compiling for speed, use the maximum.  */
821   return speed_p && cost <= if_info->max_seq_cost;
822 }
823 
824 /* Helper function for noce_try_store_flag*.  */
825 
826 static rtx
noce_emit_store_flag(struct noce_if_info * if_info,rtx x,int reversep,int normalize)827 noce_emit_store_flag (struct noce_if_info *if_info, rtx x, int reversep,
828                           int normalize)
829 {
830   rtx cond = if_info->cond;
831   int cond_complex;
832   enum rtx_code code;
833 
834   cond_complex = (! general_operand (XEXP (cond, 0), VOIDmode)
835                       || ! general_operand (XEXP (cond, 1), VOIDmode));
836 
837   /* If earliest == jump, or when the condition is complex, try to
838      build the store_flag insn directly.  */
839 
840   if (cond_complex)
841     {
842       rtx set = pc_set (if_info->jump);
843       cond = XEXP (SET_SRC (set), 0);
844       if (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
845             && label_ref_label (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (if_info->jump))
846           reversep = !reversep;
847       if (if_info->then_else_reversed)
848           reversep = !reversep;
849     }
850   else if (reversep
851              && if_info->rev_cond
852              && general_operand (XEXP (if_info->rev_cond, 0), VOIDmode)
853              && general_operand (XEXP (if_info->rev_cond, 1), VOIDmode))
854     {
855       cond = if_info->rev_cond;
856       reversep = false;
857     }
858 
859   if (reversep)
860     code = reversed_comparison_code (cond, if_info->jump);
861   else
862     code = GET_CODE (cond);
863 
864   if ((if_info->cond_earliest == if_info->jump || cond_complex)
865       && (normalize == 0 || STORE_FLAG_VALUE == normalize))
866     {
867       rtx src = gen_rtx_fmt_ee (code, GET_MODE (x), XEXP (cond, 0),
868                                         XEXP (cond, 1));
869       rtx set = gen_rtx_SET (x, src);
870 
871       start_sequence ();
872       rtx_insn *insn = emit_insn (set);
873 
874       if (recog_memoized (insn) >= 0)
875           {
876             rtx_insn *seq = get_insns ();
877             end_sequence ();
878             emit_insn (seq);
879 
880             if_info->cond_earliest = if_info->jump;
881 
882             return x;
883           }
884 
885       end_sequence ();
886     }
887 
888   /* Don't even try if the comparison operands or the mode of X are weird.  */
889   if (cond_complex || !SCALAR_INT_MODE_P (GET_MODE (x)))
890     return NULL_RTX;
891 
892   return emit_store_flag (x, code, XEXP (cond, 0),
893                                 XEXP (cond, 1), VOIDmode,
894                                 (code == LTU || code == LEU
895                                  || code == GEU || code == GTU), normalize);
896 }
897 
898 /* Return true if X can be safely forced into a register by copy_to_mode_reg
899    / force_operand.  */
900 
901 static bool
noce_can_force_operand(rtx x)902 noce_can_force_operand (rtx x)
903 {
904   if (general_operand (x, VOIDmode))
905     return true;
906   if (SUBREG_P (x))
907     {
908       if (!noce_can_force_operand (SUBREG_REG (x)))
909           return false;
910       return true;
911     }
912   if (ARITHMETIC_P (x))
913     {
914       if (!noce_can_force_operand (XEXP (x, 0))
915             || !noce_can_force_operand (XEXP (x, 1)))
916           return false;
917       switch (GET_CODE (x))
918           {
919           case MULT:
920           case DIV:
921           case MOD:
922           case UDIV:
923           case UMOD:
924             return true;
925           default:
926             return code_to_optab (GET_CODE (x));
927           }
928     }
929   if (UNARY_P (x))
930     {
931       if (!noce_can_force_operand (XEXP (x, 0)))
932           return false;
933       switch (GET_CODE (x))
934           {
935           case ZERO_EXTEND:
936           case SIGN_EXTEND:
937           case TRUNCATE:
938           case FLOAT_EXTEND:
939           case FLOAT_TRUNCATE:
940           case FIX:
941           case UNSIGNED_FIX:
942           case FLOAT:
943           case UNSIGNED_FLOAT:
944             return true;
945           default:
946             return code_to_optab (GET_CODE (x));
947           }
948     }
949   return false;
950 }
951 
952 /* Emit instruction to move an rtx, possibly into STRICT_LOW_PART.
953    X is the destination/target and Y is the value to copy.  */
954 
955 static void
noce_emit_move_insn(rtx x,rtx y)956 noce_emit_move_insn (rtx x, rtx y)
957 {
958   machine_mode outmode;
959   rtx outer, inner;
960   poly_int64 bitpos;
961 
962   if (GET_CODE (x) != STRICT_LOW_PART)
963     {
964       rtx_insn *seq, *insn;
965       rtx target;
966       optab ot;
967 
968       start_sequence ();
969       /* Check that the SET_SRC is reasonable before calling emit_move_insn,
970            otherwise construct a suitable SET pattern ourselves.  */
971       insn = (OBJECT_P (y) || CONSTANT_P (y) || GET_CODE (y) == SUBREG)
972                ? emit_move_insn (x, y)
973                : emit_insn (gen_rtx_SET (x, y));
974       seq = get_insns ();
975       end_sequence ();
976 
977       if (recog_memoized (insn) <= 0)
978           {
979             if (GET_CODE (x) == ZERO_EXTRACT)
980               {
981                 rtx op = XEXP (x, 0);
982                 unsigned HOST_WIDE_INT size = INTVAL (XEXP (x, 1));
983                 unsigned HOST_WIDE_INT start = INTVAL (XEXP (x, 2));
984 
985                 /* store_bit_field expects START to be relative to
986                      BYTES_BIG_ENDIAN and adjusts this value for machines with
987                      BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN.  In order to be able to
988                      invoke store_bit_field again it is necessary to have the START
989                      value from the first call.  */
990                 if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
991                     {
992                       if (MEM_P (op))
993                         start = BITS_PER_UNIT - start - size;
994                       else
995                         {
996                           gcc_assert (REG_P (op));
997                           start = BITS_PER_WORD - start - size;
998                         }
999                     }
1000 
1001                 gcc_assert (start < (MEM_P (op) ? BITS_PER_UNIT : BITS_PER_WORD));
1002                 store_bit_field (op, size, start, 0, 0, GET_MODE (x), y, false);
1003                 return;
1004               }
1005 
1006             switch (GET_RTX_CLASS (GET_CODE (y)))
1007               {
1008               case RTX_UNARY:
1009                 ot = code_to_optab (GET_CODE (y));
1010                 if (ot && noce_can_force_operand (XEXP (y, 0)))
1011                     {
1012                       start_sequence ();
1013                       target = expand_unop (GET_MODE (y), ot, XEXP (y, 0), x, 0);
1014                       if (target != NULL_RTX)
1015                         {
1016                           if (target != x)
1017                               emit_move_insn (x, target);
1018                           seq = get_insns ();
1019                         }
1020                       end_sequence ();
1021                     }
1022                 break;
1023 
1024               case RTX_BIN_ARITH:
1025               case RTX_COMM_ARITH:
1026                 ot = code_to_optab (GET_CODE (y));
1027                 if (ot
1028                       && noce_can_force_operand (XEXP (y, 0))
1029                       && noce_can_force_operand (XEXP (y, 1)))
1030                     {
1031                       start_sequence ();
1032                       target = expand_binop (GET_MODE (y), ot,
1033                                                    XEXP (y, 0), XEXP (y, 1),
1034                                                    x, 0, OPTAB_DIRECT);
1035                       if (target != NULL_RTX)
1036                         {
1037                           if (target != x)
1038                                 emit_move_insn (x, target);
1039                           seq = get_insns ();
1040                         }
1041                       end_sequence ();
1042                     }
1043                 break;
1044 
1045               default:
1046                 break;
1047               }
1048           }
1049 
1050       emit_insn (seq);
1051       return;
1052     }
1053 
1054   outer = XEXP (x, 0);
1055   inner = XEXP (outer, 0);
1056   outmode = GET_MODE (outer);
1057   bitpos = SUBREG_BYTE (outer) * BITS_PER_UNIT;
1058   store_bit_field (inner, GET_MODE_BITSIZE (outmode), bitpos,
1059                        0, 0, outmode, y, false);
1060 }
1061 
1062 /* Return the CC reg if it is used in COND.  */
1063 
1064 static rtx
cc_in_cond(rtx cond)1065 cc_in_cond (rtx cond)
1066 {
1067   if (have_cbranchcc4 && cond
1068       && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_CC)
1069     return XEXP (cond, 0);
1070 
1071   return NULL_RTX;
1072 }
1073 
1074 /* Return sequence of instructions generated by if conversion.  This
1075    function calls end_sequence() to end the current stream, ensures
1076    that the instructions are unshared, recognizable non-jump insns.
1077    On failure, this function returns a NULL_RTX.  */
1078 
1079 static rtx_insn *
end_ifcvt_sequence(struct noce_if_info * if_info)1080 end_ifcvt_sequence (struct noce_if_info *if_info)
1081 {
1082   rtx_insn *insn;
1083   rtx_insn *seq = get_insns ();
1084   rtx cc = cc_in_cond (if_info->cond);
1085 
1086   set_used_flags (if_info->x);
1087   set_used_flags (if_info->cond);
1088   set_used_flags (if_info->a);
1089   set_used_flags (if_info->b);
1090 
1091   for (insn = seq; insn; insn = NEXT_INSN (insn))
1092     set_used_flags (insn);
1093 
1094   unshare_all_rtl_in_chain (seq);
1095   end_sequence ();
1096 
1097   /* Make sure that all of the instructions emitted are recognizable,
1098      and that we haven't introduced a new jump instruction.
1099      As an exercise for the reader, build a general mechanism that
1100      allows proper placement of required clobbers.  */
1101   for (insn = seq; insn; insn = NEXT_INSN (insn))
1102     if (JUMP_P (insn)
1103           || recog_memoized (insn) == -1
1104              /* Make sure new generated code does not clobber CC.  */
1105           || (cc && set_of (cc, insn)))
1106       return NULL;
1107 
1108   return seq;
1109 }
1110 
1111 /* Return true iff the then and else basic block (if it exists)
1112    consist of a single simple set instruction.  */
1113 
1114 static bool
noce_simple_bbs(struct noce_if_info * if_info)1115 noce_simple_bbs (struct noce_if_info *if_info)
1116 {
1117   if (!if_info->then_simple)
1118     return false;
1119 
1120   if (if_info->else_bb)
1121     return if_info->else_simple;
1122 
1123   return true;
1124 }
1125 
1126 /* Convert "if (a != b) x = a; else x = b" into "x = a" and
1127    "if (a == b) x = a; else x = b" into "x = b".  */
1128 
1129 static int
noce_try_move(struct noce_if_info * if_info)1130 noce_try_move (struct noce_if_info *if_info)
1131 {
1132   rtx cond = if_info->cond;
1133   enum rtx_code code = GET_CODE (cond);
1134   rtx y;
1135   rtx_insn *seq;
1136 
1137   if (code != NE && code != EQ)
1138     return FALSE;
1139 
1140   if (!noce_simple_bbs (if_info))
1141     return FALSE;
1142 
1143   /* This optimization isn't valid if either A or B could be a NaN
1144      or a signed zero.  */
1145   if (HONOR_NANS (if_info->x)
1146       || HONOR_SIGNED_ZEROS (if_info->x))
1147     return FALSE;
1148 
1149   /* Check whether the operands of the comparison are A and in
1150      either order.  */
1151   if ((rtx_equal_p (if_info->a, XEXP (cond, 0))
1152        && rtx_equal_p (if_info->b, XEXP (cond, 1)))
1153       || (rtx_equal_p (if_info->a, XEXP (cond, 1))
1154             && rtx_equal_p (if_info->b, XEXP (cond, 0))))
1155     {
1156       if (!rtx_interchangeable_p (if_info->a, if_info->b))
1157           return FALSE;
1158 
1159       y = (code == EQ) ? if_info->a : if_info->b;
1160 
1161       /* Avoid generating the move if the source is the destination.  */
1162       if (! rtx_equal_p (if_info->x, y))
1163           {
1164             start_sequence ();
1165             noce_emit_move_insn (if_info->x, y);
1166             seq = end_ifcvt_sequence (if_info);
1167             if (!seq)
1168               return FALSE;
1169 
1170             emit_insn_before_setloc (seq, if_info->jump,
1171                                            INSN_LOCATION (if_info->insn_a));
1172           }
1173       if_info->transform_name = "noce_try_move";
1174       return TRUE;
1175     }
1176   return FALSE;
1177 }
1178 
1179 /* Try forming an IF_THEN_ELSE (cond, b, a) and collapsing that
1180    through simplify_rtx.  Sometimes that can eliminate the IF_THEN_ELSE.
1181    If that is the case, emit the result into x.  */
1182 
1183 static int
noce_try_ifelse_collapse(struct noce_if_info * if_info)1184 noce_try_ifelse_collapse (struct noce_if_info * if_info)
1185 {
1186   if (!noce_simple_bbs (if_info))
1187     return FALSE;
1188 
1189   machine_mode mode = GET_MODE (if_info->x);
1190   rtx if_then_else = simplify_gen_ternary (IF_THEN_ELSE, mode, mode,
1191                                                       if_info->cond, if_info->b,
1192                                                       if_info->a);
1193 
1194   if (GET_CODE (if_then_else) == IF_THEN_ELSE)
1195     return FALSE;
1196 
1197   rtx_insn *seq;
1198   start_sequence ();
1199   noce_emit_move_insn (if_info->x, if_then_else);
1200   seq = end_ifcvt_sequence (if_info);
1201   if (!seq)
1202     return FALSE;
1203 
1204   emit_insn_before_setloc (seq, if_info->jump,
1205                                 INSN_LOCATION (if_info->insn_a));
1206 
1207   if_info->transform_name = "noce_try_ifelse_collapse";
1208   return TRUE;
1209 }
1210 
1211 
1212 /* Convert "if (test) x = 1; else x = 0".
1213 
1214    Only try 0 and STORE_FLAG_VALUE here.  Other combinations will be
1215    tried in noce_try_store_flag_constants after noce_try_cmove has had
1216    a go at the conversion.  */
1217 
1218 static int
noce_try_store_flag(struct noce_if_info * if_info)1219 noce_try_store_flag (struct noce_if_info *if_info)
1220 {
1221   int reversep;
1222   rtx target;
1223   rtx_insn *seq;
1224 
1225   if (!noce_simple_bbs (if_info))
1226     return FALSE;
1227 
1228   if (CONST_INT_P (if_info->b)
1229       && INTVAL (if_info->b) == STORE_FLAG_VALUE
1230       && if_info->a == const0_rtx)
1231     reversep = 0;
1232   else if (if_info->b == const0_rtx
1233              && CONST_INT_P (if_info->a)
1234              && INTVAL (if_info->a) == STORE_FLAG_VALUE
1235              && noce_reversed_cond_code (if_info) != UNKNOWN)
1236     reversep = 1;
1237   else
1238     return FALSE;
1239 
1240   start_sequence ();
1241 
1242   target = noce_emit_store_flag (if_info, if_info->x, reversep, 0);
1243   if (target)
1244     {
1245       if (target != if_info->x)
1246           noce_emit_move_insn (if_info->x, target);
1247 
1248       seq = end_ifcvt_sequence (if_info);
1249       if (! seq)
1250           return FALSE;
1251 
1252       emit_insn_before_setloc (seq, if_info->jump,
1253                                      INSN_LOCATION (if_info->insn_a));
1254       if_info->transform_name = "noce_try_store_flag";
1255       return TRUE;
1256     }
1257   else
1258     {
1259       end_sequence ();
1260       return FALSE;
1261     }
1262 }
1263 
1264 
1265 /* Convert "if (test) x = -A; else x = A" into
1266    x = A; if (test) x = -x if the machine can do the
1267    conditional negate form of this cheaply.
1268    Try this before noce_try_cmove that will just load the
1269    immediates into two registers and do a conditional select
1270    between them.  If the target has a conditional negate or
1271    conditional invert operation we can save a potentially
1272    expensive constant synthesis.  */
1273 
1274 static bool
noce_try_inverse_constants(struct noce_if_info * if_info)1275 noce_try_inverse_constants (struct noce_if_info *if_info)
1276 {
1277   if (!noce_simple_bbs (if_info))
1278     return false;
1279 
1280   if (!CONST_INT_P (if_info->a)
1281       || !CONST_INT_P (if_info->b)
1282       || !REG_P (if_info->x))
1283     return false;
1284 
1285   machine_mode mode = GET_MODE (if_info->x);
1286 
1287   HOST_WIDE_INT val_a = INTVAL (if_info->a);
1288   HOST_WIDE_INT val_b = INTVAL (if_info->b);
1289 
1290   rtx cond = if_info->cond;
1291 
1292   rtx x = if_info->x;
1293   rtx target;
1294 
1295   start_sequence ();
1296 
1297   rtx_code code;
1298   if (val_b != HOST_WIDE_INT_MIN && val_a == -val_b)
1299     code = NEG;
1300   else if (val_a == ~val_b)
1301     code = NOT;
1302   else
1303     {
1304       end_sequence ();
1305       return false;
1306     }
1307 
1308   rtx tmp = gen_reg_rtx (mode);
1309   noce_emit_move_insn (tmp, if_info->a);
1310 
1311   target = emit_conditional_neg_or_complement (x, code, mode, cond, tmp, tmp);
1312 
1313   if (target)
1314     {
1315       rtx_insn *seq = get_insns ();
1316 
1317       if (!seq)
1318           {
1319             end_sequence ();
1320             return false;
1321           }
1322 
1323       if (target != if_info->x)
1324           noce_emit_move_insn (if_info->x, target);
1325 
1326       seq = end_ifcvt_sequence (if_info);
1327 
1328       if (!seq)
1329           return false;
1330 
1331       emit_insn_before_setloc (seq, if_info->jump,
1332                                      INSN_LOCATION (if_info->insn_a));
1333       if_info->transform_name = "noce_try_inverse_constants";
1334       return true;
1335     }
1336 
1337   end_sequence ();
1338   return false;
1339 }
1340 
1341 
1342 /* Convert "if (test) x = a; else x = b", for A and B constant.
1343    Also allow A = y + c1, B = y + c2, with a common y between A
1344    and B.  */
1345 
1346 static int
noce_try_store_flag_constants(struct noce_if_info * if_info)1347 noce_try_store_flag_constants (struct noce_if_info *if_info)
1348 {
1349   rtx target;
1350   rtx_insn *seq;
1351   bool reversep;
1352   HOST_WIDE_INT itrue, ifalse, diff, tmp;
1353   int normalize;
1354   bool can_reverse;
1355   machine_mode mode = GET_MODE (if_info->x);
1356   rtx common = NULL_RTX;
1357 
1358   rtx a = if_info->a;
1359   rtx b = if_info->b;
1360 
1361   /* Handle cases like x := test ? y + 3 : y + 4.  */
1362   if (GET_CODE (a) == PLUS
1363       && GET_CODE (b) == PLUS
1364       && CONST_INT_P (XEXP (a, 1))
1365       && CONST_INT_P (XEXP (b, 1))
1366       && rtx_equal_p (XEXP (a, 0), XEXP (b, 0))
1367       /* Allow expressions that are not using the result or plain
1368          registers where we handle overlap below.  */
1369       && (REG_P (XEXP (a, 0))
1370             || (noce_operand_ok (XEXP (a, 0))
1371                 && ! reg_overlap_mentioned_p (if_info->x, XEXP (a, 0)))))
1372     {
1373       common = XEXP (a, 0);
1374       a = XEXP (a, 1);
1375       b = XEXP (b, 1);
1376     }
1377 
1378   if (!noce_simple_bbs (if_info))
1379     return FALSE;
1380 
1381   if (CONST_INT_P (a)
1382       && CONST_INT_P (b))
1383     {
1384       ifalse = INTVAL (a);
1385       itrue = INTVAL (b);
1386       bool subtract_flag_p = false;
1387 
1388       diff = (unsigned HOST_WIDE_INT) itrue - ifalse;
1389       /* Make sure we can represent the difference between the two values.  */
1390       if ((diff > 0)
1391             != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue))
1392           return FALSE;
1393 
1394       diff = trunc_int_for_mode (diff, mode);
1395 
1396       can_reverse = noce_reversed_cond_code (if_info) != UNKNOWN;
1397       reversep = false;
1398       if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
1399           {
1400             normalize = 0;
1401             /* We could collapse these cases but it is easier to follow the
1402                diff/STORE_FLAG_VALUE combinations when they are listed
1403                explicitly.  */
1404 
1405             /* test ? 3 : 4
1406                => 4 + (test != 0).  */
1407             if (diff < 0 && STORE_FLAG_VALUE < 0)
1408                 reversep = false;
1409             /* test ? 4 : 3
1410                => can_reverse  | 4 + (test == 0)
1411                     !can_reverse | 3 - (test != 0).  */
1412             else if (diff > 0 && STORE_FLAG_VALUE < 0)
1413               {
1414                 reversep = can_reverse;
1415                 subtract_flag_p = !can_reverse;
1416                 /* If we need to subtract the flag and we have PLUS-immediate
1417                      A and B then it is unlikely to be beneficial to play tricks
1418                      here.  */
1419                 if (subtract_flag_p && common)
1420                     return FALSE;
1421               }
1422             /* test ? 3 : 4
1423                => can_reverse  | 3 + (test == 0)
1424                     !can_reverse | 4 - (test != 0).  */
1425             else if (diff < 0 && STORE_FLAG_VALUE > 0)
1426               {
1427                 reversep = can_reverse;
1428                 subtract_flag_p = !can_reverse;
1429                 /* If we need to subtract the flag and we have PLUS-immediate
1430                      A and B then it is unlikely to be beneficial to play tricks
1431                      here.  */
1432                 if (subtract_flag_p && common)
1433                     return FALSE;
1434               }
1435             /* test ? 4 : 3
1436                => 4 + (test != 0).  */
1437             else if (diff > 0 && STORE_FLAG_VALUE > 0)
1438               reversep = false;
1439             else
1440               gcc_unreachable ();
1441           }
1442       /* Is this (cond) ? 2^n : 0?  */
1443       else if (ifalse == 0 && pow2p_hwi (itrue)
1444                  && STORE_FLAG_VALUE == 1)
1445           normalize = 1;
1446       /* Is this (cond) ? 0 : 2^n?  */
1447       else if (itrue == 0 && pow2p_hwi (ifalse) && can_reverse
1448                  && STORE_FLAG_VALUE == 1)
1449           {
1450             normalize = 1;
1451             reversep = true;
1452           }
1453       /* Is this (cond) ? -1 : x?  */
1454       else if (itrue == -1
1455                  && STORE_FLAG_VALUE == -1)
1456           normalize = -1;
1457       /* Is this (cond) ? x : -1?  */
1458       else if (ifalse == -1 && can_reverse
1459                  && STORE_FLAG_VALUE == -1)
1460           {
1461             normalize = -1;
1462             reversep = true;
1463           }
1464       else
1465           return FALSE;
1466 
1467       if (reversep)
1468           {
1469             std::swap (itrue, ifalse);
1470             diff = trunc_int_for_mode (-(unsigned HOST_WIDE_INT) diff, mode);
1471           }
1472 
1473       start_sequence ();
1474 
1475       /* If we have x := test ? x + 3 : x + 4 then move the original
1476            x out of the way while we store flags.  */
1477       if (common && rtx_equal_p (common, if_info->x))
1478           {
1479             common = gen_reg_rtx (mode);
1480             noce_emit_move_insn (common, if_info->x);
1481           }
1482 
1483       target = noce_emit_store_flag (if_info, if_info->x, reversep, normalize);
1484       if (! target)
1485           {
1486             end_sequence ();
1487             return FALSE;
1488           }
1489 
1490       /* if (test) x = 3; else x = 4;
1491            =>   x = 3 + (test == 0);  */
1492       if (diff == STORE_FLAG_VALUE || diff == -STORE_FLAG_VALUE)
1493           {
1494             /* Add the common part now.  This may allow combine to merge this
1495                with the store flag operation earlier into some sort of conditional
1496                increment/decrement if the target allows it.  */
1497             if (common)
1498               target = expand_simple_binop (mode, PLUS,
1499                                                      target, common,
1500                                                      target, 0, OPTAB_WIDEN);
1501 
1502             /* Always use ifalse here.  It should have been swapped with itrue
1503                when appropriate when reversep is true.  */
1504             target = expand_simple_binop (mode, subtract_flag_p ? MINUS : PLUS,
1505                                                   gen_int_mode (ifalse, mode), target,
1506                                                   if_info->x, 0, OPTAB_WIDEN);
1507           }
1508       /* Other cases are not beneficial when the original A and B are PLUS
1509            expressions.  */
1510       else if (common)
1511           {
1512             end_sequence ();
1513             return FALSE;
1514           }
1515       /* if (test) x = 8; else x = 0;
1516            =>   x = (test != 0) << 3;  */
1517       else if (ifalse == 0 && (tmp = exact_log2 (itrue)) >= 0)
1518           {
1519             target = expand_simple_binop (mode, ASHIFT,
1520                                                   target, GEN_INT (tmp), if_info->x, 0,
1521                                                   OPTAB_WIDEN);
1522           }
1523 
1524       /* if (test) x = -1; else x = b;
1525            =>   x = -(test != 0) | b;  */
1526       else if (itrue == -1)
1527           {
1528             target = expand_simple_binop (mode, IOR,
1529                                                   target, gen_int_mode (ifalse, mode),
1530                                                   if_info->x, 0, OPTAB_WIDEN);
1531           }
1532       else
1533           {
1534             end_sequence ();
1535             return FALSE;
1536           }
1537 
1538       if (! target)
1539           {
1540             end_sequence ();
1541             return FALSE;
1542           }
1543 
1544       if (target != if_info->x)
1545           noce_emit_move_insn (if_info->x, target);
1546 
1547       seq = end_ifcvt_sequence (if_info);
1548       if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
1549           return FALSE;
1550 
1551       emit_insn_before_setloc (seq, if_info->jump,
1552                                      INSN_LOCATION (if_info->insn_a));
1553       if_info->transform_name = "noce_try_store_flag_constants";
1554 
1555       return TRUE;
1556     }
1557 
1558   return FALSE;
1559 }
1560 
1561 /* Convert "if (test) foo++" into "foo += (test != 0)", and
1562    similarly for "foo--".  */
1563 
1564 static int
noce_try_addcc(struct noce_if_info * if_info)1565 noce_try_addcc (struct noce_if_info *if_info)
1566 {
1567   rtx target;
1568   rtx_insn *seq;
1569   int subtract, normalize;
1570 
1571   if (!noce_simple_bbs (if_info))
1572     return FALSE;
1573 
1574   if (GET_CODE (if_info->a) == PLUS
1575       && rtx_equal_p (XEXP (if_info->a, 0), if_info->b)
1576       && noce_reversed_cond_code (if_info) != UNKNOWN)
1577     {
1578       rtx cond = if_info->rev_cond;
1579       enum rtx_code code;
1580 
1581       if (cond == NULL_RTX)
1582           {
1583             cond = if_info->cond;
1584             code = reversed_comparison_code (cond, if_info->jump);
1585           }
1586       else
1587           code = GET_CODE (cond);
1588 
1589       /* First try to use addcc pattern.  */
1590       if (general_operand (XEXP (cond, 0), VOIDmode)
1591             && general_operand (XEXP (cond, 1), VOIDmode))
1592           {
1593             start_sequence ();
1594             target = emit_conditional_add (if_info->x, code,
1595                                                    XEXP (cond, 0),
1596                                                    XEXP (cond, 1),
1597                                                    VOIDmode,
1598                                                    if_info->b,
1599                                                    XEXP (if_info->a, 1),
1600                                                    GET_MODE (if_info->x),
1601                                                    (code == LTU || code == GEU
1602                                                     || code == LEU || code == GTU));
1603             if (target)
1604               {
1605                 if (target != if_info->x)
1606                     noce_emit_move_insn (if_info->x, target);
1607 
1608                 seq = end_ifcvt_sequence (if_info);
1609                 if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
1610                     return FALSE;
1611 
1612                 emit_insn_before_setloc (seq, if_info->jump,
1613                                                INSN_LOCATION (if_info->insn_a));
1614                 if_info->transform_name = "noce_try_addcc";
1615 
1616                 return TRUE;
1617               }
1618             end_sequence ();
1619           }
1620 
1621       /* If that fails, construct conditional increment or decrement using
1622            setcc.  We're changing a branch and an increment to a comparison and
1623            an ADD/SUB.  */
1624       if (XEXP (if_info->a, 1) == const1_rtx
1625             || XEXP (if_info->a, 1) == constm1_rtx)
1626         {
1627             start_sequence ();
1628             if (STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
1629               subtract = 0, normalize = 0;
1630             else if (-STORE_FLAG_VALUE == INTVAL (XEXP (if_info->a, 1)))
1631               subtract = 1, normalize = 0;
1632             else
1633               subtract = 0, normalize = INTVAL (XEXP (if_info->a, 1));
1634 
1635 
1636             target = noce_emit_store_flag (if_info,
1637                                                    gen_reg_rtx (GET_MODE (if_info->x)),
1638                                                    1, normalize);
1639 
1640             if (target)
1641               target = expand_simple_binop (GET_MODE (if_info->x),
1642                                                     subtract ? MINUS : PLUS,
1643                                                     if_info->b, target, if_info->x,
1644                                                     0, OPTAB_WIDEN);
1645             if (target)
1646               {
1647                 if (target != if_info->x)
1648                     noce_emit_move_insn (if_info->x, target);
1649 
1650                 seq = end_ifcvt_sequence (if_info);
1651                 if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
1652                     return FALSE;
1653 
1654                 emit_insn_before_setloc (seq, if_info->jump,
1655                                                INSN_LOCATION (if_info->insn_a));
1656                 if_info->transform_name = "noce_try_addcc";
1657                 return TRUE;
1658               }
1659             end_sequence ();
1660           }
1661     }
1662 
1663   return FALSE;
1664 }
1665 
1666 /* Convert "if (test) x = 0;" to "x &= -(test == 0);"  */
1667 
1668 static int
noce_try_store_flag_mask(struct noce_if_info * if_info)1669 noce_try_store_flag_mask (struct noce_if_info *if_info)
1670 {
1671   rtx target;
1672   rtx_insn *seq;
1673   int reversep;
1674 
1675   if (!noce_simple_bbs (if_info))
1676     return FALSE;
1677 
1678   reversep = 0;
1679 
1680   if ((if_info->a == const0_rtx
1681        && (REG_P (if_info->b) || rtx_equal_p (if_info->b, if_info->x)))
1682       || ((reversep = (noce_reversed_cond_code (if_info) != UNKNOWN))
1683             && if_info->b == const0_rtx
1684             && (REG_P (if_info->a) || rtx_equal_p (if_info->a, if_info->x))))
1685     {
1686       start_sequence ();
1687       target = noce_emit_store_flag (if_info,
1688                                              gen_reg_rtx (GET_MODE (if_info->x)),
1689                                              reversep, -1);
1690       if (target)
1691         target = expand_simple_binop (GET_MODE (if_info->x), AND,
1692                                               reversep ? if_info->a : if_info->b,
1693                                               target, if_info->x, 0,
1694                                               OPTAB_WIDEN);
1695 
1696       if (target)
1697           {
1698             if (target != if_info->x)
1699               noce_emit_move_insn (if_info->x, target);
1700 
1701             seq = end_ifcvt_sequence (if_info);
1702             if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
1703               return FALSE;
1704 
1705             emit_insn_before_setloc (seq, if_info->jump,
1706                                            INSN_LOCATION (if_info->insn_a));
1707             if_info->transform_name = "noce_try_store_flag_mask";
1708 
1709             return TRUE;
1710           }
1711 
1712       end_sequence ();
1713     }
1714 
1715   return FALSE;
1716 }
1717 
1718 /* Helper function for noce_try_cmove and noce_try_cmove_arith.  */
1719 
1720 static rtx
noce_emit_cmove(struct noce_if_info * if_info,rtx x,enum rtx_code code,rtx cmp_a,rtx cmp_b,rtx vfalse,rtx vtrue,rtx cc_cmp,rtx rev_cc_cmp)1721 noce_emit_cmove (struct noce_if_info *if_info, rtx x, enum rtx_code code,
1722                      rtx cmp_a, rtx cmp_b, rtx vfalse, rtx vtrue, rtx cc_cmp,
1723                      rtx rev_cc_cmp)
1724 {
1725   rtx target ATTRIBUTE_UNUSED;
1726   int unsignedp ATTRIBUTE_UNUSED;
1727 
1728   /* If earliest == jump, try to build the cmove insn directly.
1729      This is helpful when combine has created some complex condition
1730      (like for alpha's cmovlbs) that we can't hope to regenerate
1731      through the normal interface.  */
1732 
1733   if (if_info->cond_earliest == if_info->jump)
1734     {
1735       rtx cond = gen_rtx_fmt_ee (code, GET_MODE (if_info->cond), cmp_a, cmp_b);
1736       rtx if_then_else = gen_rtx_IF_THEN_ELSE (GET_MODE (x),
1737                                                          cond, vtrue, vfalse);
1738       rtx set = gen_rtx_SET (x, if_then_else);
1739 
1740       start_sequence ();
1741       rtx_insn *insn = emit_insn (set);
1742 
1743       if (recog_memoized (insn) >= 0)
1744           {
1745             rtx_insn *seq = get_insns ();
1746             end_sequence ();
1747             emit_insn (seq);
1748 
1749             return x;
1750           }
1751 
1752       end_sequence ();
1753     }
1754 
1755   unsignedp = (code == LTU || code == GEU
1756                  || code == LEU || code == GTU);
1757 
1758   if (cc_cmp != NULL_RTX && rev_cc_cmp != NULL_RTX)
1759     target = emit_conditional_move (x, cc_cmp, rev_cc_cmp,
1760                                             vtrue, vfalse, GET_MODE (x));
1761   else
1762     {
1763       /* Don't even try if the comparison operands are weird
1764            except that the target supports cbranchcc4.  */
1765       if (! general_operand (cmp_a, GET_MODE (cmp_a))
1766             || ! general_operand (cmp_b, GET_MODE (cmp_b)))
1767           {
1768             if (!have_cbranchcc4
1769                 || GET_MODE_CLASS (GET_MODE (cmp_a)) != MODE_CC
1770                 || cmp_b != const0_rtx)
1771               return NULL_RTX;
1772           }
1773 
1774       target = emit_conditional_move (x, { code, cmp_a, cmp_b, VOIDmode },
1775                                               vtrue, vfalse, GET_MODE (x),
1776                                               unsignedp);
1777     }
1778 
1779   if (target)
1780     return target;
1781 
1782   /* We might be faced with a situation like:
1783 
1784      x = (reg:M TARGET)
1785      vtrue = (subreg:M (reg:N VTRUE) BYTE)
1786      vfalse = (subreg:M (reg:N VFALSE) BYTE)
1787 
1788      We can't do a conditional move in mode M, but it's possible that we
1789      could do a conditional move in mode N instead and take a subreg of
1790      the result.
1791 
1792      If we can't create new pseudos, though, don't bother.  */
1793   if (reload_completed)
1794     return NULL_RTX;
1795 
1796   if (GET_CODE (vtrue) == SUBREG && GET_CODE (vfalse) == SUBREG)
1797     {
1798       rtx reg_vtrue = SUBREG_REG (vtrue);
1799       rtx reg_vfalse = SUBREG_REG (vfalse);
1800       poly_uint64 byte_vtrue = SUBREG_BYTE (vtrue);
1801       poly_uint64 byte_vfalse = SUBREG_BYTE (vfalse);
1802       rtx promoted_target;
1803 
1804       if (GET_MODE (reg_vtrue) != GET_MODE (reg_vfalse)
1805             || maybe_ne (byte_vtrue, byte_vfalse)
1806             || (SUBREG_PROMOTED_VAR_P (vtrue)
1807                 != SUBREG_PROMOTED_VAR_P (vfalse))
1808             || (SUBREG_PROMOTED_GET (vtrue)
1809                 != SUBREG_PROMOTED_GET (vfalse)))
1810           return NULL_RTX;
1811 
1812       promoted_target = gen_reg_rtx (GET_MODE (reg_vtrue));
1813 
1814       target = emit_conditional_move (promoted_target,
1815                                               { code, cmp_a, cmp_b, VOIDmode },
1816                                               reg_vtrue, reg_vfalse,
1817                                               GET_MODE (reg_vtrue), unsignedp);
1818       /* Nope, couldn't do it in that mode either.  */
1819       if (!target)
1820           return NULL_RTX;
1821 
1822       target = gen_rtx_SUBREG (GET_MODE (vtrue), promoted_target, byte_vtrue);
1823       SUBREG_PROMOTED_VAR_P (target) = SUBREG_PROMOTED_VAR_P (vtrue);
1824       SUBREG_PROMOTED_SET (target, SUBREG_PROMOTED_GET (vtrue));
1825       emit_move_insn (x, target);
1826       return x;
1827     }
1828   else
1829     return NULL_RTX;
1830 }
1831 
1832 /* Try only simple constants and registers here.  More complex cases
1833    are handled in noce_try_cmove_arith after noce_try_store_flag_arith
1834    has had a go at it.  */
1835 
1836 static int
noce_try_cmove(struct noce_if_info * if_info)1837 noce_try_cmove (struct noce_if_info *if_info)
1838 {
1839   enum rtx_code code;
1840   rtx target;
1841   rtx_insn *seq;
1842 
1843   if (!noce_simple_bbs (if_info))
1844     return FALSE;
1845 
1846   if ((CONSTANT_P (if_info->a) || register_operand (if_info->a, VOIDmode))
1847       && (CONSTANT_P (if_info->b) || register_operand (if_info->b, VOIDmode)))
1848     {
1849       start_sequence ();
1850 
1851       code = GET_CODE (if_info->cond);
1852       target = noce_emit_cmove (if_info, if_info->x, code,
1853                                         XEXP (if_info->cond, 0),
1854                                         XEXP (if_info->cond, 1),
1855                                         if_info->a, if_info->b);
1856 
1857       if (target)
1858           {
1859             if (target != if_info->x)
1860               noce_emit_move_insn (if_info->x, target);
1861 
1862             seq = end_ifcvt_sequence (if_info);
1863             if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
1864               return FALSE;
1865 
1866             emit_insn_before_setloc (seq, if_info->jump,
1867                                            INSN_LOCATION (if_info->insn_a));
1868             if_info->transform_name = "noce_try_cmove";
1869 
1870             return TRUE;
1871           }
1872       /* If both a and b are constants try a last-ditch transformation:
1873            if (test) x = a; else x = b;
1874            =>   x = (-(test != 0) & (b - a)) + a;
1875            Try this only if the target-specific expansion above has failed.
1876            The target-specific expander may want to generate sequences that
1877            we don't know about, so give them a chance before trying this
1878            approach.  */
1879       else if (!targetm.have_conditional_execution ()
1880                     && CONST_INT_P (if_info->a) && CONST_INT_P (if_info->b))
1881           {
1882             machine_mode mode = GET_MODE (if_info->x);
1883             HOST_WIDE_INT ifalse = INTVAL (if_info->a);
1884             HOST_WIDE_INT itrue = INTVAL (if_info->b);
1885             rtx target = noce_emit_store_flag (if_info, if_info->x, false, -1);
1886             if (!target)
1887               {
1888                 end_sequence ();
1889                 return FALSE;
1890               }
1891 
1892             HOST_WIDE_INT diff = (unsigned HOST_WIDE_INT) itrue - ifalse;
1893             /* Make sure we can represent the difference
1894                between the two values.  */
1895             if ((diff > 0)
1896                 != ((ifalse < 0) != (itrue < 0) ? ifalse < 0 : ifalse < itrue))
1897               {
1898                 end_sequence ();
1899                 return FALSE;
1900               }
1901 
1902             diff = trunc_int_for_mode (diff, mode);
1903             target = expand_simple_binop (mode, AND,
1904                                                   target, gen_int_mode (diff, mode),
1905                                                   if_info->x, 0, OPTAB_WIDEN);
1906             if (target)
1907               target = expand_simple_binop (mode, PLUS,
1908                                                     target, gen_int_mode (ifalse, mode),
1909                                                     if_info->x, 0, OPTAB_WIDEN);
1910             if (target)
1911               {
1912                 if (target != if_info->x)
1913                     noce_emit_move_insn (if_info->x, target);
1914 
1915                 seq = end_ifcvt_sequence (if_info);
1916                 if (!seq || !targetm.noce_conversion_profitable_p (seq, if_info))
1917                     return FALSE;
1918 
1919                 emit_insn_before_setloc (seq, if_info->jump,
1920                                            INSN_LOCATION (if_info->insn_a));
1921                 if_info->transform_name = "noce_try_cmove";
1922                 return TRUE;
1923               }
1924             else
1925               {
1926                 end_sequence ();
1927                 return FALSE;
1928               }
1929           }
1930       else
1931           end_sequence ();
1932     }
1933 
1934   return FALSE;
1935 }
1936 
1937 /* Return true if X contains a conditional code mode rtx.  */
1938 
1939 static bool
contains_ccmode_rtx_p(rtx x)1940 contains_ccmode_rtx_p (rtx x)
1941 {
1942   subrtx_iterator::array_type array;
1943   FOR_EACH_SUBRTX (iter, array, x, ALL)
1944     if (GET_MODE_CLASS (GET_MODE (*iter)) == MODE_CC)
1945       return true;
1946 
1947   return false;
1948 }
1949 
1950 /* Helper for bb_valid_for_noce_process_p.  Validate that
1951    the rtx insn INSN is a single set that does not set
1952    the conditional register CC and is in general valid for
1953    if-conversion.  */
1954 
1955 static bool
insn_valid_noce_process_p(rtx_insn * insn,rtx cc)1956 insn_valid_noce_process_p (rtx_insn *insn, rtx cc)
1957 {
1958   if (!insn
1959       || !NONJUMP_INSN_P (insn)
1960       || (cc && set_of (cc, insn)))
1961       return false;
1962 
1963   rtx sset = single_set (insn);
1964 
1965   /* Currently support only simple single sets in test_bb.  */
1966   if (!sset
1967       || !noce_operand_ok (SET_DEST (sset))
1968       || contains_ccmode_rtx_p (SET_DEST (sset))
1969       || !noce_operand_ok (SET_SRC (sset)))
1970     return false;
1971 
1972   return true;
1973 }
1974 
1975 
1976 /* Return true iff the registers that the insns in BB_A set do not get
1977    used in BB_B.  If TO_RENAME is non-NULL then it is a location that will be
1978    renamed later by the caller and so conflicts on it should be ignored
1979    in this function.  */
1980 
1981 static bool
bbs_ok_for_cmove_arith(basic_block bb_a,basic_block bb_b,rtx to_rename)1982 bbs_ok_for_cmove_arith (basic_block bb_a, basic_block bb_b, rtx to_rename)
1983 {
1984   rtx_insn *a_insn;
1985   bitmap bba_sets = BITMAP_ALLOC (&reg_obstack);
1986 
1987   df_ref def;
1988   df_ref use;
1989 
1990   FOR_BB_INSNS (bb_a, a_insn)
1991     {
1992       if (!active_insn_p (a_insn))
1993           continue;
1994 
1995       rtx sset_a = single_set (a_insn);
1996 
1997       if (!sset_a)
1998           {
1999             BITMAP_FREE (bba_sets);
2000             return false;
2001           }
2002       /* Record all registers that BB_A sets.  */
2003       FOR_EACH_INSN_DEF (def, a_insn)
2004           if (!(to_rename && DF_REF_REG (def) == to_rename))
2005             bitmap_set_bit (bba_sets, DF_REF_REGNO (def));
2006     }
2007 
2008   rtx_insn *b_insn;
2009 
2010   FOR_BB_INSNS (bb_b, b_insn)
2011     {
2012       if (!active_insn_p (b_insn))
2013           continue;
2014 
2015       rtx sset_b = single_set (b_insn);
2016 
2017       if (!sset_b)
2018           {
2019             BITMAP_FREE (bba_sets);
2020             return false;
2021           }
2022 
2023       /* Make sure this is a REG and not some instance
2024            of ZERO_EXTRACT or SUBREG or other dangerous stuff.
2025            If we have a memory destination then we have a pair of simple
2026            basic blocks performing an operation of the form [addr] = c ? a : b.
2027            bb_valid_for_noce_process_p will have ensured that these are
2028            the only stores present.  In that case [addr] should be the location
2029            to be renamed.  Assert that the callers set this up properly.  */
2030       if (MEM_P (SET_DEST (sset_b)))
2031           gcc_assert (rtx_equal_p (SET_DEST (sset_b), to_rename));
2032       else if (!REG_P (SET_DEST (sset_b)))
2033           {
2034             BITMAP_FREE (bba_sets);
2035             return false;
2036           }
2037 
2038       /* If the insn uses a reg set in BB_A return false.  */
2039       FOR_EACH_INSN_USE (use, b_insn)
2040           {
2041             if (bitmap_bit_p (bba_sets, DF_REF_REGNO (use)))
2042               {
2043                 BITMAP_FREE (bba_sets);
2044                 return false;
2045               }
2046           }
2047 
2048     }
2049 
2050   BITMAP_FREE (bba_sets);
2051   return true;
2052 }
2053 
2054 /* Emit copies of all the active instructions in BB except the last.
2055    This is a helper for noce_try_cmove_arith.  */
2056 
2057 static void
noce_emit_all_but_last(basic_block bb)2058 noce_emit_all_but_last (basic_block bb)
2059 {
2060   rtx_insn *last = last_active_insn (bb, FALSE);
2061   rtx_insn *insn;
2062   FOR_BB_INSNS (bb, insn)
2063     {
2064       if (insn != last && active_insn_p (insn))
2065           {
2066             rtx_insn *to_emit = as_a <rtx_insn *> (copy_rtx (insn));
2067 
2068             emit_insn (PATTERN (to_emit));
2069           }
2070     }
2071 }
2072 
2073 /* Helper for noce_try_cmove_arith.  Emit the pattern TO_EMIT and return
2074    the resulting insn or NULL if it's not a valid insn.  */
2075 
2076 static rtx_insn *
noce_emit_insn(rtx to_emit)2077 noce_emit_insn (rtx to_emit)
2078 {
2079   gcc_assert (to_emit);
2080   rtx_insn *insn = emit_insn (to_emit);
2081 
2082   if (recog_memoized (insn) < 0)
2083     return NULL;
2084 
2085   return insn;
2086 }
2087 
2088 /* Helper for noce_try_cmove_arith.  Emit a copy of the insns up to
2089    and including the penultimate one in BB if it is not simple
2090    (as indicated by SIMPLE).  Then emit LAST_INSN as the last
2091    insn in the block.  The reason for that is that LAST_INSN may
2092    have been modified by the preparation in noce_try_cmove_arith.  */
2093 
2094 static bool
noce_emit_bb(rtx last_insn,basic_block bb,bool simple)2095 noce_emit_bb (rtx last_insn, basic_block bb, bool simple)
2096 {
2097   if (bb && !simple)
2098     noce_emit_all_but_last (bb);
2099 
2100   if (last_insn && !noce_emit_insn (last_insn))
2101     return false;
2102 
2103   return true;
2104 }
2105 
2106 /* Try more complex cases involving conditional_move.  */
2107 
2108 static int
noce_try_cmove_arith(struct noce_if_info * if_info)2109 noce_try_cmove_arith (struct noce_if_info *if_info)
2110 {
2111   rtx a = if_info->a;
2112   rtx b = if_info->b;
2113   rtx x = if_info->x;
2114   rtx orig_a, orig_b;
2115   rtx_insn *insn_a, *insn_b;
2116   bool a_simple = if_info->then_simple;
2117   bool b_simple = if_info->else_simple;
2118   basic_block then_bb = if_info->then_bb;
2119   basic_block else_bb = if_info->else_bb;
2120   rtx target;
2121   int is_mem = 0;
2122   enum rtx_code code;
2123   rtx cond = if_info->cond;
2124   rtx_insn *ifcvt_seq;
2125 
2126   /* A conditional move from two memory sources is equivalent to a
2127      conditional on their addresses followed by a load.  Don't do this
2128      early because it'll screw alias analysis.  Note that we've
2129      already checked for no side effects.  */
2130   if (cse_not_expected
2131       && MEM_P (a) && MEM_P (b)
2132       && MEM_ADDR_SPACE (a) == MEM_ADDR_SPACE (b))
2133     {
2134       machine_mode address_mode = get_address_mode (a);
2135 
2136       a = XEXP (a, 0);
2137       b = XEXP (b, 0);
2138       x = gen_reg_rtx (address_mode);
2139       is_mem = 1;
2140     }
2141 
2142   /* ??? We could handle this if we knew that a load from A or B could
2143      not trap or fault.  This is also true if we've already loaded
2144      from the address along the path from ENTRY.  */
2145   else if (may_trap_or_fault_p (a) || may_trap_or_fault_p (b))
2146     return FALSE;
2147 
2148   /* if (test) x = a + b; else x = c - d;
2149      => y = a + b;
2150         x = c - d;
2151           if (test)
2152             x = y;
2153   */
2154 
2155   code = GET_CODE (cond);
2156   insn_a = if_info->insn_a;
2157   insn_b = if_info->insn_b;
2158 
2159   machine_mode x_mode = GET_MODE (x);
2160 
2161   if (!can_conditionally_move_p (x_mode))
2162     return FALSE;
2163 
2164   /* Possibly rearrange operands to make things come out more natural.  */
2165   if (noce_reversed_cond_code (if_info) != UNKNOWN)
2166     {
2167       int reversep = 0;
2168       if (rtx_equal_p (b, x))
2169           reversep = 1;
2170       else if (general_operand (b, GET_MODE (b)))
2171           reversep = 1;
2172 
2173       if (reversep)
2174           {
2175             if (if_info->rev_cond)
2176               {
2177                 cond = if_info->rev_cond;
2178                 code = GET_CODE (cond);
2179               }
2180             else
2181               code = reversed_comparison_code (cond, if_info->jump);
2182             std::swap (a, b);
2183             std::swap (insn_a, insn_b);
2184             std::swap (a_simple, b_simple);
2185             std::swap (then_bb, else_bb);
2186           }
2187     }
2188 
2189   if (then_bb && else_bb
2190       && (!bbs_ok_for_cmove_arith (then_bb, else_bb,  if_info->orig_x)
2191             || !bbs_ok_for_cmove_arith (else_bb, then_bb,  if_info->orig_x)))
2192     return FALSE;
2193 
2194   start_sequence ();
2195 
2196   /* If one of the blocks is empty then the corresponding B or A value
2197      came from the test block.  The non-empty complex block that we will
2198      emit might clobber the register used by B or A, so move it to a pseudo
2199      first.  */
2200 
2201   rtx tmp_a = NULL_RTX;
2202   rtx tmp_b = NULL_RTX;
2203 
2204   if (b_simple || !else_bb)
2205     tmp_b = gen_reg_rtx (x_mode);
2206 
2207   if (a_simple || !then_bb)
2208     tmp_a = gen_reg_rtx (x_mode);
2209 
2210   orig_a = a;
2211   orig_b = b;
2212 
2213   rtx emit_a = NULL_RTX;
2214   rtx emit_b = NULL_RTX;
2215   rtx_insn *tmp_insn = NULL;
2216   bool modified_in_a = false;
2217   bool modified_in_b = false;
2218   /* If either operand is complex, load it into a register first.
2219      The best way to do this is to copy the original insn.  In this
2220      way we preserve any clobbers etc that the insn may have had.
2221      This is of course not possible in the IS_MEM case.  */
2222 
2223   if (! general_operand (a, GET_MODE (a)) || tmp_a)
2224     {
2225 
2226       if (is_mem)
2227           {
2228             rtx reg = gen_reg_rtx (GET_MODE (a));
2229             emit_a = gen_rtx_SET (reg, a);
2230           }
2231       else
2232           {
2233             if (insn_a)
2234               {
2235                 a = tmp_a ? tmp_a : gen_reg_rtx (GET_MODE (a));
2236 
2237                 rtx_insn *copy_of_a = as_a <rtx_insn *> (copy_rtx (insn_a));
2238                 rtx set = single_set (copy_of_a);
2239                 SET_DEST (set) = a;
2240 
2241                 emit_a = PATTERN (copy_of_a);
2242               }
2243             else
2244               {
2245                 rtx tmp_reg = tmp_a ? tmp_a : gen_reg_rtx (GET_MODE (a));
2246                 emit_a = gen_rtx_SET (tmp_reg, a);
2247                 a = tmp_reg;
2248               }
2249           }
2250     }
2251 
2252   if (! general_operand (b, GET_MODE (b)) || tmp_b)
2253     {
2254       if (is_mem)
2255           {
2256           rtx reg = gen_reg_rtx (GET_MODE (b));
2257             emit_b = gen_rtx_SET (reg, b);
2258           }
2259       else
2260           {
2261             if (insn_b)
2262               {
2263                 b = tmp_b ? tmp_b : gen_reg_rtx (GET_MODE (b));
2264                 rtx_insn *copy_of_b = as_a <rtx_insn *> (copy_rtx (insn_b));
2265                 rtx set = single_set (copy_of_b);
2266 
2267                 SET_DEST (set) = b;
2268                 emit_b = PATTERN (copy_of_b);
2269               }
2270             else
2271               {
2272                 rtx tmp_reg = tmp_b ? tmp_b : gen_reg_rtx (GET_MODE (b));
2273                 emit_b = gen_rtx_SET (tmp_reg, b);
2274                 b = tmp_reg;
2275               }
2276           }
2277     }
2278 
2279   modified_in_a = emit_a != NULL_RTX && modified_in_p (orig_b, emit_a);
2280   if (tmp_b && then_bb)
2281     {
2282       FOR_BB_INSNS (then_bb, tmp_insn)
2283           /* Don't check inside insn_a.  We will have changed it to emit_a
2284              with a destination that doesn't conflict.  */
2285           if (!(insn_a && tmp_insn == insn_a)
2286               && modified_in_p (orig_b, tmp_insn))
2287             {
2288               modified_in_a = true;
2289               break;
2290             }
2291 
2292     }
2293 
2294   modified_in_b = emit_b != NULL_RTX && modified_in_p (orig_a, emit_b);
2295   if (tmp_a && else_bb)
2296     {
2297       FOR_BB_INSNS (else_bb, tmp_insn)
2298       /* Don't check inside insn_b.  We will have changed it to emit_b
2299            with a destination that doesn't conflict.  */
2300       if (!(insn_b && tmp_insn == insn_b)
2301             && modified_in_p (orig_a, tmp_insn))
2302           {
2303             modified_in_b = true;
2304             break;
2305           }
2306     }
2307 
2308   /* If insn to set up A clobbers any registers B depends on, try to
2309      swap insn that sets up A with the one that sets up B.  If even
2310      that doesn't help, punt.  */
2311   if (modified_in_a && !modified_in_b)
2312     {
2313       if (!noce_emit_bb (emit_b, else_bb, b_simple))
2314           goto end_seq_and_fail;
2315 
2316       if (!noce_emit_bb (emit_a, then_bb, a_simple))
2317           goto end_seq_and_fail;
2318     }
2319   else if (!modified_in_a)
2320     {
2321       if (!noce_emit_bb (emit_a, then_bb, a_simple))
2322           goto end_seq_and_fail;
2323 
2324       if (!noce_emit_bb (emit_b, else_bb, b_simple))
2325           goto end_seq_and_fail;
2326     }
2327   else
2328     goto end_seq_and_fail;
2329 
2330   target = noce_emit_cmove (if_info, x, code, XEXP (cond, 0), XEXP (cond, 1),
2331                                   a, b);
2332 
2333   if (! target)
2334     goto end_seq_and_fail;
2335 
2336   /* If we're handling a memory for above, emit the load now.  */
2337   if (is_mem)
2338     {
2339       rtx mem = gen_rtx_MEM (GET_MODE (if_info->x), target);
2340 
2341       /* Copy over flags as appropriate.  */
2342       if (MEM_VOLATILE_P (if_info->a) || MEM_VOLATILE_P (if_info->b))
2343           MEM_VOLATILE_P (mem) = 1;
2344       if (MEM_ALIAS_SET (if_info->a) == MEM_ALIAS_SET (if_info->b))
2345           set_mem_alias_set (mem, MEM_ALIAS_SET (if_info->a));
2346       set_mem_align (mem,
2347                          MIN (MEM_ALIGN (if_info->a), MEM_ALIGN (if_info->b)));
2348 
2349       gcc_assert (MEM_ADDR_SPACE (if_info->a) == MEM_ADDR_SPACE (if_info->b));
2350       set_mem_addr_space (mem, MEM_ADDR_SPACE (if_info->a));
2351 
2352       noce_emit_move_insn (if_info->x, mem);
2353     }
2354   else if (target != x)
2355     noce_emit_move_insn (x, target);
2356 
2357   ifcvt_seq = end_ifcvt_sequence (if_info);
2358   if (!ifcvt_seq || !targetm.noce_conversion_profitable_p (ifcvt_seq, if_info))
2359     return FALSE;
2360 
2361   emit_insn_before_setloc (ifcvt_seq, if_info->jump,
2362                                  INSN_LOCATION (if_info->insn_a));
2363   if_info->transform_name = "noce_try_cmove_arith";
2364   return TRUE;
2365 
2366  end_seq_and_fail:
2367   end_sequence ();
2368   return FALSE;
2369 }
2370 
2371 /* For most cases, the simplified condition we found is the best
2372    choice, but this is not the case for the min/max/abs transforms.
2373    For these we wish to know that it is A or B in the condition.  */
2374 
2375 static rtx
noce_get_alt_condition(struct noce_if_info * if_info,rtx target,rtx_insn ** earliest)2376 noce_get_alt_condition (struct noce_if_info *if_info, rtx target,
2377                               rtx_insn **earliest)
2378 {
2379   rtx cond, set;
2380   rtx_insn *insn;
2381   int reverse;
2382 
2383   /* If target is already mentioned in the known condition, return it.  */
2384   if (reg_mentioned_p (target, if_info->cond))
2385     {
2386       *earliest = if_info->cond_earliest;
2387       return if_info->cond;
2388     }
2389 
2390   set = pc_set (if_info->jump);
2391   cond = XEXP (SET_SRC (set), 0);
2392   reverse
2393     = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
2394       && label_ref_label (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (if_info->jump);
2395   if (if_info->then_else_reversed)
2396     reverse = !reverse;
2397 
2398   /* If we're looking for a constant, try to make the conditional
2399      have that constant in it.  There are two reasons why it may
2400      not have the constant we want:
2401 
2402      1. GCC may have needed to put the constant in a register, because
2403         the target can't compare directly against that constant.  For
2404         this case, we look for a SET immediately before the comparison
2405         that puts a constant in that register.
2406 
2407      2. GCC may have canonicalized the conditional, for example
2408           replacing "if x < 4" with "if x <= 3".  We can undo that (or
2409           make equivalent types of changes) to get the constants we need
2410           if they're off by one in the right direction.  */
2411 
2412   if (CONST_INT_P (target))
2413     {
2414       enum rtx_code code = GET_CODE (if_info->cond);
2415       rtx op_a = XEXP (if_info->cond, 0);
2416       rtx op_b = XEXP (if_info->cond, 1);
2417       rtx_insn *prev_insn;
2418 
2419       /* First, look to see if we put a constant in a register.  */
2420       prev_insn = prev_nonnote_nondebug_insn (if_info->cond_earliest);
2421       if (prev_insn
2422             && BLOCK_FOR_INSN (prev_insn)
2423                == BLOCK_FOR_INSN (if_info->cond_earliest)
2424             && INSN_P (prev_insn)
2425             && GET_CODE (PATTERN (prev_insn)) == SET)
2426           {
2427             rtx src = find_reg_equal_equiv_note (prev_insn);
2428             if (!src)
2429               src = SET_SRC (PATTERN (prev_insn));
2430             if (CONST_INT_P (src))
2431               {
2432                 if (rtx_equal_p (op_a, SET_DEST (PATTERN (prev_insn))))
2433                     op_a = src;
2434                 else if (rtx_equal_p (op_b, SET_DEST (PATTERN (prev_insn))))
2435                     op_b = src;
2436 
2437                 if (CONST_INT_P (op_a))
2438                     {
2439                       std::swap (op_a, op_b);
2440                       code = swap_condition (code);
2441                     }
2442               }
2443           }
2444 
2445       /* Now, look to see if we can get the right constant by
2446            adjusting the conditional.  */
2447       if (CONST_INT_P (op_b))
2448           {
2449             HOST_WIDE_INT desired_val = INTVAL (target);
2450             HOST_WIDE_INT actual_val = INTVAL (op_b);
2451 
2452             switch (code)
2453               {
2454               case LT:
2455                 if (desired_val != HOST_WIDE_INT_MAX
2456                       && actual_val == desired_val + 1)
2457                     {
2458                       code = LE;
2459                       op_b = GEN_INT (desired_val);
2460                     }
2461                 break;
2462               case LE:
2463                 if (desired_val != HOST_WIDE_INT_MIN
2464                       && actual_val == desired_val - 1)
2465                     {
2466                       code = LT;
2467                       op_b = GEN_INT (desired_val);
2468                     }
2469                 break;
2470               case GT:
2471                 if (desired_val != HOST_WIDE_INT_MIN
2472                       && actual_val == desired_val - 1)
2473                     {
2474                       code = GE;
2475                       op_b = GEN_INT (desired_val);
2476                     }
2477                 break;
2478               case GE:
2479                 if (desired_val != HOST_WIDE_INT_MAX
2480                       && actual_val == desired_val + 1)
2481                     {
2482                       code = GT;
2483                       op_b = GEN_INT (desired_val);
2484                     }
2485                 break;
2486               default:
2487                 break;
2488               }
2489           }
2490 
2491       /* If we made any changes, generate a new conditional that is
2492            equivalent to what we started with, but has the right
2493            constants in it.  */
2494       if (code != GET_CODE (if_info->cond)
2495             || op_a != XEXP (if_info->cond, 0)
2496             || op_b != XEXP (if_info->cond, 1))
2497           {
2498             cond = gen_rtx_fmt_ee (code, GET_MODE (cond), op_a, op_b);
2499             *earliest = if_info->cond_earliest;
2500             return cond;
2501           }
2502     }
2503 
2504   cond = canonicalize_condition (if_info->jump, cond, reverse,
2505                                          earliest, target, have_cbranchcc4, true);
2506   if (! cond || ! reg_mentioned_p (target, cond))
2507     return NULL;
2508 
2509   /* We almost certainly searched back to a different place.
2510      Need to re-verify correct lifetimes.  */
2511 
2512   /* X may not be mentioned in the range (cond_earliest, jump].  */
2513   for (insn = if_info->jump; insn != *earliest; insn = PREV_INSN (insn))
2514     if (INSN_P (insn) && reg_overlap_mentioned_p (if_info->x, PATTERN (insn)))
2515       return NULL;
2516 
2517   /* A and B may not be modified in the range [cond_earliest, jump).  */
2518   for (insn = *earliest; insn != if_info->jump; insn = NEXT_INSN (insn))
2519     if (INSN_P (insn)
2520           && (modified_in_p (if_info->a, insn)
2521               || modified_in_p (if_info->b, insn)))
2522       return NULL;
2523 
2524   return cond;
2525 }
2526 
2527 /* Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc.  */
2528 
2529 static int
noce_try_minmax(struct noce_if_info * if_info)2530 noce_try_minmax (struct noce_if_info *if_info)
2531 {
2532   rtx cond, target;
2533   rtx_insn *earliest, *seq;
2534   enum rtx_code code, op;
2535   int unsignedp;
2536 
2537   if (!noce_simple_bbs (if_info))
2538     return FALSE;
2539 
2540   /* ??? Reject modes with NaNs or signed zeros since we don't know how
2541      they will be resolved with an SMIN/SMAX.  It wouldn't be too hard
2542      to get the target to tell us...  */
2543   if (HONOR_SIGNED_ZEROS (if_info->x)
2544       || HONOR_NANS (if_info->x))
2545     return FALSE;
2546 
2547   cond = noce_get_alt_condition (if_info, if_info->a, &earliest);
2548   if (!cond)
2549     return FALSE;
2550 
2551   /* Verify the condition is of the form we expect, and canonicalize
2552      the comparison code.  */
2553   code = GET_CODE (cond);
2554   if (rtx_equal_p (XEXP (cond, 0), if_info->a))
2555     {
2556       if (! rtx_equal_p (XEXP (cond, 1), if_info->b))
2557           return FALSE;
2558     }
2559   else if (rtx_equal_p (XEXP (cond, 1), if_info->a))
2560     {
2561       if (! rtx_equal_p (XEXP (cond, 0), if_info->b))
2562           return FALSE;
2563       code = swap_condition (code);
2564     }
2565   else
2566     return FALSE;
2567 
2568   /* Determine what sort of operation this is.  Note that the code is for
2569      a taken branch, so the code->operation mapping appears backwards.  */
2570   switch (code)
2571     {
2572     case LT:
2573     case LE:
2574     case UNLT:
2575     case UNLE:
2576       op = SMAX;
2577       unsignedp = 0;
2578       break;
2579     case GT:
2580     case GE:
2581     case UNGT:
2582     case UNGE:
2583       op = SMIN;
2584       unsignedp = 0;
2585       break;
2586     case LTU:
2587     case LEU:
2588       op = UMAX;
2589       unsignedp = 1;
2590       break;
2591     case GTU:
2592     case GEU:
2593       op = UMIN;
2594       unsignedp = 1;
2595       break;
2596     default:
2597       return FALSE;
2598     }
2599 
2600   start_sequence ();
2601 
2602   target = expand_simple_binop (GET_MODE (if_info->x), op,
2603                                         if_info->a, if_info->b,
2604                                         if_info->x, unsignedp, OPTAB_WIDEN);
2605   if (! target)
2606     {
2607       end_sequence ();
2608       return FALSE;
2609     }
2610   if (target != if_info->x)
2611     noce_emit_move_insn (if_info->x, target);
2612 
2613   seq = end_ifcvt_sequence (if_info);
2614   if (!seq)
2615     return FALSE;
2616 
2617   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
2618   if_info->cond = cond;
2619   if_info->cond_earliest = earliest;
2620   if_info->rev_cond = NULL_RTX;
2621   if_info->transform_name = "noce_try_minmax";
2622 
2623   return TRUE;
2624 }
2625 
2626 /* Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);",
2627    "if (a < 0) x = ~a; else x = a;" to "x = one_cmpl_abs(a);",
2628    etc.  */
2629 
2630 static int
noce_try_abs(struct noce_if_info * if_info)2631 noce_try_abs (struct noce_if_info *if_info)
2632 {
2633   rtx cond, target, a, b, c;
2634   rtx_insn *earliest, *seq;
2635   int negate;
2636   bool one_cmpl = false;
2637 
2638   if (!noce_simple_bbs (if_info))
2639     return FALSE;
2640 
2641   /* Reject modes with signed zeros.  */
2642   if (HONOR_SIGNED_ZEROS (if_info->x))
2643     return FALSE;
2644 
2645   /* Recognize A and B as constituting an ABS or NABS.  The canonical
2646      form is a branch around the negation, taken when the object is the
2647      first operand of a comparison against 0 that evaluates to true.  */
2648   a = if_info->a;
2649   b = if_info->b;
2650   if (GET_CODE (a) == NEG && rtx_equal_p (XEXP (a, 0), b))
2651     negate = 0;
2652   else if (GET_CODE (b) == NEG && rtx_equal_p (XEXP (b, 0), a))
2653     {
2654       std::swap (a, b);
2655       negate = 1;
2656     }
2657   else if (GET_CODE (a) == NOT && rtx_equal_p (XEXP (a, 0), b))
2658     {
2659       negate = 0;
2660       one_cmpl = true;
2661     }
2662   else if (GET_CODE (b) == NOT && rtx_equal_p (XEXP (b, 0), a))
2663     {
2664       std::swap (a, b);
2665       negate = 1;
2666       one_cmpl = true;
2667     }
2668   else
2669     return FALSE;
2670 
2671   cond = noce_get_alt_condition (if_info, b, &earliest);
2672   if (!cond)
2673     return FALSE;
2674 
2675   /* Verify the condition is of the form we expect.  */
2676   if (rtx_equal_p (XEXP (cond, 0), b))
2677     c = XEXP (cond, 1);
2678   else if (rtx_equal_p (XEXP (cond, 1), b))
2679     {
2680       c = XEXP (cond, 0);
2681       negate = !negate;
2682     }
2683   else
2684     return FALSE;
2685 
2686   /* Verify that C is zero.  Search one step backward for a
2687      REG_EQUAL note or a simple source if necessary.  */
2688   if (REG_P (c))
2689     {
2690       rtx set;
2691       rtx_insn *insn = prev_nonnote_nondebug_insn (earliest);
2692       if (insn
2693             && BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (earliest)
2694             && (set = single_set (insn))
2695             && rtx_equal_p (SET_DEST (set), c))
2696           {
2697             rtx note = find_reg_equal_equiv_note (insn);
2698             if (note)
2699               c = XEXP (note, 0);
2700             else
2701               c = SET_SRC (set);
2702           }
2703       else
2704           return FALSE;
2705     }
2706   if (MEM_P (c)
2707       && GET_CODE (XEXP (c, 0)) == SYMBOL_REF
2708       && CONSTANT_POOL_ADDRESS_P (XEXP (c, 0)))
2709     c = get_pool_constant (XEXP (c, 0));
2710 
2711   /* Work around funny ideas get_condition has wrt canonicalization.
2712      Note that these rtx constants are known to be CONST_INT, and
2713      therefore imply integer comparisons.
2714      The one_cmpl case is more complicated, as we want to handle
2715      only x < 0 ? ~x : x or x >= 0 ? x : ~x to one_cmpl_abs (x)
2716      and x < 0 ? x : ~x or x >= 0 ? ~x : x to ~one_cmpl_abs (x),
2717      but not other cases (x > -1 is equivalent of x >= 0).  */
2718   if (c == constm1_rtx && GET_CODE (cond) == GT)
2719     ;
2720   else if (c == const1_rtx && GET_CODE (cond) == LT)
2721     {
2722       if (one_cmpl)
2723           return FALSE;
2724     }
2725   else if (c == CONST0_RTX (GET_MODE (b)))
2726     {
2727       if (one_cmpl
2728             && GET_CODE (cond) != GE
2729             && GET_CODE (cond) != LT)
2730           return FALSE;
2731     }
2732   else
2733     return FALSE;
2734 
2735   /* Determine what sort of operation this is.  */
2736   switch (GET_CODE (cond))
2737     {
2738     case LT:
2739     case LE:
2740     case UNLT:
2741     case UNLE:
2742       negate = !negate;
2743       break;
2744     case GT:
2745     case GE:
2746     case UNGT:
2747     case UNGE:
2748       break;
2749     default:
2750       return FALSE;
2751     }
2752 
2753   start_sequence ();
2754   if (one_cmpl)
2755     target = expand_one_cmpl_abs_nojump (GET_MODE (if_info->x), b,
2756                                          if_info->x);
2757   else
2758     target = expand_abs_nojump (GET_MODE (if_info->x), b, if_info->x, 1);
2759 
2760   /* ??? It's a quandary whether cmove would be better here, especially
2761      for integers.  Perhaps combine will clean things up.  */
2762   if (target && negate)
2763     {
2764       if (one_cmpl)
2765         target = expand_simple_unop (GET_MODE (target), NOT, target,
2766                                      if_info->x, 0);
2767       else
2768         target = expand_simple_unop (GET_MODE (target), NEG, target,
2769                                      if_info->x, 0);
2770     }
2771 
2772   if (! target)
2773     {
2774       end_sequence ();
2775       return FALSE;
2776     }
2777 
2778   if (target != if_info->x)
2779     noce_emit_move_insn (if_info->x, target);
2780 
2781   seq = end_ifcvt_sequence (if_info);
2782   if (!seq)
2783     return FALSE;
2784 
2785   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
2786   if_info->cond = cond;
2787   if_info->cond_earliest = earliest;
2788   if_info->rev_cond = NULL_RTX;
2789   if_info->transform_name = "noce_try_abs";
2790 
2791   return TRUE;
2792 }
2793 
2794 /* Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;".  */
2795 
2796 static int
noce_try_sign_mask(struct noce_if_info * if_info)2797 noce_try_sign_mask (struct noce_if_info *if_info)
2798 {
2799   rtx cond, t, m, c;
2800   rtx_insn *seq;
2801   machine_mode mode;
2802   enum rtx_code code;
2803   bool t_unconditional;
2804 
2805   if (!noce_simple_bbs (if_info))
2806     return FALSE;
2807 
2808   cond = if_info->cond;
2809   code = GET_CODE (cond);
2810   m = XEXP (cond, 0);
2811   c = XEXP (cond, 1);
2812 
2813   t = NULL_RTX;
2814   if (if_info->a == const0_rtx)
2815     {
2816       if ((code == LT && c == const0_rtx)
2817             || (code == LE && c == constm1_rtx))
2818           t = if_info->b;
2819     }
2820   else if (if_info->b == const0_rtx)
2821     {
2822       if ((code == GE && c == const0_rtx)
2823             || (code == GT && c == constm1_rtx))
2824           t = if_info->a;
2825     }
2826 
2827   if (! t || side_effects_p (t))
2828     return FALSE;
2829 
2830   /* We currently don't handle different modes.  */
2831   mode = GET_MODE (t);
2832   if (GET_MODE (m) != mode)
2833     return FALSE;
2834 
2835   /* This is only profitable if T is unconditionally executed/evaluated in the
2836      original insn sequence or T is cheap and can't trap or fault.  The former
2837      happens if B is the non-zero (T) value and if INSN_B was taken from
2838      TEST_BB, or there was no INSN_B which can happen for e.g. conditional
2839      stores to memory.  For the cost computation use the block TEST_BB where
2840      the evaluation will end up after the transformation.  */
2841   t_unconditional
2842     = (t == if_info->b
2843        && (if_info->insn_b == NULL_RTX
2844              || BLOCK_FOR_INSN (if_info->insn_b) == if_info->test_bb));
2845   if (!(t_unconditional
2846           || ((set_src_cost (t, mode, if_info->speed_p)
2847                < COSTS_N_INSNS (2))
2848               && !may_trap_or_fault_p (t))))
2849     return FALSE;
2850 
2851   if (!noce_can_force_operand (t))
2852     return FALSE;
2853 
2854   start_sequence ();
2855   /* Use emit_store_flag to generate "m < 0 ? -1 : 0" instead of expanding
2856      "(signed) m >> 31" directly.  This benefits targets with specialized
2857      insns to obtain the signmask, but still uses ashr_optab otherwise.  */
2858   m = emit_store_flag (gen_reg_rtx (mode), LT, m, const0_rtx, mode, 0, -1);
2859   t = m ? expand_binop (mode, and_optab, m, t, NULL_RTX, 0, OPTAB_DIRECT)
2860           : NULL_RTX;
2861 
2862   if (!t)
2863     {
2864       end_sequence ();
2865       return FALSE;
2866     }
2867 
2868   noce_emit_move_insn (if_info->x, t);
2869 
2870   seq = end_ifcvt_sequence (if_info);
2871   if (!seq)
2872     return FALSE;
2873 
2874   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION (if_info->insn_a));
2875   if_info->transform_name = "noce_try_sign_mask";
2876 
2877   return TRUE;
2878 }
2879 
2880 
2881 /* Optimize away "if (x & C) x |= C" and similar bit manipulation
2882    transformations.  */
2883 
2884 static int
noce_try_bitop(struct noce_if_info * if_info)2885 noce_try_bitop (struct noce_if_info *if_info)
2886 {
2887   rtx cond, x, a, result;
2888   rtx_insn *seq;
2889   scalar_int_mode mode;
2890   enum rtx_code code;
2891   int bitnum;
2892 
2893   x = if_info->x;
2894   cond = if_info->cond;
2895   code = GET_CODE (cond);
2896 
2897   /* Check for an integer operation.  */
2898   if (!is_a <scalar_int_mode> (GET_MODE (x), &mode))
2899     return FALSE;
2900 
2901   if (!noce_simple_bbs (if_info))
2902     return FALSE;
2903 
2904   /* Check for no else condition.  */
2905   if (! rtx_equal_p (x, if_info->b))
2906     return FALSE;
2907 
2908   /* Check for a suitable condition.  */
2909   if (code != NE && code != EQ)
2910     return FALSE;
2911   if (XEXP (cond, 1) != const0_rtx)
2912     return FALSE;
2913   cond = XEXP (cond, 0);
2914 
2915   /* ??? We could also handle AND here.  */
2916   if (GET_CODE (cond) == ZERO_EXTRACT)
2917     {
2918       if (XEXP (cond, 1) != const1_rtx
2919             || !CONST_INT_P (XEXP (cond, 2))
2920             || ! rtx_equal_p (x, XEXP (cond, 0)))
2921           return FALSE;
2922       bitnum = INTVAL (XEXP (cond, 2));
2923       if (BITS_BIG_ENDIAN)
2924           bitnum = GET_MODE_BITSIZE (mode) - 1 - bitnum;
2925       if (bitnum < 0 || bitnum >= HOST_BITS_PER_WIDE_INT)
2926           return FALSE;
2927     }
2928   else
2929     return FALSE;
2930 
2931   a = if_info->a;
2932   if (GET_CODE (a) == IOR || GET_CODE (a) == XOR)
2933     {
2934       /* Check for "if (X & C) x = x op C".  */
2935       if (! rtx_equal_p (x, XEXP (a, 0))
2936           || !CONST_INT_P (XEXP (a, 1))
2937             || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode))
2938                != HOST_WIDE_INT_1U << bitnum)
2939         return FALSE;
2940 
2941       /* if ((x & C) == 0) x |= C; is transformed to x |= C.   */
2942       /* if ((x & C) != 0) x |= C; is transformed to nothing.  */
2943       if (GET_CODE (a) == IOR)
2944           result = (code == NE) ? a : NULL_RTX;
2945       else if (code == NE)
2946           {
2947             /* if ((x & C) == 0) x ^= C; is transformed to x |= C.   */
2948             result = gen_int_mode (HOST_WIDE_INT_1 << bitnum, mode);
2949             result = simplify_gen_binary (IOR, mode, x, result);
2950           }
2951       else
2952           {
2953             /* if ((x & C) != 0) x ^= C; is transformed to x &= ~C.  */
2954             result = gen_int_mode (~(HOST_WIDE_INT_1 << bitnum), mode);
2955             result = simplify_gen_binary (AND, mode, x, result);
2956           }
2957     }
2958   else if (GET_CODE (a) == AND)
2959     {
2960       /* Check for "if (X & C) x &= ~C".  */
2961       if (! rtx_equal_p (x, XEXP (a, 0))
2962             || !CONST_INT_P (XEXP (a, 1))
2963             || (INTVAL (XEXP (a, 1)) & GET_MODE_MASK (mode))
2964                != (~(HOST_WIDE_INT_1 << bitnum) & GET_MODE_MASK (mode)))
2965         return FALSE;
2966 
2967       /* if ((x & C) == 0) x &= ~C; is transformed to nothing.  */
2968       /* if ((x & C) != 0) x &= ~C; is transformed to x &= ~C.  */
2969       result = (code == EQ) ? a : NULL_RTX;
2970     }
2971   else
2972     return FALSE;
2973 
2974   if (result)
2975     {
2976       start_sequence ();
2977       noce_emit_move_insn (x, result);
2978       seq = end_ifcvt_sequence (if_info);
2979       if (!seq)
2980           return FALSE;
2981 
2982       emit_insn_before_setloc (seq, if_info->jump,
2983                                      INSN_LOCATION (if_info->insn_a));
2984     }
2985   if_info->transform_name = "noce_try_bitop";
2986   return TRUE;
2987 }
2988 
2989 
2990 /* Similar to get_condition, only the resulting condition must be
2991    valid at JUMP, instead of at EARLIEST.
2992 
2993    If THEN_ELSE_REVERSED is true, the fallthrough does not go to the
2994    THEN block of the caller, and we have to reverse the condition.  */
2995 
2996 static rtx
noce_get_condition(rtx_insn * jump,rtx_insn ** earliest,bool then_else_reversed)2997 noce_get_condition (rtx_insn *jump, rtx_insn **earliest, bool then_else_reversed)
2998 {
2999   rtx cond, set, tmp;
3000   bool reverse;
3001 
3002   if (! any_condjump_p (jump))
3003     return NULL_RTX;
3004 
3005   set = pc_set (jump);
3006 
3007   /* If this branches to JUMP_LABEL when the condition is false,
3008      reverse the condition.  */
3009   reverse = (GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF
3010                && label_ref_label (XEXP (SET_SRC (set), 2)) == JUMP_LABEL (jump));
3011 
3012   /* We may have to reverse because the caller's if block is not canonical,
3013      i.e. the THEN block isn't the fallthrough block for the TEST block
3014      (see find_if_header).  */
3015   if (then_else_reversed)
3016     reverse = !reverse;
3017 
3018   /* If the condition variable is a register and is MODE_INT, accept it.  */
3019 
3020   cond = XEXP (SET_SRC (set), 0);
3021   tmp = XEXP (cond, 0);
3022   if (REG_P (tmp) && GET_MODE_CLASS (GET_MODE (tmp)) == MODE_INT
3023       && (GET_MODE (tmp) != BImode
3024           || !targetm.small_register_classes_for_mode_p (BImode)))
3025     {
3026       *earliest = jump;
3027 
3028       if (reverse)
3029           cond = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond)),
3030                                      GET_MODE (cond), tmp, XEXP (cond, 1));
3031       return cond;
3032     }
3033 
3034   /* Otherwise, fall back on canonicalize_condition to do the dirty
3035      work of manipulating MODE_CC values and COMPARE rtx codes.  */
3036   tmp = canonicalize_condition (jump, cond, reverse, earliest,
3037                                         NULL_RTX, have_cbranchcc4, true);
3038 
3039   /* We don't handle side-effects in the condition, like handling
3040      REG_INC notes and making sure no duplicate conditions are emitted.  */
3041   if (tmp != NULL_RTX && side_effects_p (tmp))
3042     return NULL_RTX;
3043 
3044   return tmp;
3045 }
3046 
3047 /* Return true if OP is ok for if-then-else processing.  */
3048 
3049 static int
noce_operand_ok(const_rtx op)3050 noce_operand_ok (const_rtx op)
3051 {
3052   if (side_effects_p (op))
3053     return FALSE;
3054 
3055   /* We special-case memories, so handle any of them with
3056      no address side effects.  */
3057   if (MEM_P (op))
3058     return ! side_effects_p (XEXP (op, 0));
3059 
3060   return ! may_trap_p (op);
3061 }
3062 
3063 /* Return true iff basic block TEST_BB is valid for noce if-conversion.
3064    The condition used in this if-conversion is in COND.
3065    In practice, check that TEST_BB ends with a single set
3066    x := a and all previous computations
3067    in TEST_BB don't produce any values that are live after TEST_BB.
3068    In other words, all the insns in TEST_BB are there only
3069    to compute a value for x.  Add the rtx cost of the insns
3070    in TEST_BB to COST.  Record whether TEST_BB is a single simple
3071    set instruction in SIMPLE_P.  */
3072 
3073 static bool
bb_valid_for_noce_process_p(basic_block test_bb,rtx cond,unsigned int * cost,bool * simple_p)3074 bb_valid_for_noce_process_p (basic_block test_bb, rtx cond,
3075                                     unsigned int *cost, bool *simple_p)
3076 {
3077   if (!test_bb)
3078     return false;
3079 
3080   rtx_insn *last_insn = last_active_insn (test_bb, FALSE);
3081   rtx last_set = NULL_RTX;
3082 
3083   rtx cc = cc_in_cond (cond);
3084 
3085   if (!insn_valid_noce_process_p (last_insn, cc))
3086     return false;
3087 
3088   /* Punt on blocks ending with asm goto or jumps with other side-effects,
3089      last_active_insn ignores JUMP_INSNs.  */
3090   if (JUMP_P (BB_END (test_bb)) && !onlyjump_p (BB_END (test_bb)))
3091     return false;
3092 
3093   last_set = single_set (last_insn);
3094 
3095   rtx x = SET_DEST (last_set);
3096   rtx_insn *first_insn = first_active_insn (test_bb);
3097   rtx first_set = single_set (first_insn);
3098 
3099   if (!first_set)
3100     return false;
3101 
3102   /* We have a single simple set, that's okay.  */
3103   bool speed_p = optimize_bb_for_speed_p (test_bb);
3104 
3105   if (first_insn == last_insn)
3106     {
3107       *simple_p = noce_operand_ok (SET_DEST (first_set));
3108       *cost += pattern_cost (first_set, speed_p);
3109       return *simple_p;
3110     }
3111 
3112   rtx_insn *prev_last_insn = PREV_INSN (last_insn);
3113   gcc_assert (prev_last_insn);
3114 
3115   /* For now, disallow setting x multiple times in test_bb.  */
3116   if (REG_P (x) && reg_set_between_p (x, first_insn, prev_last_insn))
3117     return false;
3118 
3119   bitmap test_bb_temps = BITMAP_ALLOC (&reg_obstack);
3120 
3121   /* The regs that are live out of test_bb.  */
3122   bitmap test_bb_live_out = df_get_live_out (test_bb);
3123 
3124   int potential_cost = pattern_cost (last_set, speed_p);
3125   rtx_insn *insn;
3126   FOR_BB_INSNS (test_bb, insn)
3127     {
3128       if (insn != last_insn)
3129           {
3130             if (!active_insn_p (insn))
3131               continue;
3132 
3133             if (!insn_valid_noce_process_p (insn, cc))
3134               goto free_bitmap_and_fail;
3135 
3136             rtx sset = single_set (insn);
3137             gcc_assert (sset);
3138 
3139             if (contains_mem_rtx_p (SET_SRC (sset))
3140                 || !REG_P (SET_DEST (sset))
3141                 || reg_overlap_mentioned_p (SET_DEST (sset), cond))
3142               goto free_bitmap_and_fail;
3143 
3144             potential_cost += pattern_cost (sset, speed_p);
3145             bitmap_set_bit (test_bb_temps, REGNO (SET_DEST (sset)));
3146           }
3147     }
3148 
3149   /* If any of the intermediate results in test_bb are live after test_bb
3150      then fail.  */
3151   if (bitmap_intersect_p (test_bb_live_out, test_bb_temps))
3152     goto free_bitmap_and_fail;
3153 
3154   BITMAP_FREE (test_bb_temps);
3155   *cost += potential_cost;
3156   *simple_p = false;
3157   return true;
3158 
3159  free_bitmap_and_fail:
3160   BITMAP_FREE (test_bb_temps);
3161   return false;
3162 }
3163 
3164 /* Helper function to emit a cmov sequence encapsulated in
3165    start_sequence () and end_sequence ().  If NEED_CMOV is true
3166    we call noce_emit_cmove to create a cmove sequence.  Otherwise emit
3167    a simple move.  If successful, store the first instruction of the
3168    sequence in TEMP_DEST and the sequence costs in SEQ_COST.  */
3169 
3170 static rtx_insn*
try_emit_cmove_seq(struct noce_if_info * if_info,rtx temp,rtx cond,rtx new_val,rtx old_val,bool need_cmov,unsigned * cost,rtx * temp_dest,rtx cc_cmp=NULL,rtx rev_cc_cmp=NULL)3171 try_emit_cmove_seq (struct noce_if_info *if_info, rtx temp,
3172                         rtx cond, rtx new_val, rtx old_val, bool need_cmov,
3173                         unsigned *cost, rtx *temp_dest,
3174                         rtx cc_cmp = NULL, rtx rev_cc_cmp = NULL)
3175 {
3176   rtx_insn *seq = NULL;
3177   *cost = 0;
3178 
3179   rtx x = XEXP (cond, 0);
3180   rtx y = XEXP (cond, 1);
3181   rtx_code cond_code = GET_CODE (cond);
3182 
3183   start_sequence ();
3184 
3185   if (need_cmov)
3186     *temp_dest = noce_emit_cmove (if_info, temp, cond_code,
3187                                           x, y, new_val, old_val, cc_cmp, rev_cc_cmp);
3188   else
3189     {
3190       *temp_dest = temp;
3191       if (if_info->then_else_reversed)
3192           noce_emit_move_insn (temp, old_val);
3193       else
3194           noce_emit_move_insn (temp, new_val);
3195     }
3196 
3197   if (*temp_dest != NULL_RTX)
3198     {
3199       seq = get_insns ();
3200       *cost = seq_cost (seq, if_info->speed_p);
3201     }
3202 
3203   end_sequence ();
3204 
3205   return seq;
3206 }
3207 
3208 /* We have something like:
3209 
3210      if (x > y)
3211        { i = a; j = b; k = c; }
3212 
3213    Make it:
3214 
3215      tmp_i = (x > y) ? a : i;
3216      tmp_j = (x > y) ? b : j;
3217      tmp_k = (x > y) ? c : k;
3218      i = tmp_i;
3219      j = tmp_j;
3220      k = tmp_k;
3221 
3222    Subsequent passes are expected to clean up the extra moves.
3223 
3224    Look for special cases such as writes to one register which are
3225    read back in another SET, as might occur in a swap idiom or
3226    similar.
3227 
3228    These look like:
3229 
3230    if (x > y)
3231      i = a;
3232      j = i;
3233 
3234    Which we want to rewrite to:
3235 
3236      tmp_i = (x > y) ? a : i;
3237      tmp_j = (x > y) ? tmp_i : j;
3238      i = tmp_i;
3239      j = tmp_j;
3240 
3241    We can catch these when looking at (SET x y) by keeping a list of the
3242    registers we would have targeted before if-conversion and looking back
3243    through it for an overlap with Y.  If we find one, we rewire the
3244    conditional set to use the temporary we introduced earlier.
3245 
3246    IF_INFO contains the useful information about the block structure and
3247    jump instructions.  */
3248 
3249 static int
noce_convert_multiple_sets(struct noce_if_info * if_info)3250 noce_convert_multiple_sets (struct noce_if_info *if_info)
3251 {
3252   basic_block test_bb = if_info->test_bb;
3253   basic_block then_bb = if_info->then_bb;
3254   basic_block join_bb = if_info->join_bb;
3255   rtx_insn *jump = if_info->jump;
3256   rtx_insn *cond_earliest;
3257   rtx_insn *insn;
3258 
3259   start_sequence ();
3260 
3261   /* Decompose the condition attached to the jump.  */
3262   rtx cond = noce_get_condition (jump, &cond_earliest, false);
3263   rtx x = XEXP (cond, 0);
3264   rtx y = XEXP (cond, 1);
3265 
3266   /* The true targets for a conditional move.  */
3267   auto_vec<rtx> targets;
3268   /* The temporaries introduced to allow us to not consider register
3269      overlap.  */
3270   auto_vec<rtx> temporaries;
3271   /* The insns we've emitted.  */
3272   auto_vec<rtx_insn *> unmodified_insns;
3273 
3274   hash_set<rtx_insn *> need_no_cmov;
3275   hash_map<rtx_insn *, int> rewired_src;
3276 
3277   need_cmov_or_rewire (then_bb, &need_no_cmov, &rewired_src);
3278 
3279   int last_needs_comparison = -1;
3280 
3281   bool ok = noce_convert_multiple_sets_1
3282     (if_info, &need_no_cmov, &rewired_src, &targets, &temporaries,
3283      &unmodified_insns, &last_needs_comparison);
3284   if (!ok)
3285       return false;
3286 
3287   /* If there are insns that overwrite part of the initial
3288      comparison, we can still omit creating temporaries for
3289      the last of them.
3290      As the second try will always create a less expensive,
3291      valid sequence, we do not need to compare and can discard
3292      the first one.  */
3293   if (last_needs_comparison != -1)
3294     {
3295       end_sequence ();
3296       start_sequence ();
3297       ok = noce_convert_multiple_sets_1
3298           (if_info, &need_no_cmov, &rewired_src, &targets, &temporaries,
3299            &unmodified_insns, &last_needs_comparison);
3300       /* Actually we should not fail anymore if we reached here,
3301            but better still check.  */
3302       if (!ok)
3303             return false;
3304     }
3305 
3306   /* We must have seen some sort of insn to insert, otherwise we were
3307      given an empty BB to convert, and we can't handle that.  */
3308   gcc_assert (!unmodified_insns.is_empty ());
3309 
3310   /* Now fixup the assignments.  */
3311   for (unsigned i = 0; i < targets.length (); i++)
3312     if (targets[i] != temporaries[i])
3313       noce_emit_move_insn (targets[i], temporaries[i]);
3314 
3315   /* Actually emit the sequence if it isn't too expensive.  */
3316   rtx_insn *seq = get_insns ();
3317 
3318   if (!targetm.noce_conversion_profitable_p (seq, if_info))
3319     {
3320       end_sequence ();
3321       return FALSE;
3322     }
3323 
3324   for (insn = seq; insn; insn = NEXT_INSN (insn))
3325     set_used_flags (insn);
3326 
3327   /* Mark all our temporaries and targets as used.  */
3328   for (unsigned i = 0; i < targets.length (); i++)
3329     {
3330       set_used_flags (temporaries[i]);
3331       set_used_flags (targets[i]);
3332     }
3333 
3334   set_used_flags (cond);
3335   set_used_flags (x);
3336   set_used_flags (y);
3337 
3338   unshare_all_rtl_in_chain (seq);
3339   end_sequence ();
3340 
3341   if (!seq)
3342     return FALSE;
3343 
3344   for (insn = seq; insn; insn = NEXT_INSN (insn))
3345     if (JUMP_P (insn)
3346           || recog_memoized (insn) == -1)
3347       return FALSE;
3348 
3349   emit_insn_before_setloc (seq, if_info->jump,
3350                                  INSN_LOCATION (unmodified_insns.last ()));
3351 
3352   /* Clean up THEN_BB and the edges in and out of it.  */
3353   remove_edge (find_edge (test_bb, join_bb));
3354   remove_edge (find_edge (then_bb, join_bb));
3355   redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb);
3356   delete_basic_block (then_bb);
3357   num_true_changes++;
3358 
3359   /* Maybe merge blocks now the jump is simple enough.  */
3360   if (can_merge_blocks_p (test_bb, join_bb))
3361     {
3362       merge_blocks (test_bb, join_bb);
3363       num_true_changes++;
3364     }
3365 
3366   num_updated_if_blocks++;
3367   if_info->transform_name = "noce_convert_multiple_sets";
3368   return TRUE;
3369 }
3370 
3371 /* Helper function for noce_convert_multiple_sets_1.  If store to
3372    DEST can affect P[0] or P[1], clear P[0].  Called via note_stores.  */
3373 
3374 static void
check_for_cc_cmp_clobbers(rtx dest,const_rtx,void * p0)3375 check_for_cc_cmp_clobbers (rtx dest, const_rtx, void *p0)
3376 {
3377   rtx *p = (rtx *) p0;
3378   if (p[0] == NULL_RTX)
3379     return;
3380   if (reg_overlap_mentioned_p (dest, p[0])
3381       || (p[1] && reg_overlap_mentioned_p (dest, p[1])))
3382     p[0] = NULL_RTX;
3383 }
3384 
3385 /* This goes through all relevant insns of IF_INFO->then_bb and tries to
3386    create conditional moves.  In case a simple move sufficis the insn
3387    should be listed in NEED_NO_CMOV.  The rewired-src cases should be
3388    specified via REWIRED_SRC.  TARGETS, TEMPORARIES and UNMODIFIED_INSNS
3389    are specified and used in noce_convert_multiple_sets and should be passed
3390    to this function..  */
3391 
3392 static bool
noce_convert_multiple_sets_1(struct noce_if_info * if_info,hash_set<rtx_insn * > * need_no_cmov,hash_map<rtx_insn *,int> * rewired_src,auto_vec<rtx> * targets,auto_vec<rtx> * temporaries,auto_vec<rtx_insn * > * unmodified_insns,int * last_needs_comparison)3393 noce_convert_multiple_sets_1 (struct noce_if_info *if_info,
3394                                     hash_set<rtx_insn *> *need_no_cmov,
3395                                     hash_map<rtx_insn *, int> *rewired_src,
3396                                     auto_vec<rtx> *targets,
3397                                     auto_vec<rtx> *temporaries,
3398                                     auto_vec<rtx_insn *> *unmodified_insns,
3399                                     int *last_needs_comparison)
3400 {
3401   basic_block then_bb = if_info->then_bb;
3402   rtx_insn *jump = if_info->jump;
3403   rtx_insn *cond_earliest;
3404 
3405   /* Decompose the condition attached to the jump.  */
3406   rtx cond = noce_get_condition (jump, &cond_earliest, false);
3407 
3408   rtx cc_cmp = cond_exec_get_condition (jump);
3409   if (cc_cmp)
3410     cc_cmp = copy_rtx (cc_cmp);
3411   rtx rev_cc_cmp = cond_exec_get_condition (jump, /* get_reversed */ true);
3412   if (rev_cc_cmp)
3413     rev_cc_cmp = copy_rtx (rev_cc_cmp);
3414 
3415   rtx_insn *insn;
3416   int count = 0;
3417 
3418   targets->truncate (0);
3419   temporaries->truncate (0);
3420   unmodified_insns->truncate (0);
3421 
3422   bool second_try = *last_needs_comparison != -1;
3423 
3424   FOR_BB_INSNS (then_bb, insn)
3425     {
3426       /* Skip over non-insns.  */
3427       if (!active_insn_p (insn))
3428           continue;
3429 
3430       rtx set = single_set (insn);
3431       gcc_checking_assert (set);
3432 
3433       rtx target = SET_DEST (set);
3434       rtx temp;
3435 
3436       rtx new_val = SET_SRC (set);
3437       if (int *ii = rewired_src->get (insn))
3438           new_val = simplify_replace_rtx (new_val, (*targets)[*ii],
3439                                                   (*temporaries)[*ii]);
3440       rtx old_val = target;
3441 
3442       /* As we are transforming
3443            if (x > y)
3444              {
3445                a = b;
3446                c = d;
3447              }
3448            into
3449              a = (x > y) ...
3450              c = (x > y) ...
3451 
3452            we potentially check x > y before every set.
3453            Even though the check might be removed by subsequent passes, this means
3454            that we cannot transform
3455              if (x > y)
3456                {
3457                  x = y;
3458                  ...
3459                }
3460            into
3461              x = (x > y) ...
3462              ...
3463            since this would invalidate x and the following to-be-removed checks.
3464            Therefore we introduce a temporary every time we are about to
3465            overwrite a variable used in the check.  Costing of a sequence with
3466            these is going to be inaccurate so only use temporaries when
3467            needed.
3468 
3469            If performing a second try, we know how many insns require a
3470            temporary.  For the last of these, we can omit creating one.  */
3471       if (reg_overlap_mentioned_p (target, cond)
3472             && (!second_try || count < *last_needs_comparison))
3473           temp = gen_reg_rtx (GET_MODE (target));
3474       else
3475           temp = target;
3476 
3477       /* We have identified swap-style idioms before.  A normal
3478            set will need to be a cmov while the first instruction of a swap-style
3479            idiom can be a regular move.  This helps with costing.  */
3480       bool need_cmov = !need_no_cmov->contains (insn);
3481 
3482       /* If we had a non-canonical conditional jump (i.e. one where
3483            the fallthrough is to the "else" case) we need to reverse
3484            the conditional select.  */
3485       if (if_info->then_else_reversed)
3486           std::swap (old_val, new_val);
3487 
3488 
3489       /* We allow simple lowpart register subreg SET sources in
3490            bb_ok_for_noce_convert_multiple_sets.  Be careful when processing
3491            sequences like:
3492            (set (reg:SI r1) (reg:SI r2))
3493            (set (reg:HI r3) (subreg:HI (r1)))
3494            For the second insn new_val or old_val (r1 in this example) will be
3495            taken from the temporaries and have the wider mode which will not
3496            match with the mode of the other source of the conditional move, so
3497            we'll end up trying to emit r4:HI = cond ? (r1:SI) : (r3:HI).
3498            Wrap the two cmove operands into subregs if appropriate to prevent
3499            that.  */
3500 
3501       if (!CONSTANT_P (new_val)
3502             && GET_MODE (new_val) != GET_MODE (temp))
3503           {
3504             machine_mode src_mode = GET_MODE (new_val);
3505             machine_mode dst_mode = GET_MODE (temp);
3506             if (!partial_subreg_p (dst_mode, src_mode))
3507               {
3508                 end_sequence ();
3509                 return FALSE;
3510               }
3511             new_val = lowpart_subreg (dst_mode, new_val, src_mode);
3512           }
3513       if (!CONSTANT_P (old_val)
3514             && GET_MODE (old_val) != GET_MODE (temp))
3515           {
3516             machine_mode src_mode = GET_MODE (old_val);
3517             machine_mode dst_mode = GET_MODE (temp);
3518             if (!partial_subreg_p (dst_mode, src_mode))
3519               {
3520                 end_sequence ();
3521                 return FALSE;
3522               }
3523             old_val = lowpart_subreg (dst_mode, old_val, src_mode);
3524           }
3525 
3526       /* Try emitting a conditional move passing the backend the
3527            canonicalized comparison.  The backend is then able to
3528            recognize expressions like
3529 
3530              if (x > y)
3531                y = x;
3532 
3533            as min/max and emit an insn, accordingly.  */
3534       unsigned cost1 = 0, cost2 = 0;
3535       rtx_insn *seq, *seq1, *seq2 = NULL;
3536       rtx temp_dest = NULL_RTX, temp_dest1 = NULL_RTX, temp_dest2 = NULL_RTX;
3537       bool read_comparison = false;
3538 
3539       seq1 = try_emit_cmove_seq (if_info, temp, cond,
3540                                          new_val, old_val, need_cmov,
3541                                          &cost1, &temp_dest1);
3542 
3543       /* Here, we try to pass the backend a non-canonicalized cc comparison
3544            as well.  This allows the backend to emit a cmov directly without
3545            creating an additional compare for each.  If successful, costing
3546            is easier and this sequence is usually preferred.  */
3547       if (cc_cmp)
3548           seq2 = try_emit_cmove_seq (if_info, temp, cond,
3549                                            new_val, old_val, need_cmov,
3550                                            &cost2, &temp_dest2, cc_cmp, rev_cc_cmp);
3551 
3552       /* The backend might have created a sequence that uses the
3553            condition.  Check this.  */
3554       rtx_insn *walk = seq2;
3555       while (walk)
3556           {
3557             rtx set = single_set (walk);
3558 
3559             if (!set || !SET_SRC (set))
3560               {
3561                 walk = NEXT_INSN (walk);
3562                 continue;
3563               }
3564 
3565             rtx src = SET_SRC (set);
3566 
3567             if (XEXP (set, 1) && GET_CODE (XEXP (set, 1)) == IF_THEN_ELSE)
3568               ; /* We assume that this is the cmove created by the backend that
3569                      naturally uses the condition.  Therefore we ignore it.  */
3570             else
3571               {
3572                 if (reg_mentioned_p (XEXP (cond, 0), src)
3573                       || reg_mentioned_p (XEXP (cond, 1), src))
3574                     {
3575                       read_comparison = true;
3576                       break;
3577                     }
3578               }
3579 
3580             walk = NEXT_INSN (walk);
3581           }
3582 
3583       /* Check which version is less expensive.  */
3584       if (seq1 != NULL_RTX && (cost1 <= cost2 || seq2 == NULL_RTX))
3585           {
3586             seq = seq1;
3587             temp_dest = temp_dest1;
3588             if (!second_try)
3589               *last_needs_comparison = count;
3590           }
3591       else if (seq2 != NULL_RTX)
3592           {
3593             seq = seq2;
3594             temp_dest = temp_dest2;
3595             if (!second_try && read_comparison)
3596               *last_needs_comparison = count;
3597           }
3598       else
3599           {
3600             /* Nothing worked, bail out.  */
3601             end_sequence ();
3602             return FALSE;
3603           }
3604 
3605       if (cc_cmp)
3606           {
3607             /* Check if SEQ can clobber registers mentioned in
3608                cc_cmp and/or rev_cc_cmp.  If yes, we need to use
3609                only seq1 from that point on.  */
3610             rtx cc_cmp_pair[2] = { cc_cmp, rev_cc_cmp };
3611             for (walk = seq; walk; walk = NEXT_INSN (walk))
3612               {
3613                 note_stores (walk, check_for_cc_cmp_clobbers, cc_cmp_pair);
3614                 if (cc_cmp_pair[0] == NULL_RTX)
3615                     {
3616                       cc_cmp = NULL_RTX;
3617                       rev_cc_cmp = NULL_RTX;
3618                       break;
3619                     }
3620               }
3621           }
3622 
3623       /* End the sub sequence and emit to the main sequence.  */
3624       emit_insn (seq);
3625 
3626       /* Bookkeeping.  */
3627       count++;
3628       targets->safe_push (target);
3629       temporaries->safe_push (temp_dest);
3630       unmodified_insns->safe_push (insn);
3631     }
3632 
3633   /* Even if we did not actually need the comparison, we want to make sure
3634      to try a second time in order to get rid of the temporaries.  */
3635   if (*last_needs_comparison == -1)
3636     *last_needs_comparison = 0;
3637 
3638 
3639   return true;
3640 }
3641 
3642 
3643 
3644 /* Return true iff basic block TEST_BB is comprised of only
3645    (SET (REG) (REG)) insns suitable for conversion to a series
3646    of conditional moves.  Also check that we have more than one set
3647    (other routines can handle a single set better than we would), and
3648    fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets.  While going
3649    through the insns store the sum of their potential costs in COST.  */
3650 
3651 static bool
bb_ok_for_noce_convert_multiple_sets(basic_block test_bb,unsigned * cost)3652 bb_ok_for_noce_convert_multiple_sets (basic_block test_bb, unsigned *cost)
3653 {
3654   rtx_insn *insn;
3655   unsigned count = 0;
3656   unsigned param = param_max_rtl_if_conversion_insns;
3657   bool speed_p = optimize_bb_for_speed_p (test_bb);
3658   unsigned potential_cost = 0;
3659 
3660   FOR_BB_INSNS (test_bb, insn)
3661     {
3662       /* Skip over notes etc.  */
3663       if (!active_insn_p (insn))
3664           continue;
3665 
3666       /* We only handle SET insns.  */
3667       rtx set = single_set (insn);
3668       if (set == NULL_RTX)
3669           return false;
3670 
3671       rtx dest = SET_DEST (set);
3672       rtx src = SET_SRC (set);
3673 
3674       /* We can possibly relax this, but for now only handle REG to REG
3675            (including subreg) moves.  This avoids any issues that might come
3676            from introducing loads/stores that might violate data-race-freedom
3677            guarantees.  */
3678       if (!REG_P (dest))
3679           return false;
3680 
3681       if (!((REG_P (src) || CONSTANT_P (src))
3682               || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
3683                 && subreg_lowpart_p (src))))
3684           return false;
3685 
3686       /* Destination must be appropriate for a conditional write.  */
3687       if (!noce_operand_ok (dest))
3688           return false;
3689 
3690       /* We must be able to conditionally move in this mode.  */
3691       if (!can_conditionally_move_p (GET_MODE (dest)))
3692           return false;
3693 
3694       potential_cost += insn_cost (insn, speed_p);
3695 
3696       count++;
3697     }
3698 
3699   *cost += potential_cost;
3700 
3701   /* If we would only put out one conditional move, the other strategies
3702      this pass tries are better optimized and will be more appropriate.
3703      Some targets want to strictly limit the number of conditional moves
3704      that are emitted, they set this through PARAM, we need to respect
3705      that.  */
3706   return count > 1 && count <= param;
3707 }
3708 
3709 /* Compute average of two given costs weighted by relative probabilities
3710    of respective basic blocks in an IF-THEN-ELSE.  E is the IF-THEN edge.
3711    With P as the probability to take the IF-THEN branch, return
3712    P * THEN_COST + (1 - P) * ELSE_COST.  */
3713 static unsigned
average_cost(unsigned then_cost,unsigned else_cost,edge e)3714 average_cost (unsigned then_cost, unsigned else_cost, edge e)
3715 {
3716   return else_cost + e->probability.apply ((signed) (then_cost - else_cost));
3717 }
3718 
3719 /* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
3720    it without using conditional execution.  Return TRUE if we were successful
3721    at converting the block.  */
3722 
3723 static int
noce_process_if_block(struct noce_if_info * if_info)3724 noce_process_if_block (struct noce_if_info *if_info)
3725 {
3726   basic_block test_bb = if_info->test_bb;         /* test block */
3727   basic_block then_bb = if_info->then_bb;         /* THEN */
3728   basic_block else_bb = if_info->else_bb;         /* ELSE or NULL */
3729   basic_block join_bb = if_info->join_bb;         /* JOIN */
3730   rtx_insn *jump = if_info->jump;
3731   rtx cond = if_info->cond;
3732   rtx_insn *insn_a, *insn_b;
3733   rtx set_a, set_b;
3734   rtx orig_x, x, a, b;
3735 
3736   /* We're looking for patterns of the form
3737 
3738      (1) if (...) x = a; else x = b;
3739      (2) x = b; if (...) x = a;
3740      (3) if (...) x = a;   // as if with an initial x = x.
3741      (4) if (...) { x = a; y = b; z = c; }  // Like 3, for multiple SETS.
3742      The later patterns require jumps to be more expensive.
3743      For the if (...) x = a; else x = b; case we allow multiple insns
3744      inside the then and else blocks as long as their only effect is
3745      to calculate a value for x.
3746      ??? For future expansion, further expand the "multiple X" rules.  */
3747 
3748   /* First look for multiple SETS.  The original costs already include
3749      a base cost of COSTS_N_INSNS (2): one instruction for the compare
3750      (which we will be needing either way) and one instruction for the
3751      branch.  When comparing costs we want to use the branch instruction
3752      cost and the sets vs. the cmovs generated here.  Therefore subtract
3753      the costs of the compare before checking.
3754      ??? Actually, instead of the branch instruction costs we might want
3755      to use COSTS_N_INSNS (BRANCH_COST ()) as in other places.  */
3756 
3757   unsigned potential_cost = if_info->original_cost - COSTS_N_INSNS (1);
3758   unsigned old_cost = if_info->original_cost;
3759   if (!else_bb
3760       && HAVE_conditional_move
3761       && bb_ok_for_noce_convert_multiple_sets (then_bb, &potential_cost))
3762     {
3763       /* Temporarily set the original costs to what we estimated so
3764            we can determine if the transformation is worth it.  */
3765       if_info->original_cost = potential_cost;
3766       if (noce_convert_multiple_sets (if_info))
3767           {
3768             if (dump_file && if_info->transform_name)
3769               fprintf (dump_file, "if-conversion succeeded through %s\n",
3770                          if_info->transform_name);
3771             return TRUE;
3772           }
3773 
3774       /* Restore the original costs.  */
3775       if_info->original_cost = old_cost;
3776     }
3777 
3778   bool speed_p = optimize_bb_for_speed_p (test_bb);
3779   unsigned int then_cost = 0, else_cost = 0;
3780   if (!bb_valid_for_noce_process_p (then_bb, cond, &then_cost,
3781                                             &if_info->then_simple))
3782     return false;
3783 
3784   if (else_bb
3785       && !bb_valid_for_noce_process_p (else_bb, cond, &else_cost,
3786                                                &if_info->else_simple))
3787     return false;
3788 
3789   if (speed_p)
3790     if_info->original_cost += average_cost (then_cost, else_cost,
3791                                                       find_edge (test_bb, then_bb));
3792   else
3793     if_info->original_cost += then_cost + else_cost;
3794 
3795   insn_a = last_active_insn (then_bb, FALSE);
3796   set_a = single_set (insn_a);
3797   gcc_assert (set_a);
3798 
3799   x = SET_DEST (set_a);
3800   a = SET_SRC (set_a);
3801 
3802   /* Look for the other potential set.  Make sure we've got equivalent
3803      destinations.  */
3804   /* ??? This is overconservative.  Storing to two different mems is
3805      as easy as conditionally computing the address.  Storing to a
3806      single mem merely requires a scratch memory to use as one of the
3807      destination addresses; often the memory immediately below the
3808      stack pointer is available for this.  */
3809   set_b = NULL_RTX;
3810   if (else_bb)
3811     {
3812       insn_b = last_active_insn (else_bb, FALSE);
3813       set_b = single_set (insn_b);
3814       gcc_assert (set_b);
3815 
3816       if (!rtx_interchangeable_p (x, SET_DEST (set_b)))
3817           return FALSE;
3818     }
3819   else
3820     {
3821       insn_b = if_info->cond_earliest;
3822       do
3823           insn_b = prev_nonnote_nondebug_insn (insn_b);
3824       while (insn_b
3825                && (BLOCK_FOR_INSN (insn_b)
3826                      == BLOCK_FOR_INSN (if_info->cond_earliest))
3827                && !modified_in_p (x, insn_b));
3828 
3829       /* We're going to be moving the evaluation of B down from above
3830            COND_EARLIEST to JUMP.  Make sure the relevant data is still
3831            intact.  */
3832       if (! insn_b
3833             || BLOCK_FOR_INSN (insn_b) != BLOCK_FOR_INSN (if_info->cond_earliest)
3834             || !NONJUMP_INSN_P (insn_b)
3835             || (set_b = single_set (insn_b)) == NULL_RTX
3836             || ! rtx_interchangeable_p (x, SET_DEST (set_b))
3837             || ! noce_operand_ok (SET_SRC (set_b))
3838             || reg_overlap_mentioned_p (x, SET_SRC (set_b))
3839             || modified_between_p (SET_SRC (set_b), insn_b, jump)
3840             /* Avoid extending the lifetime of hard registers on small
3841                register class machines.  */
3842             || (REG_P (SET_SRC (set_b))
3843                 && HARD_REGISTER_P (SET_SRC (set_b))
3844                 && targetm.small_register_classes_for_mode_p
3845                        (GET_MODE (SET_SRC (set_b))))
3846             /* Likewise with X.  In particular this can happen when
3847                noce_get_condition looks farther back in the instruction
3848                stream than one might expect.  */
3849             || reg_overlap_mentioned_p (x, cond)
3850             || reg_overlap_mentioned_p (x, a)
3851             || modified_between_p (x, insn_b, jump))
3852           {
3853             insn_b = NULL;
3854             set_b = NULL_RTX;
3855           }
3856     }
3857 
3858   /* If x has side effects then only the if-then-else form is safe to
3859      convert.  But even in that case we would need to restore any notes
3860      (such as REG_INC) at then end.  That can be tricky if
3861      noce_emit_move_insn expands to more than one insn, so disable the
3862      optimization entirely for now if there are side effects.  */
3863   if (side_effects_p (x))
3864     return FALSE;
3865 
3866   b = (set_b ? SET_SRC (set_b) : x);
3867 
3868   /* Only operate on register destinations, and even then avoid extending
3869      the lifetime of hard registers on small register class machines.  */
3870   orig_x = x;
3871   if_info->orig_x = orig_x;
3872   if (!REG_P (x)
3873       || (HARD_REGISTER_P (x)
3874             && targetm.small_register_classes_for_mode_p (GET_MODE (x))))
3875     {
3876       if (GET_MODE (x) == BLKmode)
3877           return FALSE;
3878 
3879       if (GET_CODE (x) == ZERO_EXTRACT
3880             && (!CONST_INT_P (XEXP (x, 1))
3881                 || !CONST_INT_P (XEXP (x, 2))))
3882           return FALSE;
3883 
3884       x = gen_reg_rtx (GET_MODE (GET_CODE (x) == STRICT_LOW_PART
3885                                          ? XEXP (x, 0) : x));
3886     }
3887 
3888   /* Don't operate on sources that may trap or are volatile.  */
3889   if (! noce_operand_ok (a) || ! noce_operand_ok (b))
3890     return FALSE;
3891 
3892  retry:
3893   /* Set up the info block for our subroutines.  */
3894   if_info->insn_a = insn_a;
3895   if_info->insn_b = insn_b;
3896   if_info->x = x;
3897   if_info->a = a;
3898   if_info->b = b;
3899 
3900   /* Try optimizations in some approximation of a useful order.  */
3901   /* ??? Should first look to see if X is live incoming at all.  If it
3902      isn't, we don't need anything but an unconditional set.  */
3903 
3904   /* Look and see if A and B are really the same.  Avoid creating silly
3905      cmove constructs that no one will fix up later.  */
3906   if (noce_simple_bbs (if_info)
3907       && rtx_interchangeable_p (a, b))
3908     {
3909       /* If we have an INSN_B, we don't have to create any new rtl.  Just
3910            move the instruction that we already have.  If we don't have an
3911            INSN_B, that means that A == X, and we've got a noop move.  In
3912            that case don't do anything and let the code below delete INSN_A.  */
3913       if (insn_b && else_bb)
3914           {
3915             rtx note;
3916 
3917             if (else_bb && insn_b == BB_END (else_bb))
3918               BB_END (else_bb) = PREV_INSN (insn_b);
3919             reorder_insns (insn_b, insn_b, PREV_INSN (jump));
3920 
3921             /* If there was a REG_EQUAL note, delete it since it may have been
3922                true due to this insn being after a jump.  */
3923             if ((note = find_reg_note (insn_b, REG_EQUAL, NULL_RTX)) != 0)
3924               remove_note (insn_b, note);
3925 
3926             insn_b = NULL;
3927           }
3928       /* If we have "x = b; if (...) x = a;", and x has side-effects, then
3929            x must be executed twice.  */
3930       else if (insn_b && side_effects_p (orig_x))
3931           return FALSE;
3932 
3933       x = orig_x;
3934       goto success;
3935     }
3936 
3937   if (!set_b && MEM_P (orig_x))
3938     /* We want to avoid store speculation to avoid cases like
3939            if (pthread_mutex_trylock(mutex))
3940              ++global_variable;
3941        Rather than go to much effort here, we rely on the SSA optimizers,
3942        which do a good enough job these days.  */
3943     return FALSE;
3944 
3945   if (noce_try_move (if_info))
3946     goto success;
3947   if (noce_try_ifelse_collapse (if_info))
3948     goto success;
3949   if (noce_try_store_flag (if_info))
3950     goto success;
3951   if (noce_try_bitop (if_info))
3952     goto success;
3953   if (noce_try_minmax (if_info))
3954     goto success;
3955   if (noce_try_abs (if_info))
3956     goto success;
3957   if (noce_try_inverse_constants (if_info))
3958     goto success;
3959   if (!targetm.have_conditional_execution ()
3960       && noce_try_store_flag_constants (if_info))
3961     goto success;
3962   if (HAVE_conditional_move
3963       && noce_try_cmove (if_info))
3964     goto success;
3965   if (! targetm.have_conditional_execution ())
3966     {
3967       if (noce_try_addcc (if_info))
3968           goto success;
3969       if (noce_try_store_flag_mask (if_info))
3970           goto success;
3971       if (HAVE_conditional_move
3972             && noce_try_cmove_arith (if_info))
3973           goto success;
3974       if (noce_try_sign_mask (if_info))
3975           goto success;
3976     }
3977 
3978   if (!else_bb && set_b)
3979     {
3980       insn_b = NULL;
3981       set_b = NULL_RTX;
3982       b = orig_x;
3983       goto retry;
3984     }
3985 
3986   return FALSE;
3987 
3988  success:
3989   if (dump_file && if_info->transform_name)
3990     fprintf (dump_file, "if-conversion succeeded through %s\n",
3991                if_info->transform_name);
3992 
3993   /* If we used a temporary, fix it up now.  */
3994   if (orig_x != x)
3995     {
3996       rtx_insn *seq;
3997 
3998       start_sequence ();
3999       noce_emit_move_insn (orig_x, x);
4000       seq = get_insns ();
4001       set_used_flags (orig_x);
4002       unshare_all_rtl_in_chain (seq);
4003       end_sequence ();
4004 
4005       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATION (insn_a));
4006     }
4007 
4008   /* The original THEN and ELSE blocks may now be removed.  The test block
4009      must now jump to the join block.  If the test block and the join block
4010      can be merged, do so.  */
4011   if (else_bb)
4012     {
4013       delete_basic_block (else_bb);
4014       num_true_changes++;
4015     }
4016   else
4017     remove_edge (find_edge (test_bb, join_bb));
4018 
4019   remove_edge (find_edge (then_bb, join_bb));
4020   redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb);
4021   delete_basic_block (then_bb);
4022   num_true_changes++;
4023 
4024   if (can_merge_blocks_p (test_bb, join_bb))
4025     {
4026       merge_blocks (test_bb, join_bb);
4027       num_true_changes++;
4028     }
4029 
4030   num_updated_if_blocks++;
4031   return TRUE;
4032 }
4033 
4034 /* Check whether a block is suitable for conditional move conversion.
4035    Every insn must be a simple set of a register to a constant or a
4036    register.  For each assignment, store the value in the pointer map
4037    VALS, keyed indexed by register pointer, then store the register
4038    pointer in REGS.  COND is the condition we will test.  */
4039 
4040 static int
check_cond_move_block(basic_block bb,hash_map<rtx,rtx> * vals,vec<rtx> * regs,rtx cond)4041 check_cond_move_block (basic_block bb,
4042                            hash_map<rtx, rtx> *vals,
4043                            vec<rtx> *regs,
4044                            rtx cond)
4045 {
4046   rtx_insn *insn;
4047   rtx cc = cc_in_cond (cond);
4048 
4049    /* We can only handle simple jumps at the end of the basic block.
4050       It is almost impossible to update the CFG otherwise.  */
4051   insn = BB_END (bb);
4052   if (JUMP_P (insn) && !onlyjump_p (insn))
4053     return FALSE;
4054 
4055   FOR_BB_INSNS (bb, insn)
4056     {
4057       rtx set, dest, src;
4058 
4059       if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
4060           continue;
4061       set = single_set (insn);
4062       if (!set)
4063           return FALSE;
4064 
4065       dest = SET_DEST (set);
4066       src = SET_SRC (set);
4067       if (!REG_P (dest)
4068             || (HARD_REGISTER_P (dest)
4069                 && targetm.small_register_classes_for_mode_p (GET_MODE (dest))))
4070           return FALSE;
4071 
4072       if (!CONSTANT_P (src) && !register_operand (src, VOIDmode))
4073           return FALSE;
4074 
4075       if (side_effects_p (src) || side_effects_p (dest))
4076           return FALSE;
4077 
4078       if (may_trap_p (src) || may_trap_p (dest))
4079           return FALSE;
4080 
4081       /* Don't try to handle this if the source register was
4082            modified earlier in the block.  */
4083       if ((REG_P (src)
4084              && vals->get (src))
4085             || (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src))
4086                 && vals->get (SUBREG_REG (src))))
4087           return FALSE;
4088 
4089       /* Don't try to handle this if the destination register was
4090            modified earlier in the block.  */
4091       if (vals->get (dest))
4092           return FALSE;
4093 
4094       /* Don't try to handle this if the condition uses the
4095            destination register.  */
4096       if (reg_overlap_mentioned_p (dest, cond))
4097           return FALSE;
4098 
4099       /* Don't try to handle this if the source register is modified
4100            later in the block.  */
4101       if (!CONSTANT_P (src)
4102             && modified_between_p (src, insn, NEXT_INSN (BB_END (bb))))
4103           return FALSE;
4104 
4105       /* Skip it if the instruction to be moved might clobber CC.  */
4106       if (cc && set_of (cc, insn))
4107           return FALSE;
4108 
4109       vals->put (dest, src);
4110 
4111       regs->safe_push (dest);
4112     }
4113 
4114   return TRUE;
4115 }
4116 
4117 /* Find local swap-style idioms in BB and mark the first insn (1)
4118    that is only a temporary as not needing a conditional move as
4119    it is going to be dead afterwards anyway.
4120 
4121      (1) int tmp = a;
4122            a = b;
4123            b = tmp;
4124 
4125            ifcvt
4126            -->
4127 
4128            tmp = a;
4129            a = cond ? b : a_old;
4130            b = cond ? tmp : b_old;
4131 
4132     Additionally, store the index of insns like (2) when a subsequent
4133     SET reads from their destination.
4134 
4135     (2) int c = a;
4136           int d = c;
4137 
4138           ifcvt
4139           -->
4140 
4141           c = cond ? a : c_old;
4142           d = cond ? d : c;     // Need to use c rather than c_old here.
4143 */
4144 
4145 static void
need_cmov_or_rewire(basic_block bb,hash_set<rtx_insn * > * need_no_cmov,hash_map<rtx_insn *,int> * rewired_src)4146 need_cmov_or_rewire (basic_block bb,
4147                          hash_set<rtx_insn *> *need_no_cmov,
4148                          hash_map<rtx_insn *, int> *rewired_src)
4149 {
4150   rtx_insn *insn;
4151   int count = 0;
4152   auto_vec<rtx_insn *> insns;
4153   auto_vec<rtx> dests;
4154 
4155   /* Iterate over all SETs, storing the destinations
4156      in DEST.
4157      - If we hit a SET that reads from a destination
4158        that we have seen before and the corresponding register
4159        is dead afterwards, the register does not need to be
4160        moved conditionally.
4161      - If we encounter a previously changed register,
4162        rewire the read to the original source.  */
4163   FOR_BB_INSNS (bb, insn)
4164     {
4165       rtx set, src, dest;
4166 
4167       if (!active_insn_p (insn))
4168           continue;
4169 
4170       set = single_set (insn);
4171       if (set == NULL_RTX)
4172           continue;
4173 
4174       src = SET_SRC (set);
4175       if (SUBREG_P (src))
4176           src = SUBREG_REG (src);
4177       dest = SET_DEST (set);
4178 
4179       /* Check if the current SET's source is the same
4180            as any previously seen destination.
4181            This is quadratic but the number of insns in BB
4182            is bounded by PARAM_MAX_RTL_IF_CONVERSION_INSNS.  */
4183       if (REG_P (src))
4184           for (int i = count - 1; i >= 0; --i)
4185             if (reg_overlap_mentioned_p (src, dests[i]))
4186               {
4187                 if (find_reg_note (insn, REG_DEAD, src) != NULL_RTX)
4188                     need_no_cmov->add (insns[i]);
4189                 else
4190                     rewired_src->put (insn, i);
4191               }
4192 
4193       insns.safe_push (insn);
4194       dests.safe_push (dest);
4195 
4196       count++;
4197     }
4198 }
4199 
4200 /* Given a basic block BB suitable for conditional move conversion,
4201    a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing
4202    the register values depending on COND, emit the insns in the block as
4203    conditional moves.  If ELSE_BLOCK is true, THEN_BB was already
4204    processed.  The caller has started a sequence for the conversion.
4205    Return true if successful, false if something goes wrong.  */
4206 
4207 static bool
cond_move_convert_if_block(struct noce_if_info * if_infop,basic_block bb,rtx cond,hash_map<rtx,rtx> * then_vals,hash_map<rtx,rtx> * else_vals,bool else_block_p)4208 cond_move_convert_if_block (struct noce_if_info *if_infop,
4209                                   basic_block bb, rtx cond,
4210                                   hash_map<rtx, rtx> *then_vals,
4211                                   hash_map<rtx, rtx> *else_vals,
4212                                   bool else_block_p)
4213 {
4214   enum rtx_code code;
4215   rtx_insn *insn;
4216   rtx cond_arg0, cond_arg1;
4217 
4218   code = GET_CODE (cond);
4219   cond_arg0 = XEXP (cond, 0);
4220   cond_arg1 = XEXP (cond, 1);
4221 
4222   FOR_BB_INSNS (bb, insn)
4223     {
4224       rtx set, target, dest, t, e;
4225 
4226       /* ??? Maybe emit conditional debug insn?  */
4227       if (!NONDEBUG_INSN_P (insn) || JUMP_P (insn))
4228           continue;
4229       set = single_set (insn);
4230       gcc_assert (set && REG_P (SET_DEST (set)));
4231 
4232       dest = SET_DEST (set);
4233 
4234       rtx *then_slot = then_vals->get (dest);
4235       rtx *else_slot = else_vals->get (dest);
4236       t = then_slot ? *then_slot : NULL_RTX;
4237       e = else_slot ? *else_slot : NULL_RTX;
4238 
4239       if (else_block_p)
4240           {
4241             /* If this register was set in the then block, we already
4242                handled this case there.  */
4243             if (t)
4244               continue;
4245             t = dest;
4246             gcc_assert (e);
4247           }
4248       else
4249           {
4250             gcc_assert (t);
4251             if (!e)
4252               e = dest;
4253           }
4254 
4255       target = noce_emit_cmove (if_infop, dest, code, cond_arg0, cond_arg1,
4256                                         t, e);
4257       if (!target)
4258           return false;
4259 
4260       if (target != dest)
4261           noce_emit_move_insn (dest, target);
4262     }
4263 
4264   return true;
4265 }
4266 
4267 /* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
4268    it using only conditional moves.  Return TRUE if we were successful at
4269    converting the block.  */
4270 
4271 static int
cond_move_process_if_block(struct noce_if_info * if_info)4272 cond_move_process_if_block (struct noce_if_info *if_info)
4273 {
4274   basic_block test_bb = if_info->test_bb;
4275   basic_block then_bb = if_info->then_bb;
4276   basic_block else_bb = if_info->else_bb;
4277   basic_block join_bb = if_info->join_bb;
4278   rtx_insn *jump = if_info->jump;
4279   rtx cond = if_info->cond;
4280   rtx_insn *seq, *loc_insn;
4281   int c;
4282   vec<rtx> then_regs = vNULL;
4283   vec<rtx> else_regs = vNULL;
4284   int success_p = FALSE;
4285   int limit = param_max_rtl_if_conversion_insns;
4286 
4287   /* Build a mapping for each block to the value used for each
4288      register.  */
4289   hash_map<rtx, rtx> then_vals;
4290   hash_map<rtx, rtx> else_vals;
4291 
4292   /* Make sure the blocks are suitable.  */
4293   if (!check_cond_move_block (then_bb, &then_vals, &then_regs, cond)
4294       || (else_bb
4295             && !check_cond_move_block (else_bb, &else_vals, &else_regs, cond)))
4296     goto done;
4297 
4298   /* Make sure the blocks can be used together.  If the same register
4299      is set in both blocks, and is not set to a constant in both
4300      cases, then both blocks must set it to the same register.  We
4301      have already verified that if it is set to a register, that the
4302      source register does not change after the assignment.  Also count
4303      the number of registers set in only one of the blocks.  */
4304   c = 0;
4305   for (rtx reg : then_regs)
4306     {
4307       rtx *then_slot = then_vals.get (reg);
4308       rtx *else_slot = else_vals.get (reg);
4309 
4310       gcc_checking_assert (then_slot);
4311       if (!else_slot)
4312           ++c;
4313       else
4314           {
4315             rtx then_val = *then_slot;
4316             rtx else_val = *else_slot;
4317             if (!CONSTANT_P (then_val) && !CONSTANT_P (else_val)
4318                 && !rtx_equal_p (then_val, else_val))
4319               goto done;
4320           }
4321     }
4322 
4323   /* Finish off c for MAX_CONDITIONAL_EXECUTE.  */
4324   for (rtx reg : else_regs)
4325     {
4326       gcc_checking_assert (else_vals.get (reg));
4327       if (!then_vals.get (reg))
4328           ++c;
4329     }
4330 
4331   /* Make sure it is reasonable to convert this block.  What matters
4332      is the number of assignments currently made in only one of the
4333      branches, since if we convert we are going to always execute
4334      them.  */
4335   if (c > MAX_CONDITIONAL_EXECUTE
4336       || c > limit)
4337     goto done;
4338 
4339   /* Try to emit the conditional moves.  First do the then block,
4340      then do anything left in the else blocks.  */
4341   start_sequence ();
4342   if (!cond_move_convert_if_block (if_info, then_bb, cond,
4343                                            &then_vals, &else_vals, false)
4344       || (else_bb
4345             && !cond_move_convert_if_block (if_info, else_bb, cond,
4346                                                     &then_vals, &else_vals, true)))
4347     {
4348       end_sequence ();
4349       goto done;
4350     }
4351   seq = end_ifcvt_sequence (if_info);
4352   if (!seq)
4353     goto done;
4354 
4355   loc_insn = first_active_insn (then_bb);
4356   if (!loc_insn)
4357     {
4358       loc_insn = first_active_insn (else_bb);
4359       gcc_assert (loc_insn);
4360     }
4361   emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));
4362 
4363   if (else_bb)
4364     {
4365       delete_basic_block (else_bb);
4366       num_true_changes++;
4367     }
4368   else
4369     remove_edge (find_edge (test_bb, join_bb));
4370 
4371   remove_edge (find_edge (then_bb, join_bb));
4372   redirect_edge_and_branch_force (single_succ_edge (test_bb), join_bb);
4373   delete_basic_block (then_bb);
4374   num_true_changes++;
4375 
4376   if (can_merge_blocks_p (test_bb, join_bb))
4377     {
4378       merge_blocks (test_bb, join_bb);
4379       num_true_changes++;
4380     }
4381 
4382   num_updated_if_blocks++;
4383   success_p = TRUE;
4384 
4385 done:
4386   then_regs.release ();
4387   else_regs.release ();
4388   return success_p;
4389 }
4390 
4391 
4392 /* Determine if a given basic block heads a simple IF-THEN-JOIN or an
4393    IF-THEN-ELSE-JOIN block.
4394 
4395    If so, we'll try to convert the insns to not require the branch,
4396    using only transformations that do not require conditional execution.
4397 
4398    Return TRUE if we were successful at converting the block.  */
4399 
4400 static int
noce_find_if_block(basic_block test_bb,edge then_edge,edge else_edge,int pass)4401 noce_find_if_block (basic_block test_bb, edge then_edge, edge else_edge,
4402                         int pass)
4403 {
4404   basic_block then_bb, else_bb, join_bb;
4405   bool then_else_reversed = false;
4406   rtx_insn *jump;
4407   rtx cond;
4408   rtx_insn *cond_earliest;
4409   struct noce_if_info if_info;
4410   bool speed_p = optimize_bb_for_speed_p (test_bb);
4411 
4412   /* We only ever should get here before reload.  */
4413   gcc_assert (!reload_completed);
4414 
4415   /* Recognize an IF-THEN-ELSE-JOIN block.  */
4416   if (single_pred_p (then_edge->dest)
4417       && single_succ_p (then_edge->dest)
4418       && single_pred_p (else_edge->dest)
4419       && single_succ_p (else_edge->dest)
4420       && single_succ (then_edge->dest) == single_succ (else_edge->dest))
4421     {
4422       then_bb = then_edge->dest;
4423       else_bb = else_edge->dest;
4424       join_bb = single_succ (then_bb);
4425     }
4426   /* Recognize an IF-THEN-JOIN block.  */
4427   else if (single_pred_p (then_edge->dest)
4428              && single_succ_p (then_edge->dest)
4429              && single_succ (then_edge->dest) == else_edge->dest)
4430     {
4431       then_bb = then_edge->dest;
4432       else_bb = NULL_BLOCK;
4433       join_bb = else_edge->dest;
4434     }
4435   /* Recognize an IF-ELSE-JOIN block.  We can have those because the order
4436      of basic blocks in cfglayout mode does not matter, so the fallthrough
4437      edge can go to any basic block (and not just to bb->next_bb, like in
4438      cfgrtl mode).  */
4439   else if (single_pred_p (else_edge->dest)
4440              && single_succ_p (else_edge->dest)
4441              && single_succ (else_edge->dest) == then_edge->dest)
4442     {
4443       /* The noce transformations do not apply to IF-ELSE-JOIN blocks.
4444            To make this work, we have to invert the THEN and ELSE blocks
4445            and reverse the jump condition.  */
4446       then_bb = else_edge->dest;
4447       else_bb = NULL_BLOCK;
4448       join_bb = single_succ (then_bb);
4449       then_else_reversed = true;
4450     }
4451   else
4452     /* Not a form we can handle.  */
4453     return FALSE;
4454 
4455   /* The edges of the THEN and ELSE blocks cannot have complex edges.  */
4456   if (single_succ_edge (then_bb)->flags & EDGE_COMPLEX)
4457     return FALSE;
4458   if (else_bb
4459       && single_succ_edge (else_bb)->flags & EDGE_COMPLEX)
4460     return FALSE;
4461 
4462   num_possible_if_blocks++;
4463 
4464   if (dump_file)
4465     {
4466       fprintf (dump_file,
4467                  "\nIF-THEN%s-JOIN block found, pass %d, test %d, then %d",
4468                  (else_bb) ? "-ELSE" : "",
4469                  pass, test_bb->index, then_bb->index);
4470 
4471       if (else_bb)
4472           fprintf (dump_file, ", else %d", else_bb->index);
4473 
4474       fprintf (dump_file, ", join %d\n", join_bb->index);
4475     }
4476 
4477   /* If the conditional jump is more than just a conditional
4478      jump, then we cannot do if-conversion on this block.  */
4479   jump = BB_END (test_bb);
4480   if (! onlyjump_p (jump))
4481     return FALSE;
4482 
4483   /* If this is not a standard conditional jump, we can't parse it.  */
4484   cond = noce_get_condition (jump, &cond_earliest, then_else_reversed);
4485   if (!cond)
4486     return FALSE;
4487 
4488   /* We must be comparing objects whose modes imply the size.  */
4489   if (GET_MODE (XEXP (cond, 0)) == BLKmode)
4490     return FALSE;
4491 
4492   /* Initialize an IF_INFO struct to pass around.  */
4493   memset (&if_info, 0, sizeof if_info);
4494   if_info.test_bb = test_bb;
4495   if_info.then_bb = then_bb;
4496   if_info.else_bb = else_bb;
4497   if_info.join_bb = join_bb;
4498   if_info.cond = cond;
4499   rtx_insn *rev_cond_earliest;
4500   if_info.rev_cond = noce_get_condition (jump, &rev_cond_earliest,
4501                                                    !then_else_reversed);
4502   gcc_assert (if_info.rev_cond == NULL_RTX
4503                 || rev_cond_earliest == cond_earliest);
4504   if_info.cond_earliest = cond_earliest;
4505   if_info.jump = jump;
4506   if_info.then_else_reversed = then_else_reversed;
4507   if_info.speed_p = speed_p;
4508   if_info.max_seq_cost
4509     = targetm.max_noce_ifcvt_seq_cost (then_edge);
4510   /* We'll add in the cost of THEN_BB and ELSE_BB later, when we check
4511      that they are valid to transform.  We can't easily get back to the insn
4512      for COND (and it may not exist if we had to canonicalize to get COND),
4513      and jump_insns are always given a cost of 1 by seq_cost, so treat
4514      both instructions as having cost COSTS_N_INSNS (1).  */
4515   if_info.original_cost = COSTS_N_INSNS (2);
4516 
4517 
4518   /* Do the real work.  */
4519 
4520   if (noce_process_if_block (&if_info))
4521     return TRUE;
4522 
4523   if (HAVE_conditional_move
4524       && cond_move_process_if_block (&if_info))
4525     return TRUE;
4526 
4527   return FALSE;
4528 }
4529 
4530 
4531 /* Merge the blocks and mark for local life update.  */
4532 
4533 static void
merge_if_block(struct ce_if_block * ce_info)4534 merge_if_block (struct ce_if_block * ce_info)
4535 {
4536   basic_block test_bb = ce_info->test_bb;         /* last test block */
4537   basic_block then_bb = ce_info->then_bb;         /* THEN */
4538   basic_block else_bb = ce_info->else_bb;         /* ELSE or NULL */
4539   basic_block join_bb = ce_info->join_bb;         /* join block */
4540   basic_block combo_bb;
4541 
4542   /* All block merging is done into the lower block numbers.  */
4543 
4544   combo_bb = test_bb;
4545   df_set_bb_dirty (test_bb);
4546 
4547   /* Merge any basic blocks to handle && and || subtests.  Each of
4548      the blocks are on the fallthru path from the predecessor block.  */
4549   if (ce_info->num_multiple_test_blocks > 0)
4550     {
4551       basic_block bb = test_bb;
4552       basic_block last_test_bb = ce_info->last_test_bb;
4553       basic_block fallthru = block_fallthru (bb);
4554 
4555       do
4556           {
4557             bb = fallthru;
4558             fallthru = block_fallthru (bb);
4559             merge_blocks (combo_bb, bb);
4560             num_true_changes++;
4561           }
4562       while (bb != last_test_bb);
4563     }
4564 
4565   /* Merge TEST block into THEN block.  Normally the THEN block won't have a
4566      label, but it might if there were || tests.  That label's count should be
4567      zero, and it normally should be removed.  */
4568 
4569   if (then_bb)
4570     {
4571       /* If THEN_BB has no successors, then there's a BARRIER after it.
4572            If COMBO_BB has more than one successor (THEN_BB), then that BARRIER
4573            is no longer needed, and in fact it is incorrect to leave it in
4574            the insn stream.  */
4575       if (EDGE_COUNT (then_bb->succs) == 0
4576             && EDGE_COUNT (combo_bb->succs) > 1)
4577           {
4578             rtx_insn *end = NEXT_INSN (BB_END (then_bb));
4579             while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
4580               end = NEXT_INSN (end);
4581 
4582             if (end && BARRIER_P (end))
4583               delete_insn (end);
4584           }
4585       merge_blocks (combo_bb, then_bb);
4586       num_true_changes++;
4587     }
4588 
4589   /* The ELSE block, if it existed, had a label.  That label count
4590      will almost always be zero, but odd things can happen when labels
4591      get their addresses taken.  */
4592   if (else_bb)
4593     {
4594       /* If ELSE_BB has no successors, then there's a BARRIER after it.
4595            If COMBO_BB has more than one successor (ELSE_BB), then that BARRIER
4596            is no longer needed, and in fact it is incorrect to leave it in
4597            the insn stream.  */
4598       if (EDGE_COUNT (else_bb->succs) == 0
4599             && EDGE_COUNT (combo_bb->succs) > 1)
4600           {
4601             rtx_insn *end = NEXT_INSN (BB_END (else_bb));
4602             while (end && NOTE_P (end) && !NOTE_INSN_BASIC_BLOCK_P (end))
4603               end = NEXT_INSN (end);
4604 
4605             if (end && BARRIER_P (end))
4606               delete_insn (end);
4607           }
4608       merge_blocks (combo_bb, else_bb);
4609       num_true_changes++;
4610     }
4611 
4612   /* If there was no join block reported, that means it was not adjacent
4613      to the others, and so we cannot merge them.  */
4614 
4615   if (! join_bb)
4616     {
4617       rtx_insn *last = BB_END (combo_bb);
4618 
4619       /* The outgoing edge for the current COMBO block should already
4620            be correct.  Verify this.  */
4621       if (EDGE_COUNT (combo_bb->succs) == 0)
4622           gcc_assert (find_reg_note (last, REG_NORETURN, NULL)
4623                         || (NONJUMP_INSN_P (last)
4624                               && GET_CODE (PATTERN (last)) == TRAP_IF
4625                               && (TRAP_CONDITION (PATTERN (last))
4626                                   == const_true_rtx)));
4627 
4628       else
4629       /* There should still be something at the end of the THEN or ELSE
4630          blocks taking us to our final destination.  */
4631           gcc_assert (JUMP_P (last)
4632                         || (EDGE_SUCC (combo_bb, 0)->dest
4633                               == EXIT_BLOCK_PTR_FOR_FN (cfun)
4634                               && CALL_P (last)
4635                               && SIBLING_CALL_P (last))
4636                         || ((EDGE_SUCC (combo_bb, 0)->flags & EDGE_EH)
4637                               && can_throw_internal (last)));
4638     }
4639 
4640   /* The JOIN block may have had quite a number of other predecessors too.
4641      Since we've already merged the TEST, THEN and ELSE blocks, we should
4642      have only one remaining edge from our if-then-else diamond.  If there
4643      is more than one remaining edge, it must come from elsewhere.  There
4644      may be zero incoming edges if the THEN block didn't actually join
4645      back up (as with a call to a non-return function).  */
4646   else if (EDGE_COUNT (join_bb->preds) < 2
4647              && join_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4648     {
4649       /* We can merge the JOIN cleanly and update the dataflow try
4650            again on this pass.*/
4651       merge_blocks (combo_bb, join_bb);
4652       num_true_changes++;
4653     }
4654   else
4655     {
4656       /* We cannot merge the JOIN.  */
4657 
4658       /* The outgoing edge for the current COMBO block should already
4659            be correct.  Verify this.  */
4660       gcc_assert (single_succ_p (combo_bb)
4661                       && single_succ (combo_bb) == join_bb);
4662 
4663       /* Remove the jump and cruft from the end of the COMBO block.  */
4664       if (join_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4665           tidy_fallthru_edge (single_succ_edge (combo_bb));
4666     }
4667 
4668   num_updated_if_blocks++;
4669 }
4670 
4671 /* Find a block ending in a simple IF condition and try to transform it
4672    in some way.  When converting a multi-block condition, put the new code
4673    in the first such block and delete the rest.  Return a pointer to this
4674    first block if some transformation was done.  Return NULL otherwise.  */
4675 
4676 static basic_block
find_if_header(basic_block test_bb,int pass)4677 find_if_header (basic_block test_bb, int pass)
4678 {
4679   ce_if_block ce_info;
4680   edge then_edge;
4681   edge else_edge;
4682 
4683   /* The kind of block we're looking for has exactly two successors.  */
4684   if (EDGE_COUNT (test_bb->succs) != 2)
4685     return NULL;
4686 
4687   then_edge = EDGE_SUCC (test_bb, 0);
4688   else_edge = EDGE_SUCC (test_bb, 1);
4689 
4690   if (df_get_bb_dirty (then_edge->dest))
4691     return NULL;
4692   if (df_get_bb_dirty (else_edge->dest))
4693     return NULL;
4694 
4695   /* Neither edge should be abnormal.  */
4696   if ((then_edge->flags & EDGE_COMPLEX)
4697       || (else_edge->flags & EDGE_COMPLEX))
4698     return NULL;
4699 
4700   /* Nor exit the loop.  */
4701   if ((then_edge->flags & EDGE_LOOP_EXIT)
4702       || (else_edge->flags & EDGE_LOOP_EXIT))
4703     return NULL;
4704 
4705   /* The THEN edge is canonically the one that falls through.  */
4706   if (then_edge->flags & EDGE_FALLTHRU)
4707     ;
4708   else if (else_edge->flags & EDGE_FALLTHRU)
4709     std::swap (then_edge, else_edge);
4710   else
4711     /* Otherwise this must be a multiway branch of some sort.  */
4712     return NULL;
4713 
4714   memset (&ce_info, 0, sizeof (ce_info));
4715   ce_info.test_bb = test_bb;
4716   ce_info.then_bb = then_edge->dest;
4717   ce_info.else_bb = else_edge->dest;
4718   ce_info.pass = pass;
4719 
4720 #ifdef IFCVT_MACHDEP_INIT
4721   IFCVT_MACHDEP_INIT (&ce_info);
4722 #endif
4723 
4724   if (!reload_completed
4725       && noce_find_if_block (test_bb, then_edge, else_edge, pass))
4726     goto success;
4727 
4728   if (reload_completed
4729       && targetm.have_conditional_execution ()
4730       && cond_exec_find_if_block (&ce_info))
4731     goto success;
4732 
4733   if (targetm.have_trap ()
4734       && optab_handler (ctrap_optab, word_mode) != CODE_FOR_nothing
4735       && find_cond_trap (test_bb, then_edge, else_edge))
4736     goto success;
4737 
4738   if (dom_info_state (CDI_POST_DOMINATORS) >= DOM_NO_FAST_QUERY
4739       && (reload_completed || !targetm.have_conditional_execution ()))
4740     {
4741       if (find_if_case_1 (test_bb, then_edge, else_edge))
4742           goto success;
4743       if (find_if_case_2 (test_bb, then_edge, else_edge))
4744           goto success;
4745     }
4746 
4747   return NULL;
4748 
4749  success:
4750   if (dump_file)
4751     fprintf (dump_file, "Conversion succeeded on pass %d.\n", pass);
4752   /* Set this so we continue looking.  */
4753   cond_exec_changed_p = TRUE;
4754   return ce_info.test_bb;
4755 }
4756 
4757 /* Return true if a block has two edges, one of which falls through to the next
4758    block, and the other jumps to a specific block, so that we can tell if the
4759    block is part of an && test or an || test.  Returns either -1 or the number
4760    of non-note, non-jump, non-USE/CLOBBER insns in the block.  */
4761 
4762 static int
block_jumps_and_fallthru_p(basic_block cur_bb,basic_block target_bb)4763 block_jumps_and_fallthru_p (basic_block cur_bb, basic_block target_bb)
4764 {
4765   edge cur_edge;
4766   int fallthru_p = FALSE;
4767   int jump_p = FALSE;
4768   rtx_insn *insn;
4769   rtx_insn *end;
4770   int n_insns = 0;
4771   edge_iterator ei;
4772 
4773   if (!cur_bb || !target_bb)
4774     return -1;
4775 
4776   /* If no edges, obviously it doesn't jump or fallthru.  */
4777   if (EDGE_COUNT (cur_bb->succs) == 0)
4778     return FALSE;
4779 
4780   FOR_EACH_EDGE (cur_edge, ei, cur_bb->succs)
4781     {
4782       if (cur_edge->flags & EDGE_COMPLEX)
4783           /* Anything complex isn't what we want.  */
4784           return -1;
4785 
4786       else if (cur_edge->flags & EDGE_FALLTHRU)
4787           fallthru_p = TRUE;
4788 
4789       else if (cur_edge->dest == target_bb)
4790           jump_p = TRUE;
4791 
4792       else
4793           return -1;
4794     }
4795 
4796   if ((jump_p & fallthru_p) == 0)
4797     return -1;
4798 
4799   /* Don't allow calls in the block, since this is used to group && and ||
4800      together for conditional execution support.  ??? we should support
4801      conditional execution support across calls for IA-64 some day, but
4802      for now it makes the code simpler.  */
4803   end = BB_END (cur_bb);
4804   insn = BB_HEAD (cur_bb);
4805 
4806   while (insn != NULL_RTX)
4807     {
4808       if (CALL_P (insn))
4809           return -1;
4810 
4811       if (INSN_P (insn)
4812             && !JUMP_P (insn)
4813             && !DEBUG_INSN_P (insn)
4814             && GET_CODE (PATTERN (insn)) != USE
4815             && GET_CODE (PATTERN (insn)) != CLOBBER)
4816           n_insns++;
4817 
4818       if (insn == end)
4819           break;
4820 
4821       insn = NEXT_INSN (insn);
4822     }
4823 
4824   return n_insns;
4825 }
4826 
4827 /* Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE
4828    block.  If so, we'll try to convert the insns to not require the branch.
4829    Return TRUE if we were successful at converting the block.  */
4830 
4831 static int
cond_exec_find_if_block(struct ce_if_block * ce_info)4832 cond_exec_find_if_block (struct ce_if_block * ce_info)
4833 {
4834   basic_block test_bb = ce_info->test_bb;
4835   basic_block then_bb = ce_info->then_bb;
4836   basic_block else_bb = ce_info->else_bb;
4837   basic_block join_bb = NULL_BLOCK;
4838   edge cur_edge;
4839   basic_block next;
4840   edge_iterator ei;
4841 
4842   ce_info->last_test_bb = test_bb;
4843 
4844   /* We only ever should get here after reload,
4845      and if we have conditional execution.  */
4846   gcc_assert (reload_completed && targetm.have_conditional_execution ());
4847 
4848   /* Discover if any fall through predecessors of the current test basic block
4849      were && tests (which jump to the else block) or || tests (which jump to
4850      the then block).  */
4851   if (single_pred_p (test_bb)
4852       && single_pred_edge (test_bb)->flags == EDGE_FALLTHRU)
4853     {
4854       basic_block bb = single_pred (test_bb);
4855       basic_block target_bb;
4856       int max_insns = MAX_CONDITIONAL_EXECUTE;
4857       int n_insns;
4858 
4859       /* Determine if the preceding block is an && or || block.  */
4860       if ((n_insns = block_jumps_and_fallthru_p (bb, else_bb)) >= 0)
4861           {
4862             ce_info->and_and_p = TRUE;
4863             target_bb = else_bb;
4864           }
4865       else if ((n_insns = block_jumps_and_fallthru_p (bb, then_bb)) >= 0)
4866           {
4867             ce_info->and_and_p = FALSE;
4868             target_bb = then_bb;
4869           }
4870       else
4871           target_bb = NULL_BLOCK;
4872 
4873       if (target_bb && n_insns <= max_insns)
4874           {
4875             int total_insns = 0;
4876             int blocks = 0;
4877 
4878             ce_info->last_test_bb = test_bb;
4879 
4880             /* Found at least one && or || block, look for more.  */
4881             do
4882               {
4883                 ce_info->test_bb = test_bb = bb;
4884                 total_insns += n_insns;
4885                 blocks++;
4886 
4887                 if (!single_pred_p (bb))
4888                     break;
4889 
4890                 bb = single_pred (bb);
4891                 n_insns = block_jumps_and_fallthru_p (bb, target_bb);
4892               }
4893             while (n_insns >= 0 && (total_insns + n_insns) <= max_insns);
4894 
4895             ce_info->num_multiple_test_blocks = blocks;
4896             ce_info->num_multiple_test_insns = total_insns;
4897 
4898             if (ce_info->and_and_p)
4899               ce_info->num_and_and_blocks = blocks;
4900             else
4901               ce_info->num_or_or_blocks = blocks;
4902           }
4903     }
4904 
4905   /* The THEN block of an IF-THEN combo must have exactly one predecessor,
4906      other than any || blocks which jump to the THEN block.  */
4907   if ((EDGE_COUNT (then_bb->preds) - ce_info->num_or_or_blocks) != 1)
4908     return FALSE;
4909 
4910   /* The edges of the THEN and ELSE blocks cannot have complex edges.  */
4911   FOR_EACH_EDGE (cur_edge, ei, then_bb->preds)
4912     {
4913       if (cur_edge->flags & EDGE_COMPLEX)
4914           return FALSE;
4915     }
4916 
4917   FOR_EACH_EDGE (cur_edge, ei, else_bb->preds)
4918     {
4919       if (cur_edge->flags & EDGE_COMPLEX)
4920           return FALSE;
4921     }
4922 
4923   /* The THEN block of an IF-THEN combo must have zero or one successors.  */
4924   if (EDGE_COUNT (then_bb->succs) > 0
4925       && (!single_succ_p (then_bb)
4926           || (single_succ_edge (then_bb)->flags & EDGE_COMPLEX)
4927             || (epilogue_completed
4928                 && tablejump_p (BB_END (then_bb), NULL, NULL))))
4929     return FALSE;
4930 
4931   /* If the THEN block has no successors, conditional execution can still
4932      make a conditional call.  Don't do this unless the ELSE block has
4933      only one incoming edge -- the CFG manipulation is too ugly otherwise.
4934      Check for the last insn of the THEN block being an indirect jump, which
4935      is listed as not having any successors, but confuses the rest of the CE
4936      code processing.  ??? we should fix this in the future.  */
4937   if (EDGE_COUNT (then_bb->succs) == 0)
4938     {
4939       if (single_pred_p (else_bb) && else_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
4940           {
4941             rtx_insn *last_insn = BB_END (then_bb);
4942 
4943             while (last_insn
4944                      && NOTE_P (last_insn)
4945                      && last_insn != BB_HEAD (then_bb))
4946               last_insn = PREV_INSN (last_insn);
4947 
4948             if (last_insn
4949                 && JUMP_P (last_insn)
4950                 && ! simplejump_p (last_insn))
4951               return FALSE;
4952 
4953             join_bb = else_bb;
4954             else_bb = NULL_BLOCK;
4955           }
4956       else
4957           return FALSE;
4958     }
4959 
4960   /* If the THEN block's successor is the other edge out of the TEST block,
4961      then we have an IF-THEN combo without an ELSE.  */
4962   else if (single_succ (then_bb) == else_bb)
4963     {
4964       join_bb = else_bb;
4965       else_bb = NULL_BLOCK;
4966     }
4967 
4968   /* If the THEN and ELSE block meet in a subsequent block, and the ELSE
4969      has exactly one predecessor and one successor, and the outgoing edge
4970      is not complex, then we have an IF-THEN-ELSE combo.  */
4971   else if (single_succ_p (else_bb)
4972              && single_succ (then_bb) == single_succ (else_bb)
4973              && single_pred_p (else_bb)
4974              && !(single_succ_edge (else_bb)->flags & EDGE_COMPLEX)
4975              && !(epilogue_completed
4976                     && tablejump_p (BB_END (else_bb), NULL, NULL)))
4977     join_bb = single_succ (else_bb);
4978 
4979   /* Otherwise it is not an IF-THEN or IF-THEN-ELSE combination.  */
4980   else
4981     return FALSE;
4982 
4983   num_possible_if_blocks++;
4984 
4985   if (dump_file)
4986     {
4987       fprintf (dump_file,
4988                  "\nIF-THEN%s block found, pass %d, start block %d "
4989                  "[insn %d], then %d [%d]",
4990                  (else_bb) ? "-ELSE" : "",
4991                  ce_info->pass,
4992                  test_bb->index,
4993                  BB_HEAD (test_bb) ? (int)INSN_UID (BB_HEAD (test_bb)) : -1,
4994                  then_bb->index,
4995                  BB_HEAD (then_bb) ? (int)INSN_UID (BB_HEAD (then_bb)) : -1);
4996 
4997       if (else_bb)
4998           fprintf (dump_file, ", else %d [%d]",
4999                      else_bb->index,
5000                      BB_HEAD (else_bb) ? (int)INSN_UID (BB_HEAD (else_bb)) : -1);
5001 
5002       fprintf (dump_file, ", join %d [%d]",
5003                  join_bb->index,
5004                  BB_HEAD (join_bb) ? (int)INSN_UID (BB_HEAD (join_bb)) : -1);
5005 
5006       if (ce_info->num_multiple_test_blocks > 0)
5007           fprintf (dump_file, ", %d %s block%s last test %d [%d]",
5008                      ce_info->num_multiple_test_blocks,
5009                      (ce_info->and_and_p) ? "&&" : "||",
5010                      (ce_info->num_multiple_test_blocks == 1) ? "" : "s",
5011                      ce_info->last_test_bb->index,
5012                      ((BB_HEAD (ce_info->last_test_bb))
5013                       ? (int)INSN_UID (BB_HEAD (ce_info->last_test_bb))
5014                       : -1));
5015 
5016       fputc ('\n', dump_file);
5017     }
5018 
5019   /* Make sure IF, THEN, and ELSE, blocks are adjacent.  Actually, we get the
5020      first condition for free, since we've already asserted that there's a
5021      fallthru edge from IF to THEN.  Likewise for the && and || blocks, since
5022      we checked the FALLTHRU flag, those are already adjacent to the last IF
5023      block.  */
5024   /* ??? As an enhancement, move the ELSE block.  Have to deal with
5025      BLOCK notes, if by no other means than backing out the merge if they
5026      exist.  Sticky enough I don't want to think about it now.  */
5027   next = then_bb;
5028   if (else_bb && (next = next->next_bb) != else_bb)
5029     return FALSE;
5030   if ((next = next->next_bb) != join_bb
5031       && join_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
5032     {
5033       if (else_bb)
5034           join_bb = NULL;
5035       else
5036           return FALSE;
5037     }
5038 
5039   /* Do the real work.  */
5040 
5041   ce_info->else_bb = else_bb;
5042   ce_info->join_bb = join_bb;
5043 
5044   /* If we have && and || tests, try to first handle combining the && and ||
5045      tests into the conditional code, and if that fails, go back and handle
5046      it without the && and ||, which at present handles the && case if there
5047      was no ELSE block.  */
5048   if (cond_exec_process_if_block (ce_info, TRUE))
5049     return TRUE;
5050 
5051   if (ce_info->num_multiple_test_blocks)
5052     {
5053       cancel_changes (0);
5054 
5055       if (cond_exec_process_if_block (ce_info, FALSE))
5056           return TRUE;
5057     }
5058 
5059   return FALSE;
5060 }
5061 
5062 /* Convert a branch over a trap, or a branch
5063    to a trap, into a conditional trap.  */
5064 
5065 static int
find_cond_trap(basic_block test_bb,edge then_edge,edge else_edge)5066 find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
5067 {
5068   basic_block then_bb = then_edge->dest;
5069   basic_block else_bb = else_edge->dest;
5070   basic_block other_bb, trap_bb;
5071   rtx_insn *trap, *jump;
5072   rtx cond;
5073   rtx_insn *cond_earliest;
5074 
5075   /* Locate the block with the trap instruction.  */
5076   /* ??? While we look for no successors, we really ought to allow
5077      EH successors.  Need to fix merge_if_block for that to work.  */
5078   if ((trap = block_has_only_trap (then_bb)) != NULL)
5079     trap_bb = then_bb, other_bb = else_bb;
5080   else if ((trap = block_has_only_trap (else_bb)) != NULL)
5081     trap_bb = else_bb, other_bb = then_bb;
5082   else
5083     return FALSE;
5084 
5085   if (dump_file)
5086     {
5087       fprintf (dump_file, "\nTRAP-IF block found, start %d, trap %d\n",
5088                  test_bb->index, trap_bb->index);
5089     }
5090 
5091   /* If this is not a standard conditional jump, we can't parse it.  */
5092   jump = BB_END (test_bb);
5093   cond = noce_get_condition (jump, &cond_earliest, then_bb == trap_bb);
5094   if (! cond)
5095     return FALSE;
5096 
5097   /* If the conditional jump is more than just a conditional jump, then
5098      we cannot do if-conversion on this block.  Give up for returnjump_p,
5099      changing a conditional return followed by unconditional trap for
5100      conditional trap followed by unconditional return is likely not
5101      beneficial and harder to handle.  */
5102   if (! onlyjump_p (jump) || returnjump_p (jump))
5103     return FALSE;
5104 
5105   /* We must be comparing objects whose modes imply the size.  */
5106   if (GET_MODE (XEXP (cond, 0)) == BLKmode)
5107     return FALSE;
5108 
5109   /* Attempt to generate the conditional trap.  */
5110   rtx_insn *seq = gen_cond_trap (GET_CODE (cond), copy_rtx (XEXP (cond, 0)),
5111                                          copy_rtx (XEXP (cond, 1)),
5112                                          TRAP_CODE (PATTERN (trap)));
5113   if (seq == NULL)
5114     return FALSE;
5115 
5116   /* If that results in an invalid insn, back out.  */
5117   for (rtx_insn *x = seq; x; x = NEXT_INSN (x))
5118     if (reload_completed
5119           ? !valid_insn_p (x)
5120           : recog_memoized (x) < 0)
5121       return FALSE;
5122 
5123   /* Emit the new insns before cond_earliest.  */
5124   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap));
5125 
5126   /* Delete the trap block if possible.  */
5127   remove_edge (trap_bb == then_bb ? then_edge : else_edge);
5128   df_set_bb_dirty (test_bb);
5129   df_set_bb_dirty (then_bb);
5130   df_set_bb_dirty (else_bb);
5131 
5132   if (EDGE_COUNT (trap_bb->preds) == 0)
5133     {
5134       delete_basic_block (trap_bb);
5135       num_true_changes++;
5136     }
5137 
5138   /* Wire together the blocks again.  */
5139   if (current_ir_type () == IR_RTL_CFGLAYOUT)
5140     single_succ_edge (test_bb)->flags |= EDGE_FALLTHRU;
5141   else if (trap_bb == then_bb)
5142     {
5143       rtx lab = JUMP_LABEL (jump);
5144       rtx_insn *seq = targetm.gen_jump (lab);
5145       rtx_jump_insn *newjump = emit_jump_insn_after (seq, jump);
5146       LABEL_NUSES (lab) += 1;
5147       JUMP_LABEL (newjump) = lab;
5148       emit_barrier_after (newjump);
5149     }
5150   delete_insn (jump);
5151 
5152   if (can_merge_blocks_p (test_bb, other_bb))
5153     {
5154       merge_blocks (test_bb, other_bb);
5155       num_true_changes++;
5156     }
5157 
5158   num_updated_if_blocks++;
5159   return TRUE;
5160 }
5161 
5162 /* Subroutine of find_cond_trap: if BB contains only a trap insn,
5163    return it.  */
5164 
5165 static rtx_insn *
block_has_only_trap(basic_block bb)5166 block_has_only_trap (basic_block bb)
5167 {
5168   rtx_insn *trap;
5169 
5170   /* We're not the exit block.  */
5171   if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
5172     return NULL;
5173 
5174   /* The block must have no successors.  */
5175   if (EDGE_COUNT (bb->succs) > 0)
5176     return NULL;
5177 
5178   /* The only instruction in the THEN block must be the trap.  */
5179   trap = first_active_insn (bb);
5180   if (! (trap == BB_END (bb)
5181            && GET_CODE (PATTERN (trap)) == TRAP_IF
5182          && TRAP_CONDITION (PATTERN (trap)) == const_true_rtx))
5183     return NULL;
5184 
5185   return trap;
5186 }
5187 
5188 /* Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
5189    transformable, but not necessarily the other.  There need be no
5190    JOIN block.
5191 
5192    Return TRUE if we were successful at converting the block.
5193 
5194    Cases we'd like to look at:
5195 
5196    (1)
5197           if (test) goto over; // x not live
5198           x = a;
5199           goto label;
5200           over:
5201 
5202    becomes
5203 
5204           x = a;
5205           if (! test) goto label;
5206 
5207    (2)
5208           if (test) goto E; // x not live
5209           x = big();
5210           goto L;
5211           E:
5212           x = b;
5213           goto M;
5214 
5215    becomes
5216 
5217           x = b;
5218           if (test) goto M;
5219           x = big();
5220           goto L;
5221 
5222    (3) // This one's really only interesting for targets that can do
5223        // multiway branching, e.g. IA-64 BBB bundles.  For other targets
5224        // it results in multiple branches on a cache line, which often
5225        // does not sit well with predictors.
5226 
5227           if (test1) goto E; // predicted not taken
5228           x = a;
5229           if (test2) goto F;
5230           ...
5231           E:
5232           x = b;
5233           J:
5234 
5235    becomes
5236 
5237           x = a;
5238           if (test1) goto E;
5239           if (test2) goto F;
5240 
5241    Notes:
5242 
5243    (A) Don't do (2) if the branch is predicted against the block we're
5244    eliminating.  Do it anyway if we can eliminate a branch; this requires
5245    that the sole successor of the eliminated block postdominate the other
5246    side of the if.
5247 
5248    (B) With CE, on (3) we can steal from both sides of the if, creating
5249 
5250           if (test1) x = a;
5251           if (!test1) x = b;
5252           if (test1) goto J;
5253           if (test2) goto F;
5254           ...
5255           J:
5256 
5257    Again, this is most useful if J postdominates.
5258 
5259    (C) CE substitutes for helpful life information.
5260 
5261    (D) These heuristics need a lot of work.  */
5262 
5263 /* Tests for case 1 above.  */
5264 
5265 static int
find_if_case_1(basic_block test_bb,edge then_edge,edge else_edge)5266 find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
5267 {
5268   basic_block then_bb = then_edge->dest;
5269   basic_block else_bb = else_edge->dest;
5270   basic_block new_bb;
5271   int then_bb_index;
5272   profile_probability then_prob;
5273   rtx else_target = NULL_RTX;
5274 
5275   /* If we are partitioning hot/cold basic blocks, we don't want to
5276      mess up unconditional or indirect jumps that cross between hot
5277      and cold sections.
5278 
5279      Basic block partitioning may result in some jumps that appear to
5280      be optimizable (or blocks that appear to be mergeable), but which really
5281      must be left untouched (they are required to make it safely across
5282      partition boundaries).  See  the comments at the top of
5283      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
5284 
5285   if ((BB_END (then_bb)
5286        && JUMP_P (BB_END (then_bb))
5287        && CROSSING_JUMP_P (BB_END (then_bb)))
5288       || (JUMP_P (BB_END (test_bb))
5289             && CROSSING_JUMP_P (BB_END (test_bb)))
5290       || (BB_END (else_bb)
5291             && JUMP_P (BB_END (else_bb))
5292             && CROSSING_JUMP_P (BB_END (else_bb))))
5293     return FALSE;
5294 
5295   /* Verify test_bb ends in a conditional jump with no other side-effects.  */
5296   if (!onlyjump_p (BB_END (test_bb)))
5297     return FALSE;
5298 
5299   /* THEN has one successor.  */
5300   if (!single_succ_p (then_bb))
5301     return FALSE;
5302 
5303   /* THEN does not fall through, but is not strange either.  */
5304   if (single_succ_edge (then_bb)->flags & (EDGE_COMPLEX | EDGE_FALLTHRU))
5305     return FALSE;
5306 
5307   /* THEN has one predecessor.  */
5308   if (!single_pred_p (then_bb))
5309     return FALSE;
5310 
5311   /* THEN must do something.  */
5312   if (forwarder_block_p (then_bb))
5313     return FALSE;
5314 
5315   num_possible_if_blocks++;
5316   if (dump_file)
5317     fprintf (dump_file,
5318                "\nIF-CASE-1 found, start %d, then %d\n",
5319                test_bb->index, then_bb->index);
5320 
5321   then_prob = then_edge->probability.invert ();
5322 
5323   /* We're speculating from the THEN path, we want to make sure the cost
5324      of speculation is within reason.  */
5325   if (! cheap_bb_rtx_cost_p (then_bb, then_prob,
5326           COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (then_edge->src),
5327                                             predictable_edge_p (then_edge)))))
5328     return FALSE;
5329 
5330   if (else_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
5331     {
5332       rtx_insn *jump = BB_END (else_edge->src);
5333       gcc_assert (JUMP_P (jump));
5334       else_target = JUMP_LABEL (jump);
5335     }
5336 
5337   /* Registers set are dead, or are predicable.  */
5338   if (! dead_or_predicable (test_bb, then_bb, else_bb,
5339                                   single_succ_edge (then_bb), 1))
5340     return FALSE;
5341 
5342   /* Conversion went ok, including moving the insns and fixing up the
5343      jump.  Adjust the CFG to match.  */
5344 
5345   /* We can avoid creating a new basic block if then_bb is immediately
5346      followed by else_bb, i.e. deleting then_bb allows test_bb to fall
5347      through to else_bb.  */
5348 
5349   if (then_bb->next_bb == else_bb
5350       && then_bb->prev_bb == test_bb
5351       && else_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
5352     {
5353       redirect_edge_succ (FALLTHRU_EDGE (test_bb), else_bb);
5354       new_bb = 0;
5355     }
5356   else if (else_bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
5357     new_bb = force_nonfallthru_and_redirect (FALLTHRU_EDGE (test_bb),
5358                                                        else_bb, else_target);
5359   else
5360     new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb),
5361                                                        else_bb);
5362 
5363   df_set_bb_dirty (test_bb);
5364   df_set_bb_dirty (else_bb);
5365 
5366   then_bb_index = then_bb->index;
5367   delete_basic_block (then_bb);
5368 
5369   /* Make rest of code believe that the newly created block is the THEN_BB
5370      block we removed.  */
5371   if (new_bb)
5372     {
5373       df_bb_replace (then_bb_index, new_bb);
5374       /* This should have been done above via force_nonfallthru_and_redirect
5375          (possibly called from redirect_edge_and_branch_force).  */
5376       gcc_checking_assert (BB_PARTITION (new_bb) == BB_PARTITION (test_bb));
5377     }
5378 
5379   num_true_changes++;
5380   num_updated_if_blocks++;
5381   return TRUE;
5382 }
5383 
5384 /* Test for case 2 above.  */
5385 
5386 static int
find_if_case_2(basic_block test_bb,edge then_edge,edge else_edge)5387 find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
5388 {
5389   basic_block then_bb = then_edge->dest;
5390   basic_block else_bb = else_edge->dest;
5391   edge else_succ;
5392   profile_probability then_prob, else_prob;
5393 
5394   /* We do not want to speculate (empty) loop latches.  */
5395   if (current_loops
5396       && else_bb->loop_father->latch == else_bb)
5397     return FALSE;
5398 
5399   /* If we are partitioning hot/cold basic blocks, we don't want to
5400      mess up unconditional or indirect jumps that cross between hot
5401      and cold sections.
5402 
5403      Basic block partitioning may result in some jumps that appear to
5404      be optimizable (or blocks that appear to be mergeable), but which really
5405      must be left untouched (they are required to make it safely across
5406      partition boundaries).  See  the comments at the top of
5407      bb-reorder.cc:partition_hot_cold_basic_blocks for complete details.  */
5408 
5409   if ((BB_END (then_bb)
5410        && JUMP_P (BB_END (then_bb))
5411        && CROSSING_JUMP_P (BB_END (then_bb)))
5412       || (JUMP_P (BB_END (test_bb))
5413             && CROSSING_JUMP_P (BB_END (test_bb)))
5414       || (BB_END (else_bb)
5415             && JUMP_P (BB_END (else_bb))
5416             && CROSSING_JUMP_P (BB_END (else_bb))))
5417     return FALSE;
5418 
5419   /* Verify test_bb ends in a conditional jump with no other side-effects.  */
5420   if (!onlyjump_p (BB_END (test_bb)))
5421     return FALSE;
5422 
5423   /* ELSE has one successor.  */
5424   if (!single_succ_p (else_bb))
5425     return FALSE;
5426   else
5427     else_succ = single_succ_edge (else_bb);
5428 
5429   /* ELSE outgoing edge is not complex.  */
5430   if (else_succ->flags & EDGE_COMPLEX)
5431     return FALSE;
5432 
5433   /* ELSE has one predecessor.  */
5434   if (!single_pred_p (else_bb))
5435     return FALSE;
5436 
5437   /* THEN is not EXIT.  */
5438   if (then_bb->index < NUM_FIXED_BLOCKS)
5439     return FALSE;
5440 
5441   else_prob = else_edge->probability;
5442   then_prob = else_prob.invert ();
5443 
5444   /* ELSE is predicted or SUCC(ELSE) postdominates THEN.  */
5445   if (else_prob > then_prob)
5446     ;
5447   else if (else_succ->dest->index < NUM_FIXED_BLOCKS
5448              || dominated_by_p (CDI_POST_DOMINATORS, then_bb,
5449                                     else_succ->dest))
5450     ;
5451   else
5452     return FALSE;
5453 
5454   num_possible_if_blocks++;
5455   if (dump_file)
5456     fprintf (dump_file,
5457                "\nIF-CASE-2 found, start %d, else %d\n",
5458                test_bb->index, else_bb->index);
5459 
5460   /* We're speculating from the ELSE path, we want to make sure the cost
5461      of speculation is within reason.  */
5462   if (! cheap_bb_rtx_cost_p (else_bb, else_prob,
5463           COSTS_N_INSNS (BRANCH_COST (optimize_bb_for_speed_p (else_edge->src),
5464                                             predictable_edge_p (else_edge)))))
5465     return FALSE;
5466 
5467   /* Registers set are dead, or are predicable.  */
5468   if (! dead_or_predicable (test_bb, else_bb, then_bb, else_succ, 0))
5469     return FALSE;
5470 
5471   /* Conversion went ok, including moving the insns and fixing up the
5472      jump.  Adjust the CFG to match.  */
5473 
5474   df_set_bb_dirty (test_bb);
5475   df_set_bb_dirty (then_bb);
5476   delete_basic_block (else_bb);
5477 
5478   num_true_changes++;
5479   num_updated_if_blocks++;
5480 
5481   /* ??? We may now fallthru from one of THEN's successors into a join
5482      block.  Rerun cleanup_cfg?  Examine things manually?  Wait?  */
5483 
5484   return TRUE;
5485 }
5486 
5487 /* Used by the code above to perform the actual rtl transformations.
5488    Return TRUE if successful.
5489 
5490    TEST_BB is the block containing the conditional branch.  MERGE_BB
5491    is the block containing the code to manipulate.  DEST_EDGE is an
5492    edge representing a jump to the join block; after the conversion,
5493    TEST_BB should be branching to its destination.
5494    REVERSEP is true if the sense of the branch should be reversed.  */
5495 
5496 static int
dead_or_predicable(basic_block test_bb,basic_block merge_bb,basic_block other_bb,edge dest_edge,int reversep)5497 dead_or_predicable (basic_block test_bb, basic_block merge_bb,
5498                         basic_block other_bb, edge dest_edge, int reversep)
5499 {
5500   basic_block new_dest = dest_edge->dest;
5501   rtx_insn *head, *end, *jump;
5502   rtx_insn *earliest = NULL;
5503   rtx old_dest;
5504   bitmap merge_set = NULL;
5505   /* Number of pending changes.  */
5506   int n_validated_changes = 0;
5507   rtx new_dest_label = NULL_RTX;
5508 
5509   jump = BB_END (test_bb);
5510 
5511   /* Find the extent of the real code in the merge block.  */
5512   head = BB_HEAD (merge_bb);
5513   end = BB_END (merge_bb);
5514 
5515   while (DEBUG_INSN_P (end) && end != head)
5516     end = PREV_INSN (end);
5517 
5518   /* If merge_bb ends with a tablejump, predicating/moving insn's
5519      into test_bb and then deleting merge_bb will result in the jumptable
5520      that follows merge_bb being removed along with merge_bb and then we
5521      get an unresolved reference to the jumptable.  */
5522   if (tablejump_p (end, NULL, NULL))
5523     return FALSE;
5524 
5525   if (LABEL_P (head))
5526     head = NEXT_INSN (head);
5527   while (DEBUG_INSN_P (head) && head != end)
5528     head = NEXT_INSN (head);
5529   if (NOTE_P (head))
5530     {
5531       if (head == end)
5532           {
5533             head = end = NULL;
5534             goto no_body;
5535           }
5536       head = NEXT_INSN (head);
5537       while (DEBUG_INSN_P (head) && head != end)
5538           head = NEXT_INSN (head);
5539     }
5540 
5541   if (JUMP_P (end))
5542     {
5543       if (!onlyjump_p (end))
5544           return FALSE;
5545       if (head == end)
5546           {
5547             head = end = NULL;
5548             goto no_body;
5549           }
5550       end = PREV_INSN (end);
5551       while (DEBUG_INSN_P (end) && end != head)
5552           end = PREV_INSN (end);
5553     }
5554 
5555   /* Don't move frame-related insn across the conditional branch.  This
5556      can lead to one of the paths of the branch having wrong unwind info.  */
5557   if (epilogue_completed)
5558     {
5559       rtx_insn *insn = head;
5560       while (1)
5561           {
5562             if (INSN_P (insn) && RTX_FRAME_RELATED_P (insn))
5563               return FALSE;
5564             if (insn == end)
5565               break;
5566             insn = NEXT_INSN (insn);
5567           }
5568     }
5569 
5570   /* Disable handling dead code by conditional execution if the machine needs
5571      to do anything funny with the tests, etc.  */
5572 #ifndef IFCVT_MODIFY_TESTS
5573   if (targetm.have_conditional_execution ())
5574     {
5575       /* In the conditional execution case, we have things easy.  We know
5576            the condition is reversible.  We don't have to check life info
5577            because we're going to conditionally execute the code anyway.
5578            All that's left is making sure the insns involved can actually
5579            be predicated.  */
5580 
5581       rtx cond;
5582 
5583       /* If the conditional jump is more than just a conditional jump,
5584            then we cannot do conditional execution conversion on this block.  */
5585       if (!onlyjump_p (jump))
5586           goto nce;
5587 
5588       cond = cond_exec_get_condition (jump);
5589       if (! cond)
5590           goto nce;
5591 
5592       rtx note = find_reg_note (jump, REG_BR_PROB, NULL_RTX);
5593       profile_probability prob_val
5594             = (note ? profile_probability::from_reg_br_prob_note (XINT (note, 0))
5595                : profile_probability::uninitialized ());
5596 
5597       if (reversep)
5598           {
5599             enum rtx_code rev = reversed_comparison_code (cond, jump);
5600             if (rev == UNKNOWN)
5601               return FALSE;
5602             cond = gen_rtx_fmt_ee (rev, GET_MODE (cond), XEXP (cond, 0),
5603                                        XEXP (cond, 1));
5604             prob_val = prob_val.invert ();
5605           }
5606 
5607       if (cond_exec_process_insns (NULL, head, end, cond, prob_val, 0)
5608             && verify_changes (0))
5609           n_validated_changes = num_validated_changes ();
5610       else
5611           cancel_changes (0);
5612 
5613       earliest = jump;
5614     }
5615  nce:
5616 #endif
5617 
5618   /* If we allocated new pseudos (e.g. in the conditional move
5619      expander called from noce_emit_cmove), we must resize the
5620      array first.  */
5621   if (max_regno < max_reg_num ())
5622     max_regno = max_reg_num ();
5623 
5624   /* Try the NCE path if the CE path did not result in any changes.  */
5625   if (n_validated_changes == 0)
5626     {
5627       rtx cond;
5628       rtx_insn *insn;
5629       regset live;
5630       bool success;
5631 
5632       /* In the non-conditional execution case, we have to verify that there
5633            are no trapping operations, no calls, no references to memory, and
5634            that any registers modified are dead at the branch site.  */
5635 
5636       if (!any_condjump_p (jump))
5637           return FALSE;
5638 
5639       /* Find the extent of the conditional.  */
5640       cond = noce_get_condition (jump, &earliest, false);
5641       if (!cond)
5642           return FALSE;
5643 
5644       live = BITMAP_ALLOC (&reg_obstack);
5645       simulate_backwards_to_point (merge_bb, live, end);
5646       success = can_move_insns_across (head, end, earliest, jump,
5647                                                merge_bb, live,
5648                                                df_get_live_in (other_bb), NULL);
5649       BITMAP_FREE (live);
5650       if (!success)
5651           return FALSE;
5652 
5653       /* Collect the set of registers set in MERGE_BB.  */
5654       merge_set = BITMAP_ALLOC (&reg_obstack);
5655 
5656       FOR_BB_INSNS (merge_bb, insn)
5657           if (NONDEBUG_INSN_P (insn))
5658             df_simulate_find_defs (insn, merge_set);
5659 
5660       /* If shrink-wrapping, disable this optimization when test_bb is
5661            the first basic block and merge_bb exits.  The idea is to not
5662            move code setting up a return register as that may clobber a
5663            register used to pass function parameters, which then must be
5664            saved in caller-saved regs.  A caller-saved reg requires the
5665            prologue, killing a shrink-wrap opportunity.  */
5666       if ((SHRINK_WRAPPING_ENABLED && !epilogue_completed)
5667             && ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb == test_bb
5668             && single_succ_p (new_dest)
5669             && single_succ (new_dest) == EXIT_BLOCK_PTR_FOR_FN (cfun)
5670             && bitmap_intersect_p (df_get_live_in (new_dest), merge_set))
5671           {
5672             regset return_regs;
5673             unsigned int i;
5674 
5675             return_regs = BITMAP_ALLOC (&reg_obstack);
5676 
5677             /* Start off with the intersection of regs used to pass
5678                params and regs used to return values.  */
5679             for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
5680               if (FUNCTION_ARG_REGNO_P (i)
5681                     && targetm.calls.function_value_regno_p (i))
5682                 bitmap_set_bit (return_regs, INCOMING_REGNO (i));
5683 
5684             bitmap_and_into (return_regs,
5685                                  df_get_live_out (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
5686             bitmap_and_into (return_regs,
5687                                  df_get_live_in (EXIT_BLOCK_PTR_FOR_FN (cfun)));
5688             if (!bitmap_empty_p (return_regs))
5689               {
5690                 FOR_BB_INSNS_REVERSE (new_dest, insn)
5691                     if (NONDEBUG_INSN_P (insn))
5692                       {
5693                         df_ref def;
5694 
5695                         /* If this insn sets any reg in return_regs, add all
5696                            reg uses to the set of regs we're interested in.  */
5697                         FOR_EACH_INSN_DEF (def, insn)
5698                           if (bitmap_bit_p (return_regs, DF_REF_REGNO (def)))
5699                               {
5700                                 df_simulate_uses (insn, return_regs);
5701                                 break;
5702                               }
5703                       }
5704                 if (bitmap_intersect_p (merge_set, return_regs))
5705                     {
5706                       BITMAP_FREE (return_regs);
5707                       BITMAP_FREE (merge_set);
5708                       return FALSE;
5709                     }
5710               }
5711             BITMAP_FREE (return_regs);
5712           }
5713     }
5714 
5715  no_body:
5716   /* We don't want to use normal invert_jump or redirect_jump because
5717      we don't want to delete_insn called.  Also, we want to do our own
5718      change group management.  */
5719 
5720   old_dest = JUMP_LABEL (jump);
5721   if (other_bb != new_dest)
5722     {
5723       if (!any_condjump_p (jump))
5724           goto cancel;
5725 
5726       if (JUMP_P (BB_END (dest_edge->src)))
5727           new_dest_label = JUMP_LABEL (BB_END (dest_edge->src));
5728       else if (new_dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
5729           new_dest_label = ret_rtx;
5730       else
5731           new_dest_label = block_label (new_dest);
5732 
5733       rtx_jump_insn *jump_insn = as_a <rtx_jump_insn *> (jump);
5734       if (reversep
5735             ? ! invert_jump_1 (jump_insn, new_dest_label)
5736             : ! redirect_jump_1 (jump_insn, new_dest_label))
5737           goto cancel;
5738     }
5739 
5740   if (verify_changes (n_validated_changes))
5741     confirm_change_group ();
5742   else
5743     goto cancel;
5744 
5745   if (other_bb != new_dest)
5746     {
5747       redirect_jump_2 (as_a <rtx_jump_insn *> (jump), old_dest, new_dest_label,
5748                            0, reversep);
5749 
5750       redirect_edge_succ (BRANCH_EDGE (test_bb), new_dest);
5751       if (reversep)
5752           {
5753             std::swap (BRANCH_EDGE (test_bb)->probability,
5754                          FALLTHRU_EDGE (test_bb)->probability);
5755             update_br_prob_note (test_bb);
5756           }
5757     }
5758 
5759   /* Move the insns out of MERGE_BB to before the branch.  */
5760   if (head != NULL)
5761     {
5762       rtx_insn *insn;
5763 
5764       if (end == BB_END (merge_bb))
5765           BB_END (merge_bb) = PREV_INSN (head);
5766 
5767       /* PR 21767: when moving insns above a conditional branch, the REG_EQUAL
5768            notes being moved might become invalid.  */
5769       insn = head;
5770       do
5771           {
5772             rtx note;
5773 
5774             if (! INSN_P (insn))
5775               continue;
5776             note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
5777             if (! note)
5778               continue;
5779             remove_note (insn, note);
5780           } while (insn != end && (insn = NEXT_INSN (insn)));
5781 
5782       /* PR46315: when moving insns above a conditional branch, the REG_EQUAL
5783            notes referring to the registers being set might become invalid.  */
5784       if (merge_set)
5785           {
5786             unsigned i;
5787             bitmap_iterator bi;
5788 
5789             EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)
5790               remove_reg_equal_equiv_notes_for_regno (i);
5791 
5792             BITMAP_FREE (merge_set);
5793           }
5794 
5795       reorder_insns (head, end, PREV_INSN (earliest));
5796     }
5797 
5798   /* Remove the jump and edge if we can.  */
5799   if (other_bb == new_dest)
5800     {
5801       delete_insn (jump);
5802       remove_edge (BRANCH_EDGE (test_bb));
5803       /* ??? Can't merge blocks here, as then_bb is still in use.
5804            At minimum, the merge will get done just before bb-reorder.  */
5805     }
5806 
5807   return TRUE;
5808 
5809  cancel:
5810   cancel_changes (0);
5811 
5812   if (merge_set)
5813     BITMAP_FREE (merge_set);
5814 
5815   return FALSE;
5816 }
5817 
5818 /* Main entry point for all if-conversion.  AFTER_COMBINE is true if
5819    we are after combine pass.  */
5820 
5821 static void
if_convert(bool after_combine)5822 if_convert (bool after_combine)
5823 {
5824   basic_block bb;
5825   int pass;
5826 
5827   if (optimize == 1)
5828     {
5829       df_live_add_problem ();
5830       df_live_set_all_dirty ();
5831     }
5832 
5833   /* Record whether we are after combine pass.  */
5834   ifcvt_after_combine = after_combine;
5835   have_cbranchcc4 = (direct_optab_handler (cbranch_optab, CCmode)
5836                          != CODE_FOR_nothing);
5837   num_possible_if_blocks = 0;
5838   num_updated_if_blocks = 0;
5839   num_true_changes = 0;
5840 
5841   loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
5842   mark_loop_exit_edges ();
5843   loop_optimizer_finalize ();
5844   free_dominance_info (CDI_DOMINATORS);
5845 
5846   /* Compute postdominators.  */
5847   calculate_dominance_info (CDI_POST_DOMINATORS);
5848 
5849   df_set_flags (DF_LR_RUN_DCE);
5850 
5851   /* Go through each of the basic blocks looking for things to convert.  If we
5852      have conditional execution, we make multiple passes to allow us to handle
5853      IF-THEN{-ELSE} blocks within other IF-THEN{-ELSE} blocks.  */
5854   pass = 0;
5855   do
5856     {
5857       df_analyze ();
5858       /* Only need to do dce on the first pass.  */
5859       df_clear_flags (DF_LR_RUN_DCE);
5860       cond_exec_changed_p = FALSE;
5861       pass++;
5862 
5863 #ifdef IFCVT_MULTIPLE_DUMPS
5864       if (dump_file && pass > 1)
5865           fprintf (dump_file, "\n\n========== Pass %d ==========\n", pass);
5866 #endif
5867 
5868       FOR_EACH_BB_FN (bb, cfun)
5869           {
5870           basic_block new_bb;
5871           while (!df_get_bb_dirty (bb)
5872                  && (new_bb = find_if_header (bb, pass)) != NULL)
5873             bb = new_bb;
5874           }
5875 
5876 #ifdef IFCVT_MULTIPLE_DUMPS
5877       if (dump_file && cond_exec_changed_p)
5878           print_rtl_with_bb (dump_file, get_insns (), dump_flags);
5879 #endif
5880     }
5881   while (cond_exec_changed_p);
5882 
5883 #ifdef IFCVT_MULTIPLE_DUMPS
5884   if (dump_file)
5885     fprintf (dump_file, "\n\n========== no more changes\n");
5886 #endif
5887 
5888   free_dominance_info (CDI_POST_DOMINATORS);
5889 
5890   if (dump_file)
5891     fflush (dump_file);
5892 
5893   clear_aux_for_blocks ();
5894 
5895   /* If we allocated new pseudos, we must resize the array for sched1.  */
5896   if (max_regno < max_reg_num ())
5897     max_regno = max_reg_num ();
5898 
5899   /* Write the final stats.  */
5900   if (dump_file && num_possible_if_blocks > 0)
5901     {
5902       fprintf (dump_file,
5903                  "\n%d possible IF blocks searched.\n",
5904                  num_possible_if_blocks);
5905       fprintf (dump_file,
5906                  "%d IF blocks converted.\n",
5907                  num_updated_if_blocks);
5908       fprintf (dump_file,
5909                  "%d true changes made.\n\n\n",
5910                  num_true_changes);
5911     }
5912 
5913   if (optimize == 1)
5914     df_remove_problem (df_live);
5915 
5916   /* Some non-cold blocks may now be only reachable from cold blocks.
5917      Fix that up.  */
5918   fixup_partitions ();
5919 
5920   checking_verify_flow_info ();
5921 }
5922 
5923 /* If-conversion and CFG cleanup.  */
5924 static unsigned int
rest_of_handle_if_conversion(void)5925 rest_of_handle_if_conversion (void)
5926 {
5927   int flags = 0;
5928 
5929   if (flag_if_conversion)
5930     {
5931       if (dump_file)
5932           {
5933             dump_reg_info (dump_file);
5934             dump_flow_info (dump_file, dump_flags);
5935           }
5936       cleanup_cfg (CLEANUP_EXPENSIVE);
5937       if_convert (false);
5938       if (num_updated_if_blocks)
5939           /* Get rid of any dead CC-related instructions.  */
5940           flags |= CLEANUP_FORCE_FAST_DCE;
5941     }
5942 
5943   cleanup_cfg (flags);
5944   return 0;
5945 }
5946 
5947 namespace {
5948 
5949 const pass_data pass_data_rtl_ifcvt =
5950 {
5951   RTL_PASS, /* type */
5952   "ce1", /* name */
5953   OPTGROUP_NONE, /* optinfo_flags */
5954   TV_IFCVT, /* tv_id */
5955   0, /* properties_required */
5956   0, /* properties_provided */
5957   0, /* properties_destroyed */
5958   0, /* todo_flags_start */
5959   TODO_df_finish, /* todo_flags_finish */
5960 };
5961 
5962 class pass_rtl_ifcvt : public rtl_opt_pass
5963 {
5964 public:
pass_rtl_ifcvt(gcc::context * ctxt)5965   pass_rtl_ifcvt (gcc::context *ctxt)
5966     : rtl_opt_pass (pass_data_rtl_ifcvt, ctxt)
5967   {}
5968 
5969   /* opt_pass methods: */
gate(function *)5970   virtual bool gate (function *)
5971     {
5972       return (optimize > 0) && dbg_cnt (if_conversion);
5973     }
5974 
execute(function *)5975   virtual unsigned int execute (function *)
5976     {
5977       return rest_of_handle_if_conversion ();
5978     }
5979 
5980 }; // class pass_rtl_ifcvt
5981 
5982 } // anon namespace
5983 
5984 rtl_opt_pass *
make_pass_rtl_ifcvt(gcc::context * ctxt)5985 make_pass_rtl_ifcvt (gcc::context *ctxt)
5986 {
5987   return new pass_rtl_ifcvt (ctxt);
5988 }
5989 
5990 
5991 /* Rerun if-conversion, as combine may have simplified things enough
5992    to now meet sequence length restrictions.  */
5993 
5994 namespace {
5995 
5996 const pass_data pass_data_if_after_combine =
5997 {
5998   RTL_PASS, /* type */
5999   "ce2", /* name */
6000   OPTGROUP_NONE, /* optinfo_flags */
6001   TV_IFCVT, /* tv_id */
6002   0, /* properties_required */
6003   0, /* properties_provided */
6004   0, /* properties_destroyed */
6005   0, /* todo_flags_start */
6006   TODO_df_finish, /* todo_flags_finish */
6007 };
6008 
6009 class pass_if_after_combine : public rtl_opt_pass
6010 {
6011 public:
pass_if_after_combine(gcc::context * ctxt)6012   pass_if_after_combine (gcc::context *ctxt)
6013     : rtl_opt_pass (pass_data_if_after_combine, ctxt)
6014   {}
6015 
6016   /* opt_pass methods: */
gate(function *)6017   virtual bool gate (function *)
6018     {
6019       return optimize > 0 && flag_if_conversion
6020           && dbg_cnt (if_after_combine);
6021     }
6022 
execute(function *)6023   virtual unsigned int execute (function *)
6024     {
6025       if_convert (true);
6026       return 0;
6027     }
6028 
6029 }; // class pass_if_after_combine
6030 
6031 } // anon namespace
6032 
6033 rtl_opt_pass *
make_pass_if_after_combine(gcc::context * ctxt)6034 make_pass_if_after_combine (gcc::context *ctxt)
6035 {
6036   return new pass_if_after_combine (ctxt);
6037 }
6038 
6039 
6040 namespace {
6041 
6042 const pass_data pass_data_if_after_reload =
6043 {
6044   RTL_PASS, /* type */
6045   "ce3", /* name */
6046   OPTGROUP_NONE, /* optinfo_flags */
6047   TV_IFCVT2, /* tv_id */
6048   0, /* properties_required */
6049   0, /* properties_provided */
6050   0, /* properties_destroyed */
6051   0, /* todo_flags_start */
6052   TODO_df_finish, /* todo_flags_finish */
6053 };
6054 
6055 class pass_if_after_reload : public rtl_opt_pass
6056 {
6057 public:
pass_if_after_reload(gcc::context * ctxt)6058   pass_if_after_reload (gcc::context *ctxt)
6059     : rtl_opt_pass (pass_data_if_after_reload, ctxt)
6060   {}
6061 
6062   /* opt_pass methods: */
gate(function *)6063   virtual bool gate (function *)
6064     {
6065       return optimize > 0 && flag_if_conversion2
6066           && dbg_cnt (if_after_reload);
6067     }
6068 
execute(function *)6069   virtual unsigned int execute (function *)
6070     {
6071       if_convert (true);
6072       return 0;
6073     }
6074 
6075 }; // class pass_if_after_reload
6076 
6077 } // anon namespace
6078 
6079 rtl_opt_pass *
make_pass_if_after_reload(gcc::context * ctxt)6080 make_pass_if_after_reload (gcc::context *ctxt)
6081 {
6082   return new pass_if_after_reload (ctxt);
6083 }
6084