xref: /netbsd-src/external/gpl3/gcc/dist/gcc/ifcvt.cc (revision b1e838363e3c6fc78a55519254d99869742dd33c)
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