1 /* Optimization of PHI nodes by converting them into straightline code.
2    Copyright (C) 2004-2014 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 the
8 Free Software Foundation; either version 3, or (at your option) any
9 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 or
13 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 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 "hash-table.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "stor-layout.h"
27 #include "flags.h"
28 #include "tm_p.h"
29 #include "basic-block.h"
30 #include "pointer-set.h"
31 #include "tree-ssa-alias.h"
32 #include "internal-fn.h"
33 #include "gimple-expr.h"
34 #include "is-a.h"
35 #include "gimple.h"
36 #include "gimplify.h"
37 #include "gimple-iterator.h"
38 #include "gimplify-me.h"
39 #include "gimple-ssa.h"
40 #include "tree-cfg.h"
41 #include "tree-phinodes.h"
42 #include "ssa-iterators.h"
43 #include "stringpool.h"
44 #include "tree-ssanames.h"
45 #include "expr.h"
46 #include "tree-dfa.h"
47 #include "tree-pass.h"
48 #include "langhooks.h"
49 #include "domwalk.h"
50 #include "cfgloop.h"
51 #include "tree-data-ref.h"
52 #include "gimple-pretty-print.h"
53 #include "insn-config.h"
54 #include "expr.h"
55 #include "optabs.h"
56 #include "tree-scalar-evolution.h"
57 
58 #ifndef HAVE_conditional_move
59 #define HAVE_conditional_move (0)
60 #endif
61 
62 static unsigned int tree_ssa_phiopt (void);
63 static unsigned int tree_ssa_phiopt_worker (bool, bool);
64 static bool conditional_replacement (basic_block, basic_block,
65 				     edge, edge, gimple, tree, tree);
66 static int value_replacement (basic_block, basic_block,
67 			      edge, edge, gimple, tree, tree);
68 static bool minmax_replacement (basic_block, basic_block,
69 				edge, edge, gimple, tree, tree);
70 static bool abs_replacement (basic_block, basic_block,
71 			     edge, edge, gimple, tree, tree);
72 static bool neg_replacement (basic_block, basic_block,
73 			     edge, edge, gimple, tree, tree);
74 static bool cond_store_replacement (basic_block, basic_block, edge, edge,
75 				    struct pointer_set_t *);
76 static bool cond_if_else_store_replacement (basic_block, basic_block, basic_block);
77 static struct pointer_set_t * get_non_trapping (void);
78 static void replace_phi_edge_with_variable (basic_block, edge, gimple, tree);
79 static void hoist_adjacent_loads (basic_block, basic_block,
80 				  basic_block, basic_block);
81 static bool gate_hoist_loads (void);
82 
83 /* This pass tries to replaces an if-then-else block with an
84    assignment.  We have four kinds of transformations.  Some of these
85    transformations are also performed by the ifcvt RTL optimizer.
86 
87    Conditional Replacement
88    -----------------------
89 
90    This transformation, implemented in conditional_replacement,
91    replaces
92 
93      bb0:
94       if (cond) goto bb2; else goto bb1;
95      bb1:
96      bb2:
97       x = PHI <0 (bb1), 1 (bb0), ...>;
98 
99    with
100 
101      bb0:
102       x' = cond;
103       goto bb2;
104      bb2:
105       x = PHI <x' (bb0), ...>;
106 
107    We remove bb1 as it becomes unreachable.  This occurs often due to
108    gimplification of conditionals.
109 
110    Value Replacement
111    -----------------
112 
113    This transformation, implemented in value_replacement, replaces
114 
115      bb0:
116        if (a != b) goto bb2; else goto bb1;
117      bb1:
118      bb2:
119        x = PHI <a (bb1), b (bb0), ...>;
120 
121    with
122 
123      bb0:
124      bb2:
125        x = PHI <b (bb0), ...>;
126 
127    This opportunity can sometimes occur as a result of other
128    optimizations.
129 
130 
131    Another case caught by value replacement looks like this:
132 
133      bb0:
134        t1 = a == CONST;
135        t2 = b > c;
136        t3 = t1 & t2;
137        if (t3 != 0) goto bb1; else goto bb2;
138      bb1:
139      bb2:
140        x = PHI (CONST, a)
141 
142    Gets replaced with:
143      bb0:
144      bb2:
145        t1 = a == CONST;
146        t2 = b > c;
147        t3 = t1 & t2;
148        x = a;
149 
150    ABS Replacement
151    ---------------
152 
153    This transformation, implemented in abs_replacement, replaces
154 
155      bb0:
156        if (a >= 0) goto bb2; else goto bb1;
157      bb1:
158        x = -a;
159      bb2:
160        x = PHI <x (bb1), a (bb0), ...>;
161 
162    with
163 
164      bb0:
165        x' = ABS_EXPR< a >;
166      bb2:
167        x = PHI <x' (bb0), ...>;
168 
169    MIN/MAX Replacement
170    -------------------
171 
172    This transformation, minmax_replacement replaces
173 
174      bb0:
175        if (a <= b) goto bb2; else goto bb1;
176      bb1:
177      bb2:
178        x = PHI <b (bb1), a (bb0), ...>;
179 
180    with
181 
182      bb0:
183        x' = MIN_EXPR (a, b)
184      bb2:
185        x = PHI <x' (bb0), ...>;
186 
187    A similar transformation is done for MAX_EXPR.
188 
189 
190    This pass also performs a fifth transformation of a slightly different
191    flavor.
192 
193    Adjacent Load Hoisting
194    ----------------------
195 
196    This transformation replaces
197 
198      bb0:
199        if (...) goto bb2; else goto bb1;
200      bb1:
201        x1 = (<expr>).field1;
202        goto bb3;
203      bb2:
204        x2 = (<expr>).field2;
205      bb3:
206        # x = PHI <x1, x2>;
207 
208    with
209 
210      bb0:
211        x1 = (<expr>).field1;
212        x2 = (<expr>).field2;
213        if (...) goto bb2; else goto bb1;
214      bb1:
215        goto bb3;
216      bb2:
217      bb3:
218        # x = PHI <x1, x2>;
219 
220    The purpose of this transformation is to enable generation of conditional
221    move instructions such as Intel CMOVE or PowerPC ISEL.  Because one of
222    the loads is speculative, the transformation is restricted to very
223    specific cases to avoid introducing a page fault.  We are looking for
224    the common idiom:
225 
226      if (...)
227        x = y->left;
228      else
229        x = y->right;
230 
231    where left and right are typically adjacent pointers in a tree structure.  */
232 
233 static unsigned int
tree_ssa_phiopt(void)234 tree_ssa_phiopt (void)
235 {
236   return tree_ssa_phiopt_worker (false, gate_hoist_loads ());
237 }
238 
239 /* This pass tries to transform conditional stores into unconditional
240    ones, enabling further simplifications with the simpler then and else
241    blocks.  In particular it replaces this:
242 
243      bb0:
244        if (cond) goto bb2; else goto bb1;
245      bb1:
246        *p = RHS;
247      bb2:
248 
249    with
250 
251      bb0:
252        if (cond) goto bb1; else goto bb2;
253      bb1:
254        condtmp' = *p;
255      bb2:
256        condtmp = PHI <RHS, condtmp'>
257        *p = condtmp;
258 
259    This transformation can only be done under several constraints,
260    documented below.  It also replaces:
261 
262      bb0:
263        if (cond) goto bb2; else goto bb1;
264      bb1:
265        *p = RHS1;
266        goto bb3;
267      bb2:
268        *p = RHS2;
269      bb3:
270 
271    with
272 
273      bb0:
274        if (cond) goto bb3; else goto bb1;
275      bb1:
276      bb3:
277        condtmp = PHI <RHS1, RHS2>
278        *p = condtmp;  */
279 
280 static unsigned int
tree_ssa_cs_elim(void)281 tree_ssa_cs_elim (void)
282 {
283   unsigned todo;
284   /* ???  We are not interested in loop related info, but the following
285      will create it, ICEing as we didn't init loops with pre-headers.
286      An interfacing issue of find_data_references_in_bb.  */
287   loop_optimizer_init (LOOPS_NORMAL);
288   scev_initialize ();
289   todo = tree_ssa_phiopt_worker (true, false);
290   scev_finalize ();
291   loop_optimizer_finalize ();
292   return todo;
293 }
294 
295 /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */
296 
297 static gimple
single_non_singleton_phi_for_edges(gimple_seq seq,edge e0,edge e1)298 single_non_singleton_phi_for_edges (gimple_seq seq, edge e0, edge e1)
299 {
300   gimple_stmt_iterator i;
301   gimple phi = NULL;
302   if (gimple_seq_singleton_p (seq))
303     return gsi_stmt (gsi_start (seq));
304   for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
305     {
306       gimple p = gsi_stmt (i);
307       /* If the PHI arguments are equal then we can skip this PHI. */
308       if (operand_equal_for_phi_arg_p (gimple_phi_arg_def (p, e0->dest_idx),
309 				       gimple_phi_arg_def (p, e1->dest_idx)))
310 	continue;
311 
312       /* If we already have a PHI that has the two edge arguments are
313 	 different, then return it is not a singleton for these PHIs. */
314       if (phi)
315 	return NULL;
316 
317       phi = p;
318     }
319   return phi;
320 }
321 
322 /* The core routine of conditional store replacement and normal
323    phi optimizations.  Both share much of the infrastructure in how
324    to match applicable basic block patterns.  DO_STORE_ELIM is true
325    when we want to do conditional store replacement, false otherwise.
326    DO_HOIST_LOADS is true when we want to hoist adjacent loads out
327    of diamond control flow patterns, false otherwise.  */
328 static unsigned int
tree_ssa_phiopt_worker(bool do_store_elim,bool do_hoist_loads)329 tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads)
330 {
331   basic_block bb;
332   basic_block *bb_order;
333   unsigned n, i;
334   bool cfgchanged = false;
335   struct pointer_set_t *nontrap = 0;
336 
337   if (do_store_elim)
338     /* Calculate the set of non-trapping memory accesses.  */
339     nontrap = get_non_trapping ();
340 
341   /* The replacement of conditional negation with a non-branching
342      sequence is really only a win when optimizing for speed and we
343      can avoid transformations by gimple if-conversion that result
344      in poor RTL generation.
345 
346      Ideally either gimple if-conversion or the RTL expanders will
347      be improved and the code to emit branchless conditional negation
348      can be removed.  */
349   bool replace_conditional_negation = false;
350   if (!do_store_elim)
351     replace_conditional_negation
352       = ((!optimize_size && optimize >= 2)
353 	 || (((flag_tree_loop_vectorize || cfun->has_force_vect_loops)
354 	      && flag_tree_loop_if_convert != 0)
355 	     || flag_tree_loop_if_convert == 1
356 	     || flag_tree_loop_if_convert_stores == 1));
357 
358   /* Search every basic block for COND_EXPR we may be able to optimize.
359 
360      We walk the blocks in order that guarantees that a block with
361      a single predecessor is processed before the predecessor.
362      This ensures that we collapse inner ifs before visiting the
363      outer ones, and also that we do not try to visit a removed
364      block.  */
365   bb_order = single_pred_before_succ_order ();
366   n = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
367 
368   for (i = 0; i < n; i++)
369     {
370       gimple cond_stmt, phi;
371       basic_block bb1, bb2;
372       edge e1, e2;
373       tree arg0, arg1;
374 
375       bb = bb_order[i];
376 
377       cond_stmt = last_stmt (bb);
378       /* Check to see if the last statement is a GIMPLE_COND.  */
379       if (!cond_stmt
380           || gimple_code (cond_stmt) != GIMPLE_COND)
381         continue;
382 
383       e1 = EDGE_SUCC (bb, 0);
384       bb1 = e1->dest;
385       e2 = EDGE_SUCC (bb, 1);
386       bb2 = e2->dest;
387 
388       /* We cannot do the optimization on abnormal edges.  */
389       if ((e1->flags & EDGE_ABNORMAL) != 0
390           || (e2->flags & EDGE_ABNORMAL) != 0)
391        continue;
392 
393       /* If either bb1's succ or bb2 or bb2's succ is non NULL.  */
394       if (EDGE_COUNT (bb1->succs) == 0
395           || bb2 == NULL
396 	  || EDGE_COUNT (bb2->succs) == 0)
397         continue;
398 
399       /* Find the bb which is the fall through to the other.  */
400       if (EDGE_SUCC (bb1, 0)->dest == bb2)
401         ;
402       else if (EDGE_SUCC (bb2, 0)->dest == bb1)
403         {
404 	  basic_block bb_tmp = bb1;
405 	  edge e_tmp = e1;
406 	  bb1 = bb2;
407 	  bb2 = bb_tmp;
408 	  e1 = e2;
409 	  e2 = e_tmp;
410 	}
411       else if (do_store_elim
412 	       && EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest)
413 	{
414 	  basic_block bb3 = EDGE_SUCC (bb1, 0)->dest;
415 
416 	  if (!single_succ_p (bb1)
417 	      || (EDGE_SUCC (bb1, 0)->flags & EDGE_FALLTHRU) == 0
418 	      || !single_succ_p (bb2)
419 	      || (EDGE_SUCC (bb2, 0)->flags & EDGE_FALLTHRU) == 0
420 	      || EDGE_COUNT (bb3->preds) != 2)
421 	    continue;
422 	  if (cond_if_else_store_replacement (bb1, bb2, bb3))
423 	    cfgchanged = true;
424 	  continue;
425 	}
426       else if (do_hoist_loads
427 		 && EDGE_SUCC (bb1, 0)->dest == EDGE_SUCC (bb2, 0)->dest)
428 	{
429 	  basic_block bb3 = EDGE_SUCC (bb1, 0)->dest;
430 
431 	  if (!FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (cond_stmt)))
432 	      && single_succ_p (bb1)
433 	      && single_succ_p (bb2)
434 	      && single_pred_p (bb1)
435 	      && single_pred_p (bb2)
436 	      && EDGE_COUNT (bb->succs) == 2
437 	      && EDGE_COUNT (bb3->preds) == 2
438 	      /* If one edge or the other is dominant, a conditional move
439 		 is likely to perform worse than the well-predicted branch.  */
440 	      && !predictable_edge_p (EDGE_SUCC (bb, 0))
441 	      && !predictable_edge_p (EDGE_SUCC (bb, 1)))
442 	    hoist_adjacent_loads (bb, bb1, bb2, bb3);
443 	  continue;
444 	}
445       else
446 	continue;
447 
448       e1 = EDGE_SUCC (bb1, 0);
449 
450       /* Make sure that bb1 is just a fall through.  */
451       if (!single_succ_p (bb1)
452 	  || (e1->flags & EDGE_FALLTHRU) == 0)
453         continue;
454 
455       /* Also make sure that bb1 only have one predecessor and that it
456 	 is bb.  */
457       if (!single_pred_p (bb1)
458           || single_pred (bb1) != bb)
459 	continue;
460 
461       if (do_store_elim)
462 	{
463 	  /* bb1 is the middle block, bb2 the join block, bb the split block,
464 	     e1 the fallthrough edge from bb1 to bb2.  We can't do the
465 	     optimization if the join block has more than two predecessors.  */
466 	  if (EDGE_COUNT (bb2->preds) > 2)
467 	    continue;
468 	  if (cond_store_replacement (bb1, bb2, e1, e2, nontrap))
469 	    cfgchanged = true;
470 	}
471       else
472 	{
473 	  gimple_seq phis = phi_nodes (bb2);
474 	  gimple_stmt_iterator gsi;
475 	  bool candorest = true;
476 
477 	  /* Value replacement can work with more than one PHI
478 	     so try that first. */
479 	  for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
480 	    {
481 	      phi = gsi_stmt (gsi);
482 	      arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
483 	      arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
484 	      if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1) == 2)
485 		{
486 		  candorest = false;
487 	          cfgchanged = true;
488 		  break;
489 		}
490 	    }
491 
492 	  if (!candorest)
493 	    continue;
494 
495 	  phi = single_non_singleton_phi_for_edges (phis, e1, e2);
496 	  if (!phi)
497 	    continue;
498 
499 	  arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
500 	  arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
501 
502 	  /* Something is wrong if we cannot find the arguments in the PHI
503 	     node.  */
504 	  gcc_assert (arg0 != NULL && arg1 != NULL);
505 
506 	  /* Do the replacement of conditional if it can be done.  */
507 	  if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
508 	    cfgchanged = true;
509 	  else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
510 	    cfgchanged = true;
511 	  else if (replace_conditional_negation
512 		   && neg_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
513 	    cfgchanged = true;
514 	  else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
515 	    cfgchanged = true;
516 	}
517     }
518 
519   free (bb_order);
520 
521   if (do_store_elim)
522     pointer_set_destroy (nontrap);
523   /* If the CFG has changed, we should cleanup the CFG.  */
524   if (cfgchanged && do_store_elim)
525     {
526       /* In cond-store replacement we have added some loads on edges
527          and new VOPS (as we moved the store, and created a load).  */
528       gsi_commit_edge_inserts ();
529       return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals;
530     }
531   else if (cfgchanged)
532     return TODO_cleanup_cfg;
533   return 0;
534 }
535 
536 /* Replace PHI node element whose edge is E in block BB with variable NEW.
537    Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
538    is known to have two edges, one of which must reach BB).  */
539 
540 static void
replace_phi_edge_with_variable(basic_block cond_block,edge e,gimple phi,tree new_tree)541 replace_phi_edge_with_variable (basic_block cond_block,
542 				edge e, gimple phi, tree new_tree)
543 {
544   basic_block bb = gimple_bb (phi);
545   basic_block block_to_remove;
546   gimple_stmt_iterator gsi;
547 
548   /* Change the PHI argument to new.  */
549   SET_USE (PHI_ARG_DEF_PTR (phi, e->dest_idx), new_tree);
550 
551   /* Remove the empty basic block.  */
552   if (EDGE_SUCC (cond_block, 0)->dest == bb)
553     {
554       EDGE_SUCC (cond_block, 0)->flags |= EDGE_FALLTHRU;
555       EDGE_SUCC (cond_block, 0)->flags &= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
556       EDGE_SUCC (cond_block, 0)->probability = REG_BR_PROB_BASE;
557       EDGE_SUCC (cond_block, 0)->count += EDGE_SUCC (cond_block, 1)->count;
558 
559       block_to_remove = EDGE_SUCC (cond_block, 1)->dest;
560     }
561   else
562     {
563       EDGE_SUCC (cond_block, 1)->flags |= EDGE_FALLTHRU;
564       EDGE_SUCC (cond_block, 1)->flags
565 	&= ~(EDGE_TRUE_VALUE | EDGE_FALSE_VALUE);
566       EDGE_SUCC (cond_block, 1)->probability = REG_BR_PROB_BASE;
567       EDGE_SUCC (cond_block, 1)->count += EDGE_SUCC (cond_block, 0)->count;
568 
569       block_to_remove = EDGE_SUCC (cond_block, 0)->dest;
570     }
571   delete_basic_block (block_to_remove);
572 
573   /* Eliminate the COND_EXPR at the end of COND_BLOCK.  */
574   gsi = gsi_last_bb (cond_block);
575   gsi_remove (&gsi, true);
576 
577   if (dump_file && (dump_flags & TDF_DETAILS))
578     fprintf (dump_file,
579 	      "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
580 	      cond_block->index,
581 	      bb->index);
582 }
583 
584 /*  The function conditional_replacement does the main work of doing the
585     conditional replacement.  Return true if the replacement is done.
586     Otherwise return false.
587     BB is the basic block where the replacement is going to be done on.  ARG0
588     is argument 0 from PHI.  Likewise for ARG1.  */
589 
590 static bool
conditional_replacement(basic_block cond_bb,basic_block middle_bb,edge e0,edge e1,gimple phi,tree arg0,tree arg1)591 conditional_replacement (basic_block cond_bb, basic_block middle_bb,
592 			 edge e0, edge e1, gimple phi,
593 			 tree arg0, tree arg1)
594 {
595   tree result;
596   gimple stmt, new_stmt;
597   tree cond;
598   gimple_stmt_iterator gsi;
599   edge true_edge, false_edge;
600   tree new_var, new_var2;
601   bool neg;
602 
603   /* FIXME: Gimplification of complex type is too hard for now.  */
604   /* We aren't prepared to handle vectors either (and it is a question
605      if it would be worthwhile anyway).  */
606   if (!(INTEGRAL_TYPE_P (TREE_TYPE (arg0))
607 	|| POINTER_TYPE_P (TREE_TYPE (arg0)))
608       || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1))
609 	   || POINTER_TYPE_P (TREE_TYPE (arg1))))
610     return false;
611 
612   /* The PHI arguments have the constants 0 and 1, or 0 and -1, then
613      convert it to the conditional.  */
614   if ((integer_zerop (arg0) && integer_onep (arg1))
615       || (integer_zerop (arg1) && integer_onep (arg0)))
616     neg = false;
617   else if ((integer_zerop (arg0) && integer_all_onesp (arg1))
618 	   || (integer_zerop (arg1) && integer_all_onesp (arg0)))
619     neg = true;
620   else
621     return false;
622 
623   if (!empty_block_p (middle_bb))
624     return false;
625 
626   /* At this point we know we have a GIMPLE_COND with two successors.
627      One successor is BB, the other successor is an empty block which
628      falls through into BB.
629 
630      There is a single PHI node at the join point (BB) and its arguments
631      are constants (0, 1) or (0, -1).
632 
633      So, given the condition COND, and the two PHI arguments, we can
634      rewrite this PHI into non-branching code:
635 
636        dest = (COND) or dest = COND'
637 
638      We use the condition as-is if the argument associated with the
639      true edge has the value one or the argument associated with the
640      false edge as the value zero.  Note that those conditions are not
641      the same since only one of the outgoing edges from the GIMPLE_COND
642      will directly reach BB and thus be associated with an argument.  */
643 
644   stmt = last_stmt (cond_bb);
645   result = PHI_RESULT (phi);
646 
647   /* To handle special cases like floating point comparison, it is easier and
648      less error-prone to build a tree and gimplify it on the fly though it is
649      less efficient.  */
650   cond = fold_build2_loc (gimple_location (stmt),
651 			  gimple_cond_code (stmt), boolean_type_node,
652 			  gimple_cond_lhs (stmt), gimple_cond_rhs (stmt));
653 
654   /* We need to know which is the true edge and which is the false
655      edge so that we know when to invert the condition below.  */
656   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
657   if ((e0 == true_edge && integer_zerop (arg0))
658       || (e0 == false_edge && !integer_zerop (arg0))
659       || (e1 == true_edge && integer_zerop (arg1))
660       || (e1 == false_edge && !integer_zerop (arg1)))
661     cond = fold_build1_loc (gimple_location (stmt),
662                             TRUTH_NOT_EXPR, TREE_TYPE (cond), cond);
663 
664   if (neg)
665     {
666       cond = fold_convert_loc (gimple_location (stmt),
667                                TREE_TYPE (result), cond);
668       cond = fold_build1_loc (gimple_location (stmt),
669                               NEGATE_EXPR, TREE_TYPE (cond), cond);
670     }
671 
672   /* Insert our new statements at the end of conditional block before the
673      COND_STMT.  */
674   gsi = gsi_for_stmt (stmt);
675   new_var = force_gimple_operand_gsi (&gsi, cond, true, NULL, true,
676 				      GSI_SAME_STMT);
677 
678   if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var)))
679     {
680       source_location locus_0, locus_1;
681 
682       new_var2 = make_ssa_name (TREE_TYPE (result), NULL);
683       new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2,
684 					       new_var, NULL);
685       gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
686       new_var = new_var2;
687 
688       /* Set the locus to the first argument, unless is doesn't have one.  */
689       locus_0 = gimple_phi_arg_location (phi, 0);
690       locus_1 = gimple_phi_arg_location (phi, 1);
691       if (locus_0 == UNKNOWN_LOCATION)
692         locus_0 = locus_1;
693       gimple_set_location (new_stmt, locus_0);
694     }
695 
696   replace_phi_edge_with_variable (cond_bb, e1, phi, new_var);
697 
698   /* Note that we optimized this PHI.  */
699   return true;
700 }
701 
702 /* Update *ARG which is defined in STMT so that it contains the
703    computed value if that seems profitable.  Return true if the
704    statement is made dead by that rewriting.  */
705 
706 static bool
jump_function_from_stmt(tree * arg,gimple stmt)707 jump_function_from_stmt (tree *arg, gimple stmt)
708 {
709   enum tree_code code = gimple_assign_rhs_code (stmt);
710   if (code == ADDR_EXPR)
711     {
712       /* For arg = &p->i transform it to p, if possible.  */
713       tree rhs1 = gimple_assign_rhs1 (stmt);
714       HOST_WIDE_INT offset;
715       tree tem = get_addr_base_and_unit_offset (TREE_OPERAND (rhs1, 0),
716 						&offset);
717       if (tem
718 	  && TREE_CODE (tem) == MEM_REF
719 	  && (mem_ref_offset (tem) + double_int::from_shwi (offset)).is_zero ())
720 	{
721 	  *arg = TREE_OPERAND (tem, 0);
722 	  return true;
723 	}
724     }
725   /* TODO: Much like IPA-CP jump-functions we want to handle constant
726      additions symbolically here, and we'd need to update the comparison
727      code that compares the arg + cst tuples in our caller.  For now the
728      code above exactly handles the VEC_BASE pattern from vec.h.  */
729   return false;
730 }
731 
732 /* RHS is a source argument in a BIT_AND_EXPR which feeds a conditional
733    of the form SSA_NAME NE 0.
734 
735    If RHS is fed by a simple EQ_EXPR comparison of two values, see if
736    the two input values of the EQ_EXPR match arg0 and arg1.
737 
738    If so update *code and return TRUE.  Otherwise return FALSE.  */
739 
740 static bool
rhs_is_fed_for_value_replacement(const_tree arg0,const_tree arg1,enum tree_code * code,const_tree rhs)741 rhs_is_fed_for_value_replacement (const_tree arg0, const_tree arg1,
742 				  enum tree_code *code, const_tree rhs)
743 {
744   /* Obviously if RHS is not an SSA_NAME, we can't look at the defining
745      statement.  */
746   if (TREE_CODE (rhs) == SSA_NAME)
747     {
748       gimple def1 = SSA_NAME_DEF_STMT (rhs);
749 
750       /* Verify the defining statement has an EQ_EXPR on the RHS.  */
751       if (is_gimple_assign (def1) && gimple_assign_rhs_code (def1) == EQ_EXPR)
752 	{
753 	  /* Finally verify the source operands of the EQ_EXPR are equal
754 	     to arg0 and arg1.  */
755 	  tree op0 = gimple_assign_rhs1 (def1);
756 	  tree op1 = gimple_assign_rhs2 (def1);
757 	  if ((operand_equal_for_phi_arg_p (arg0, op0)
758 	       && operand_equal_for_phi_arg_p (arg1, op1))
759 	      || (operand_equal_for_phi_arg_p (arg0, op1)
760                && operand_equal_for_phi_arg_p (arg1, op0)))
761 	    {
762 	      /* We will perform the optimization.  */
763 	      *code = gimple_assign_rhs_code (def1);
764 	      return true;
765 	    }
766 	}
767     }
768   return false;
769 }
770 
771 /* Return TRUE if arg0/arg1 are equal to the rhs/lhs or lhs/rhs of COND.
772 
773    Also return TRUE if arg0/arg1 are equal to the source arguments of a
774    an EQ comparison feeding a BIT_AND_EXPR which feeds COND.
775 
776    Return FALSE otherwise.  */
777 
778 static bool
operand_equal_for_value_replacement(const_tree arg0,const_tree arg1,enum tree_code * code,gimple cond)779 operand_equal_for_value_replacement (const_tree arg0, const_tree arg1,
780 				     enum tree_code *code, gimple cond)
781 {
782   gimple def;
783   tree lhs = gimple_cond_lhs (cond);
784   tree rhs = gimple_cond_rhs (cond);
785 
786   if ((operand_equal_for_phi_arg_p (arg0, lhs)
787        && operand_equal_for_phi_arg_p (arg1, rhs))
788       || (operand_equal_for_phi_arg_p (arg1, lhs)
789 	  && operand_equal_for_phi_arg_p (arg0, rhs)))
790     return true;
791 
792   /* Now handle more complex case where we have an EQ comparison
793      which feeds a BIT_AND_EXPR which feeds COND.
794 
795      First verify that COND is of the form SSA_NAME NE 0.  */
796   if (*code != NE_EXPR || !integer_zerop (rhs)
797       || TREE_CODE (lhs) != SSA_NAME)
798     return false;
799 
800   /* Now ensure that SSA_NAME is set by a BIT_AND_EXPR.  */
801   def = SSA_NAME_DEF_STMT (lhs);
802   if (!is_gimple_assign (def) || gimple_assign_rhs_code (def) != BIT_AND_EXPR)
803     return false;
804 
805   /* Now verify arg0/arg1 correspond to the source arguments of an
806      EQ comparison feeding the BIT_AND_EXPR.  */
807 
808   tree tmp = gimple_assign_rhs1 (def);
809   if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp))
810     return true;
811 
812   tmp = gimple_assign_rhs2 (def);
813   if (rhs_is_fed_for_value_replacement (arg0, arg1, code, tmp))
814     return true;
815 
816   return false;
817 }
818 
819 /*  The function value_replacement does the main work of doing the value
820     replacement.  Return non-zero if the replacement is done.  Otherwise return
821     0.  If we remove the middle basic block, return 2.
822     BB is the basic block where the replacement is going to be done on.  ARG0
823     is argument 0 from the PHI.  Likewise for ARG1.  */
824 
825 static int
value_replacement(basic_block cond_bb,basic_block middle_bb,edge e0,edge e1,gimple phi,tree arg0,tree arg1)826 value_replacement (basic_block cond_bb, basic_block middle_bb,
827 		   edge e0, edge e1, gimple phi,
828 		   tree arg0, tree arg1)
829 {
830   gimple_stmt_iterator gsi;
831   gimple cond;
832   edge true_edge, false_edge;
833   enum tree_code code;
834   bool emtpy_or_with_defined_p = true;
835 
836   /* If the type says honor signed zeros we cannot do this
837      optimization.  */
838   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
839     return 0;
840 
841   /* If there is a statement in MIDDLE_BB that defines one of the PHI
842      arguments, then adjust arg0 or arg1.  */
843   gsi = gsi_after_labels (middle_bb);
844   if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
845     gsi_next_nondebug (&gsi);
846   while (!gsi_end_p (gsi))
847     {
848       gimple stmt = gsi_stmt (gsi);
849       tree lhs;
850       gsi_next_nondebug (&gsi);
851       if (!is_gimple_assign (stmt))
852 	{
853 	  emtpy_or_with_defined_p = false;
854 	  continue;
855 	}
856       /* Now try to adjust arg0 or arg1 according to the computation
857 	 in the statement.  */
858       lhs = gimple_assign_lhs (stmt);
859       if (!(lhs == arg0
860 	     && jump_function_from_stmt (&arg0, stmt))
861 	    || (lhs == arg1
862 		&& jump_function_from_stmt (&arg1, stmt)))
863 	emtpy_or_with_defined_p = false;
864     }
865 
866   cond = last_stmt (cond_bb);
867   code = gimple_cond_code (cond);
868 
869   /* This transformation is only valid for equality comparisons.  */
870   if (code != NE_EXPR && code != EQ_EXPR)
871     return 0;
872 
873   /* We need to know which is the true edge and which is the false
874       edge so that we know if have abs or negative abs.  */
875   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
876 
877   /* At this point we know we have a COND_EXPR with two successors.
878      One successor is BB, the other successor is an empty block which
879      falls through into BB.
880 
881      The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
882 
883      There is a single PHI node at the join point (BB) with two arguments.
884 
885      We now need to verify that the two arguments in the PHI node match
886      the two arguments to the equality comparison.  */
887 
888   if (operand_equal_for_value_replacement (arg0, arg1, &code, cond))
889     {
890       edge e;
891       tree arg;
892 
893       /* For NE_EXPR, we want to build an assignment result = arg where
894 	 arg is the PHI argument associated with the true edge.  For
895 	 EQ_EXPR we want the PHI argument associated with the false edge.  */
896       e = (code == NE_EXPR ? true_edge : false_edge);
897 
898       /* Unfortunately, E may not reach BB (it may instead have gone to
899 	 OTHER_BLOCK).  If that is the case, then we want the single outgoing
900 	 edge from OTHER_BLOCK which reaches BB and represents the desired
901 	 path from COND_BLOCK.  */
902       if (e->dest == middle_bb)
903 	e = single_succ_edge (e->dest);
904 
905       /* Now we know the incoming edge to BB that has the argument for the
906 	 RHS of our new assignment statement.  */
907       if (e0 == e)
908 	arg = arg0;
909       else
910 	arg = arg1;
911 
912       /* If the middle basic block was empty or is defining the
913 	 PHI arguments and this is a single phi where the args are different
914 	 for the edges e0 and e1 then we can remove the middle basic block. */
915       if (emtpy_or_with_defined_p
916 	  && single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi)),
917 							    e0, e1))
918 	{
919           replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
920 	  /* Note that we optimized this PHI.  */
921 	  return 2;
922 	}
923       else
924 	{
925 	  /* Replace the PHI arguments with arg. */
926 	  SET_PHI_ARG_DEF (phi, e0->dest_idx, arg);
927 	  SET_PHI_ARG_DEF (phi, e1->dest_idx, arg);
928 	  if (dump_file && (dump_flags & TDF_DETAILS))
929 	    {
930 	      fprintf (dump_file, "PHI ");
931 	      print_generic_expr (dump_file, gimple_phi_result (phi), 0);
932 	      fprintf (dump_file, " reduced for COND_EXPR in block %d to ",
933 		       cond_bb->index);
934 	      print_generic_expr (dump_file, arg, 0);
935 	      fprintf (dump_file, ".\n");
936             }
937           return 1;
938 	}
939 
940     }
941   return 0;
942 }
943 
944 /*  The function minmax_replacement does the main work of doing the minmax
945     replacement.  Return true if the replacement is done.  Otherwise return
946     false.
947     BB is the basic block where the replacement is going to be done on.  ARG0
948     is argument 0 from the PHI.  Likewise for ARG1.  */
949 
950 static bool
minmax_replacement(basic_block cond_bb,basic_block middle_bb,edge e0,edge e1,gimple phi,tree arg0,tree arg1)951 minmax_replacement (basic_block cond_bb, basic_block middle_bb,
952 		    edge e0, edge e1, gimple phi,
953 		    tree arg0, tree arg1)
954 {
955   tree result, type;
956   gimple cond, new_stmt;
957   edge true_edge, false_edge;
958   enum tree_code cmp, minmax, ass_code;
959   tree smaller, larger, arg_true, arg_false;
960   gimple_stmt_iterator gsi, gsi_from;
961 
962   type = TREE_TYPE (PHI_RESULT (phi));
963 
964   /* The optimization may be unsafe due to NaNs.  */
965   if (HONOR_NANS (TYPE_MODE (type)))
966     return false;
967 
968   cond = last_stmt (cond_bb);
969   cmp = gimple_cond_code (cond);
970 
971   /* This transformation is only valid for order comparisons.  Record which
972      operand is smaller/larger if the result of the comparison is true.  */
973   if (cmp == LT_EXPR || cmp == LE_EXPR)
974     {
975       smaller = gimple_cond_lhs (cond);
976       larger = gimple_cond_rhs (cond);
977     }
978   else if (cmp == GT_EXPR || cmp == GE_EXPR)
979     {
980       smaller = gimple_cond_rhs (cond);
981       larger = gimple_cond_lhs (cond);
982     }
983   else
984     return false;
985 
986   /* We need to know which is the true edge and which is the false
987       edge so that we know if have abs or negative abs.  */
988   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
989 
990   /* Forward the edges over the middle basic block.  */
991   if (true_edge->dest == middle_bb)
992     true_edge = EDGE_SUCC (true_edge->dest, 0);
993   if (false_edge->dest == middle_bb)
994     false_edge = EDGE_SUCC (false_edge->dest, 0);
995 
996   if (true_edge == e0)
997     {
998       gcc_assert (false_edge == e1);
999       arg_true = arg0;
1000       arg_false = arg1;
1001     }
1002   else
1003     {
1004       gcc_assert (false_edge == e0);
1005       gcc_assert (true_edge == e1);
1006       arg_true = arg1;
1007       arg_false = arg0;
1008     }
1009 
1010   if (empty_block_p (middle_bb))
1011     {
1012       if (operand_equal_for_phi_arg_p (arg_true, smaller)
1013 	  && operand_equal_for_phi_arg_p (arg_false, larger))
1014 	{
1015 	  /* Case
1016 
1017 	     if (smaller < larger)
1018 	     rslt = smaller;
1019 	     else
1020 	     rslt = larger;  */
1021 	  minmax = MIN_EXPR;
1022 	}
1023       else if (operand_equal_for_phi_arg_p (arg_false, smaller)
1024 	       && operand_equal_for_phi_arg_p (arg_true, larger))
1025 	minmax = MAX_EXPR;
1026       else
1027 	return false;
1028     }
1029   else
1030     {
1031       /* Recognize the following case, assuming d <= u:
1032 
1033 	 if (a <= u)
1034 	   b = MAX (a, d);
1035 	 x = PHI <b, u>
1036 
1037 	 This is equivalent to
1038 
1039 	 b = MAX (a, d);
1040 	 x = MIN (b, u);  */
1041 
1042       gimple assign = last_and_only_stmt (middle_bb);
1043       tree lhs, op0, op1, bound;
1044 
1045       if (!assign
1046 	  || gimple_code (assign) != GIMPLE_ASSIGN)
1047 	return false;
1048 
1049       lhs = gimple_assign_lhs (assign);
1050       ass_code = gimple_assign_rhs_code (assign);
1051       if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
1052 	return false;
1053       op0 = gimple_assign_rhs1 (assign);
1054       op1 = gimple_assign_rhs2 (assign);
1055 
1056       if (true_edge->src == middle_bb)
1057 	{
1058 	  /* We got here if the condition is true, i.e., SMALLER < LARGER.  */
1059 	  if (!operand_equal_for_phi_arg_p (lhs, arg_true))
1060 	    return false;
1061 
1062 	  if (operand_equal_for_phi_arg_p (arg_false, larger))
1063 	    {
1064 	      /* Case
1065 
1066 		 if (smaller < larger)
1067 		   {
1068 		     r' = MAX_EXPR (smaller, bound)
1069 		   }
1070 		 r = PHI <r', larger>  --> to be turned to MIN_EXPR.  */
1071 	      if (ass_code != MAX_EXPR)
1072 		return false;
1073 
1074 	      minmax = MIN_EXPR;
1075 	      if (operand_equal_for_phi_arg_p (op0, smaller))
1076 		bound = op1;
1077 	      else if (operand_equal_for_phi_arg_p (op1, smaller))
1078 		bound = op0;
1079 	      else
1080 		return false;
1081 
1082 	      /* We need BOUND <= LARGER.  */
1083 	      if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
1084 						  bound, larger)))
1085 		return false;
1086 	    }
1087 	  else if (operand_equal_for_phi_arg_p (arg_false, smaller))
1088 	    {
1089 	      /* Case
1090 
1091 		 if (smaller < larger)
1092 		   {
1093 		     r' = MIN_EXPR (larger, bound)
1094 		   }
1095 		 r = PHI <r', smaller>  --> to be turned to MAX_EXPR.  */
1096 	      if (ass_code != MIN_EXPR)
1097 		return false;
1098 
1099 	      minmax = MAX_EXPR;
1100 	      if (operand_equal_for_phi_arg_p (op0, larger))
1101 		bound = op1;
1102 	      else if (operand_equal_for_phi_arg_p (op1, larger))
1103 		bound = op0;
1104 	      else
1105 		return false;
1106 
1107 	      /* We need BOUND >= SMALLER.  */
1108 	      if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
1109 						  bound, smaller)))
1110 		return false;
1111 	    }
1112 	  else
1113 	    return false;
1114 	}
1115       else
1116 	{
1117 	  /* We got here if the condition is false, i.e., SMALLER > LARGER.  */
1118 	  if (!operand_equal_for_phi_arg_p (lhs, arg_false))
1119 	    return false;
1120 
1121 	  if (operand_equal_for_phi_arg_p (arg_true, larger))
1122 	    {
1123 	      /* Case
1124 
1125 		 if (smaller > larger)
1126 		   {
1127 		     r' = MIN_EXPR (smaller, bound)
1128 		   }
1129 		 r = PHI <r', larger>  --> to be turned to MAX_EXPR.  */
1130 	      if (ass_code != MIN_EXPR)
1131 		return false;
1132 
1133 	      minmax = MAX_EXPR;
1134 	      if (operand_equal_for_phi_arg_p (op0, smaller))
1135 		bound = op1;
1136 	      else if (operand_equal_for_phi_arg_p (op1, smaller))
1137 		bound = op0;
1138 	      else
1139 		return false;
1140 
1141 	      /* We need BOUND >= LARGER.  */
1142 	      if (!integer_nonzerop (fold_build2 (GE_EXPR, boolean_type_node,
1143 						  bound, larger)))
1144 		return false;
1145 	    }
1146 	  else if (operand_equal_for_phi_arg_p (arg_true, smaller))
1147 	    {
1148 	      /* Case
1149 
1150 		 if (smaller > larger)
1151 		   {
1152 		     r' = MAX_EXPR (larger, bound)
1153 		   }
1154 		 r = PHI <r', smaller>  --> to be turned to MIN_EXPR.  */
1155 	      if (ass_code != MAX_EXPR)
1156 		return false;
1157 
1158 	      minmax = MIN_EXPR;
1159 	      if (operand_equal_for_phi_arg_p (op0, larger))
1160 		bound = op1;
1161 	      else if (operand_equal_for_phi_arg_p (op1, larger))
1162 		bound = op0;
1163 	      else
1164 		return false;
1165 
1166 	      /* We need BOUND <= SMALLER.  */
1167 	      if (!integer_nonzerop (fold_build2 (LE_EXPR, boolean_type_node,
1168 						  bound, smaller)))
1169 		return false;
1170 	    }
1171 	  else
1172 	    return false;
1173 	}
1174 
1175       /* Move the statement from the middle block.  */
1176       gsi = gsi_last_bb (cond_bb);
1177       gsi_from = gsi_last_nondebug_bb (middle_bb);
1178       gsi_move_before (&gsi_from, &gsi);
1179     }
1180 
1181   /* Emit the statement to compute min/max.  */
1182   result = duplicate_ssa_name (PHI_RESULT (phi), NULL);
1183   new_stmt = gimple_build_assign_with_ops (minmax, result, arg0, arg1);
1184   gsi = gsi_last_bb (cond_bb);
1185   gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
1186 
1187   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
1188   return true;
1189 }
1190 
1191 /*  The function absolute_replacement does the main work of doing the absolute
1192     replacement.  Return true if the replacement is done.  Otherwise return
1193     false.
1194     bb is the basic block where the replacement is going to be done on.  arg0
1195     is argument 0 from the phi.  Likewise for arg1.  */
1196 
1197 static bool
abs_replacement(basic_block cond_bb,basic_block middle_bb,edge e0 ATTRIBUTE_UNUSED,edge e1,gimple phi,tree arg0,tree arg1)1198 abs_replacement (basic_block cond_bb, basic_block middle_bb,
1199 		 edge e0 ATTRIBUTE_UNUSED, edge e1,
1200 		 gimple phi, tree arg0, tree arg1)
1201 {
1202   tree result;
1203   gimple new_stmt, cond;
1204   gimple_stmt_iterator gsi;
1205   edge true_edge, false_edge;
1206   gimple assign;
1207   edge e;
1208   tree rhs, lhs;
1209   bool negate;
1210   enum tree_code cond_code;
1211 
1212   /* If the type says honor signed zeros we cannot do this
1213      optimization.  */
1214   if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
1215     return false;
1216 
1217   /* OTHER_BLOCK must have only one executable statement which must have the
1218      form arg0 = -arg1 or arg1 = -arg0.  */
1219 
1220   assign = last_and_only_stmt (middle_bb);
1221   /* If we did not find the proper negation assignment, then we can not
1222      optimize.  */
1223   if (assign == NULL)
1224     return false;
1225 
1226   /* If we got here, then we have found the only executable statement
1227      in OTHER_BLOCK.  If it is anything other than arg = -arg1 or
1228      arg1 = -arg0, then we can not optimize.  */
1229   if (gimple_code (assign) != GIMPLE_ASSIGN)
1230     return false;
1231 
1232   lhs = gimple_assign_lhs (assign);
1233 
1234   if (gimple_assign_rhs_code (assign) != NEGATE_EXPR)
1235     return false;
1236 
1237   rhs = gimple_assign_rhs1 (assign);
1238 
1239   /* The assignment has to be arg0 = -arg1 or arg1 = -arg0.  */
1240   if (!(lhs == arg0 && rhs == arg1)
1241       && !(lhs == arg1 && rhs == arg0))
1242     return false;
1243 
1244   cond = last_stmt (cond_bb);
1245   result = PHI_RESULT (phi);
1246 
1247   /* Only relationals comparing arg[01] against zero are interesting.  */
1248   cond_code = gimple_cond_code (cond);
1249   if (cond_code != GT_EXPR && cond_code != GE_EXPR
1250       && cond_code != LT_EXPR && cond_code != LE_EXPR)
1251     return false;
1252 
1253   /* Make sure the conditional is arg[01] OP y.  */
1254   if (gimple_cond_lhs (cond) != rhs)
1255     return false;
1256 
1257   if (FLOAT_TYPE_P (TREE_TYPE (gimple_cond_rhs (cond)))
1258 	       ? real_zerop (gimple_cond_rhs (cond))
1259 	       : integer_zerop (gimple_cond_rhs (cond)))
1260     ;
1261   else
1262     return false;
1263 
1264   /* We need to know which is the true edge and which is the false
1265      edge so that we know if have abs or negative abs.  */
1266   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
1267 
1268   /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
1269      will need to negate the result.  Similarly for LT_EXPR/LE_EXPR if
1270      the false edge goes to OTHER_BLOCK.  */
1271   if (cond_code == GT_EXPR || cond_code == GE_EXPR)
1272     e = true_edge;
1273   else
1274     e = false_edge;
1275 
1276   if (e->dest == middle_bb)
1277     negate = true;
1278   else
1279     negate = false;
1280 
1281   result = duplicate_ssa_name (result, NULL);
1282 
1283   if (negate)
1284     lhs = make_ssa_name (TREE_TYPE (result), NULL);
1285   else
1286     lhs = result;
1287 
1288   /* Build the modify expression with abs expression.  */
1289   new_stmt = gimple_build_assign_with_ops (ABS_EXPR, lhs, rhs, NULL);
1290 
1291   gsi = gsi_last_bb (cond_bb);
1292   gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
1293 
1294   if (negate)
1295     {
1296       /* Get the right GSI.  We want to insert after the recently
1297 	 added ABS_EXPR statement (which we know is the first statement
1298 	 in the block.  */
1299       new_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, result, lhs, NULL);
1300 
1301       gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
1302     }
1303 
1304   replace_phi_edge_with_variable (cond_bb, e1, phi, result);
1305 
1306   /* Note that we optimized this PHI.  */
1307   return true;
1308 }
1309 
1310 /*  The function neg_replacement replaces conditional negation with
1311     equivalent straight line code.  Returns TRUE if replacement is done,
1312     otherwise returns FALSE.
1313 
1314     COND_BB branches around negation occuring in MIDDLE_BB.
1315 
1316     E0 and E1 are edges out of COND_BB.  E0 reaches MIDDLE_BB and
1317     E1 reaches the other successor which should contain PHI with
1318     arguments ARG0 and ARG1.
1319 
1320     Assuming negation is to occur when the condition is true,
1321     then the non-branching sequence is:
1322 
1323        result = (rhs ^ -cond) + cond
1324 
1325     Inverting the condition or its result gives us negation
1326     when the original condition is false.  */
1327 
1328 static bool
neg_replacement(basic_block cond_bb,basic_block middle_bb,edge e0 ATTRIBUTE_UNUSED,edge e1,gimple phi,tree arg0,tree arg1)1329 neg_replacement (basic_block cond_bb, basic_block middle_bb,
1330 		 edge e0 ATTRIBUTE_UNUSED, edge e1,
1331 		 gimple phi, tree arg0, tree arg1)
1332 {
1333   gimple new_stmt, cond;
1334   gimple_stmt_iterator gsi;
1335   gimple assign;
1336   edge true_edge, false_edge;
1337   tree rhs, lhs;
1338   enum tree_code cond_code;
1339   bool invert = false;
1340 
1341   /* This transformation performs logical operations on the
1342      incoming arguments.  So force them to be integral types.   */
1343   if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0)))
1344     return false;
1345 
1346   /* OTHER_BLOCK must have only one executable statement which must have the
1347      form arg0 = -arg1 or arg1 = -arg0.  */
1348 
1349   assign = last_and_only_stmt (middle_bb);
1350   /* If we did not find the proper negation assignment, then we can not
1351      optimize.  */
1352   if (assign == NULL)
1353     return false;
1354 
1355   /* If we got here, then we have found the only executable statement
1356      in OTHER_BLOCK.  If it is anything other than arg0 = -arg1 or
1357      arg1 = -arg0, then we can not optimize.  */
1358   if (gimple_code (assign) != GIMPLE_ASSIGN)
1359     return false;
1360 
1361   lhs = gimple_assign_lhs (assign);
1362 
1363   if (gimple_assign_rhs_code (assign) != NEGATE_EXPR)
1364     return false;
1365 
1366   rhs = gimple_assign_rhs1 (assign);
1367 
1368   /* The assignment has to be arg0 = -arg1 or arg1 = -arg0.  */
1369   if (!(lhs == arg0 && rhs == arg1)
1370       && !(lhs == arg1 && rhs == arg0))
1371     return false;
1372 
1373   /* The basic sequence assumes we negate when the condition is true.
1374      If we need the opposite, then we will either need to invert the
1375      condition or its result.  */
1376   extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
1377   invert = false_edge->dest == middle_bb;
1378 
1379   /* Unlike abs_replacement, we can handle arbitrary conditionals here.  */
1380   cond = last_stmt (cond_bb);
1381   cond_code = gimple_cond_code (cond);
1382 
1383   /* If inversion is needed, first try to invert the test since
1384      that's cheapest.  */
1385   if (invert)
1386     {
1387       bool honor_nans
1388 	= HONOR_NANS (TYPE_MODE (TREE_TYPE (gimple_cond_lhs (cond))));
1389       enum tree_code new_code = invert_tree_comparison (cond_code, honor_nans);
1390 
1391       /* If invert_tree_comparison was successful, then use its return
1392 	 value as the new code and note that inversion is no longer
1393 	 needed.  */
1394       if (new_code != ERROR_MARK)
1395 	{
1396 	  cond_code = new_code;
1397 	  invert = false;
1398 	}
1399     }
1400 
1401   tree cond_val = make_ssa_name (boolean_type_node, NULL);
1402   new_stmt = gimple_build_assign_with_ops (cond_code, cond_val,
1403 					   gimple_cond_lhs (cond),
1404 					   gimple_cond_rhs (cond));
1405   gsi = gsi_last_bb (cond_bb);
1406   gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
1407 
1408   /* If we still need inversion, then invert the result of the
1409      condition.  */
1410   if (invert)
1411     {
1412       tree tmp = make_ssa_name (boolean_type_node, NULL);
1413       new_stmt = gimple_build_assign_with_ops (BIT_XOR_EXPR, tmp,
1414 					       cond_val, boolean_true_node);
1415       gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
1416       cond_val = tmp;
1417     }
1418 
1419   /* Get the condition in the right type so that we can perform
1420      logical and arithmetic operations on it.  */
1421   tree cond_val_converted = make_ssa_name (TREE_TYPE (rhs), NULL);
1422   new_stmt = gimple_build_assign_with_ops (NOP_EXPR, cond_val_converted,
1423 					   cond_val, NULL_TREE);
1424   gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
1425 
1426   tree neg_cond_val_converted = make_ssa_name (TREE_TYPE (rhs), NULL);
1427   new_stmt = gimple_build_assign_with_ops (NEGATE_EXPR, neg_cond_val_converted,
1428 					   cond_val_converted, NULL_TREE);
1429   gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
1430 
1431   tree tmp = make_ssa_name (TREE_TYPE (rhs), NULL);
1432   new_stmt = gimple_build_assign_with_ops (BIT_XOR_EXPR, tmp,
1433 					   rhs, neg_cond_val_converted);
1434   gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
1435 
1436   tree new_lhs = make_ssa_name (TREE_TYPE (rhs), NULL);
1437   new_stmt = gimple_build_assign_with_ops (PLUS_EXPR, new_lhs,
1438 					   tmp, cond_val_converted);
1439   gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
1440 
1441   replace_phi_edge_with_variable (cond_bb, e1, phi, new_lhs);
1442 
1443   /* Note that we optimized this PHI.  */
1444   return true;
1445 }
1446 
1447 /* Auxiliary functions to determine the set of memory accesses which
1448    can't trap because they are preceded by accesses to the same memory
1449    portion.  We do that for MEM_REFs, so we only need to track
1450    the SSA_NAME of the pointer indirectly referenced.  The algorithm
1451    simply is a walk over all instructions in dominator order.  When
1452    we see an MEM_REF we determine if we've already seen a same
1453    ref anywhere up to the root of the dominator tree.  If we do the
1454    current access can't trap.  If we don't see any dominating access
1455    the current access might trap, but might also make later accesses
1456    non-trapping, so we remember it.  We need to be careful with loads
1457    or stores, for instance a load might not trap, while a store would,
1458    so if we see a dominating read access this doesn't mean that a later
1459    write access would not trap.  Hence we also need to differentiate the
1460    type of access(es) seen.
1461 
1462    ??? We currently are very conservative and assume that a load might
1463    trap even if a store doesn't (write-only memory).  This probably is
1464    overly conservative.  */
1465 
1466 /* A hash-table of SSA_NAMEs, and in which basic block an MEM_REF
1467    through it was seen, which would constitute a no-trap region for
1468    same accesses.  */
1469 struct name_to_bb
1470 {
1471   unsigned int ssa_name_ver;
1472   unsigned int phase;
1473   bool store;
1474   HOST_WIDE_INT offset, size;
1475   basic_block bb;
1476 };
1477 
1478 /* Hashtable helpers.  */
1479 
1480 struct ssa_names_hasher : typed_free_remove <name_to_bb>
1481 {
1482   typedef name_to_bb value_type;
1483   typedef name_to_bb compare_type;
1484   static inline hashval_t hash (const value_type *);
1485   static inline bool equal (const value_type *, const compare_type *);
1486 };
1487 
1488 /* Used for quick clearing of the hash-table when we see calls.
1489    Hash entries with phase < nt_call_phase are invalid.  */
1490 static unsigned int nt_call_phase;
1491 
1492 /* The hash function.  */
1493 
1494 inline hashval_t
hash(const value_type * n)1495 ssa_names_hasher::hash (const value_type *n)
1496 {
1497   return n->ssa_name_ver ^ (((hashval_t) n->store) << 31)
1498          ^ (n->offset << 6) ^ (n->size << 3);
1499 }
1500 
1501 /* The equality function of *P1 and *P2.  */
1502 
1503 inline bool
equal(const value_type * n1,const compare_type * n2)1504 ssa_names_hasher::equal (const value_type *n1, const compare_type *n2)
1505 {
1506   return n1->ssa_name_ver == n2->ssa_name_ver
1507          && n1->store == n2->store
1508          && n1->offset == n2->offset
1509          && n1->size == n2->size;
1510 }
1511 
1512 /* The hash table for remembering what we've seen.  */
1513 static hash_table <ssa_names_hasher> seen_ssa_names;
1514 
1515 /* We see the expression EXP in basic block BB.  If it's an interesting
1516    expression (an MEM_REF through an SSA_NAME) possibly insert the
1517    expression into the set NONTRAP or the hash table of seen expressions.
1518    STORE is true if this expression is on the LHS, otherwise it's on
1519    the RHS.  */
1520 static void
add_or_mark_expr(basic_block bb,tree exp,struct pointer_set_t * nontrap,bool store)1521 add_or_mark_expr (basic_block bb, tree exp,
1522 		  struct pointer_set_t *nontrap, bool store)
1523 {
1524   HOST_WIDE_INT size;
1525 
1526   if (TREE_CODE (exp) == MEM_REF
1527       && TREE_CODE (TREE_OPERAND (exp, 0)) == SSA_NAME
1528       && tree_fits_shwi_p (TREE_OPERAND (exp, 1))
1529       && (size = int_size_in_bytes (TREE_TYPE (exp))) > 0)
1530     {
1531       tree name = TREE_OPERAND (exp, 0);
1532       struct name_to_bb map;
1533       name_to_bb **slot;
1534       struct name_to_bb *n2bb;
1535       basic_block found_bb = 0;
1536 
1537       /* Try to find the last seen MEM_REF through the same
1538          SSA_NAME, which can trap.  */
1539       map.ssa_name_ver = SSA_NAME_VERSION (name);
1540       map.phase = 0;
1541       map.bb = 0;
1542       map.store = store;
1543       map.offset = tree_to_shwi (TREE_OPERAND (exp, 1));
1544       map.size = size;
1545 
1546       slot = seen_ssa_names.find_slot (&map, INSERT);
1547       n2bb = *slot;
1548       if (n2bb && n2bb->phase >= nt_call_phase)
1549         found_bb = n2bb->bb;
1550 
1551       /* If we've found a trapping MEM_REF, _and_ it dominates EXP
1552          (it's in a basic block on the path from us to the dominator root)
1553 	 then we can't trap.  */
1554       if (found_bb && (((size_t)found_bb->aux) & 1) == 1)
1555 	{
1556 	  pointer_set_insert (nontrap, exp);
1557 	}
1558       else
1559         {
1560 	  /* EXP might trap, so insert it into the hash table.  */
1561 	  if (n2bb)
1562 	    {
1563 	      n2bb->phase = nt_call_phase;
1564 	      n2bb->bb = bb;
1565 	    }
1566 	  else
1567 	    {
1568 	      n2bb = XNEW (struct name_to_bb);
1569 	      n2bb->ssa_name_ver = SSA_NAME_VERSION (name);
1570 	      n2bb->phase = nt_call_phase;
1571 	      n2bb->bb = bb;
1572 	      n2bb->store = store;
1573 	      n2bb->offset = map.offset;
1574 	      n2bb->size = size;
1575 	      *slot = n2bb;
1576 	    }
1577 	}
1578     }
1579 }
1580 
1581 class nontrapping_dom_walker : public dom_walker
1582 {
1583 public:
nontrapping_dom_walker(cdi_direction direction,pointer_set_t * ps)1584   nontrapping_dom_walker (cdi_direction direction, pointer_set_t *ps)
1585     : dom_walker (direction), m_nontrapping (ps) {}
1586 
1587   virtual void before_dom_children (basic_block);
1588   virtual void after_dom_children (basic_block);
1589 
1590 private:
1591   pointer_set_t *m_nontrapping;
1592 };
1593 
1594 /* Called by walk_dominator_tree, when entering the block BB.  */
1595 void
before_dom_children(basic_block bb)1596 nontrapping_dom_walker::before_dom_children (basic_block bb)
1597 {
1598   edge e;
1599   edge_iterator ei;
1600   gimple_stmt_iterator gsi;
1601 
1602   /* If we haven't seen all our predecessors, clear the hash-table.  */
1603   FOR_EACH_EDGE (e, ei, bb->preds)
1604     if ((((size_t)e->src->aux) & 2) == 0)
1605       {
1606 	nt_call_phase++;
1607 	break;
1608       }
1609 
1610   /* Mark this BB as being on the path to dominator root and as visited.  */
1611   bb->aux = (void*)(1 | 2);
1612 
1613   /* And walk the statements in order.  */
1614   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
1615     {
1616       gimple stmt = gsi_stmt (gsi);
1617 
1618       if (is_gimple_call (stmt) && !nonfreeing_call_p (stmt))
1619 	nt_call_phase++;
1620       else if (gimple_assign_single_p (stmt) && !gimple_has_volatile_ops (stmt))
1621 	{
1622 	  add_or_mark_expr (bb, gimple_assign_lhs (stmt), m_nontrapping, true);
1623 	  add_or_mark_expr (bb, gimple_assign_rhs1 (stmt), m_nontrapping, false);
1624 	}
1625     }
1626 }
1627 
1628 /* Called by walk_dominator_tree, when basic block BB is exited.  */
1629 void
after_dom_children(basic_block bb)1630 nontrapping_dom_walker::after_dom_children (basic_block bb)
1631 {
1632   /* This BB isn't on the path to dominator root anymore.  */
1633   bb->aux = (void*)2;
1634 }
1635 
1636 /* This is the entry point of gathering non trapping memory accesses.
1637    It will do a dominator walk over the whole function, and it will
1638    make use of the bb->aux pointers.  It returns a set of trees
1639    (the MEM_REFs itself) which can't trap.  */
1640 static struct pointer_set_t *
get_non_trapping(void)1641 get_non_trapping (void)
1642 {
1643   nt_call_phase = 0;
1644   pointer_set_t *nontrap = pointer_set_create ();
1645   seen_ssa_names.create (128);
1646   /* We're going to do a dominator walk, so ensure that we have
1647      dominance information.  */
1648   calculate_dominance_info (CDI_DOMINATORS);
1649 
1650   nontrapping_dom_walker (CDI_DOMINATORS, nontrap)
1651     .walk (cfun->cfg->x_entry_block_ptr);
1652 
1653   seen_ssa_names.dispose ();
1654 
1655   clear_aux_for_blocks ();
1656   return nontrap;
1657 }
1658 
1659 /* Do the main work of conditional store replacement.  We already know
1660    that the recognized pattern looks like so:
1661 
1662    split:
1663      if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
1664    MIDDLE_BB:
1665      something
1666      fallthrough (edge E0)
1667    JOIN_BB:
1668      some more
1669 
1670    We check that MIDDLE_BB contains only one store, that that store
1671    doesn't trap (not via NOTRAP, but via checking if an access to the same
1672    memory location dominates us) and that the store has a "simple" RHS.  */
1673 
1674 static bool
cond_store_replacement(basic_block middle_bb,basic_block join_bb,edge e0,edge e1,struct pointer_set_t * nontrap)1675 cond_store_replacement (basic_block middle_bb, basic_block join_bb,
1676 			edge e0, edge e1, struct pointer_set_t *nontrap)
1677 {
1678   gimple assign = last_and_only_stmt (middle_bb);
1679   tree lhs, rhs, name, name2;
1680   gimple newphi, new_stmt;
1681   gimple_stmt_iterator gsi;
1682   source_location locus;
1683 
1684   /* Check if middle_bb contains of only one store.  */
1685   if (!assign
1686       || !gimple_assign_single_p (assign)
1687       || gimple_has_volatile_ops (assign))
1688     return false;
1689 
1690   locus = gimple_location (assign);
1691   lhs = gimple_assign_lhs (assign);
1692   rhs = gimple_assign_rhs1 (assign);
1693   if (TREE_CODE (lhs) != MEM_REF
1694       || TREE_CODE (TREE_OPERAND (lhs, 0)) != SSA_NAME
1695       || !is_gimple_reg_type (TREE_TYPE (lhs)))
1696     return false;
1697 
1698   /* Prove that we can move the store down.  We could also check
1699      TREE_THIS_NOTRAP here, but in that case we also could move stores,
1700      whose value is not available readily, which we want to avoid.  */
1701   if (!pointer_set_contains (nontrap, lhs))
1702     return false;
1703 
1704   /* Now we've checked the constraints, so do the transformation:
1705      1) Remove the single store.  */
1706   gsi = gsi_for_stmt (assign);
1707   unlink_stmt_vdef (assign);
1708   gsi_remove (&gsi, true);
1709   release_defs (assign);
1710 
1711   /* 2) Insert a load from the memory of the store to the temporary
1712         on the edge which did not contain the store.  */
1713   lhs = unshare_expr (lhs);
1714   name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
1715   new_stmt = gimple_build_assign (name, lhs);
1716   gimple_set_location (new_stmt, locus);
1717   gsi_insert_on_edge (e1, new_stmt);
1718 
1719   /* 3) Create a PHI node at the join block, with one argument
1720         holding the old RHS, and the other holding the temporary
1721         where we stored the old memory contents.  */
1722   name2 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
1723   newphi = create_phi_node (name2, join_bb);
1724   add_phi_arg (newphi, rhs, e0, locus);
1725   add_phi_arg (newphi, name, e1, locus);
1726 
1727   lhs = unshare_expr (lhs);
1728   new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
1729 
1730   /* 4) Insert that PHI node.  */
1731   gsi = gsi_after_labels (join_bb);
1732   if (gsi_end_p (gsi))
1733     {
1734       gsi = gsi_last_bb (join_bb);
1735       gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
1736     }
1737   else
1738     gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
1739 
1740   return true;
1741 }
1742 
1743 /* Do the main work of conditional store replacement.  */
1744 
1745 static bool
cond_if_else_store_replacement_1(basic_block then_bb,basic_block else_bb,basic_block join_bb,gimple then_assign,gimple else_assign)1746 cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb,
1747 				  basic_block join_bb, gimple then_assign,
1748 				  gimple else_assign)
1749 {
1750   tree lhs_base, lhs, then_rhs, else_rhs, name;
1751   source_location then_locus, else_locus;
1752   gimple_stmt_iterator gsi;
1753   gimple newphi, new_stmt;
1754 
1755   if (then_assign == NULL
1756       || !gimple_assign_single_p (then_assign)
1757       || gimple_clobber_p (then_assign)
1758       || gimple_has_volatile_ops (then_assign)
1759       || else_assign == NULL
1760       || !gimple_assign_single_p (else_assign)
1761       || gimple_clobber_p (else_assign)
1762       || gimple_has_volatile_ops (else_assign))
1763     return false;
1764 
1765   lhs = gimple_assign_lhs (then_assign);
1766   if (!is_gimple_reg_type (TREE_TYPE (lhs))
1767       || !operand_equal_p (lhs, gimple_assign_lhs (else_assign), 0))
1768     return false;
1769 
1770   lhs_base = get_base_address (lhs);
1771   if (lhs_base == NULL_TREE
1772       || (!DECL_P (lhs_base) && TREE_CODE (lhs_base) != MEM_REF))
1773     return false;
1774 
1775   then_rhs = gimple_assign_rhs1 (then_assign);
1776   else_rhs = gimple_assign_rhs1 (else_assign);
1777   then_locus = gimple_location (then_assign);
1778   else_locus = gimple_location (else_assign);
1779 
1780   /* Now we've checked the constraints, so do the transformation:
1781      1) Remove the stores.  */
1782   gsi = gsi_for_stmt (then_assign);
1783   unlink_stmt_vdef (then_assign);
1784   gsi_remove (&gsi, true);
1785   release_defs (then_assign);
1786 
1787   gsi = gsi_for_stmt (else_assign);
1788   unlink_stmt_vdef (else_assign);
1789   gsi_remove (&gsi, true);
1790   release_defs (else_assign);
1791 
1792   /* 2) Create a PHI node at the join block, with one argument
1793 	holding the old RHS, and the other holding the temporary
1794 	where we stored the old memory contents.  */
1795   name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
1796   newphi = create_phi_node (name, join_bb);
1797   add_phi_arg (newphi, then_rhs, EDGE_SUCC (then_bb, 0), then_locus);
1798   add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus);
1799 
1800   new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
1801 
1802   /* 3) Insert that PHI node.  */
1803   gsi = gsi_after_labels (join_bb);
1804   if (gsi_end_p (gsi))
1805     {
1806       gsi = gsi_last_bb (join_bb);
1807       gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
1808     }
1809   else
1810     gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
1811 
1812   return true;
1813 }
1814 
1815 /* Conditional store replacement.  We already know
1816    that the recognized pattern looks like so:
1817 
1818    split:
1819      if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
1820    THEN_BB:
1821      ...
1822      X = Y;
1823      ...
1824      goto JOIN_BB;
1825    ELSE_BB:
1826      ...
1827      X = Z;
1828      ...
1829      fallthrough (edge E0)
1830    JOIN_BB:
1831      some more
1832 
1833    We check that it is safe to sink the store to JOIN_BB by verifying that
1834    there are no read-after-write or write-after-write dependencies in
1835    THEN_BB and ELSE_BB.  */
1836 
1837 static bool
cond_if_else_store_replacement(basic_block then_bb,basic_block else_bb,basic_block join_bb)1838 cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb,
1839                                 basic_block join_bb)
1840 {
1841   gimple then_assign = last_and_only_stmt (then_bb);
1842   gimple else_assign = last_and_only_stmt (else_bb);
1843   vec<data_reference_p> then_datarefs, else_datarefs;
1844   vec<ddr_p> then_ddrs, else_ddrs;
1845   gimple then_store, else_store;
1846   bool found, ok = false, res;
1847   struct data_dependence_relation *ddr;
1848   data_reference_p then_dr, else_dr;
1849   int i, j;
1850   tree then_lhs, else_lhs;
1851   basic_block blocks[3];
1852 
1853   if (MAX_STORES_TO_SINK == 0)
1854     return false;
1855 
1856   /* Handle the case with single statement in THEN_BB and ELSE_BB.  */
1857   if (then_assign && else_assign)
1858     return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
1859                                              then_assign, else_assign);
1860 
1861   /* Find data references.  */
1862   then_datarefs.create (1);
1863   else_datarefs.create (1);
1864   if ((find_data_references_in_bb (NULL, then_bb, &then_datarefs)
1865         == chrec_dont_know)
1866       || !then_datarefs.length ()
1867       || (find_data_references_in_bb (NULL, else_bb, &else_datarefs)
1868 	  == chrec_dont_know)
1869       || !else_datarefs.length ())
1870     {
1871       free_data_refs (then_datarefs);
1872       free_data_refs (else_datarefs);
1873       return false;
1874     }
1875 
1876   /* Find pairs of stores with equal LHS.  */
1877   auto_vec<gimple, 1> then_stores, else_stores;
1878   FOR_EACH_VEC_ELT (then_datarefs, i, then_dr)
1879     {
1880       if (DR_IS_READ (then_dr))
1881         continue;
1882 
1883       then_store = DR_STMT (then_dr);
1884       then_lhs = gimple_get_lhs (then_store);
1885       if (then_lhs == NULL_TREE)
1886 	continue;
1887       found = false;
1888 
1889       FOR_EACH_VEC_ELT (else_datarefs, j, else_dr)
1890         {
1891           if (DR_IS_READ (else_dr))
1892             continue;
1893 
1894           else_store = DR_STMT (else_dr);
1895           else_lhs = gimple_get_lhs (else_store);
1896 	  if (else_lhs == NULL_TREE)
1897 	    continue;
1898 
1899           if (operand_equal_p (then_lhs, else_lhs, 0))
1900             {
1901               found = true;
1902               break;
1903             }
1904         }
1905 
1906       if (!found)
1907         continue;
1908 
1909       then_stores.safe_push (then_store);
1910       else_stores.safe_push (else_store);
1911     }
1912 
1913   /* No pairs of stores found.  */
1914   if (!then_stores.length ()
1915       || then_stores.length () > (unsigned) MAX_STORES_TO_SINK)
1916     {
1917       free_data_refs (then_datarefs);
1918       free_data_refs (else_datarefs);
1919       return false;
1920     }
1921 
1922   /* Compute and check data dependencies in both basic blocks.  */
1923   then_ddrs.create (1);
1924   else_ddrs.create (1);
1925   if (!compute_all_dependences (then_datarefs, &then_ddrs,
1926 				vNULL, false)
1927       || !compute_all_dependences (else_datarefs, &else_ddrs,
1928 				   vNULL, false))
1929     {
1930       free_dependence_relations (then_ddrs);
1931       free_dependence_relations (else_ddrs);
1932       free_data_refs (then_datarefs);
1933       free_data_refs (else_datarefs);
1934       return false;
1935     }
1936   blocks[0] = then_bb;
1937   blocks[1] = else_bb;
1938   blocks[2] = join_bb;
1939   renumber_gimple_stmt_uids_in_blocks (blocks, 3);
1940 
1941   /* Check that there are no read-after-write or write-after-write dependencies
1942      in THEN_BB.  */
1943   FOR_EACH_VEC_ELT (then_ddrs, i, ddr)
1944     {
1945       struct data_reference *dra = DDR_A (ddr);
1946       struct data_reference *drb = DDR_B (ddr);
1947 
1948       if (DDR_ARE_DEPENDENT (ddr) != chrec_known
1949           && ((DR_IS_READ (dra) && DR_IS_WRITE (drb)
1950                && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb)))
1951               || (DR_IS_READ (drb) && DR_IS_WRITE (dra)
1952                   && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra)))
1953               || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))))
1954         {
1955           free_dependence_relations (then_ddrs);
1956           free_dependence_relations (else_ddrs);
1957 	  free_data_refs (then_datarefs);
1958 	  free_data_refs (else_datarefs);
1959           return false;
1960         }
1961     }
1962 
1963   /* Check that there are no read-after-write or write-after-write dependencies
1964      in ELSE_BB.  */
1965   FOR_EACH_VEC_ELT (else_ddrs, i, ddr)
1966     {
1967       struct data_reference *dra = DDR_A (ddr);
1968       struct data_reference *drb = DDR_B (ddr);
1969 
1970       if (DDR_ARE_DEPENDENT (ddr) != chrec_known
1971           && ((DR_IS_READ (dra) && DR_IS_WRITE (drb)
1972                && gimple_uid (DR_STMT (dra)) > gimple_uid (DR_STMT (drb)))
1973               || (DR_IS_READ (drb) && DR_IS_WRITE (dra)
1974                   && gimple_uid (DR_STMT (drb)) > gimple_uid (DR_STMT (dra)))
1975               || (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))))
1976         {
1977           free_dependence_relations (then_ddrs);
1978           free_dependence_relations (else_ddrs);
1979 	  free_data_refs (then_datarefs);
1980 	  free_data_refs (else_datarefs);
1981           return false;
1982         }
1983     }
1984 
1985   /* Sink stores with same LHS.  */
1986   FOR_EACH_VEC_ELT (then_stores, i, then_store)
1987     {
1988       else_store = else_stores[i];
1989       res = cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
1990                                               then_store, else_store);
1991       ok = ok || res;
1992     }
1993 
1994   free_dependence_relations (then_ddrs);
1995   free_dependence_relations (else_ddrs);
1996   free_data_refs (then_datarefs);
1997   free_data_refs (else_datarefs);
1998 
1999   return ok;
2000 }
2001 
2002 /* Return TRUE if STMT has a VUSE whose corresponding VDEF is in BB.  */
2003 
2004 static bool
local_mem_dependence(gimple stmt,basic_block bb)2005 local_mem_dependence (gimple stmt, basic_block bb)
2006 {
2007   tree vuse = gimple_vuse (stmt);
2008   gimple def;
2009 
2010   if (!vuse)
2011     return false;
2012 
2013   def = SSA_NAME_DEF_STMT (vuse);
2014   return (def && gimple_bb (def) == bb);
2015 }
2016 
2017 /* Given a "diamond" control-flow pattern where BB0 tests a condition,
2018    BB1 and BB2 are "then" and "else" blocks dependent on this test,
2019    and BB3 rejoins control flow following BB1 and BB2, look for
2020    opportunities to hoist loads as follows.  If BB3 contains a PHI of
2021    two loads, one each occurring in BB1 and BB2, and the loads are
2022    provably of adjacent fields in the same structure, then move both
2023    loads into BB0.  Of course this can only be done if there are no
2024    dependencies preventing such motion.
2025 
2026    One of the hoisted loads will always be speculative, so the
2027    transformation is currently conservative:
2028 
2029     - The fields must be strictly adjacent.
2030     - The two fields must occupy a single memory block that is
2031       guaranteed to not cross a page boundary.
2032 
2033     The last is difficult to prove, as such memory blocks should be
2034     aligned on the minimum of the stack alignment boundary and the
2035     alignment guaranteed by heap allocation interfaces.  Thus we rely
2036     on a parameter for the alignment value.
2037 
2038     Provided a good value is used for the last case, the first
2039     restriction could possibly be relaxed.  */
2040 
2041 static void
hoist_adjacent_loads(basic_block bb0,basic_block bb1,basic_block bb2,basic_block bb3)2042 hoist_adjacent_loads (basic_block bb0, basic_block bb1,
2043 		      basic_block bb2, basic_block bb3)
2044 {
2045   int param_align = PARAM_VALUE (PARAM_L1_CACHE_LINE_SIZE);
2046   unsigned param_align_bits = (unsigned) (param_align * BITS_PER_UNIT);
2047   gimple_stmt_iterator gsi;
2048 
2049   /* Walk the phis in bb3 looking for an opportunity.  We are looking
2050      for phis of two SSA names, one each of which is defined in bb1 and
2051      bb2.  */
2052   for (gsi = gsi_start_phis (bb3); !gsi_end_p (gsi); gsi_next (&gsi))
2053     {
2054       gimple phi_stmt = gsi_stmt (gsi);
2055       gimple def1, def2, defswap;
2056       tree arg1, arg2, ref1, ref2, field1, field2, fieldswap;
2057       tree tree_offset1, tree_offset2, tree_size2, next;
2058       int offset1, offset2, size2;
2059       unsigned align1;
2060       gimple_stmt_iterator gsi2;
2061       basic_block bb_for_def1, bb_for_def2;
2062 
2063       if (gimple_phi_num_args (phi_stmt) != 2
2064 	  || virtual_operand_p (gimple_phi_result (phi_stmt)))
2065 	continue;
2066 
2067       arg1 = gimple_phi_arg_def (phi_stmt, 0);
2068       arg2 = gimple_phi_arg_def (phi_stmt, 1);
2069 
2070       if (TREE_CODE (arg1) != SSA_NAME
2071 	  || TREE_CODE (arg2) != SSA_NAME
2072 	  || SSA_NAME_IS_DEFAULT_DEF (arg1)
2073 	  || SSA_NAME_IS_DEFAULT_DEF (arg2))
2074 	continue;
2075 
2076       def1 = SSA_NAME_DEF_STMT (arg1);
2077       def2 = SSA_NAME_DEF_STMT (arg2);
2078 
2079       if ((gimple_bb (def1) != bb1 || gimple_bb (def2) != bb2)
2080 	  && (gimple_bb (def2) != bb1 || gimple_bb (def1) != bb2))
2081 	continue;
2082 
2083       /* Check the mode of the arguments to be sure a conditional move
2084 	 can be generated for it.  */
2085       if (optab_handler (movcc_optab, TYPE_MODE (TREE_TYPE (arg1)))
2086 	  == CODE_FOR_nothing)
2087 	continue;
2088 
2089       /* Both statements must be assignments whose RHS is a COMPONENT_REF.  */
2090       if (!gimple_assign_single_p (def1)
2091 	  || !gimple_assign_single_p (def2)
2092 	  || gimple_has_volatile_ops (def1)
2093 	  || gimple_has_volatile_ops (def2))
2094 	continue;
2095 
2096       ref1 = gimple_assign_rhs1 (def1);
2097       ref2 = gimple_assign_rhs1 (def2);
2098 
2099       if (TREE_CODE (ref1) != COMPONENT_REF
2100 	  || TREE_CODE (ref2) != COMPONENT_REF)
2101 	continue;
2102 
2103       /* The zeroth operand of the two component references must be
2104 	 identical.  It is not sufficient to compare get_base_address of
2105 	 the two references, because this could allow for different
2106 	 elements of the same array in the two trees.  It is not safe to
2107 	 assume that the existence of one array element implies the
2108 	 existence of a different one.  */
2109       if (!operand_equal_p (TREE_OPERAND (ref1, 0), TREE_OPERAND (ref2, 0), 0))
2110 	continue;
2111 
2112       field1 = TREE_OPERAND (ref1, 1);
2113       field2 = TREE_OPERAND (ref2, 1);
2114 
2115       /* Check for field adjacency, and ensure field1 comes first.  */
2116       for (next = DECL_CHAIN (field1);
2117 	   next && TREE_CODE (next) != FIELD_DECL;
2118 	   next = DECL_CHAIN (next))
2119 	;
2120 
2121       if (next != field2)
2122 	{
2123 	  for (next = DECL_CHAIN (field2);
2124 	       next && TREE_CODE (next) != FIELD_DECL;
2125 	       next = DECL_CHAIN (next))
2126 	    ;
2127 
2128 	  if (next != field1)
2129 	    continue;
2130 
2131 	  fieldswap = field1;
2132 	  field1 = field2;
2133 	  field2 = fieldswap;
2134 	  defswap = def1;
2135 	  def1 = def2;
2136 	  def2 = defswap;
2137 	}
2138 
2139       bb_for_def1 = gimple_bb (def1);
2140       bb_for_def2 = gimple_bb (def2);
2141 
2142       /* Check for proper alignment of the first field.  */
2143       tree_offset1 = bit_position (field1);
2144       tree_offset2 = bit_position (field2);
2145       tree_size2 = DECL_SIZE (field2);
2146 
2147       if (!tree_fits_uhwi_p (tree_offset1)
2148 	  || !tree_fits_uhwi_p (tree_offset2)
2149 	  || !tree_fits_uhwi_p (tree_size2))
2150 	continue;
2151 
2152       offset1 = tree_to_uhwi (tree_offset1);
2153       offset2 = tree_to_uhwi (tree_offset2);
2154       size2 = tree_to_uhwi (tree_size2);
2155       align1 = DECL_ALIGN (field1) % param_align_bits;
2156 
2157       if (offset1 % BITS_PER_UNIT != 0)
2158 	continue;
2159 
2160       /* For profitability, the two field references should fit within
2161 	 a single cache line.  */
2162       if (align1 + offset2 - offset1 + size2 > param_align_bits)
2163 	continue;
2164 
2165       /* The two expressions cannot be dependent upon vdefs defined
2166 	 in bb1/bb2.  */
2167       if (local_mem_dependence (def1, bb_for_def1)
2168 	  || local_mem_dependence (def2, bb_for_def2))
2169 	continue;
2170 
2171       /* The conditions are satisfied; hoist the loads from bb1 and bb2 into
2172 	 bb0.  We hoist the first one first so that a cache miss is handled
2173          efficiently regardless of hardware cache-fill policy.  */
2174       gsi2 = gsi_for_stmt (def1);
2175       gsi_move_to_bb_end (&gsi2, bb0);
2176       gsi2 = gsi_for_stmt (def2);
2177       gsi_move_to_bb_end (&gsi2, bb0);
2178 
2179       if (dump_file && (dump_flags & TDF_DETAILS))
2180 	{
2181 	  fprintf (dump_file,
2182 		   "\nHoisting adjacent loads from %d and %d into %d: \n",
2183 		   bb_for_def1->index, bb_for_def2->index, bb0->index);
2184 	  print_gimple_stmt (dump_file, def1, 0, TDF_VOPS|TDF_MEMSYMS);
2185 	  print_gimple_stmt (dump_file, def2, 0, TDF_VOPS|TDF_MEMSYMS);
2186 	}
2187     }
2188 }
2189 
2190 /* Determine whether we should attempt to hoist adjacent loads out of
2191    diamond patterns in pass_phiopt.  Always hoist loads if
2192    -fhoist-adjacent-loads is specified and the target machine has
2193    both a conditional move instruction and a defined cache line size.  */
2194 
2195 static bool
gate_hoist_loads(void)2196 gate_hoist_loads (void)
2197 {
2198   return (flag_hoist_adjacent_loads == 1
2199 	  && PARAM_VALUE (PARAM_L1_CACHE_LINE_SIZE)
2200 	  && HAVE_conditional_move);
2201 }
2202 
2203 /* Always do these optimizations if we have SSA
2204    trees to work on.  */
2205 static bool
gate_phiopt(void)2206 gate_phiopt (void)
2207 {
2208   return 1;
2209 }
2210 
2211 namespace {
2212 
2213 const pass_data pass_data_phiopt =
2214 {
2215   GIMPLE_PASS, /* type */
2216   "phiopt", /* name */
2217   OPTGROUP_NONE, /* optinfo_flags */
2218   true, /* has_gate */
2219   true, /* has_execute */
2220   TV_TREE_PHIOPT, /* tv_id */
2221   ( PROP_cfg | PROP_ssa ), /* properties_required */
2222   0, /* properties_provided */
2223   0, /* properties_destroyed */
2224   0, /* todo_flags_start */
2225   ( TODO_verify_ssa | TODO_verify_flow
2226     | TODO_verify_stmts ), /* todo_flags_finish */
2227 };
2228 
2229 class pass_phiopt : public gimple_opt_pass
2230 {
2231 public:
pass_phiopt(gcc::context * ctxt)2232   pass_phiopt (gcc::context *ctxt)
2233     : gimple_opt_pass (pass_data_phiopt, ctxt)
2234   {}
2235 
2236   /* opt_pass methods: */
clone()2237   opt_pass * clone () { return new pass_phiopt (m_ctxt); }
gate()2238   bool gate () { return gate_phiopt (); }
execute()2239   unsigned int execute () { return tree_ssa_phiopt (); }
2240 
2241 }; // class pass_phiopt
2242 
2243 } // anon namespace
2244 
2245 gimple_opt_pass *
make_pass_phiopt(gcc::context * ctxt)2246 make_pass_phiopt (gcc::context *ctxt)
2247 {
2248   return new pass_phiopt (ctxt);
2249 }
2250 
2251 static bool
gate_cselim(void)2252 gate_cselim (void)
2253 {
2254   return flag_tree_cselim;
2255 }
2256 
2257 namespace {
2258 
2259 const pass_data pass_data_cselim =
2260 {
2261   GIMPLE_PASS, /* type */
2262   "cselim", /* name */
2263   OPTGROUP_NONE, /* optinfo_flags */
2264   true, /* has_gate */
2265   true, /* has_execute */
2266   TV_TREE_PHIOPT, /* tv_id */
2267   ( PROP_cfg | PROP_ssa ), /* properties_required */
2268   0, /* properties_provided */
2269   0, /* properties_destroyed */
2270   0, /* todo_flags_start */
2271   ( TODO_verify_ssa | TODO_verify_flow
2272     | TODO_verify_stmts ), /* todo_flags_finish */
2273 };
2274 
2275 class pass_cselim : public gimple_opt_pass
2276 {
2277 public:
pass_cselim(gcc::context * ctxt)2278   pass_cselim (gcc::context *ctxt)
2279     : gimple_opt_pass (pass_data_cselim, ctxt)
2280   {}
2281 
2282   /* opt_pass methods: */
gate()2283   bool gate () { return gate_cselim (); }
execute()2284   unsigned int execute () { return tree_ssa_cs_elim (); }
2285 
2286 }; // class pass_cselim
2287 
2288 } // anon namespace
2289 
2290 gimple_opt_pass *
make_pass_cselim(gcc::context * ctxt)2291 make_pass_cselim (gcc::context *ctxt)
2292 {
2293   return new pass_cselim (ctxt);
2294 }
2295