1 /* Optimization of PHI nodes by converting them into straightline code.
2 Copyright (C) 2004-2014 Free Software Foundation, Inc.
4 This file is part of GCC.
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
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
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/>. */
22 #include "coretypes.h"
23 #include "hash-table.h"
26 #include "stor-layout.h"
29 #include "basic-block.h"
31 #include "tree-ssa-alias.h"
32 #include "internal-fn.h"
33 #include "gimple-expr.h"
37 #include "gimple-iterator.h"
38 #include "gimplify-me.h"
39 #include "gimple-ssa.h"
41 #include "tree-phinodes.h"
42 #include "ssa-iterators.h"
43 #include "stringpool.h"
44 #include "tree-ssanames.h"
47 #include "tree-pass.h"
48 #include "langhooks.h"
51 #include "tree-data-ref.h"
52 #include "gimple-pretty-print.h"
53 #include "insn-config.h"
56 #include "tree-scalar-evolution.h"
57 #include "tree-inline.h"
59 #ifndef HAVE_conditional_move
60 #define HAVE_conditional_move (0)
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
,
76 static bool cond_if_else_store_replacement (basic_block
, basic_block
, basic_block
);
77 static hash_set
<tree
> * get_non_trapping ();
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);
83 /* This pass tries to transform conditional stores into unconditional
84 ones, enabling further simplifications with the simpler then and else
85 blocks. In particular it replaces this:
88 if (cond) goto bb2; else goto bb1;
96 if (cond) goto bb1; else goto bb2;
100 condtmp = PHI <RHS, condtmp'>
103 This transformation can only be done under several constraints,
104 documented below. It also replaces:
107 if (cond) goto bb2; else goto bb1;
118 if (cond) goto bb3; else goto bb1;
121 condtmp = PHI <RHS1, RHS2>
125 tree_ssa_cs_elim (void)
128 /* ??? We are not interested in loop related info, but the following
129 will create it, ICEing as we didn't init loops with pre-headers.
130 An interfacing issue of find_data_references_in_bb. */
131 loop_optimizer_init (LOOPS_NORMAL
);
133 todo
= tree_ssa_phiopt_worker (true, false);
135 loop_optimizer_finalize ();
139 /* Return the singleton PHI in the SEQ of PHIs for edges E0 and E1. */
142 single_non_singleton_phi_for_edges (gimple_seq seq
, edge e0
, edge e1
)
144 gimple_stmt_iterator i
;
146 if (gimple_seq_singleton_p (seq
))
147 return gsi_stmt (gsi_start (seq
));
148 for (i
= gsi_start (seq
); !gsi_end_p (i
); gsi_next (&i
))
150 gimple p
= gsi_stmt (i
);
151 /* If the PHI arguments are equal then we can skip this PHI. */
152 if (operand_equal_for_phi_arg_p (gimple_phi_arg_def (p
, e0
->dest_idx
),
153 gimple_phi_arg_def (p
, e1
->dest_idx
)))
156 /* If we already have a PHI that has the two edge arguments are
157 different, then return it is not a singleton for these PHIs. */
166 /* The core routine of conditional store replacement and normal
167 phi optimizations. Both share much of the infrastructure in how
168 to match applicable basic block patterns. DO_STORE_ELIM is true
169 when we want to do conditional store replacement, false otherwise.
170 DO_HOIST_LOADS is true when we want to hoist adjacent loads out
171 of diamond control flow patterns, false otherwise. */
173 tree_ssa_phiopt_worker (bool do_store_elim
, bool do_hoist_loads
)
176 basic_block
*bb_order
;
178 bool cfgchanged
= false;
179 hash_set
<tree
> *nontrap
= 0;
182 /* Calculate the set of non-trapping memory accesses. */
183 nontrap
= get_non_trapping ();
185 /* The replacement of conditional negation with a non-branching
186 sequence is really only a win when optimizing for speed and we
187 can avoid transformations by gimple if-conversion that result
188 in poor RTL generation.
190 Ideally either gimple if-conversion or the RTL expanders will
191 be improved and the code to emit branchless conditional negation
193 bool replace_conditional_negation
= false;
195 replace_conditional_negation
196 = ((!optimize_size
&& optimize
>= 2)
197 || (((flag_tree_loop_vectorize
|| cfun
->has_force_vectorize_loops
)
198 && flag_tree_loop_if_convert
!= 0)
199 || flag_tree_loop_if_convert
== 1
200 || flag_tree_loop_if_convert_stores
== 1));
202 /* Search every basic block for COND_EXPR we may be able to optimize.
204 We walk the blocks in order that guarantees that a block with
205 a single predecessor is processed before the predecessor.
206 This ensures that we collapse inner ifs before visiting the
207 outer ones, and also that we do not try to visit a removed
209 bb_order
= single_pred_before_succ_order ();
210 n
= n_basic_blocks_for_fn (cfun
) - NUM_FIXED_BLOCKS
;
212 for (i
= 0; i
< n
; i
++)
214 gimple cond_stmt
, phi
;
215 basic_block bb1
, bb2
;
221 cond_stmt
= last_stmt (bb
);
222 /* Check to see if the last statement is a GIMPLE_COND. */
224 || gimple_code (cond_stmt
) != GIMPLE_COND
)
227 e1
= EDGE_SUCC (bb
, 0);
229 e2
= EDGE_SUCC (bb
, 1);
232 /* We cannot do the optimization on abnormal edges. */
233 if ((e1
->flags
& EDGE_ABNORMAL
) != 0
234 || (e2
->flags
& EDGE_ABNORMAL
) != 0)
237 /* If either bb1's succ or bb2 or bb2's succ is non NULL. */
238 if (EDGE_COUNT (bb1
->succs
) == 0
240 || EDGE_COUNT (bb2
->succs
) == 0)
243 /* Find the bb which is the fall through to the other. */
244 if (EDGE_SUCC (bb1
, 0)->dest
== bb2
)
246 else if (EDGE_SUCC (bb2
, 0)->dest
== bb1
)
248 basic_block bb_tmp
= bb1
;
255 else if (do_store_elim
256 && EDGE_SUCC (bb1
, 0)->dest
== EDGE_SUCC (bb2
, 0)->dest
)
258 basic_block bb3
= EDGE_SUCC (bb1
, 0)->dest
;
260 if (!single_succ_p (bb1
)
261 || (EDGE_SUCC (bb1
, 0)->flags
& EDGE_FALLTHRU
) == 0
262 || !single_succ_p (bb2
)
263 || (EDGE_SUCC (bb2
, 0)->flags
& EDGE_FALLTHRU
) == 0
264 || EDGE_COUNT (bb3
->preds
) != 2)
266 if (cond_if_else_store_replacement (bb1
, bb2
, bb3
))
270 else if (do_hoist_loads
271 && EDGE_SUCC (bb1
, 0)->dest
== EDGE_SUCC (bb2
, 0)->dest
)
273 basic_block bb3
= EDGE_SUCC (bb1
, 0)->dest
;
275 if (!FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (cond_stmt
)))
276 && single_succ_p (bb1
)
277 && single_succ_p (bb2
)
278 && single_pred_p (bb1
)
279 && single_pred_p (bb2
)
280 && EDGE_COUNT (bb
->succs
) == 2
281 && EDGE_COUNT (bb3
->preds
) == 2
282 /* If one edge or the other is dominant, a conditional move
283 is likely to perform worse than the well-predicted branch. */
284 && !predictable_edge_p (EDGE_SUCC (bb
, 0))
285 && !predictable_edge_p (EDGE_SUCC (bb
, 1)))
286 hoist_adjacent_loads (bb
, bb1
, bb2
, bb3
);
292 e1
= EDGE_SUCC (bb1
, 0);
294 /* Make sure that bb1 is just a fall through. */
295 if (!single_succ_p (bb1
)
296 || (e1
->flags
& EDGE_FALLTHRU
) == 0)
299 /* Also make sure that bb1 only have one predecessor and that it
301 if (!single_pred_p (bb1
)
302 || single_pred (bb1
) != bb
)
307 /* bb1 is the middle block, bb2 the join block, bb the split block,
308 e1 the fallthrough edge from bb1 to bb2. We can't do the
309 optimization if the join block has more than two predecessors. */
310 if (EDGE_COUNT (bb2
->preds
) > 2)
312 if (cond_store_replacement (bb1
, bb2
, e1
, e2
, nontrap
))
317 gimple_seq phis
= phi_nodes (bb2
);
318 gimple_stmt_iterator gsi
;
319 bool candorest
= true;
321 /* Value replacement can work with more than one PHI
322 so try that first. */
323 for (gsi
= gsi_start (phis
); !gsi_end_p (gsi
); gsi_next (&gsi
))
325 phi
= gsi_stmt (gsi
);
326 arg0
= gimple_phi_arg_def (phi
, e1
->dest_idx
);
327 arg1
= gimple_phi_arg_def (phi
, e2
->dest_idx
);
328 if (value_replacement (bb
, bb1
, e1
, e2
, phi
, arg0
, arg1
) == 2)
339 phi
= single_non_singleton_phi_for_edges (phis
, e1
, e2
);
343 arg0
= gimple_phi_arg_def (phi
, e1
->dest_idx
);
344 arg1
= gimple_phi_arg_def (phi
, e2
->dest_idx
);
346 /* Something is wrong if we cannot find the arguments in the PHI
348 gcc_assert (arg0
!= NULL
&& arg1
!= NULL
);
350 /* Do the replacement of conditional if it can be done. */
351 if (conditional_replacement (bb
, bb1
, e1
, e2
, phi
, arg0
, arg1
))
353 else if (abs_replacement (bb
, bb1
, e1
, e2
, phi
, arg0
, arg1
))
355 else if (replace_conditional_negation
356 && neg_replacement (bb
, bb1
, e1
, e2
, phi
, arg0
, arg1
))
358 else if (minmax_replacement (bb
, bb1
, e1
, e2
, phi
, arg0
, arg1
))
367 /* If the CFG has changed, we should cleanup the CFG. */
368 if (cfgchanged
&& do_store_elim
)
370 /* In cond-store replacement we have added some loads on edges
371 and new VOPS (as we moved the store, and created a load). */
372 gsi_commit_edge_inserts ();
373 return TODO_cleanup_cfg
| TODO_update_ssa_only_virtuals
;
376 return TODO_cleanup_cfg
;
380 /* Replace PHI node element whose edge is E in block BB with variable NEW.
381 Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
382 is known to have two edges, one of which must reach BB). */
385 replace_phi_edge_with_variable (basic_block cond_block
,
386 edge e
, gimple phi
, tree new_tree
)
388 basic_block bb
= gimple_bb (phi
);
389 basic_block block_to_remove
;
390 gimple_stmt_iterator gsi
;
392 /* Change the PHI argument to new. */
393 SET_USE (PHI_ARG_DEF_PTR (phi
, e
->dest_idx
), new_tree
);
395 /* Remove the empty basic block. */
396 if (EDGE_SUCC (cond_block
, 0)->dest
== bb
)
398 EDGE_SUCC (cond_block
, 0)->flags
|= EDGE_FALLTHRU
;
399 EDGE_SUCC (cond_block
, 0)->flags
&= ~(EDGE_TRUE_VALUE
| EDGE_FALSE_VALUE
);
400 EDGE_SUCC (cond_block
, 0)->probability
= REG_BR_PROB_BASE
;
401 EDGE_SUCC (cond_block
, 0)->count
+= EDGE_SUCC (cond_block
, 1)->count
;
403 block_to_remove
= EDGE_SUCC (cond_block
, 1)->dest
;
407 EDGE_SUCC (cond_block
, 1)->flags
|= EDGE_FALLTHRU
;
408 EDGE_SUCC (cond_block
, 1)->flags
409 &= ~(EDGE_TRUE_VALUE
| EDGE_FALSE_VALUE
);
410 EDGE_SUCC (cond_block
, 1)->probability
= REG_BR_PROB_BASE
;
411 EDGE_SUCC (cond_block
, 1)->count
+= EDGE_SUCC (cond_block
, 0)->count
;
413 block_to_remove
= EDGE_SUCC (cond_block
, 0)->dest
;
415 delete_basic_block (block_to_remove
);
417 /* Eliminate the COND_EXPR at the end of COND_BLOCK. */
418 gsi
= gsi_last_bb (cond_block
);
419 gsi_remove (&gsi
, true);
421 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
423 "COND_EXPR in block %d and PHI in block %d converted to straightline code.\n",
428 /* The function conditional_replacement does the main work of doing the
429 conditional replacement. Return true if the replacement is done.
430 Otherwise return false.
431 BB is the basic block where the replacement is going to be done on. ARG0
432 is argument 0 from PHI. Likewise for ARG1. */
435 conditional_replacement (basic_block cond_bb
, basic_block middle_bb
,
436 edge e0
, edge e1
, gimple phi
,
437 tree arg0
, tree arg1
)
441 gimple_assign new_stmt
;
443 gimple_stmt_iterator gsi
;
444 edge true_edge
, false_edge
;
445 tree new_var
, new_var2
;
448 /* FIXME: Gimplification of complex type is too hard for now. */
449 /* We aren't prepared to handle vectors either (and it is a question
450 if it would be worthwhile anyway). */
451 if (!(INTEGRAL_TYPE_P (TREE_TYPE (arg0
))
452 || POINTER_TYPE_P (TREE_TYPE (arg0
)))
453 || !(INTEGRAL_TYPE_P (TREE_TYPE (arg1
))
454 || POINTER_TYPE_P (TREE_TYPE (arg1
))))
457 /* The PHI arguments have the constants 0 and 1, or 0 and -1, then
458 convert it to the conditional. */
459 if ((integer_zerop (arg0
) && integer_onep (arg1
))
460 || (integer_zerop (arg1
) && integer_onep (arg0
)))
462 else if ((integer_zerop (arg0
) && integer_all_onesp (arg1
))
463 || (integer_zerop (arg1
) && integer_all_onesp (arg0
)))
468 if (!empty_block_p (middle_bb
))
471 /* At this point we know we have a GIMPLE_COND with two successors.
472 One successor is BB, the other successor is an empty block which
473 falls through into BB.
475 There is a single PHI node at the join point (BB) and its arguments
476 are constants (0, 1) or (0, -1).
478 So, given the condition COND, and the two PHI arguments, we can
479 rewrite this PHI into non-branching code:
481 dest = (COND) or dest = COND'
483 We use the condition as-is if the argument associated with the
484 true edge has the value one or the argument associated with the
485 false edge as the value zero. Note that those conditions are not
486 the same since only one of the outgoing edges from the GIMPLE_COND
487 will directly reach BB and thus be associated with an argument. */
489 stmt
= last_stmt (cond_bb
);
490 result
= PHI_RESULT (phi
);
492 /* To handle special cases like floating point comparison, it is easier and
493 less error-prone to build a tree and gimplify it on the fly though it is
495 cond
= fold_build2_loc (gimple_location (stmt
),
496 gimple_cond_code (stmt
), boolean_type_node
,
497 gimple_cond_lhs (stmt
), gimple_cond_rhs (stmt
));
499 /* We need to know which is the true edge and which is the false
500 edge so that we know when to invert the condition below. */
501 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
502 if ((e0
== true_edge
&& integer_zerop (arg0
))
503 || (e0
== false_edge
&& !integer_zerop (arg0
))
504 || (e1
== true_edge
&& integer_zerop (arg1
))
505 || (e1
== false_edge
&& !integer_zerop (arg1
)))
506 cond
= fold_build1_loc (gimple_location (stmt
),
507 TRUTH_NOT_EXPR
, TREE_TYPE (cond
), cond
);
511 cond
= fold_convert_loc (gimple_location (stmt
),
512 TREE_TYPE (result
), cond
);
513 cond
= fold_build1_loc (gimple_location (stmt
),
514 NEGATE_EXPR
, TREE_TYPE (cond
), cond
);
517 /* Insert our new statements at the end of conditional block before the
519 gsi
= gsi_for_stmt (stmt
);
520 new_var
= force_gimple_operand_gsi (&gsi
, cond
, true, NULL
, true,
523 if (!useless_type_conversion_p (TREE_TYPE (result
), TREE_TYPE (new_var
)))
525 source_location locus_0
, locus_1
;
527 new_var2
= make_ssa_name (TREE_TYPE (result
), NULL
);
528 new_stmt
= gimple_build_assign_with_ops (CONVERT_EXPR
, new_var2
,
530 gsi_insert_before (&gsi
, new_stmt
, GSI_SAME_STMT
);
533 /* Set the locus to the first argument, unless is doesn't have one. */
534 locus_0
= gimple_phi_arg_location (phi
, 0);
535 locus_1
= gimple_phi_arg_location (phi
, 1);
536 if (locus_0
== UNKNOWN_LOCATION
)
538 gimple_set_location (new_stmt
, locus_0
);
541 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, new_var
);
543 /* Note that we optimized this PHI. */
547 /* Update *ARG which is defined in STMT so that it contains the
548 computed value if that seems profitable. Return true if the
549 statement is made dead by that rewriting. */
552 jump_function_from_stmt (tree
*arg
, gimple stmt
)
554 enum tree_code code
= gimple_assign_rhs_code (stmt
);
555 if (code
== ADDR_EXPR
)
557 /* For arg = &p->i transform it to p, if possible. */
558 tree rhs1
= gimple_assign_rhs1 (stmt
);
559 HOST_WIDE_INT offset
;
560 tree tem
= get_addr_base_and_unit_offset (TREE_OPERAND (rhs1
, 0),
563 && TREE_CODE (tem
) == MEM_REF
564 && (mem_ref_offset (tem
) + offset
) == 0)
566 *arg
= TREE_OPERAND (tem
, 0);
570 /* TODO: Much like IPA-CP jump-functions we want to handle constant
571 additions symbolically here, and we'd need to update the comparison
572 code that compares the arg + cst tuples in our caller. For now the
573 code above exactly handles the VEC_BASE pattern from vec.h. */
577 /* RHS is a source argument in a BIT_AND_EXPR which feeds a conditional
578 of the form SSA_NAME NE 0.
580 If RHS is fed by a simple EQ_EXPR comparison of two values, see if
581 the two input values of the EQ_EXPR match arg0 and arg1.
583 If so update *code and return TRUE. Otherwise return FALSE. */
586 rhs_is_fed_for_value_replacement (const_tree arg0
, const_tree arg1
,
587 enum tree_code
*code
, const_tree rhs
)
589 /* Obviously if RHS is not an SSA_NAME, we can't look at the defining
591 if (TREE_CODE (rhs
) == SSA_NAME
)
593 gimple def1
= SSA_NAME_DEF_STMT (rhs
);
595 /* Verify the defining statement has an EQ_EXPR on the RHS. */
596 if (is_gimple_assign (def1
) && gimple_assign_rhs_code (def1
) == EQ_EXPR
)
598 /* Finally verify the source operands of the EQ_EXPR are equal
600 tree op0
= gimple_assign_rhs1 (def1
);
601 tree op1
= gimple_assign_rhs2 (def1
);
602 if ((operand_equal_for_phi_arg_p (arg0
, op0
)
603 && operand_equal_for_phi_arg_p (arg1
, op1
))
604 || (operand_equal_for_phi_arg_p (arg0
, op1
)
605 && operand_equal_for_phi_arg_p (arg1
, op0
)))
607 /* We will perform the optimization. */
608 *code
= gimple_assign_rhs_code (def1
);
616 /* Return TRUE if arg0/arg1 are equal to the rhs/lhs or lhs/rhs of COND.
618 Also return TRUE if arg0/arg1 are equal to the source arguments of a
619 an EQ comparison feeding a BIT_AND_EXPR which feeds COND.
621 Return FALSE otherwise. */
624 operand_equal_for_value_replacement (const_tree arg0
, const_tree arg1
,
625 enum tree_code
*code
, gimple cond
)
628 tree lhs
= gimple_cond_lhs (cond
);
629 tree rhs
= gimple_cond_rhs (cond
);
631 if ((operand_equal_for_phi_arg_p (arg0
, lhs
)
632 && operand_equal_for_phi_arg_p (arg1
, rhs
))
633 || (operand_equal_for_phi_arg_p (arg1
, lhs
)
634 && operand_equal_for_phi_arg_p (arg0
, rhs
)))
637 /* Now handle more complex case where we have an EQ comparison
638 which feeds a BIT_AND_EXPR which feeds COND.
640 First verify that COND is of the form SSA_NAME NE 0. */
641 if (*code
!= NE_EXPR
|| !integer_zerop (rhs
)
642 || TREE_CODE (lhs
) != SSA_NAME
)
645 /* Now ensure that SSA_NAME is set by a BIT_AND_EXPR. */
646 def
= SSA_NAME_DEF_STMT (lhs
);
647 if (!is_gimple_assign (def
) || gimple_assign_rhs_code (def
) != BIT_AND_EXPR
)
650 /* Now verify arg0/arg1 correspond to the source arguments of an
651 EQ comparison feeding the BIT_AND_EXPR. */
653 tree tmp
= gimple_assign_rhs1 (def
);
654 if (rhs_is_fed_for_value_replacement (arg0
, arg1
, code
, tmp
))
657 tmp
= gimple_assign_rhs2 (def
);
658 if (rhs_is_fed_for_value_replacement (arg0
, arg1
, code
, tmp
))
664 /* Returns true if ARG is a neutral element for operation CODE
665 on the RIGHT side. */
668 neutral_element_p (tree_code code
, tree arg
, bool right
)
675 return integer_zerop (arg
);
682 case POINTER_PLUS_EXPR
:
683 return right
&& integer_zerop (arg
);
686 return integer_onep (arg
);
693 return right
&& integer_onep (arg
);
696 return integer_all_onesp (arg
);
703 /* Returns true if ARG is an absorbing element for operation CODE. */
706 absorbing_element_p (tree_code code
, tree arg
)
711 return integer_all_onesp (arg
);
715 return integer_zerop (arg
);
722 /* The function value_replacement does the main work of doing the value
723 replacement. Return non-zero if the replacement is done. Otherwise return
724 0. If we remove the middle basic block, return 2.
725 BB is the basic block where the replacement is going to be done on. ARG0
726 is argument 0 from the PHI. Likewise for ARG1. */
729 value_replacement (basic_block cond_bb
, basic_block middle_bb
,
730 edge e0
, edge e1
, gimple phi
,
731 tree arg0
, tree arg1
)
733 gimple_stmt_iterator gsi
;
735 edge true_edge
, false_edge
;
737 bool emtpy_or_with_defined_p
= true;
739 /* If the type says honor signed zeros we cannot do this
741 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1
))))
744 /* If there is a statement in MIDDLE_BB that defines one of the PHI
745 arguments, then adjust arg0 or arg1. */
746 gsi
= gsi_start_nondebug_after_labels_bb (middle_bb
);
747 while (!gsi_end_p (gsi
))
749 gimple stmt
= gsi_stmt (gsi
);
751 gsi_next_nondebug (&gsi
);
752 if (!is_gimple_assign (stmt
))
754 emtpy_or_with_defined_p
= false;
757 /* Now try to adjust arg0 or arg1 according to the computation
759 lhs
= gimple_assign_lhs (stmt
);
761 && jump_function_from_stmt (&arg0
, stmt
))
763 && jump_function_from_stmt (&arg1
, stmt
)))
764 emtpy_or_with_defined_p
= false;
767 cond
= last_stmt (cond_bb
);
768 code
= gimple_cond_code (cond
);
770 /* This transformation is only valid for equality comparisons. */
771 if (code
!= NE_EXPR
&& code
!= EQ_EXPR
)
774 /* We need to know which is the true edge and which is the false
775 edge so that we know if have abs or negative abs. */
776 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
778 /* At this point we know we have a COND_EXPR with two successors.
779 One successor is BB, the other successor is an empty block which
780 falls through into BB.
782 The condition for the COND_EXPR is known to be NE_EXPR or EQ_EXPR.
784 There is a single PHI node at the join point (BB) with two arguments.
786 We now need to verify that the two arguments in the PHI node match
787 the two arguments to the equality comparison. */
789 if (operand_equal_for_value_replacement (arg0
, arg1
, &code
, cond
))
794 /* For NE_EXPR, we want to build an assignment result = arg where
795 arg is the PHI argument associated with the true edge. For
796 EQ_EXPR we want the PHI argument associated with the false edge. */
797 e
= (code
== NE_EXPR
? true_edge
: false_edge
);
799 /* Unfortunately, E may not reach BB (it may instead have gone to
800 OTHER_BLOCK). If that is the case, then we want the single outgoing
801 edge from OTHER_BLOCK which reaches BB and represents the desired
802 path from COND_BLOCK. */
803 if (e
->dest
== middle_bb
)
804 e
= single_succ_edge (e
->dest
);
806 /* Now we know the incoming edge to BB that has the argument for the
807 RHS of our new assignment statement. */
813 /* If the middle basic block was empty or is defining the
814 PHI arguments and this is a single phi where the args are different
815 for the edges e0 and e1 then we can remove the middle basic block. */
816 if (emtpy_or_with_defined_p
817 && single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi
)),
820 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, arg
);
821 /* Note that we optimized this PHI. */
826 /* Replace the PHI arguments with arg. */
827 SET_PHI_ARG_DEF (phi
, e0
->dest_idx
, arg
);
828 SET_PHI_ARG_DEF (phi
, e1
->dest_idx
, arg
);
829 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
831 fprintf (dump_file
, "PHI ");
832 print_generic_expr (dump_file
, gimple_phi_result (phi
), 0);
833 fprintf (dump_file
, " reduced for COND_EXPR in block %d to ",
835 print_generic_expr (dump_file
, arg
, 0);
836 fprintf (dump_file
, ".\n");
843 /* Now optimize (x != 0) ? x + y : y to just y.
844 The following condition is too restrictive, there can easily be another
845 stmt in middle_bb, for instance a CONVERT_EXPR for the second argument. */
846 gimple assign
= last_and_only_stmt (middle_bb
);
847 if (!assign
|| gimple_code (assign
) != GIMPLE_ASSIGN
848 || gimple_assign_rhs_class (assign
) != GIMPLE_BINARY_RHS
849 || (!INTEGRAL_TYPE_P (TREE_TYPE (arg0
))
850 && !POINTER_TYPE_P (TREE_TYPE (arg0
))))
853 /* Punt if there are (degenerate) PHIs in middle_bb, there should not be. */
854 if (!gimple_seq_empty_p (phi_nodes (middle_bb
)))
857 /* Only transform if it removes the condition. */
858 if (!single_non_singleton_phi_for_edges (phi_nodes (gimple_bb (phi
)), e0
, e1
))
861 /* Size-wise, this is always profitable. */
862 if (optimize_bb_for_speed_p (cond_bb
)
863 /* The special case is useless if it has a low probability. */
864 && profile_status_for_fn (cfun
) != PROFILE_ABSENT
865 && EDGE_PRED (middle_bb
, 0)->probability
< PROB_EVEN
866 /* If assign is cheap, there is no point avoiding it. */
867 && estimate_num_insns (assign
, &eni_time_weights
)
868 >= 3 * estimate_num_insns (cond
, &eni_time_weights
))
871 tree lhs
= gimple_assign_lhs (assign
);
872 tree rhs1
= gimple_assign_rhs1 (assign
);
873 tree rhs2
= gimple_assign_rhs2 (assign
);
874 enum tree_code code_def
= gimple_assign_rhs_code (assign
);
875 tree cond_lhs
= gimple_cond_lhs (cond
);
876 tree cond_rhs
= gimple_cond_rhs (cond
);
878 if (((code
== NE_EXPR
&& e1
== false_edge
)
879 || (code
== EQ_EXPR
&& e1
== true_edge
))
882 && operand_equal_for_phi_arg_p (rhs2
, cond_lhs
)
883 && neutral_element_p (code_def
, cond_rhs
, true))
885 && operand_equal_for_phi_arg_p (rhs1
, cond_lhs
)
886 && neutral_element_p (code_def
, cond_rhs
, false))
887 || (operand_equal_for_phi_arg_p (arg1
, cond_rhs
)
888 && (operand_equal_for_phi_arg_p (rhs2
, cond_lhs
)
889 || operand_equal_for_phi_arg_p (rhs1
, cond_lhs
))
890 && absorbing_element_p (code_def
, cond_rhs
))))
892 gsi
= gsi_for_stmt (cond
);
893 gimple_stmt_iterator gsi_from
= gsi_for_stmt (assign
);
894 gsi_move_before (&gsi_from
, &gsi
);
895 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, lhs
);
902 /* The function minmax_replacement does the main work of doing the minmax
903 replacement. Return true if the replacement is done. Otherwise return
905 BB is the basic block where the replacement is going to be done on. ARG0
906 is argument 0 from the PHI. Likewise for ARG1. */
909 minmax_replacement (basic_block cond_bb
, basic_block middle_bb
,
910 edge e0
, edge e1
, gimple phi
,
911 tree arg0
, tree arg1
)
915 gimple_assign new_stmt
;
916 edge true_edge
, false_edge
;
917 enum tree_code cmp
, minmax
, ass_code
;
918 tree smaller
, larger
, arg_true
, arg_false
;
919 gimple_stmt_iterator gsi
, gsi_from
;
921 type
= TREE_TYPE (PHI_RESULT (phi
));
923 /* The optimization may be unsafe due to NaNs. */
924 if (HONOR_NANS (TYPE_MODE (type
)))
927 cond
= as_a
<gimple_cond
> (last_stmt (cond_bb
));
928 cmp
= gimple_cond_code (cond
);
930 /* This transformation is only valid for order comparisons. Record which
931 operand is smaller/larger if the result of the comparison is true. */
932 if (cmp
== LT_EXPR
|| cmp
== LE_EXPR
)
934 smaller
= gimple_cond_lhs (cond
);
935 larger
= gimple_cond_rhs (cond
);
937 else if (cmp
== GT_EXPR
|| cmp
== GE_EXPR
)
939 smaller
= gimple_cond_rhs (cond
);
940 larger
= gimple_cond_lhs (cond
);
945 /* We need to know which is the true edge and which is the false
946 edge so that we know if have abs or negative abs. */
947 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
949 /* Forward the edges over the middle basic block. */
950 if (true_edge
->dest
== middle_bb
)
951 true_edge
= EDGE_SUCC (true_edge
->dest
, 0);
952 if (false_edge
->dest
== middle_bb
)
953 false_edge
= EDGE_SUCC (false_edge
->dest
, 0);
957 gcc_assert (false_edge
== e1
);
963 gcc_assert (false_edge
== e0
);
964 gcc_assert (true_edge
== e1
);
969 if (empty_block_p (middle_bb
))
971 if (operand_equal_for_phi_arg_p (arg_true
, smaller
)
972 && operand_equal_for_phi_arg_p (arg_false
, larger
))
976 if (smaller < larger)
982 else if (operand_equal_for_phi_arg_p (arg_false
, smaller
)
983 && operand_equal_for_phi_arg_p (arg_true
, larger
))
990 /* Recognize the following case, assuming d <= u:
996 This is equivalent to
1001 gimple assign
= last_and_only_stmt (middle_bb
);
1002 tree lhs
, op0
, op1
, bound
;
1005 || gimple_code (assign
) != GIMPLE_ASSIGN
)
1008 lhs
= gimple_assign_lhs (assign
);
1009 ass_code
= gimple_assign_rhs_code (assign
);
1010 if (ass_code
!= MAX_EXPR
&& ass_code
!= MIN_EXPR
)
1012 op0
= gimple_assign_rhs1 (assign
);
1013 op1
= gimple_assign_rhs2 (assign
);
1015 if (true_edge
->src
== middle_bb
)
1017 /* We got here if the condition is true, i.e., SMALLER < LARGER. */
1018 if (!operand_equal_for_phi_arg_p (lhs
, arg_true
))
1021 if (operand_equal_for_phi_arg_p (arg_false
, larger
))
1025 if (smaller < larger)
1027 r' = MAX_EXPR (smaller, bound)
1029 r = PHI <r', larger> --> to be turned to MIN_EXPR. */
1030 if (ass_code
!= MAX_EXPR
)
1034 if (operand_equal_for_phi_arg_p (op0
, smaller
))
1036 else if (operand_equal_for_phi_arg_p (op1
, smaller
))
1041 /* We need BOUND <= LARGER. */
1042 if (!integer_nonzerop (fold_build2 (LE_EXPR
, boolean_type_node
,
1046 else if (operand_equal_for_phi_arg_p (arg_false
, smaller
))
1050 if (smaller < larger)
1052 r' = MIN_EXPR (larger, bound)
1054 r = PHI <r', smaller> --> to be turned to MAX_EXPR. */
1055 if (ass_code
!= MIN_EXPR
)
1059 if (operand_equal_for_phi_arg_p (op0
, larger
))
1061 else if (operand_equal_for_phi_arg_p (op1
, larger
))
1066 /* We need BOUND >= SMALLER. */
1067 if (!integer_nonzerop (fold_build2 (GE_EXPR
, boolean_type_node
,
1076 /* We got here if the condition is false, i.e., SMALLER > LARGER. */
1077 if (!operand_equal_for_phi_arg_p (lhs
, arg_false
))
1080 if (operand_equal_for_phi_arg_p (arg_true
, larger
))
1084 if (smaller > larger)
1086 r' = MIN_EXPR (smaller, bound)
1088 r = PHI <r', larger> --> to be turned to MAX_EXPR. */
1089 if (ass_code
!= MIN_EXPR
)
1093 if (operand_equal_for_phi_arg_p (op0
, smaller
))
1095 else if (operand_equal_for_phi_arg_p (op1
, smaller
))
1100 /* We need BOUND >= LARGER. */
1101 if (!integer_nonzerop (fold_build2 (GE_EXPR
, boolean_type_node
,
1105 else if (operand_equal_for_phi_arg_p (arg_true
, smaller
))
1109 if (smaller > larger)
1111 r' = MAX_EXPR (larger, bound)
1113 r = PHI <r', smaller> --> to be turned to MIN_EXPR. */
1114 if (ass_code
!= MAX_EXPR
)
1118 if (operand_equal_for_phi_arg_p (op0
, larger
))
1120 else if (operand_equal_for_phi_arg_p (op1
, larger
))
1125 /* We need BOUND <= SMALLER. */
1126 if (!integer_nonzerop (fold_build2 (LE_EXPR
, boolean_type_node
,
1134 /* Move the statement from the middle block. */
1135 gsi
= gsi_last_bb (cond_bb
);
1136 gsi_from
= gsi_last_nondebug_bb (middle_bb
);
1137 gsi_move_before (&gsi_from
, &gsi
);
1140 /* Emit the statement to compute min/max. */
1141 result
= duplicate_ssa_name (PHI_RESULT (phi
), NULL
);
1142 new_stmt
= gimple_build_assign_with_ops (minmax
, result
, arg0
, arg1
);
1143 gsi
= gsi_last_bb (cond_bb
);
1144 gsi_insert_before (&gsi
, new_stmt
, GSI_NEW_STMT
);
1146 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, result
);
1150 /* The function absolute_replacement does the main work of doing the absolute
1151 replacement. Return true if the replacement is done. Otherwise return
1153 bb is the basic block where the replacement is going to be done on. arg0
1154 is argument 0 from the phi. Likewise for arg1. */
1157 abs_replacement (basic_block cond_bb
, basic_block middle_bb
,
1158 edge e0 ATTRIBUTE_UNUSED
, edge e1
,
1159 gimple phi
, tree arg0
, tree arg1
)
1162 gimple_assign new_stmt
;
1164 gimple_stmt_iterator gsi
;
1165 edge true_edge
, false_edge
;
1170 enum tree_code cond_code
;
1172 /* If the type says honor signed zeros we cannot do this
1174 if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1
))))
1177 /* OTHER_BLOCK must have only one executable statement which must have the
1178 form arg0 = -arg1 or arg1 = -arg0. */
1180 assign
= last_and_only_stmt (middle_bb
);
1181 /* If we did not find the proper negation assignment, then we can not
1186 /* If we got here, then we have found the only executable statement
1187 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
1188 arg1 = -arg0, then we can not optimize. */
1189 if (gimple_code (assign
) != GIMPLE_ASSIGN
)
1192 lhs
= gimple_assign_lhs (assign
);
1194 if (gimple_assign_rhs_code (assign
) != NEGATE_EXPR
)
1197 rhs
= gimple_assign_rhs1 (assign
);
1199 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
1200 if (!(lhs
== arg0
&& rhs
== arg1
)
1201 && !(lhs
== arg1
&& rhs
== arg0
))
1204 cond
= last_stmt (cond_bb
);
1205 result
= PHI_RESULT (phi
);
1207 /* Only relationals comparing arg[01] against zero are interesting. */
1208 cond_code
= gimple_cond_code (cond
);
1209 if (cond_code
!= GT_EXPR
&& cond_code
!= GE_EXPR
1210 && cond_code
!= LT_EXPR
&& cond_code
!= LE_EXPR
)
1213 /* Make sure the conditional is arg[01] OP y. */
1214 if (gimple_cond_lhs (cond
) != rhs
)
1217 if (FLOAT_TYPE_P (TREE_TYPE (gimple_cond_rhs (cond
)))
1218 ? real_zerop (gimple_cond_rhs (cond
))
1219 : integer_zerop (gimple_cond_rhs (cond
)))
1224 /* We need to know which is the true edge and which is the false
1225 edge so that we know if have abs or negative abs. */
1226 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
1228 /* For GT_EXPR/GE_EXPR, if the true edge goes to OTHER_BLOCK, then we
1229 will need to negate the result. Similarly for LT_EXPR/LE_EXPR if
1230 the false edge goes to OTHER_BLOCK. */
1231 if (cond_code
== GT_EXPR
|| cond_code
== GE_EXPR
)
1236 if (e
->dest
== middle_bb
)
1241 result
= duplicate_ssa_name (result
, NULL
);
1244 lhs
= make_ssa_name (TREE_TYPE (result
), NULL
);
1248 /* Build the modify expression with abs expression. */
1249 new_stmt
= gimple_build_assign_with_ops (ABS_EXPR
, lhs
, rhs
, NULL
);
1251 gsi
= gsi_last_bb (cond_bb
);
1252 gsi_insert_before (&gsi
, new_stmt
, GSI_NEW_STMT
);
1256 /* Get the right GSI. We want to insert after the recently
1257 added ABS_EXPR statement (which we know is the first statement
1259 new_stmt
= gimple_build_assign_with_ops (NEGATE_EXPR
, result
, lhs
, NULL
);
1261 gsi_insert_after (&gsi
, new_stmt
, GSI_NEW_STMT
);
1264 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, result
);
1266 /* Note that we optimized this PHI. */
1270 /* The function neg_replacement replaces conditional negation with
1271 equivalent straight line code. Returns TRUE if replacement is done,
1272 otherwise returns FALSE.
1274 COND_BB branches around negation occuring in MIDDLE_BB.
1276 E0 and E1 are edges out of COND_BB. E0 reaches MIDDLE_BB and
1277 E1 reaches the other successor which should contain PHI with
1278 arguments ARG0 and ARG1.
1280 Assuming negation is to occur when the condition is true,
1281 then the non-branching sequence is:
1283 result = (rhs ^ -cond) + cond
1285 Inverting the condition or its result gives us negation
1286 when the original condition is false. */
1289 neg_replacement (basic_block cond_bb
, basic_block middle_bb
,
1290 edge e0 ATTRIBUTE_UNUSED
, edge e1
,
1291 gimple phi
, tree arg0
, tree arg1
)
1293 gimple new_stmt
, cond
;
1294 gimple_stmt_iterator gsi
;
1296 edge true_edge
, false_edge
;
1298 enum tree_code cond_code
;
1299 bool invert
= false;
1301 /* This transformation performs logical operations on the
1302 incoming arguments. So force them to be integral types. */
1303 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0
)))
1306 /* OTHER_BLOCK must have only one executable statement which must have the
1307 form arg0 = -arg1 or arg1 = -arg0. */
1309 assign
= last_and_only_stmt (middle_bb
);
1310 /* If we did not find the proper negation assignment, then we can not
1315 /* If we got here, then we have found the only executable statement
1316 in OTHER_BLOCK. If it is anything other than arg0 = -arg1 or
1317 arg1 = -arg0, then we can not optimize. */
1318 if (gimple_code (assign
) != GIMPLE_ASSIGN
)
1321 lhs
= gimple_assign_lhs (assign
);
1323 if (gimple_assign_rhs_code (assign
) != NEGATE_EXPR
)
1326 rhs
= gimple_assign_rhs1 (assign
);
1328 /* The assignment has to be arg0 = -arg1 or arg1 = -arg0. */
1329 if (!(lhs
== arg0
&& rhs
== arg1
)
1330 && !(lhs
== arg1
&& rhs
== arg0
))
1333 /* The basic sequence assumes we negate when the condition is true.
1334 If we need the opposite, then we will either need to invert the
1335 condition or its result. */
1336 extract_true_false_edges_from_block (cond_bb
, &true_edge
, &false_edge
);
1337 invert
= false_edge
->dest
== middle_bb
;
1339 /* Unlike abs_replacement, we can handle arbitrary conditionals here. */
1340 cond
= last_stmt (cond_bb
);
1341 cond_code
= gimple_cond_code (cond
);
1343 /* If inversion is needed, first try to invert the test since
1348 = HONOR_NANS (TYPE_MODE (TREE_TYPE (gimple_cond_lhs (cond
))));
1349 enum tree_code new_code
= invert_tree_comparison (cond_code
, honor_nans
);
1351 /* If invert_tree_comparison was successful, then use its return
1352 value as the new code and note that inversion is no longer
1354 if (new_code
!= ERROR_MARK
)
1356 cond_code
= new_code
;
1361 tree cond_val
= make_ssa_name (boolean_type_node
, NULL
);
1362 new_stmt
= gimple_build_assign_with_ops (cond_code
, cond_val
,
1363 gimple_cond_lhs (cond
),
1364 gimple_cond_rhs (cond
));
1365 gsi
= gsi_last_bb (cond_bb
);
1366 gsi_insert_before (&gsi
, new_stmt
, GSI_NEW_STMT
);
1368 /* If we still need inversion, then invert the result of the
1372 tree tmp
= make_ssa_name (boolean_type_node
, NULL
);
1373 new_stmt
= gimple_build_assign_with_ops (BIT_XOR_EXPR
, tmp
,
1374 cond_val
, boolean_true_node
);
1375 gsi_insert_after (&gsi
, new_stmt
, GSI_NEW_STMT
);
1379 /* Get the condition in the right type so that we can perform
1380 logical and arithmetic operations on it. */
1381 tree cond_val_converted
= make_ssa_name (TREE_TYPE (rhs
), NULL
);
1382 new_stmt
= gimple_build_assign_with_ops (NOP_EXPR
, cond_val_converted
,
1383 cond_val
, NULL_TREE
);
1384 gsi_insert_after (&gsi
, new_stmt
, GSI_NEW_STMT
);
1386 tree neg_cond_val_converted
= make_ssa_name (TREE_TYPE (rhs
), NULL
);
1387 new_stmt
= gimple_build_assign_with_ops (NEGATE_EXPR
, neg_cond_val_converted
,
1388 cond_val_converted
, NULL_TREE
);
1389 gsi_insert_after (&gsi
, new_stmt
, GSI_NEW_STMT
);
1391 tree tmp
= make_ssa_name (TREE_TYPE (rhs
), NULL
);
1392 new_stmt
= gimple_build_assign_with_ops (BIT_XOR_EXPR
, tmp
,
1393 rhs
, neg_cond_val_converted
);
1394 gsi_insert_after (&gsi
, new_stmt
, GSI_NEW_STMT
);
1396 tree new_lhs
= make_ssa_name (TREE_TYPE (rhs
), NULL
);
1397 new_stmt
= gimple_build_assign_with_ops (PLUS_EXPR
, new_lhs
,
1398 tmp
, cond_val_converted
);
1399 gsi_insert_after (&gsi
, new_stmt
, GSI_NEW_STMT
);
1401 replace_phi_edge_with_variable (cond_bb
, e1
, phi
, new_lhs
);
1403 /* Note that we optimized this PHI. */
1407 /* Auxiliary functions to determine the set of memory accesses which
1408 can't trap because they are preceded by accesses to the same memory
1409 portion. We do that for MEM_REFs, so we only need to track
1410 the SSA_NAME of the pointer indirectly referenced. The algorithm
1411 simply is a walk over all instructions in dominator order. When
1412 we see an MEM_REF we determine if we've already seen a same
1413 ref anywhere up to the root of the dominator tree. If we do the
1414 current access can't trap. If we don't see any dominating access
1415 the current access might trap, but might also make later accesses
1416 non-trapping, so we remember it. We need to be careful with loads
1417 or stores, for instance a load might not trap, while a store would,
1418 so if we see a dominating read access this doesn't mean that a later
1419 write access would not trap. Hence we also need to differentiate the
1420 type of access(es) seen.
1422 ??? We currently are very conservative and assume that a load might
1423 trap even if a store doesn't (write-only memory). This probably is
1424 overly conservative. */
1426 /* A hash-table of SSA_NAMEs, and in which basic block an MEM_REF
1427 through it was seen, which would constitute a no-trap region for
1431 unsigned int ssa_name_ver
;
1434 HOST_WIDE_INT offset
, size
;
1438 /* Hashtable helpers. */
1440 struct ssa_names_hasher
: typed_free_remove
<name_to_bb
>
1442 typedef name_to_bb value_type
;
1443 typedef name_to_bb compare_type
;
1444 static inline hashval_t
hash (const value_type
*);
1445 static inline bool equal (const value_type
*, const compare_type
*);
1448 /* Used for quick clearing of the hash-table when we see calls.
1449 Hash entries with phase < nt_call_phase are invalid. */
1450 static unsigned int nt_call_phase
;
1452 /* The hash function. */
1455 ssa_names_hasher::hash (const value_type
*n
)
1457 return n
->ssa_name_ver
^ (((hashval_t
) n
->store
) << 31)
1458 ^ (n
->offset
<< 6) ^ (n
->size
<< 3);
1461 /* The equality function of *P1 and *P2. */
1464 ssa_names_hasher::equal (const value_type
*n1
, const compare_type
*n2
)
1466 return n1
->ssa_name_ver
== n2
->ssa_name_ver
1467 && n1
->store
== n2
->store
1468 && n1
->offset
== n2
->offset
1469 && n1
->size
== n2
->size
;
1472 class nontrapping_dom_walker
: public dom_walker
1475 nontrapping_dom_walker (cdi_direction direction
, hash_set
<tree
> *ps
)
1476 : dom_walker (direction
), m_nontrapping (ps
), m_seen_ssa_names (128) {}
1478 virtual void before_dom_children (basic_block
);
1479 virtual void after_dom_children (basic_block
);
1483 /* We see the expression EXP in basic block BB. If it's an interesting
1484 expression (an MEM_REF through an SSA_NAME) possibly insert the
1485 expression into the set NONTRAP or the hash table of seen expressions.
1486 STORE is true if this expression is on the LHS, otherwise it's on
1488 void add_or_mark_expr (basic_block
, tree
, bool);
1490 hash_set
<tree
> *m_nontrapping
;
1492 /* The hash table for remembering what we've seen. */
1493 hash_table
<ssa_names_hasher
> m_seen_ssa_names
;
1496 /* Called by walk_dominator_tree, when entering the block BB. */
1498 nontrapping_dom_walker::before_dom_children (basic_block bb
)
1502 gimple_stmt_iterator gsi
;
1504 /* If we haven't seen all our predecessors, clear the hash-table. */
1505 FOR_EACH_EDGE (e
, ei
, bb
->preds
)
1506 if ((((size_t)e
->src
->aux
) & 2) == 0)
1512 /* Mark this BB as being on the path to dominator root and as visited. */
1513 bb
->aux
= (void*)(1 | 2);
1515 /* And walk the statements in order. */
1516 for (gsi
= gsi_start_bb (bb
); !gsi_end_p (gsi
); gsi_next (&gsi
))
1518 gimple stmt
= gsi_stmt (gsi
);
1520 if (is_gimple_call (stmt
) && !nonfreeing_call_p (stmt
))
1522 else if (gimple_assign_single_p (stmt
) && !gimple_has_volatile_ops (stmt
))
1524 add_or_mark_expr (bb
, gimple_assign_lhs (stmt
), true);
1525 add_or_mark_expr (bb
, gimple_assign_rhs1 (stmt
), false);
1530 /* Called by walk_dominator_tree, when basic block BB is exited. */
1532 nontrapping_dom_walker::after_dom_children (basic_block bb
)
1534 /* This BB isn't on the path to dominator root anymore. */
1538 /* We see the expression EXP in basic block BB. If it's an interesting
1539 expression (an MEM_REF through an SSA_NAME) possibly insert the
1540 expression into the set NONTRAP or the hash table of seen expressions.
1541 STORE is true if this expression is on the LHS, otherwise it's on
1544 nontrapping_dom_walker::add_or_mark_expr (basic_block bb
, tree exp
, bool store
)
1548 if (TREE_CODE (exp
) == MEM_REF
1549 && TREE_CODE (TREE_OPERAND (exp
, 0)) == SSA_NAME
1550 && tree_fits_shwi_p (TREE_OPERAND (exp
, 1))
1551 && (size
= int_size_in_bytes (TREE_TYPE (exp
))) > 0)
1553 tree name
= TREE_OPERAND (exp
, 0);
1554 struct name_to_bb map
;
1556 struct name_to_bb
*n2bb
;
1557 basic_block found_bb
= 0;
1559 /* Try to find the last seen MEM_REF through the same
1560 SSA_NAME, which can trap. */
1561 map
.ssa_name_ver
= SSA_NAME_VERSION (name
);
1565 map
.offset
= tree_to_shwi (TREE_OPERAND (exp
, 1));
1568 slot
= m_seen_ssa_names
.find_slot (&map
, INSERT
);
1570 if (n2bb
&& n2bb
->phase
>= nt_call_phase
)
1571 found_bb
= n2bb
->bb
;
1573 /* If we've found a trapping MEM_REF, _and_ it dominates EXP
1574 (it's in a basic block on the path from us to the dominator root)
1575 then we can't trap. */
1576 if (found_bb
&& (((size_t)found_bb
->aux
) & 1) == 1)
1578 m_nontrapping
->add (exp
);
1582 /* EXP might trap, so insert it into the hash table. */
1585 n2bb
->phase
= nt_call_phase
;
1590 n2bb
= XNEW (struct name_to_bb
);
1591 n2bb
->ssa_name_ver
= SSA_NAME_VERSION (name
);
1592 n2bb
->phase
= nt_call_phase
;
1594 n2bb
->store
= store
;
1595 n2bb
->offset
= map
.offset
;
1603 /* This is the entry point of gathering non trapping memory accesses.
1604 It will do a dominator walk over the whole function, and it will
1605 make use of the bb->aux pointers. It returns a set of trees
1606 (the MEM_REFs itself) which can't trap. */
1607 static hash_set
<tree
> *
1608 get_non_trapping (void)
1611 hash_set
<tree
> *nontrap
= new hash_set
<tree
>;
1612 /* We're going to do a dominator walk, so ensure that we have
1613 dominance information. */
1614 calculate_dominance_info (CDI_DOMINATORS
);
1616 nontrapping_dom_walker (CDI_DOMINATORS
, nontrap
)
1617 .walk (cfun
->cfg
->x_entry_block_ptr
);
1619 clear_aux_for_blocks ();
1623 /* Do the main work of conditional store replacement. We already know
1624 that the recognized pattern looks like so:
1627 if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
1630 fallthrough (edge E0)
1634 We check that MIDDLE_BB contains only one store, that that store
1635 doesn't trap (not via NOTRAP, but via checking if an access to the same
1636 memory location dominates us) and that the store has a "simple" RHS. */
1639 cond_store_replacement (basic_block middle_bb
, basic_block join_bb
,
1640 edge e0
, edge e1
, hash_set
<tree
> *nontrap
)
1642 gimple assign
= last_and_only_stmt (middle_bb
);
1643 tree lhs
, rhs
, name
, name2
;
1645 gimple_assign new_stmt
;
1646 gimple_stmt_iterator gsi
;
1647 source_location locus
;
1649 /* Check if middle_bb contains of only one store. */
1651 || !gimple_assign_single_p (assign
)
1652 || gimple_has_volatile_ops (assign
))
1655 locus
= gimple_location (assign
);
1656 lhs
= gimple_assign_lhs (assign
);
1657 rhs
= gimple_assign_rhs1 (assign
);
1658 if (TREE_CODE (lhs
) != MEM_REF
1659 || TREE_CODE (TREE_OPERAND (lhs
, 0)) != SSA_NAME
1660 || !is_gimple_reg_type (TREE_TYPE (lhs
)))
1663 /* Prove that we can move the store down. We could also check
1664 TREE_THIS_NOTRAP here, but in that case we also could move stores,
1665 whose value is not available readily, which we want to avoid. */
1666 if (!nontrap
->contains (lhs
))
1669 /* Now we've checked the constraints, so do the transformation:
1670 1) Remove the single store. */
1671 gsi
= gsi_for_stmt (assign
);
1672 unlink_stmt_vdef (assign
);
1673 gsi_remove (&gsi
, true);
1674 release_defs (assign
);
1676 /* 2) Insert a load from the memory of the store to the temporary
1677 on the edge which did not contain the store. */
1678 lhs
= unshare_expr (lhs
);
1679 name
= make_temp_ssa_name (TREE_TYPE (lhs
), NULL
, "cstore");
1680 new_stmt
= gimple_build_assign (name
, lhs
);
1681 gimple_set_location (new_stmt
, locus
);
1682 gsi_insert_on_edge (e1
, new_stmt
);
1684 /* 3) Create a PHI node at the join block, with one argument
1685 holding the old RHS, and the other holding the temporary
1686 where we stored the old memory contents. */
1687 name2
= make_temp_ssa_name (TREE_TYPE (lhs
), NULL
, "cstore");
1688 newphi
= create_phi_node (name2
, join_bb
);
1689 add_phi_arg (newphi
, rhs
, e0
, locus
);
1690 add_phi_arg (newphi
, name
, e1
, locus
);
1692 lhs
= unshare_expr (lhs
);
1693 new_stmt
= gimple_build_assign (lhs
, PHI_RESULT (newphi
));
1695 /* 4) Insert that PHI node. */
1696 gsi
= gsi_after_labels (join_bb
);
1697 if (gsi_end_p (gsi
))
1699 gsi
= gsi_last_bb (join_bb
);
1700 gsi_insert_after (&gsi
, new_stmt
, GSI_NEW_STMT
);
1703 gsi_insert_before (&gsi
, new_stmt
, GSI_NEW_STMT
);
1708 /* Do the main work of conditional store replacement. */
1711 cond_if_else_store_replacement_1 (basic_block then_bb
, basic_block else_bb
,
1712 basic_block join_bb
, gimple then_assign
,
1715 tree lhs_base
, lhs
, then_rhs
, else_rhs
, name
;
1716 source_location then_locus
, else_locus
;
1717 gimple_stmt_iterator gsi
;
1719 gimple_assign new_stmt
;
1721 if (then_assign
== NULL
1722 || !gimple_assign_single_p (then_assign
)
1723 || gimple_clobber_p (then_assign
)
1724 || gimple_has_volatile_ops (then_assign
)
1725 || else_assign
== NULL
1726 || !gimple_assign_single_p (else_assign
)
1727 || gimple_clobber_p (else_assign
)
1728 || gimple_has_volatile_ops (else_assign
))
1731 lhs
= gimple_assign_lhs (then_assign
);
1732 if (!is_gimple_reg_type (TREE_TYPE (lhs
))
1733 || !operand_equal_p (lhs
, gimple_assign_lhs (else_assign
), 0))
1736 lhs_base
= get_base_address (lhs
);
1737 if (lhs_base
== NULL_TREE
1738 || (!DECL_P (lhs_base
) && TREE_CODE (lhs_base
) != MEM_REF
))
1741 then_rhs
= gimple_assign_rhs1 (then_assign
);
1742 else_rhs
= gimple_assign_rhs1 (else_assign
);
1743 then_locus
= gimple_location (then_assign
);
1744 else_locus
= gimple_location (else_assign
);
1746 /* Now we've checked the constraints, so do the transformation:
1747 1) Remove the stores. */
1748 gsi
= gsi_for_stmt (then_assign
);
1749 unlink_stmt_vdef (then_assign
);
1750 gsi_remove (&gsi
, true);
1751 release_defs (then_assign
);
1753 gsi
= gsi_for_stmt (else_assign
);
1754 unlink_stmt_vdef (else_assign
);
1755 gsi_remove (&gsi
, true);
1756 release_defs (else_assign
);
1758 /* 2) Create a PHI node at the join block, with one argument
1759 holding the old RHS, and the other holding the temporary
1760 where we stored the old memory contents. */
1761 name
= make_temp_ssa_name (TREE_TYPE (lhs
), NULL
, "cstore");
1762 newphi
= create_phi_node (name
, join_bb
);
1763 add_phi_arg (newphi
, then_rhs
, EDGE_SUCC (then_bb
, 0), then_locus
);
1764 add_phi_arg (newphi
, else_rhs
, EDGE_SUCC (else_bb
, 0), else_locus
);
1766 new_stmt
= gimple_build_assign (lhs
, PHI_RESULT (newphi
));
1768 /* 3) Insert that PHI node. */
1769 gsi
= gsi_after_labels (join_bb
);
1770 if (gsi_end_p (gsi
))
1772 gsi
= gsi_last_bb (join_bb
);
1773 gsi_insert_after (&gsi
, new_stmt
, GSI_NEW_STMT
);
1776 gsi_insert_before (&gsi
, new_stmt
, GSI_NEW_STMT
);
1781 /* Conditional store replacement. We already know
1782 that the recognized pattern looks like so:
1785 if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
1795 fallthrough (edge E0)
1799 We check that it is safe to sink the store to JOIN_BB by verifying that
1800 there are no read-after-write or write-after-write dependencies in
1801 THEN_BB and ELSE_BB. */
1804 cond_if_else_store_replacement (basic_block then_bb
, basic_block else_bb
,
1805 basic_block join_bb
)
1807 gimple then_assign
= last_and_only_stmt (then_bb
);
1808 gimple else_assign
= last_and_only_stmt (else_bb
);
1809 vec
<data_reference_p
> then_datarefs
, else_datarefs
;
1810 vec
<ddr_p
> then_ddrs
, else_ddrs
;
1811 gimple then_store
, else_store
;
1812 bool found
, ok
= false, res
;
1813 struct data_dependence_relation
*ddr
;
1814 data_reference_p then_dr
, else_dr
;
1816 tree then_lhs
, else_lhs
;
1817 basic_block blocks
[3];
1819 if (MAX_STORES_TO_SINK
== 0)
1822 /* Handle the case with single statement in THEN_BB and ELSE_BB. */
1823 if (then_assign
&& else_assign
)
1824 return cond_if_else_store_replacement_1 (then_bb
, else_bb
, join_bb
,
1825 then_assign
, else_assign
);
1827 /* Find data references. */
1828 then_datarefs
.create (1);
1829 else_datarefs
.create (1);
1830 if ((find_data_references_in_bb (NULL
, then_bb
, &then_datarefs
)
1832 || !then_datarefs
.length ()
1833 || (find_data_references_in_bb (NULL
, else_bb
, &else_datarefs
)
1835 || !else_datarefs
.length ())
1837 free_data_refs (then_datarefs
);
1838 free_data_refs (else_datarefs
);
1842 /* Find pairs of stores with equal LHS. */
1843 auto_vec
<gimple
, 1> then_stores
, else_stores
;
1844 FOR_EACH_VEC_ELT (then_datarefs
, i
, then_dr
)
1846 if (DR_IS_READ (then_dr
))
1849 then_store
= DR_STMT (then_dr
);
1850 then_lhs
= gimple_get_lhs (then_store
);
1851 if (then_lhs
== NULL_TREE
)
1855 FOR_EACH_VEC_ELT (else_datarefs
, j
, else_dr
)
1857 if (DR_IS_READ (else_dr
))
1860 else_store
= DR_STMT (else_dr
);
1861 else_lhs
= gimple_get_lhs (else_store
);
1862 if (else_lhs
== NULL_TREE
)
1865 if (operand_equal_p (then_lhs
, else_lhs
, 0))
1875 then_stores
.safe_push (then_store
);
1876 else_stores
.safe_push (else_store
);
1879 /* No pairs of stores found. */
1880 if (!then_stores
.length ()
1881 || then_stores
.length () > (unsigned) MAX_STORES_TO_SINK
)
1883 free_data_refs (then_datarefs
);
1884 free_data_refs (else_datarefs
);
1888 /* Compute and check data dependencies in both basic blocks. */
1889 then_ddrs
.create (1);
1890 else_ddrs
.create (1);
1891 if (!compute_all_dependences (then_datarefs
, &then_ddrs
,
1893 || !compute_all_dependences (else_datarefs
, &else_ddrs
,
1896 free_dependence_relations (then_ddrs
);
1897 free_dependence_relations (else_ddrs
);
1898 free_data_refs (then_datarefs
);
1899 free_data_refs (else_datarefs
);
1902 blocks
[0] = then_bb
;
1903 blocks
[1] = else_bb
;
1904 blocks
[2] = join_bb
;
1905 renumber_gimple_stmt_uids_in_blocks (blocks
, 3);
1907 /* Check that there are no read-after-write or write-after-write dependencies
1909 FOR_EACH_VEC_ELT (then_ddrs
, i
, ddr
)
1911 struct data_reference
*dra
= DDR_A (ddr
);
1912 struct data_reference
*drb
= DDR_B (ddr
);
1914 if (DDR_ARE_DEPENDENT (ddr
) != chrec_known
1915 && ((DR_IS_READ (dra
) && DR_IS_WRITE (drb
)
1916 && gimple_uid (DR_STMT (dra
)) > gimple_uid (DR_STMT (drb
)))
1917 || (DR_IS_READ (drb
) && DR_IS_WRITE (dra
)
1918 && gimple_uid (DR_STMT (drb
)) > gimple_uid (DR_STMT (dra
)))
1919 || (DR_IS_WRITE (dra
) && DR_IS_WRITE (drb
))))
1921 free_dependence_relations (then_ddrs
);
1922 free_dependence_relations (else_ddrs
);
1923 free_data_refs (then_datarefs
);
1924 free_data_refs (else_datarefs
);
1929 /* Check that there are no read-after-write or write-after-write dependencies
1931 FOR_EACH_VEC_ELT (else_ddrs
, i
, ddr
)
1933 struct data_reference
*dra
= DDR_A (ddr
);
1934 struct data_reference
*drb
= DDR_B (ddr
);
1936 if (DDR_ARE_DEPENDENT (ddr
) != chrec_known
1937 && ((DR_IS_READ (dra
) && DR_IS_WRITE (drb
)
1938 && gimple_uid (DR_STMT (dra
)) > gimple_uid (DR_STMT (drb
)))
1939 || (DR_IS_READ (drb
) && DR_IS_WRITE (dra
)
1940 && gimple_uid (DR_STMT (drb
)) > gimple_uid (DR_STMT (dra
)))
1941 || (DR_IS_WRITE (dra
) && DR_IS_WRITE (drb
))))
1943 free_dependence_relations (then_ddrs
);
1944 free_dependence_relations (else_ddrs
);
1945 free_data_refs (then_datarefs
);
1946 free_data_refs (else_datarefs
);
1951 /* Sink stores with same LHS. */
1952 FOR_EACH_VEC_ELT (then_stores
, i
, then_store
)
1954 else_store
= else_stores
[i
];
1955 res
= cond_if_else_store_replacement_1 (then_bb
, else_bb
, join_bb
,
1956 then_store
, else_store
);
1960 free_dependence_relations (then_ddrs
);
1961 free_dependence_relations (else_ddrs
);
1962 free_data_refs (then_datarefs
);
1963 free_data_refs (else_datarefs
);
1968 /* Return TRUE if STMT has a VUSE whose corresponding VDEF is in BB. */
1971 local_mem_dependence (gimple stmt
, basic_block bb
)
1973 tree vuse
= gimple_vuse (stmt
);
1979 def
= SSA_NAME_DEF_STMT (vuse
);
1980 return (def
&& gimple_bb (def
) == bb
);
1983 /* Given a "diamond" control-flow pattern where BB0 tests a condition,
1984 BB1 and BB2 are "then" and "else" blocks dependent on this test,
1985 and BB3 rejoins control flow following BB1 and BB2, look for
1986 opportunities to hoist loads as follows. If BB3 contains a PHI of
1987 two loads, one each occurring in BB1 and BB2, and the loads are
1988 provably of adjacent fields in the same structure, then move both
1989 loads into BB0. Of course this can only be done if there are no
1990 dependencies preventing such motion.
1992 One of the hoisted loads will always be speculative, so the
1993 transformation is currently conservative:
1995 - The fields must be strictly adjacent.
1996 - The two fields must occupy a single memory block that is
1997 guaranteed to not cross a page boundary.
1999 The last is difficult to prove, as such memory blocks should be
2000 aligned on the minimum of the stack alignment boundary and the
2001 alignment guaranteed by heap allocation interfaces. Thus we rely
2002 on a parameter for the alignment value.
2004 Provided a good value is used for the last case, the first
2005 restriction could possibly be relaxed. */
2008 hoist_adjacent_loads (basic_block bb0
, basic_block bb1
,
2009 basic_block bb2
, basic_block bb3
)
2011 int param_align
= PARAM_VALUE (PARAM_L1_CACHE_LINE_SIZE
);
2012 unsigned param_align_bits
= (unsigned) (param_align
* BITS_PER_UNIT
);
2013 gimple_phi_iterator gsi
;
2015 /* Walk the phis in bb3 looking for an opportunity. We are looking
2016 for phis of two SSA names, one each of which is defined in bb1 and
2018 for (gsi
= gsi_start_phis (bb3
); !gsi_end_p (gsi
); gsi_next (&gsi
))
2020 gimple_phi phi_stmt
= gsi
.phi ();
2021 gimple def1
, def2
, defswap
;
2022 tree arg1
, arg2
, ref1
, ref2
, field1
, field2
, fieldswap
;
2023 tree tree_offset1
, tree_offset2
, tree_size2
, next
;
2024 int offset1
, offset2
, size2
;
2026 gimple_stmt_iterator gsi2
;
2027 basic_block bb_for_def1
, bb_for_def2
;
2029 if (gimple_phi_num_args (phi_stmt
) != 2
2030 || virtual_operand_p (gimple_phi_result (phi_stmt
)))
2033 arg1
= gimple_phi_arg_def (phi_stmt
, 0);
2034 arg2
= gimple_phi_arg_def (phi_stmt
, 1);
2036 if (TREE_CODE (arg1
) != SSA_NAME
2037 || TREE_CODE (arg2
) != SSA_NAME
2038 || SSA_NAME_IS_DEFAULT_DEF (arg1
)
2039 || SSA_NAME_IS_DEFAULT_DEF (arg2
))
2042 def1
= SSA_NAME_DEF_STMT (arg1
);
2043 def2
= SSA_NAME_DEF_STMT (arg2
);
2045 if ((gimple_bb (def1
) != bb1
|| gimple_bb (def2
) != bb2
)
2046 && (gimple_bb (def2
) != bb1
|| gimple_bb (def1
) != bb2
))
2049 /* Check the mode of the arguments to be sure a conditional move
2050 can be generated for it. */
2051 if (optab_handler (movcc_optab
, TYPE_MODE (TREE_TYPE (arg1
)))
2052 == CODE_FOR_nothing
)
2055 /* Both statements must be assignments whose RHS is a COMPONENT_REF. */
2056 if (!gimple_assign_single_p (def1
)
2057 || !gimple_assign_single_p (def2
)
2058 || gimple_has_volatile_ops (def1
)
2059 || gimple_has_volatile_ops (def2
))
2062 ref1
= gimple_assign_rhs1 (def1
);
2063 ref2
= gimple_assign_rhs1 (def2
);
2065 if (TREE_CODE (ref1
) != COMPONENT_REF
2066 || TREE_CODE (ref2
) != COMPONENT_REF
)
2069 /* The zeroth operand of the two component references must be
2070 identical. It is not sufficient to compare get_base_address of
2071 the two references, because this could allow for different
2072 elements of the same array in the two trees. It is not safe to
2073 assume that the existence of one array element implies the
2074 existence of a different one. */
2075 if (!operand_equal_p (TREE_OPERAND (ref1
, 0), TREE_OPERAND (ref2
, 0), 0))
2078 field1
= TREE_OPERAND (ref1
, 1);
2079 field2
= TREE_OPERAND (ref2
, 1);
2081 /* Check for field adjacency, and ensure field1 comes first. */
2082 for (next
= DECL_CHAIN (field1
);
2083 next
&& TREE_CODE (next
) != FIELD_DECL
;
2084 next
= DECL_CHAIN (next
))
2089 for (next
= DECL_CHAIN (field2
);
2090 next
&& TREE_CODE (next
) != FIELD_DECL
;
2091 next
= DECL_CHAIN (next
))
2105 bb_for_def1
= gimple_bb (def1
);
2106 bb_for_def2
= gimple_bb (def2
);
2108 /* Check for proper alignment of the first field. */
2109 tree_offset1
= bit_position (field1
);
2110 tree_offset2
= bit_position (field2
);
2111 tree_size2
= DECL_SIZE (field2
);
2113 if (!tree_fits_uhwi_p (tree_offset1
)
2114 || !tree_fits_uhwi_p (tree_offset2
)
2115 || !tree_fits_uhwi_p (tree_size2
))
2118 offset1
= tree_to_uhwi (tree_offset1
);
2119 offset2
= tree_to_uhwi (tree_offset2
);
2120 size2
= tree_to_uhwi (tree_size2
);
2121 align1
= DECL_ALIGN (field1
) % param_align_bits
;
2123 if (offset1
% BITS_PER_UNIT
!= 0)
2126 /* For profitability, the two field references should fit within
2127 a single cache line. */
2128 if (align1
+ offset2
- offset1
+ size2
> param_align_bits
)
2131 /* The two expressions cannot be dependent upon vdefs defined
2133 if (local_mem_dependence (def1
, bb_for_def1
)
2134 || local_mem_dependence (def2
, bb_for_def2
))
2137 /* The conditions are satisfied; hoist the loads from bb1 and bb2 into
2138 bb0. We hoist the first one first so that a cache miss is handled
2139 efficiently regardless of hardware cache-fill policy. */
2140 gsi2
= gsi_for_stmt (def1
);
2141 gsi_move_to_bb_end (&gsi2
, bb0
);
2142 gsi2
= gsi_for_stmt (def2
);
2143 gsi_move_to_bb_end (&gsi2
, bb0
);
2145 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
2148 "\nHoisting adjacent loads from %d and %d into %d: \n",
2149 bb_for_def1
->index
, bb_for_def2
->index
, bb0
->index
);
2150 print_gimple_stmt (dump_file
, def1
, 0, TDF_VOPS
|TDF_MEMSYMS
);
2151 print_gimple_stmt (dump_file
, def2
, 0, TDF_VOPS
|TDF_MEMSYMS
);
2156 /* Determine whether we should attempt to hoist adjacent loads out of
2157 diamond patterns in pass_phiopt. Always hoist loads if
2158 -fhoist-adjacent-loads is specified and the target machine has
2159 both a conditional move instruction and a defined cache line size. */
2162 gate_hoist_loads (void)
2164 return (flag_hoist_adjacent_loads
== 1
2165 && PARAM_VALUE (PARAM_L1_CACHE_LINE_SIZE
)
2166 && HAVE_conditional_move
);
2169 /* This pass tries to replaces an if-then-else block with an
2170 assignment. We have four kinds of transformations. Some of these
2171 transformations are also performed by the ifcvt RTL optimizer.
2173 Conditional Replacement
2174 -----------------------
2176 This transformation, implemented in conditional_replacement,
2180 if (cond) goto bb2; else goto bb1;
2183 x = PHI <0 (bb1), 1 (bb0), ...>;
2191 x = PHI <x' (bb0), ...>;
2193 We remove bb1 as it becomes unreachable. This occurs often due to
2194 gimplification of conditionals.
2199 This transformation, implemented in value_replacement, replaces
2202 if (a != b) goto bb2; else goto bb1;
2205 x = PHI <a (bb1), b (bb0), ...>;
2211 x = PHI <b (bb0), ...>;
2213 This opportunity can sometimes occur as a result of other
2217 Another case caught by value replacement looks like this:
2223 if (t3 != 0) goto bb1; else goto bb2;
2239 This transformation, implemented in abs_replacement, replaces
2242 if (a >= 0) goto bb2; else goto bb1;
2246 x = PHI <x (bb1), a (bb0), ...>;
2253 x = PHI <x' (bb0), ...>;
2258 This transformation, minmax_replacement replaces
2261 if (a <= b) goto bb2; else goto bb1;
2264 x = PHI <b (bb1), a (bb0), ...>;
2269 x' = MIN_EXPR (a, b)
2271 x = PHI <x' (bb0), ...>;
2273 A similar transformation is done for MAX_EXPR.
2276 This pass also performs a fifth transformation of a slightly different
2279 Adjacent Load Hoisting
2280 ----------------------
2282 This transformation replaces
2285 if (...) goto bb2; else goto bb1;
2287 x1 = (<expr>).field1;
2290 x2 = (<expr>).field2;
2297 x1 = (<expr>).field1;
2298 x2 = (<expr>).field2;
2299 if (...) goto bb2; else goto bb1;
2306 The purpose of this transformation is to enable generation of conditional
2307 move instructions such as Intel CMOVE or PowerPC ISEL. Because one of
2308 the loads is speculative, the transformation is restricted to very
2309 specific cases to avoid introducing a page fault. We are looking for
2317 where left and right are typically adjacent pointers in a tree structure. */
2321 const pass_data pass_data_phiopt
=
2323 GIMPLE_PASS
, /* type */
2324 "phiopt", /* name */
2325 OPTGROUP_NONE
, /* optinfo_flags */
2326 TV_TREE_PHIOPT
, /* tv_id */
2327 ( PROP_cfg
| PROP_ssa
), /* properties_required */
2328 0, /* properties_provided */
2329 0, /* properties_destroyed */
2330 0, /* todo_flags_start */
2331 0, /* todo_flags_finish */
2334 class pass_phiopt
: public gimple_opt_pass
2337 pass_phiopt (gcc::context
*ctxt
)
2338 : gimple_opt_pass (pass_data_phiopt
, ctxt
)
2341 /* opt_pass methods: */
2342 opt_pass
* clone () { return new pass_phiopt (m_ctxt
); }
2343 virtual bool gate (function
*) { return flag_ssa_phiopt
; }
2344 virtual unsigned int execute (function
*)
2346 return tree_ssa_phiopt_worker (false, gate_hoist_loads ());
2349 }; // class pass_phiopt
2354 make_pass_phiopt (gcc::context
*ctxt
)
2356 return new pass_phiopt (ctxt
);
2361 const pass_data pass_data_cselim
=
2363 GIMPLE_PASS
, /* type */
2364 "cselim", /* name */
2365 OPTGROUP_NONE
, /* optinfo_flags */
2366 TV_TREE_PHIOPT
, /* tv_id */
2367 ( PROP_cfg
| PROP_ssa
), /* properties_required */
2368 0, /* properties_provided */
2369 0, /* properties_destroyed */
2370 0, /* todo_flags_start */
2371 0, /* todo_flags_finish */
2374 class pass_cselim
: public gimple_opt_pass
2377 pass_cselim (gcc::context
*ctxt
)
2378 : gimple_opt_pass (pass_data_cselim
, ctxt
)
2381 /* opt_pass methods: */
2382 virtual bool gate (function
*) { return flag_tree_cselim
; }
2383 virtual unsigned int execute (function
*) { return tree_ssa_cs_elim (); }
2385 }; // class pass_cselim
2390 make_pass_cselim (gcc::context
*ctxt
)
2392 return new pass_cselim (ctxt
);