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