]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-forwprop.c
2015-06-04 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / tree-ssa-forwprop.c
CommitLineData
291d763b 1/* Forward propagation of expressions for single use variables.
d353bf18 2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
4ee9c684 3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8c4c00c1 8the Free Software Foundation; either version 3, or (at your option)
4ee9c684 9any later version.
10
11GCC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
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"
23#include "tm.h"
b20a8bb4 24#include "hash-set.h"
b20a8bb4 25#include "vec.h"
b20a8bb4 26#include "input.h"
27#include "alias.h"
28#include "symtab.h"
b20a8bb4 29#include "inchash.h"
4ee9c684 30#include "tree.h"
b20a8bb4 31#include "fold-const.h"
9ed99284 32#include "stor-layout.h"
4ee9c684 33#include "tm_p.h"
94ea8568 34#include "predict.h"
94ea8568 35#include "hard-reg-set.h"
94ea8568 36#include "function.h"
37#include "dominance.h"
38#include "cfg.h"
4ee9c684 39#include "basic-block.h"
e5b1e080 40#include "gimple-pretty-print.h"
bc61cadb 41#include "tree-ssa-alias.h"
42#include "internal-fn.h"
43#include "gimple-fold.h"
44#include "tree-eh.h"
45#include "gimple-expr.h"
46#include "is-a.h"
073c1fd5 47#include "gimple.h"
a8783bee 48#include "gimplify.h"
dcf1a1ec 49#include "gimple-iterator.h"
e795d6e1 50#include "gimplify-me.h"
073c1fd5 51#include "gimple-ssa.h"
52#include "tree-cfg.h"
53#include "tree-phinodes.h"
54#include "ssa-iterators.h"
9ed99284 55#include "stringpool.h"
073c1fd5 56#include "tree-ssanames.h"
d53441c8 57#include "hashtab.h"
58#include "rtl.h"
59#include "flags.h"
60#include "statistics.h"
d53441c8 61#include "insn-config.h"
62#include "expmed.h"
63#include "dojump.h"
64#include "explow.h"
65#include "calls.h"
66#include "emit-rtl.h"
67#include "varasm.h"
68#include "stmt.h"
9ed99284 69#include "expr.h"
073c1fd5 70#include "tree-dfa.h"
4ee9c684 71#include "tree-pass.h"
291d763b 72#include "langhooks.h"
8f79c655 73#include "diagnostic.h"
6b42039a 74#include "cfgloop.h"
34517c64 75#include "insn-codes.h"
d1938a4b 76#include "optabs.h"
58bf5219 77#include "tree-ssa-propagate.h"
424a4a92 78#include "tree-ssa-dom.h"
f7715905 79#include "builtins.h"
f619ecae 80#include "tree-cfgcleanup.h"
81#include "tree-into-ssa.h"
94ea8568 82#include "cfganal.h"
4ee9c684 83
291d763b 84/* This pass propagates the RHS of assignment statements into use
85 sites of the LHS of the assignment. It's basically a specialized
8f628ee8 86 form of tree combination. It is hoped all of this can disappear
87 when we have a generalized tree combiner.
4ee9c684 88
291d763b 89 One class of common cases we handle is forward propagating a single use
48e1416a 90 variable into a COND_EXPR.
4ee9c684 91
92 bb0:
93 x = a COND b;
94 if (x) goto ... else goto ...
95
96 Will be transformed into:
97
98 bb0:
99 if (a COND b) goto ... else goto ...
48e1416a 100
4ee9c684 101 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
102
103 Or (assuming c1 and c2 are constants):
104
105 bb0:
48e1416a 106 x = a + c1;
4ee9c684 107 if (x EQ/NEQ c2) goto ... else goto ...
108
109 Will be transformed into:
110
111 bb0:
112 if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
113
114 Similarly for x = a - c1.
48e1416a 115
4ee9c684 116 Or
117
118 bb0:
119 x = !a
120 if (x) goto ... else goto ...
121
122 Will be transformed into:
123
124 bb0:
125 if (a == 0) goto ... else goto ...
126
127 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
128 For these cases, we propagate A into all, possibly more than one,
129 COND_EXPRs that use X.
130
f5c8cff5 131 Or
132
133 bb0:
134 x = (typecast) a
135 if (x) goto ... else goto ...
136
137 Will be transformed into:
138
139 bb0:
140 if (a != 0) goto ... else goto ...
141
142 (Assuming a is an integral type and x is a boolean or x is an
143 integral and a is a boolean.)
144
145 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
146 For these cases, we propagate A into all, possibly more than one,
147 COND_EXPRs that use X.
148
4ee9c684 149 In addition to eliminating the variable and the statement which assigns
150 a value to the variable, we may be able to later thread the jump without
e6dfde59 151 adding insane complexity in the dominator optimizer.
4ee9c684 152
f5c8cff5 153 Also note these transformations can cascade. We handle this by having
154 a worklist of COND_EXPR statements to examine. As we make a change to
155 a statement, we put it back on the worklist to examine on the next
156 iteration of the main loop.
157
291d763b 158 A second class of propagation opportunities arises for ADDR_EXPR
159 nodes.
160
161 ptr = &x->y->z;
162 res = *ptr;
163
164 Will get turned into
165
166 res = x->y->z;
167
50f39ec6 168 Or
169 ptr = (type1*)&type2var;
170 res = *ptr
171
172 Will get turned into (if type1 and type2 are the same size
173 and neither have volatile on them):
174 res = VIEW_CONVERT_EXPR<type1>(type2var)
175
291d763b 176 Or
177
178 ptr = &x[0];
179 ptr2 = ptr + <constant>;
180
181 Will get turned into
182
183 ptr2 = &x[constant/elementsize];
184
185 Or
186
187 ptr = &x[0];
188 offset = index * element_size;
189 offset_p = (pointer) offset;
190 ptr2 = ptr + offset_p
191
192 Will get turned into:
193
194 ptr2 = &x[index];
195
1c4607fd 196 Or
197 ssa = (int) decl
198 res = ssa & 1
199
200 Provided that decl has known alignment >= 2, will get turned into
201
202 res = 0
203
8f628ee8 204 We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to
205 allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent
206 {NOT_EXPR,NEG_EXPR}.
291d763b 207
4ee9c684 208 This will (of course) be extended as other needs arise. */
209
bfb89138 210static bool forward_propagate_addr_expr (tree, tree, bool);
148aa112 211
b59e1c90 212/* Set to true if we delete dead edges during the optimization. */
148aa112 213static bool cfg_changed;
214
75a70cf9 215static tree rhs_to_tree (tree type, gimple stmt);
148aa112 216
770ae4bb 217static bitmap to_purge;
218
219/* Const-and-copy lattice. */
220static vec<tree> lattice;
221
222/* Set the lattice entry for NAME to VAL. */
223static void
224fwprop_set_lattice_val (tree name, tree val)
225{
226 if (TREE_CODE (name) == SSA_NAME)
227 {
228 if (SSA_NAME_VERSION (name) >= lattice.length ())
229 {
230 lattice.reserve (num_ssa_names - lattice.length ());
231 lattice.quick_grow_cleared (num_ssa_names);
232 }
233 lattice[SSA_NAME_VERSION (name)] = val;
234 }
235}
236
237/* Invalidate the lattice entry for NAME, done when releasing SSA names. */
238static void
239fwprop_invalidate_lattice (tree name)
240{
241 if (name
242 && TREE_CODE (name) == SSA_NAME
243 && SSA_NAME_VERSION (name) < lattice.length ())
244 lattice[SSA_NAME_VERSION (name)] = NULL_TREE;
245}
246
247
5adc1066 248/* Get the statement we can propagate from into NAME skipping
249 trivial copies. Returns the statement which defines the
250 propagation source or NULL_TREE if there is no such one.
251 If SINGLE_USE_ONLY is set considers only sources which have
252 a single use chain up to NAME. If SINGLE_USE_P is non-null,
253 it is set to whether the chain to NAME is a single use chain
254 or not. SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set. */
4ee9c684 255
75a70cf9 256static gimple
5adc1066 257get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
f5c8cff5 258{
5adc1066 259 bool single_use = true;
260
261 do {
75a70cf9 262 gimple def_stmt = SSA_NAME_DEF_STMT (name);
5adc1066 263
264 if (!has_single_use (name))
265 {
266 single_use = false;
267 if (single_use_only)
75a70cf9 268 return NULL;
5adc1066 269 }
270
271 /* If name is defined by a PHI node or is the default def, bail out. */
8f0b877f 272 if (!is_gimple_assign (def_stmt))
75a70cf9 273 return NULL;
5adc1066 274
ab31ca23 275 /* If def_stmt is a simple copy, continue looking. */
276 if (gimple_assign_rhs_code (def_stmt) == SSA_NAME)
277 name = gimple_assign_rhs1 (def_stmt);
278 else
5adc1066 279 {
280 if (!single_use_only && single_use_p)
281 *single_use_p = single_use;
282
ab31ca23 283 return def_stmt;
5adc1066 284 }
5adc1066 285 } while (1);
286}
e6dfde59 287
5adc1066 288/* Checks if the destination ssa name in DEF_STMT can be used as
289 propagation source. Returns true if so, otherwise false. */
e6dfde59 290
5adc1066 291static bool
75a70cf9 292can_propagate_from (gimple def_stmt)
5adc1066 293{
75a70cf9 294 gcc_assert (is_gimple_assign (def_stmt));
8f0b877f 295
484b827b 296 /* If the rhs has side-effects we cannot propagate from it. */
75a70cf9 297 if (gimple_has_volatile_ops (def_stmt))
484b827b 298 return false;
299
300 /* If the rhs is a load we cannot propagate from it. */
75a70cf9 301 if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_reference
302 || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_declaration)
484b827b 303 return false;
304
b9e98b8a 305 /* Constants can be always propagated. */
8f0b877f 306 if (gimple_assign_single_p (def_stmt)
307 && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
b9e98b8a 308 return true;
309
75a70cf9 310 /* We cannot propagate ssa names that occur in abnormal phi nodes. */
32cdcc42 311 if (stmt_references_abnormal_ssa_name (def_stmt))
312 return false;
4ee9c684 313
5adc1066 314 /* If the definition is a conversion of a pointer to a function type,
75a70cf9 315 then we can not apply optimizations as some targets require
316 function pointers to be canonicalized and in this case this
317 optimization could eliminate a necessary canonicalization. */
8f0b877f 318 if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
75a70cf9 319 {
320 tree rhs = gimple_assign_rhs1 (def_stmt);
321 if (POINTER_TYPE_P (TREE_TYPE (rhs))
322 && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs))) == FUNCTION_TYPE)
323 return false;
324 }
8f0b877f 325
5adc1066 326 return true;
e6dfde59 327}
328
ff0739e0 329/* Remove a chain of dead statements starting at the definition of
330 NAME. The chain is linked via the first operand of the defining statements.
5d2361b0 331 If NAME was replaced in its only use then this function can be used
ff0739e0 332 to clean up dead stmts. The function handles already released SSA
333 names gracefully.
334 Returns true if cleanup-cfg has to run. */
8f628ee8 335
5adc1066 336static bool
5d2361b0 337remove_prop_source_from_use (tree name)
5adc1066 338{
75a70cf9 339 gimple_stmt_iterator gsi;
340 gimple stmt;
5d2361b0 341 bool cfg_changed = false;
8f628ee8 342
5adc1066 343 do {
5d2361b0 344 basic_block bb;
345
ff0739e0 346 if (SSA_NAME_IN_FREE_LIST (name)
347 || SSA_NAME_IS_DEFAULT_DEF (name)
348 || !has_zero_uses (name))
5d2361b0 349 return cfg_changed;
8f628ee8 350
5adc1066 351 stmt = SSA_NAME_DEF_STMT (name);
ff0739e0 352 if (gimple_code (stmt) == GIMPLE_PHI
353 || gimple_has_side_effects (stmt))
6f9714b3 354 return cfg_changed;
ff0739e0 355
356 bb = gimple_bb (stmt);
6f9714b3 357 gsi = gsi_for_stmt (stmt);
ff0739e0 358 unlink_stmt_vdef (stmt);
13ff78a4 359 if (gsi_remove (&gsi, true))
770ae4bb 360 bitmap_set_bit (to_purge, bb->index);
361 fwprop_invalidate_lattice (gimple_get_lhs (stmt));
ff0739e0 362 release_defs (stmt);
8f628ee8 363
ff0739e0 364 name = is_gimple_assign (stmt) ? gimple_assign_rhs1 (stmt) : NULL_TREE;
75a70cf9 365 } while (name && TREE_CODE (name) == SSA_NAME);
8f628ee8 366
5d2361b0 367 return cfg_changed;
5adc1066 368}
8f628ee8 369
1a91d914 370/* Return the rhs of a gassign *STMT in a form of a single tree,
75a70cf9 371 converted to type TYPE.
48e1416a 372
75a70cf9 373 This should disappear, but is needed so we can combine expressions and use
374 the fold() interfaces. Long term, we need to develop folding and combine
375 routines that deal with gimple exclusively . */
376
377static tree
378rhs_to_tree (tree type, gimple stmt)
379{
389dd41b 380 location_t loc = gimple_location (stmt);
75a70cf9 381 enum tree_code code = gimple_assign_rhs_code (stmt);
57c45d70 382 if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
383 return fold_build3_loc (loc, code, type, gimple_assign_rhs1 (stmt),
384 gimple_assign_rhs2 (stmt),
385 gimple_assign_rhs3 (stmt));
386 else if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
389dd41b 387 return fold_build2_loc (loc, code, type, gimple_assign_rhs1 (stmt),
fb8ed03f 388 gimple_assign_rhs2 (stmt));
75a70cf9 389 else if (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS)
fb8ed03f 390 return build1 (code, type, gimple_assign_rhs1 (stmt));
75a70cf9 391 else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
392 return gimple_assign_rhs1 (stmt);
393 else
394 gcc_unreachable ();
395}
396
5adc1066 397/* Combine OP0 CODE OP1 in the context of a COND_EXPR. Returns
398 the folded result in a form suitable for COND_EXPR_COND or
399 NULL_TREE, if there is no suitable simplified form. If
400 INVARIANT_ONLY is true only gimple_min_invariant results are
401 considered simplified. */
8f628ee8 402
403static tree
c73fee76 404combine_cond_expr_cond (gimple stmt, enum tree_code code, tree type,
5adc1066 405 tree op0, tree op1, bool invariant_only)
8f628ee8 406{
5adc1066 407 tree t;
8f628ee8 408
5adc1066 409 gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
8f628ee8 410
c73fee76 411 fold_defer_overflow_warnings ();
412 t = fold_binary_loc (gimple_location (stmt), code, type, op0, op1);
5adc1066 413 if (!t)
c73fee76 414 {
415 fold_undefer_overflow_warnings (false, NULL, 0);
416 return NULL_TREE;
417 }
8f628ee8 418
5adc1066 419 /* Require that we got a boolean type out if we put one in. */
420 gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
8f628ee8 421
a7392604 422 /* Canonicalize the combined condition for use in a COND_EXPR. */
423 t = canonicalize_cond_expr_cond (t);
8f628ee8 424
5adc1066 425 /* Bail out if we required an invariant but didn't get one. */
75a70cf9 426 if (!t || (invariant_only && !is_gimple_min_invariant (t)))
c73fee76 427 {
428 fold_undefer_overflow_warnings (false, NULL, 0);
429 return NULL_TREE;
430 }
431
432 fold_undefer_overflow_warnings (!gimple_no_warning_p (stmt), stmt, 0);
8f628ee8 433
a7392604 434 return t;
8f628ee8 435}
436
c8126d25 437/* Combine the comparison OP0 CODE OP1 at LOC with the defining statements
438 of its operand. Return a new comparison tree or NULL_TREE if there
439 were no simplifying combines. */
440
441static tree
c73fee76 442forward_propagate_into_comparison_1 (gimple stmt,
678b2f5b 443 enum tree_code code, tree type,
444 tree op0, tree op1)
c8126d25 445{
446 tree tmp = NULL_TREE;
447 tree rhs0 = NULL_TREE, rhs1 = NULL_TREE;
448 bool single_use0_p = false, single_use1_p = false;
449
450 /* For comparisons use the first operand, that is likely to
451 simplify comparisons against constants. */
452 if (TREE_CODE (op0) == SSA_NAME)
453 {
454 gimple def_stmt = get_prop_source_stmt (op0, false, &single_use0_p);
455 if (def_stmt && can_propagate_from (def_stmt))
456 {
a34867d6 457 enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
458 bool invariant_only_p = !single_use0_p;
459
c8126d25 460 rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
a34867d6 461
462 /* Always combine comparisons or conversions from booleans. */
463 if (TREE_CODE (op1) == INTEGER_CST
464 && ((CONVERT_EXPR_CODE_P (def_code)
465 && TREE_CODE (TREE_TYPE (TREE_OPERAND (rhs0, 0)))
466 == BOOLEAN_TYPE)
467 || TREE_CODE_CLASS (def_code) == tcc_comparison))
468 invariant_only_p = false;
469
c73fee76 470 tmp = combine_cond_expr_cond (stmt, code, type,
a34867d6 471 rhs0, op1, invariant_only_p);
c8126d25 472 if (tmp)
473 return tmp;
474 }
475 }
476
477 /* If that wasn't successful, try the second operand. */
478 if (TREE_CODE (op1) == SSA_NAME)
479 {
480 gimple def_stmt = get_prop_source_stmt (op1, false, &single_use1_p);
481 if (def_stmt && can_propagate_from (def_stmt))
482 {
483 rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
c73fee76 484 tmp = combine_cond_expr_cond (stmt, code, type,
c8126d25 485 op0, rhs1, !single_use1_p);
486 if (tmp)
487 return tmp;
488 }
489 }
490
491 /* If that wasn't successful either, try both operands. */
492 if (rhs0 != NULL_TREE
493 && rhs1 != NULL_TREE)
c73fee76 494 tmp = combine_cond_expr_cond (stmt, code, type,
c8126d25 495 rhs0, rhs1,
496 !(single_use0_p && single_use1_p));
497
498 return tmp;
499}
500
678b2f5b 501/* Propagate from the ssa name definition statements of the assignment
502 from a comparison at *GSI into the conditional if that simplifies it.
6f9714b3 503 Returns 1 if the stmt was modified and 2 if the CFG needs cleanup,
504 otherwise returns 0. */
c8126d25 505
6f9714b3 506static int
678b2f5b 507forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
c8126d25 508{
678b2f5b 509 gimple stmt = gsi_stmt (*gsi);
510 tree tmp;
6f9714b3 511 bool cfg_changed = false;
56632de0 512 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
6f9714b3 513 tree rhs1 = gimple_assign_rhs1 (stmt);
514 tree rhs2 = gimple_assign_rhs2 (stmt);
c8126d25 515
516 /* Combine the comparison with defining statements. */
c73fee76 517 tmp = forward_propagate_into_comparison_1 (stmt,
678b2f5b 518 gimple_assign_rhs_code (stmt),
56632de0 519 type, rhs1, rhs2);
520 if (tmp && useless_type_conversion_p (type, TREE_TYPE (tmp)))
c8126d25 521 {
678b2f5b 522 gimple_assign_set_rhs_from_tree (gsi, tmp);
50aacf4c 523 fold_stmt (gsi);
524 update_stmt (gsi_stmt (*gsi));
75200312 525
6f9714b3 526 if (TREE_CODE (rhs1) == SSA_NAME)
527 cfg_changed |= remove_prop_source_from_use (rhs1);
528 if (TREE_CODE (rhs2) == SSA_NAME)
529 cfg_changed |= remove_prop_source_from_use (rhs2);
530 return cfg_changed ? 2 : 1;
c8126d25 531 }
532
6f9714b3 533 return 0;
c8126d25 534}
535
5adc1066 536/* Propagate from the ssa name definition statements of COND_EXPR
75a70cf9 537 in GIMPLE_COND statement STMT into the conditional if that simplifies it.
538 Returns zero if no statement was changed, one if there were
539 changes and two if cfg_cleanup needs to run.
48e1416a 540
75a70cf9 541 This must be kept in sync with forward_propagate_into_cond. */
542
543static int
1a91d914 544forward_propagate_into_gimple_cond (gcond *stmt)
75a70cf9 545{
678b2f5b 546 tree tmp;
547 enum tree_code code = gimple_cond_code (stmt);
6f9714b3 548 bool cfg_changed = false;
549 tree rhs1 = gimple_cond_lhs (stmt);
550 tree rhs2 = gimple_cond_rhs (stmt);
678b2f5b 551
552 /* We can do tree combining on SSA_NAME and comparison expressions. */
553 if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
554 return 0;
555
c73fee76 556 tmp = forward_propagate_into_comparison_1 (stmt, code,
678b2f5b 557 boolean_type_node,
6f9714b3 558 rhs1, rhs2);
678b2f5b 559 if (tmp)
560 {
561 if (dump_file && tmp)
562 {
678b2f5b 563 fprintf (dump_file, " Replaced '");
6f9714b3 564 print_gimple_expr (dump_file, stmt, 0, 0);
678b2f5b 565 fprintf (dump_file, "' with '");
566 print_generic_expr (dump_file, tmp, 0);
567 fprintf (dump_file, "'\n");
568 }
75a70cf9 569
678b2f5b 570 gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp));
571 update_stmt (stmt);
75a70cf9 572
6f9714b3 573 if (TREE_CODE (rhs1) == SSA_NAME)
574 cfg_changed |= remove_prop_source_from_use (rhs1);
575 if (TREE_CODE (rhs2) == SSA_NAME)
576 cfg_changed |= remove_prop_source_from_use (rhs2);
577 return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1;
678b2f5b 578 }
75a70cf9 579
10a6edd6 580 /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges. */
581 if ((TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE
582 || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
583 && TYPE_PRECISION (TREE_TYPE (rhs1)) == 1))
584 && ((code == EQ_EXPR
585 && integer_zerop (rhs2))
586 || (code == NE_EXPR
587 && integer_onep (rhs2))))
588 {
589 basic_block bb = gimple_bb (stmt);
590 gimple_cond_set_code (stmt, NE_EXPR);
591 gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1)));
592 EDGE_SUCC (bb, 0)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
593 EDGE_SUCC (bb, 1)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
594 return 1;
595 }
596
6f9714b3 597 return 0;
75a70cf9 598}
599
600
601/* Propagate from the ssa name definition statements of COND_EXPR
602 in the rhs of statement STMT into the conditional if that simplifies it.
8a2caf10 603 Returns true zero if the stmt was changed. */
4ee9c684 604
8a2caf10 605static bool
75a70cf9 606forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
e6dfde59 607{
75a70cf9 608 gimple stmt = gsi_stmt (*gsi_p);
678b2f5b 609 tree tmp = NULL_TREE;
610 tree cond = gimple_assign_rhs1 (stmt);
def3cb70 611 enum tree_code code = gimple_assign_rhs_code (stmt);
d080be9e 612
678b2f5b 613 /* We can do tree combining on SSA_NAME and comparison expressions. */
614 if (COMPARISON_CLASS_P (cond))
c73fee76 615 tmp = forward_propagate_into_comparison_1 (stmt, TREE_CODE (cond),
f2c1848b 616 TREE_TYPE (cond),
c8126d25 617 TREE_OPERAND (cond, 0),
618 TREE_OPERAND (cond, 1));
678b2f5b 619 else if (TREE_CODE (cond) == SSA_NAME)
620 {
def3cb70 621 enum tree_code def_code;
8a2caf10 622 tree name = cond;
678b2f5b 623 gimple def_stmt = get_prop_source_stmt (name, true, NULL);
624 if (!def_stmt || !can_propagate_from (def_stmt))
6f9714b3 625 return 0;
5adc1066 626
def3cb70 627 def_code = gimple_assign_rhs_code (def_stmt);
628 if (TREE_CODE_CLASS (def_code) == tcc_comparison)
8a2caf10 629 tmp = fold_build2_loc (gimple_location (def_stmt),
def3cb70 630 def_code,
bc112f18 631 TREE_TYPE (cond),
8a2caf10 632 gimple_assign_rhs1 (def_stmt),
633 gimple_assign_rhs2 (def_stmt));
678b2f5b 634 }
5adc1066 635
25f48be0 636 if (tmp
637 && is_gimple_condexpr (tmp))
678b2f5b 638 {
639 if (dump_file && tmp)
640 {
641 fprintf (dump_file, " Replaced '");
642 print_generic_expr (dump_file, cond, 0);
643 fprintf (dump_file, "' with '");
644 print_generic_expr (dump_file, tmp, 0);
645 fprintf (dump_file, "'\n");
646 }
d080be9e 647
def3cb70 648 if ((code == VEC_COND_EXPR) ? integer_all_onesp (tmp)
649 : integer_onep (tmp))
8a2caf10 650 gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs2 (stmt));
651 else if (integer_zerop (tmp))
652 gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
653 else
84debb86 654 gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
678b2f5b 655 stmt = gsi_stmt (*gsi_p);
656 update_stmt (stmt);
5adc1066 657
8a2caf10 658 return true;
678b2f5b 659 }
d080be9e 660
6f9714b3 661 return 0;
4ee9c684 662}
663
48e1416a 664/* We've just substituted an ADDR_EXPR into stmt. Update all the
148aa112 665 relevant data structures to match. */
666
667static void
75a70cf9 668tidy_after_forward_propagate_addr (gimple stmt)
148aa112 669{
148aa112 670 /* We may have turned a trapping insn into a non-trapping insn. */
770ae4bb 671 if (maybe_clean_or_replace_eh_stmt (stmt, stmt))
672 bitmap_set_bit (to_purge, gimple_bb (stmt)->index);
f2fae51f 673
75a70cf9 674 if (TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
675 recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
148aa112 676}
677
15ec875c 678/* NAME is a SSA_NAME representing DEF_RHS which is of the form
679 ADDR_EXPR <whatever>.
291d763b 680
3d5cfe81 681 Try to forward propagate the ADDR_EXPR into the use USE_STMT.
291d763b 682 Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
3d5cfe81 683 node or for recovery of array indexing from pointer arithmetic.
75a70cf9 684
6b5a5c42 685 Return true if the propagation was successful (the propagation can
686 be not totally successful, yet things may have been changed). */
291d763b 687
688static bool
75a70cf9 689forward_propagate_addr_expr_1 (tree name, tree def_rhs,
690 gimple_stmt_iterator *use_stmt_gsi,
6776dec8 691 bool single_use_p)
291d763b 692{
75a70cf9 693 tree lhs, rhs, rhs2, array_ref;
75a70cf9 694 gimple use_stmt = gsi_stmt (*use_stmt_gsi);
695 enum tree_code rhs_code;
9e019299 696 bool res = true;
291d763b 697
971c637a 698 gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
291d763b 699
75a70cf9 700 lhs = gimple_assign_lhs (use_stmt);
701 rhs_code = gimple_assign_rhs_code (use_stmt);
702 rhs = gimple_assign_rhs1 (use_stmt);
15ec875c 703
bfb89138 704 /* Do not perform copy-propagation but recurse through copy chains. */
705 if (TREE_CODE (lhs) == SSA_NAME
706 && rhs_code == SSA_NAME)
707 return forward_propagate_addr_expr (lhs, def_rhs, single_use_p);
708
709 /* The use statement could be a conversion. Recurse to the uses of the
710 lhs as copyprop does not copy through pointer to integer to pointer
711 conversions and FRE does not catch all cases either.
712 Treat the case of a single-use name and
6776dec8 713 a conversion to def_rhs type separate, though. */
971c637a 714 if (TREE_CODE (lhs) == SSA_NAME
bfb89138 715 && CONVERT_EXPR_CODE_P (rhs_code))
6776dec8 716 {
bfb89138 717 /* If there is a point in a conversion chain where the types match
718 so we can remove a conversion re-materialize the address here
719 and stop. */
720 if (single_use_p
721 && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
722 {
723 gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
724 gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs));
725 return true;
726 }
727
728 /* Else recurse if the conversion preserves the address value. */
729 if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
730 || POINTER_TYPE_P (TREE_TYPE (lhs)))
731 && (TYPE_PRECISION (TREE_TYPE (lhs))
732 >= TYPE_PRECISION (TREE_TYPE (def_rhs))))
733 return forward_propagate_addr_expr (lhs, def_rhs, single_use_p);
734
735 return false;
6776dec8 736 }
971c637a 737
bfb89138 738 /* If this isn't a conversion chain from this on we only can propagate
739 into compatible pointer contexts. */
740 if (!types_compatible_p (TREE_TYPE (name), TREE_TYPE (def_rhs)))
741 return false;
742
182cf5a9 743 /* Propagate through constant pointer adjustments. */
744 if (TREE_CODE (lhs) == SSA_NAME
745 && rhs_code == POINTER_PLUS_EXPR
746 && rhs == name
747 && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST)
748 {
749 tree new_def_rhs;
750 /* As we come here with non-invariant addresses in def_rhs we need
751 to make sure we can build a valid constant offsetted address
752 for further propagation. Simply rely on fold building that
753 and check after the fact. */
754 new_def_rhs = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (rhs)),
755 def_rhs,
756 fold_convert (ptr_type_node,
757 gimple_assign_rhs2 (use_stmt)));
758 if (TREE_CODE (new_def_rhs) == MEM_REF
f5d03f27 759 && !is_gimple_mem_ref_addr (TREE_OPERAND (new_def_rhs, 0)))
182cf5a9 760 return false;
761 new_def_rhs = build_fold_addr_expr_with_type (new_def_rhs,
762 TREE_TYPE (rhs));
763
764 /* Recurse. If we could propagate into all uses of lhs do not
765 bother to replace into the current use but just pretend we did. */
766 if (TREE_CODE (new_def_rhs) == ADDR_EXPR
bfb89138 767 && forward_propagate_addr_expr (lhs, new_def_rhs, single_use_p))
182cf5a9 768 return true;
769
770 if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_def_rhs)))
771 gimple_assign_set_rhs_with_ops (use_stmt_gsi, TREE_CODE (new_def_rhs),
806413d2 772 new_def_rhs);
182cf5a9 773 else if (is_gimple_min_invariant (new_def_rhs))
806413d2 774 gimple_assign_set_rhs_with_ops (use_stmt_gsi, NOP_EXPR, new_def_rhs);
182cf5a9 775 else
776 return false;
777 gcc_assert (gsi_stmt (*use_stmt_gsi) == use_stmt);
778 update_stmt (use_stmt);
779 return true;
780 }
781
48e1416a 782 /* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
971c637a 783 ADDR_EXPR will not appear on the LHS. */
d0d1ecb8 784 tree *lhsp = gimple_assign_lhs_ptr (use_stmt);
785 while (handled_component_p (*lhsp))
786 lhsp = &TREE_OPERAND (*lhsp, 0);
787 lhs = *lhsp;
971c637a 788
182cf5a9 789 /* Now see if the LHS node is a MEM_REF using NAME. If so,
971c637a 790 propagate the ADDR_EXPR into the use of NAME and fold the result. */
182cf5a9 791 if (TREE_CODE (lhs) == MEM_REF
9e019299 792 && TREE_OPERAND (lhs, 0) == name)
971c637a 793 {
182cf5a9 794 tree def_rhs_base;
795 HOST_WIDE_INT def_rhs_offset;
796 /* If the address is invariant we can always fold it. */
797 if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0),
798 &def_rhs_offset)))
9e019299 799 {
5de9d3ed 800 offset_int off = mem_ref_offset (lhs);
182cf5a9 801 tree new_ptr;
e913b5cd 802 off += def_rhs_offset;
182cf5a9 803 if (TREE_CODE (def_rhs_base) == MEM_REF)
804 {
cf8f0e63 805 off += mem_ref_offset (def_rhs_base);
182cf5a9 806 new_ptr = TREE_OPERAND (def_rhs_base, 0);
807 }
808 else
809 new_ptr = build_fold_addr_expr (def_rhs_base);
810 TREE_OPERAND (lhs, 0) = new_ptr;
811 TREE_OPERAND (lhs, 1)
e913b5cd 812 = wide_int_to_tree (TREE_TYPE (TREE_OPERAND (lhs, 1)), off);
9e019299 813 tidy_after_forward_propagate_addr (use_stmt);
9e019299 814 /* Continue propagating into the RHS if this was not the only use. */
815 if (single_use_p)
816 return true;
817 }
182cf5a9 818 /* If the LHS is a plain dereference and the value type is the same as
819 that of the pointed-to type of the address we can put the
820 dereferenced address on the LHS preserving the original alias-type. */
d0d1ecb8 821 else if (integer_zerop (TREE_OPERAND (lhs, 1))
822 && ((gimple_assign_lhs (use_stmt) == lhs
823 && useless_type_conversion_p
824 (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
825 TREE_TYPE (gimple_assign_rhs1 (use_stmt))))
826 || types_compatible_p (TREE_TYPE (lhs),
827 TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
f6e2e4ff 828 /* Don't forward anything into clobber stmts if it would result
829 in the lhs no longer being a MEM_REF. */
830 && (!gimple_clobber_p (use_stmt)
831 || TREE_CODE (TREE_OPERAND (def_rhs, 0)) == MEM_REF))
182cf5a9 832 {
833 tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
98d96c6f 834 tree new_offset, new_base, saved, new_lhs;
182cf5a9 835 while (handled_component_p (*def_rhs_basep))
836 def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
837 saved = *def_rhs_basep;
838 if (TREE_CODE (*def_rhs_basep) == MEM_REF)
839 {
840 new_base = TREE_OPERAND (*def_rhs_basep, 0);
b97e39a0 841 new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (lhs, 1)),
842 TREE_OPERAND (*def_rhs_basep, 1));
182cf5a9 843 }
844 else
845 {
846 new_base = build_fold_addr_expr (*def_rhs_basep);
847 new_offset = TREE_OPERAND (lhs, 1);
848 }
849 *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
850 new_base, new_offset);
2e5dc41c 851 TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (lhs);
31fa5b0d 852 TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (lhs);
2e5dc41c 853 TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (lhs);
98d96c6f 854 new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
d0d1ecb8 855 *lhsp = new_lhs;
98d96c6f 856 TREE_THIS_VOLATILE (new_lhs) = TREE_THIS_VOLATILE (lhs);
31fa5b0d 857 TREE_SIDE_EFFECTS (new_lhs) = TREE_SIDE_EFFECTS (lhs);
182cf5a9 858 *def_rhs_basep = saved;
859 tidy_after_forward_propagate_addr (use_stmt);
860 /* Continue propagating into the RHS if this was not the
861 only use. */
862 if (single_use_p)
863 return true;
864 }
9e019299 865 else
866 /* We can have a struct assignment dereferencing our name twice.
867 Note that we didn't propagate into the lhs to not falsely
868 claim we did when propagating into the rhs. */
869 res = false;
971c637a 870 }
15ec875c 871
631d5db6 872 /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
873 nodes from the RHS. */
d0d1ecb8 874 tree *rhsp = gimple_assign_rhs1_ptr (use_stmt);
875 if (TREE_CODE (*rhsp) == ADDR_EXPR)
876 rhsp = &TREE_OPERAND (*rhsp, 0);
877 while (handled_component_p (*rhsp))
878 rhsp = &TREE_OPERAND (*rhsp, 0);
879 rhs = *rhsp;
291d763b 880
182cf5a9 881 /* Now see if the RHS node is a MEM_REF using NAME. If so,
291d763b 882 propagate the ADDR_EXPR into the use of NAME and fold the result. */
182cf5a9 883 if (TREE_CODE (rhs) == MEM_REF
884 && TREE_OPERAND (rhs, 0) == name)
291d763b 885 {
182cf5a9 886 tree def_rhs_base;
887 HOST_WIDE_INT def_rhs_offset;
888 if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0),
889 &def_rhs_offset)))
890 {
5de9d3ed 891 offset_int off = mem_ref_offset (rhs);
182cf5a9 892 tree new_ptr;
e913b5cd 893 off += def_rhs_offset;
182cf5a9 894 if (TREE_CODE (def_rhs_base) == MEM_REF)
895 {
cf8f0e63 896 off += mem_ref_offset (def_rhs_base);
182cf5a9 897 new_ptr = TREE_OPERAND (def_rhs_base, 0);
898 }
899 else
900 new_ptr = build_fold_addr_expr (def_rhs_base);
901 TREE_OPERAND (rhs, 0) = new_ptr;
902 TREE_OPERAND (rhs, 1)
e913b5cd 903 = wide_int_to_tree (TREE_TYPE (TREE_OPERAND (rhs, 1)), off);
50aacf4c 904 fold_stmt_inplace (use_stmt_gsi);
182cf5a9 905 tidy_after_forward_propagate_addr (use_stmt);
906 return res;
907 }
2e5dc41c 908 /* If the RHS is a plain dereference and the value type is the same as
182cf5a9 909 that of the pointed-to type of the address we can put the
2e5dc41c 910 dereferenced address on the RHS preserving the original alias-type. */
d0d1ecb8 911 else if (integer_zerop (TREE_OPERAND (rhs, 1))
912 && ((gimple_assign_rhs1 (use_stmt) == rhs
913 && useless_type_conversion_p
914 (TREE_TYPE (gimple_assign_lhs (use_stmt)),
915 TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
916 || types_compatible_p (TREE_TYPE (rhs),
917 TREE_TYPE (TREE_OPERAND (def_rhs, 0)))))
182cf5a9 918 {
919 tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
98d96c6f 920 tree new_offset, new_base, saved, new_rhs;
182cf5a9 921 while (handled_component_p (*def_rhs_basep))
922 def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
923 saved = *def_rhs_basep;
924 if (TREE_CODE (*def_rhs_basep) == MEM_REF)
925 {
926 new_base = TREE_OPERAND (*def_rhs_basep, 0);
b97e39a0 927 new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (rhs, 1)),
928 TREE_OPERAND (*def_rhs_basep, 1));
182cf5a9 929 }
930 else
931 {
932 new_base = build_fold_addr_expr (*def_rhs_basep);
933 new_offset = TREE_OPERAND (rhs, 1);
934 }
935 *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
936 new_base, new_offset);
2e5dc41c 937 TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (rhs);
31fa5b0d 938 TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (rhs);
2e5dc41c 939 TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs);
98d96c6f 940 new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
d0d1ecb8 941 *rhsp = new_rhs;
98d96c6f 942 TREE_THIS_VOLATILE (new_rhs) = TREE_THIS_VOLATILE (rhs);
31fa5b0d 943 TREE_SIDE_EFFECTS (new_rhs) = TREE_SIDE_EFFECTS (rhs);
182cf5a9 944 *def_rhs_basep = saved;
50aacf4c 945 fold_stmt_inplace (use_stmt_gsi);
182cf5a9 946 tidy_after_forward_propagate_addr (use_stmt);
947 return res;
948 }
291d763b 949 }
950
971c637a 951 /* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
952 is nothing to do. */
75a70cf9 953 if (gimple_assign_rhs_code (use_stmt) != POINTER_PLUS_EXPR
954 || gimple_assign_rhs1 (use_stmt) != name)
971c637a 955 return false;
956
291d763b 957 /* The remaining cases are all for turning pointer arithmetic into
958 array indexing. They only apply when we have the address of
959 element zero in an array. If that is not the case then there
960 is nothing to do. */
15ec875c 961 array_ref = TREE_OPERAND (def_rhs, 0);
182cf5a9 962 if ((TREE_CODE (array_ref) != ARRAY_REF
963 || TREE_CODE (TREE_TYPE (TREE_OPERAND (array_ref, 0))) != ARRAY_TYPE
964 || TREE_CODE (TREE_OPERAND (array_ref, 1)) != INTEGER_CST)
965 && TREE_CODE (TREE_TYPE (array_ref)) != ARRAY_TYPE)
291d763b 966 return false;
967
75a70cf9 968 rhs2 = gimple_assign_rhs2 (use_stmt);
704d7315 969 /* Optimize &x[C1] p+ C2 to &x p+ C3 with C3 = C1 * element_size + C2. */
75a70cf9 970 if (TREE_CODE (rhs2) == INTEGER_CST)
291d763b 971 {
704d7315 972 tree new_rhs = build1_loc (gimple_location (use_stmt),
973 ADDR_EXPR, TREE_TYPE (def_rhs),
974 fold_build2 (MEM_REF,
975 TREE_TYPE (TREE_TYPE (def_rhs)),
976 unshare_expr (def_rhs),
977 fold_convert (ptr_type_node,
978 rhs2)));
979 gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
980 use_stmt = gsi_stmt (*use_stmt_gsi);
981 update_stmt (use_stmt);
982 tidy_after_forward_propagate_addr (use_stmt);
983 return true;
291d763b 984 }
985
291d763b 986 return false;
987}
988
3d5cfe81 989/* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.
990
991 Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME.
992 Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
993 node or for recovery of array indexing from pointer arithmetic.
bfb89138 994
995 PARENT_SINGLE_USE_P tells if, when in a recursive invocation, NAME was
996 the single use in the previous invocation. Pass true when calling
997 this as toplevel.
998
3d5cfe81 999 Returns true, if all uses have been propagated into. */
1000
1001static bool
bfb89138 1002forward_propagate_addr_expr (tree name, tree rhs, bool parent_single_use_p)
3d5cfe81 1003{
3d5cfe81 1004 imm_use_iterator iter;
75a70cf9 1005 gimple use_stmt;
3d5cfe81 1006 bool all = true;
bfb89138 1007 bool single_use_p = parent_single_use_p && has_single_use (name);
3d5cfe81 1008
09aca5bc 1009 FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
3d5cfe81 1010 {
c96420f8 1011 bool result;
9481f629 1012 tree use_rhs;
3d5cfe81 1013
1014 /* If the use is not in a simple assignment statement, then
1015 there is nothing we can do. */
162efce1 1016 if (!is_gimple_assign (use_stmt))
3d5cfe81 1017 {
688ff29b 1018 if (!is_gimple_debug (use_stmt))
9845d120 1019 all = false;
3d5cfe81 1020 continue;
1021 }
1022
162efce1 1023 gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
1024 result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
1025 single_use_p);
1026 /* If the use has moved to a different statement adjust
1027 the update machinery for the old statement too. */
1028 if (use_stmt != gsi_stmt (gsi))
3d5cfe81 1029 {
162efce1 1030 update_stmt (use_stmt);
1031 use_stmt = gsi_stmt (gsi);
3d5cfe81 1032 }
162efce1 1033 update_stmt (use_stmt);
c96420f8 1034 all &= result;
de6ed584 1035
15ec875c 1036 /* Remove intermediate now unused copy and conversion chains. */
75a70cf9 1037 use_rhs = gimple_assign_rhs1 (use_stmt);
15ec875c 1038 if (result
75a70cf9 1039 && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
7b705d94 1040 && TREE_CODE (use_rhs) == SSA_NAME
1041 && has_zero_uses (gimple_assign_lhs (use_stmt)))
15ec875c 1042 {
75a70cf9 1043 gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
770ae4bb 1044 fwprop_invalidate_lattice (gimple_get_lhs (use_stmt));
15ec875c 1045 release_defs (use_stmt);
75a70cf9 1046 gsi_remove (&gsi, true);
15ec875c 1047 }
3d5cfe81 1048 }
1049
628ce22b 1050 return all && has_zero_uses (name);
3d5cfe81 1051}
1052
678b2f5b 1053
b59e1c90 1054/* Helper function for simplify_gimple_switch. Remove case labels that
1055 have values outside the range of the new type. */
1056
1057static void
1a91d914 1058simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type)
b59e1c90 1059{
1060 unsigned int branch_num = gimple_switch_num_labels (stmt);
c2078b80 1061 auto_vec<tree> labels (branch_num);
b59e1c90 1062 unsigned int i, len;
1063
1064 /* Collect the existing case labels in a VEC, and preprocess it as if
1065 we are gimplifying a GENERIC SWITCH_EXPR. */
1066 for (i = 1; i < branch_num; i++)
f1f41a6c 1067 labels.quick_push (gimple_switch_label (stmt, i));
b59e1c90 1068 preprocess_case_label_vec_for_gimple (labels, index_type, NULL);
1069
1070 /* If any labels were removed, replace the existing case labels
1071 in the GIMPLE_SWITCH statement with the correct ones.
1072 Note that the type updates were done in-place on the case labels,
1073 so we only have to replace the case labels in the GIMPLE_SWITCH
1074 if the number of labels changed. */
f1f41a6c 1075 len = labels.length ();
b59e1c90 1076 if (len < branch_num - 1)
1077 {
1078 bitmap target_blocks;
1079 edge_iterator ei;
1080 edge e;
1081
1082 /* Corner case: *all* case labels have been removed as being
1083 out-of-range for INDEX_TYPE. Push one label and let the
1084 CFG cleanups deal with this further. */
1085 if (len == 0)
1086 {
1087 tree label, elt;
1088
1089 label = CASE_LABEL (gimple_switch_default_label (stmt));
1090 elt = build_case_label (build_int_cst (index_type, 0), NULL, label);
f1f41a6c 1091 labels.quick_push (elt);
b59e1c90 1092 len = 1;
1093 }
1094
f1f41a6c 1095 for (i = 0; i < labels.length (); i++)
1096 gimple_switch_set_label (stmt, i + 1, labels[i]);
b59e1c90 1097 for (i++ ; i < branch_num; i++)
1098 gimple_switch_set_label (stmt, i, NULL_TREE);
1099 gimple_switch_set_num_labels (stmt, len + 1);
1100
1101 /* Cleanup any edges that are now dead. */
1102 target_blocks = BITMAP_ALLOC (NULL);
1103 for (i = 0; i < gimple_switch_num_labels (stmt); i++)
1104 {
1105 tree elt = gimple_switch_label (stmt, i);
1106 basic_block target = label_to_block (CASE_LABEL (elt));
1107 bitmap_set_bit (target_blocks, target->index);
1108 }
1109 for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); )
1110 {
1111 if (! bitmap_bit_p (target_blocks, e->dest->index))
1112 {
1113 remove_edge (e);
1114 cfg_changed = true;
1115 free_dominance_info (CDI_DOMINATORS);
1116 }
1117 else
1118 ei_next (&ei);
1119 }
1120 BITMAP_FREE (target_blocks);
1121 }
b59e1c90 1122}
1123
b5860aba 1124/* STMT is a SWITCH_EXPR for which we attempt to find equivalent forms of
1125 the condition which we may be able to optimize better. */
1126
678b2f5b 1127static bool
1a91d914 1128simplify_gimple_switch (gswitch *stmt)
b5860aba 1129{
b5860aba 1130 /* The optimization that we really care about is removing unnecessary
1131 casts. That will let us do much better in propagating the inferred
1132 constant at the switch target. */
00bffa46 1133 tree cond = gimple_switch_index (stmt);
b5860aba 1134 if (TREE_CODE (cond) == SSA_NAME)
1135 {
00bffa46 1136 gimple def_stmt = SSA_NAME_DEF_STMT (cond);
1137 if (gimple_assign_cast_p (def_stmt))
b5860aba 1138 {
00bffa46 1139 tree def = gimple_assign_rhs1 (def_stmt);
1140 if (TREE_CODE (def) != SSA_NAME)
1141 return false;
1142
1143 /* If we have an extension or sign-change that preserves the
1144 values we check against then we can copy the source value into
1145 the switch. */
1146 tree ti = TREE_TYPE (def);
1147 if (INTEGRAL_TYPE_P (ti)
1148 && TYPE_PRECISION (ti) <= TYPE_PRECISION (TREE_TYPE (cond)))
b5860aba 1149 {
00bffa46 1150 size_t n = gimple_switch_num_labels (stmt);
1151 tree min = NULL_TREE, max = NULL_TREE;
1152 if (n > 1)
1153 {
1154 min = CASE_LOW (gimple_switch_label (stmt, 1));
1155 if (CASE_HIGH (gimple_switch_label (stmt, n - 1)))
1156 max = CASE_HIGH (gimple_switch_label (stmt, n - 1));
1157 else
1158 max = CASE_LOW (gimple_switch_label (stmt, n - 1));
1159 }
1160 if ((!min || int_fits_type_p (min, ti))
1161 && (!max || int_fits_type_p (max, ti)))
b5860aba 1162 {
75a70cf9 1163 gimple_switch_set_index (stmt, def);
b59e1c90 1164 simplify_gimple_switch_label_vec (stmt, ti);
b5860aba 1165 update_stmt (stmt);
678b2f5b 1166 return true;
b5860aba 1167 }
1168 }
1169 }
1170 }
678b2f5b 1171
1172 return false;
b5860aba 1173}
1174
27f931ff 1175/* For pointers p2 and p1 return p2 - p1 if the
1176 difference is known and constant, otherwise return NULL. */
1177
1178static tree
1179constant_pointer_difference (tree p1, tree p2)
1180{
1181 int i, j;
1182#define CPD_ITERATIONS 5
1183 tree exps[2][CPD_ITERATIONS];
1184 tree offs[2][CPD_ITERATIONS];
1185 int cnt[2];
1186
1187 for (i = 0; i < 2; i++)
1188 {
1189 tree p = i ? p1 : p2;
1190 tree off = size_zero_node;
1191 gimple stmt;
1192 enum tree_code code;
1193
1194 /* For each of p1 and p2 we need to iterate at least
1195 twice, to handle ADDR_EXPR directly in p1/p2,
1196 SSA_NAME with ADDR_EXPR or POINTER_PLUS_EXPR etc.
1197 on definition's stmt RHS. Iterate a few extra times. */
1198 j = 0;
1199 do
1200 {
1201 if (!POINTER_TYPE_P (TREE_TYPE (p)))
1202 break;
1203 if (TREE_CODE (p) == ADDR_EXPR)
1204 {
1205 tree q = TREE_OPERAND (p, 0);
1206 HOST_WIDE_INT offset;
1207 tree base = get_addr_base_and_unit_offset (q, &offset);
1208 if (base)
1209 {
1210 q = base;
1211 if (offset)
1212 off = size_binop (PLUS_EXPR, off, size_int (offset));
1213 }
1214 if (TREE_CODE (q) == MEM_REF
1215 && TREE_CODE (TREE_OPERAND (q, 0)) == SSA_NAME)
1216 {
1217 p = TREE_OPERAND (q, 0);
1218 off = size_binop (PLUS_EXPR, off,
e913b5cd 1219 wide_int_to_tree (sizetype,
1220 mem_ref_offset (q)));
27f931ff 1221 }
1222 else
1223 {
1224 exps[i][j] = q;
1225 offs[i][j++] = off;
1226 break;
1227 }
1228 }
1229 if (TREE_CODE (p) != SSA_NAME)
1230 break;
1231 exps[i][j] = p;
1232 offs[i][j++] = off;
1233 if (j == CPD_ITERATIONS)
1234 break;
1235 stmt = SSA_NAME_DEF_STMT (p);
1236 if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != p)
1237 break;
1238 code = gimple_assign_rhs_code (stmt);
1239 if (code == POINTER_PLUS_EXPR)
1240 {
1241 if (TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
1242 break;
1243 off = size_binop (PLUS_EXPR, off, gimple_assign_rhs2 (stmt));
1244 p = gimple_assign_rhs1 (stmt);
1245 }
d09ef31a 1246 else if (code == ADDR_EXPR || CONVERT_EXPR_CODE_P (code))
27f931ff 1247 p = gimple_assign_rhs1 (stmt);
1248 else
1249 break;
1250 }
1251 while (1);
1252 cnt[i] = j;
1253 }
1254
1255 for (i = 0; i < cnt[0]; i++)
1256 for (j = 0; j < cnt[1]; j++)
1257 if (exps[0][i] == exps[1][j])
1258 return size_binop (MINUS_EXPR, offs[0][i], offs[1][j]);
1259
1260 return NULL_TREE;
1261}
1262
1263/* *GSI_P is a GIMPLE_CALL to a builtin function.
1264 Optimize
1265 memcpy (p, "abcd", 4);
1266 memset (p + 4, ' ', 3);
1267 into
1268 memcpy (p, "abcd ", 7);
1269 call if the latter can be stored by pieces during expansion. */
1270
1271static bool
1272simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
1273{
1274 gimple stmt1, stmt2 = gsi_stmt (*gsi_p);
1275 tree vuse = gimple_vuse (stmt2);
1276 if (vuse == NULL)
1277 return false;
1278 stmt1 = SSA_NAME_DEF_STMT (vuse);
1279
1280 switch (DECL_FUNCTION_CODE (callee2))
1281 {
1282 case BUILT_IN_MEMSET:
1283 if (gimple_call_num_args (stmt2) != 3
1284 || gimple_call_lhs (stmt2)
1285 || CHAR_BIT != 8
1286 || BITS_PER_UNIT != 8)
1287 break;
1288 else
1289 {
1290 tree callee1;
1291 tree ptr1, src1, str1, off1, len1, lhs1;
1292 tree ptr2 = gimple_call_arg (stmt2, 0);
1293 tree val2 = gimple_call_arg (stmt2, 1);
1294 tree len2 = gimple_call_arg (stmt2, 2);
1295 tree diff, vdef, new_str_cst;
1296 gimple use_stmt;
1297 unsigned int ptr1_align;
1298 unsigned HOST_WIDE_INT src_len;
1299 char *src_buf;
1300 use_operand_p use_p;
1301
e913b5cd 1302 if (!tree_fits_shwi_p (val2)
94c2a912 1303 || !tree_fits_uhwi_p (len2)
1304 || compare_tree_int (len2, 1024) == 1)
27f931ff 1305 break;
1306 if (is_gimple_call (stmt1))
1307 {
1308 /* If first stmt is a call, it needs to be memcpy
1309 or mempcpy, with string literal as second argument and
1310 constant length. */
1311 callee1 = gimple_call_fndecl (stmt1);
1312 if (callee1 == NULL_TREE
1313 || DECL_BUILT_IN_CLASS (callee1) != BUILT_IN_NORMAL
1314 || gimple_call_num_args (stmt1) != 3)
1315 break;
1316 if (DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMCPY
1317 && DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMPCPY)
1318 break;
1319 ptr1 = gimple_call_arg (stmt1, 0);
1320 src1 = gimple_call_arg (stmt1, 1);
1321 len1 = gimple_call_arg (stmt1, 2);
1322 lhs1 = gimple_call_lhs (stmt1);
e913b5cd 1323 if (!tree_fits_uhwi_p (len1))
27f931ff 1324 break;
1325 str1 = string_constant (src1, &off1);
1326 if (str1 == NULL_TREE)
1327 break;
e913b5cd 1328 if (!tree_fits_uhwi_p (off1)
27f931ff 1329 || compare_tree_int (off1, TREE_STRING_LENGTH (str1) - 1) > 0
1330 || compare_tree_int (len1, TREE_STRING_LENGTH (str1)
e913b5cd 1331 - tree_to_uhwi (off1)) > 0
27f931ff 1332 || TREE_CODE (TREE_TYPE (str1)) != ARRAY_TYPE
1333 || TYPE_MODE (TREE_TYPE (TREE_TYPE (str1)))
1334 != TYPE_MODE (char_type_node))
1335 break;
1336 }
1337 else if (gimple_assign_single_p (stmt1))
1338 {
1339 /* Otherwise look for length 1 memcpy optimized into
1340 assignment. */
1341 ptr1 = gimple_assign_lhs (stmt1);
1342 src1 = gimple_assign_rhs1 (stmt1);
1343 if (TREE_CODE (ptr1) != MEM_REF
1344 || TYPE_MODE (TREE_TYPE (ptr1)) != TYPE_MODE (char_type_node)
e913b5cd 1345 || !tree_fits_shwi_p (src1))
27f931ff 1346 break;
1347 ptr1 = build_fold_addr_expr (ptr1);
1348 callee1 = NULL_TREE;
1349 len1 = size_one_node;
1350 lhs1 = NULL_TREE;
1351 off1 = size_zero_node;
1352 str1 = NULL_TREE;
1353 }
1354 else
1355 break;
1356
1357 diff = constant_pointer_difference (ptr1, ptr2);
1358 if (diff == NULL && lhs1 != NULL)
1359 {
1360 diff = constant_pointer_difference (lhs1, ptr2);
1361 if (DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY
1362 && diff != NULL)
1363 diff = size_binop (PLUS_EXPR, diff,
1364 fold_convert (sizetype, len1));
1365 }
1366 /* If the difference between the second and first destination pointer
1367 is not constant, or is bigger than memcpy length, bail out. */
1368 if (diff == NULL
e913b5cd 1369 || !tree_fits_uhwi_p (diff)
94c2a912 1370 || tree_int_cst_lt (len1, diff)
1371 || compare_tree_int (diff, 1024) == 1)
27f931ff 1372 break;
1373
1374 /* Use maximum of difference plus memset length and memcpy length
1375 as the new memcpy length, if it is too big, bail out. */
e913b5cd 1376 src_len = tree_to_uhwi (diff);
1377 src_len += tree_to_uhwi (len2);
aa59f000 1378 if (src_len < tree_to_uhwi (len1))
e913b5cd 1379 src_len = tree_to_uhwi (len1);
27f931ff 1380 if (src_len > 1024)
1381 break;
1382
1383 /* If mempcpy value is used elsewhere, bail out, as mempcpy
1384 with bigger length will return different result. */
1385 if (lhs1 != NULL_TREE
1386 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY
1387 && (TREE_CODE (lhs1) != SSA_NAME
1388 || !single_imm_use (lhs1, &use_p, &use_stmt)
1389 || use_stmt != stmt2))
1390 break;
1391
1392 /* If anything reads memory in between memcpy and memset
1393 call, the modified memcpy call might change it. */
1394 vdef = gimple_vdef (stmt1);
1395 if (vdef != NULL
1396 && (!single_imm_use (vdef, &use_p, &use_stmt)
1397 || use_stmt != stmt2))
1398 break;
1399
957d0361 1400 ptr1_align = get_pointer_alignment (ptr1);
27f931ff 1401 /* Construct the new source string literal. */
1402 src_buf = XALLOCAVEC (char, src_len + 1);
1403 if (callee1)
1404 memcpy (src_buf,
e913b5cd 1405 TREE_STRING_POINTER (str1) + tree_to_uhwi (off1),
1406 tree_to_uhwi (len1));
27f931ff 1407 else
e913b5cd 1408 src_buf[0] = tree_to_shwi (src1);
1409 memset (src_buf + tree_to_uhwi (diff),
1410 tree_to_shwi (val2), tree_to_uhwi (len2));
27f931ff 1411 src_buf[src_len] = '\0';
1412 /* Neither builtin_strncpy_read_str nor builtin_memcpy_read_str
1413 handle embedded '\0's. */
1414 if (strlen (src_buf) != src_len)
1415 break;
1416 rtl_profile_for_bb (gimple_bb (stmt2));
1417 /* If the new memcpy wouldn't be emitted by storing the literal
1418 by pieces, this optimization might enlarge .rodata too much,
1419 as commonly used string literals couldn't be shared any
1420 longer. */
1421 if (!can_store_by_pieces (src_len,
1422 builtin_strncpy_read_str,
1423 src_buf, ptr1_align, false))
1424 break;
1425
1426 new_str_cst = build_string_literal (src_len, src_buf);
1427 if (callee1)
1428 {
1429 /* If STMT1 is a mem{,p}cpy call, adjust it and remove
1430 memset call. */
1431 if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
1432 gimple_call_set_lhs (stmt1, NULL_TREE);
1433 gimple_call_set_arg (stmt1, 1, new_str_cst);
1434 gimple_call_set_arg (stmt1, 2,
1435 build_int_cst (TREE_TYPE (len1), src_len));
1436 update_stmt (stmt1);
1437 unlink_stmt_vdef (stmt2);
1438 gsi_remove (gsi_p, true);
770ae4bb 1439 fwprop_invalidate_lattice (gimple_get_lhs (stmt2));
27f931ff 1440 release_defs (stmt2);
1441 if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
770ae4bb 1442 {
1443 fwprop_invalidate_lattice (lhs1);
1444 release_ssa_name (lhs1);
1445 }
27f931ff 1446 return true;
1447 }
1448 else
1449 {
1450 /* Otherwise, if STMT1 is length 1 memcpy optimized into
1451 assignment, remove STMT1 and change memset call into
1452 memcpy call. */
1453 gimple_stmt_iterator gsi = gsi_for_stmt (stmt1);
1454
7ecb2e7c 1455 if (!is_gimple_val (ptr1))
1456 ptr1 = force_gimple_operand_gsi (gsi_p, ptr1, true, NULL_TREE,
1457 true, GSI_SAME_STMT);
b9a16870 1458 gimple_call_set_fndecl (stmt2,
1459 builtin_decl_explicit (BUILT_IN_MEMCPY));
27f931ff 1460 gimple_call_set_arg (stmt2, 0, ptr1);
1461 gimple_call_set_arg (stmt2, 1, new_str_cst);
1462 gimple_call_set_arg (stmt2, 2,
1463 build_int_cst (TREE_TYPE (len2), src_len));
1464 unlink_stmt_vdef (stmt1);
1465 gsi_remove (&gsi, true);
770ae4bb 1466 fwprop_invalidate_lattice (gimple_get_lhs (stmt1));
27f931ff 1467 release_defs (stmt1);
1468 update_stmt (stmt2);
1469 return false;
1470 }
1471 }
1472 break;
1473 default:
1474 break;
1475 }
1476 return false;
1477}
1478
10fbe63d 1479/* Given a ssa_name in NAME see if it was defined by an assignment and
1480 set CODE to be the code and ARG1 to the first operand on the rhs and ARG2
1481 to the second operand on the rhs. */
1482
1483static inline void
1484defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
1485{
1486 gimple def;
1487 enum tree_code code1;
1488 tree arg11;
1489 tree arg21;
1490 tree arg31;
1491 enum gimple_rhs_class grhs_class;
1492
1493 code1 = TREE_CODE (name);
1494 arg11 = name;
1495 arg21 = NULL_TREE;
1496 grhs_class = get_gimple_rhs_class (code1);
1497
1498 if (code1 == SSA_NAME)
1499 {
1500 def = SSA_NAME_DEF_STMT (name);
1501
1502 if (def && is_gimple_assign (def)
1503 && can_propagate_from (def))
1504 {
1505 code1 = gimple_assign_rhs_code (def);
1506 arg11 = gimple_assign_rhs1 (def);
1507 arg21 = gimple_assign_rhs2 (def);
1508 arg31 = gimple_assign_rhs2 (def);
1509 }
1510 }
1511 else if (grhs_class == GIMPLE_TERNARY_RHS
1512 || GIMPLE_BINARY_RHS
1513 || GIMPLE_UNARY_RHS
1514 || GIMPLE_SINGLE_RHS)
1515 extract_ops_from_tree_1 (name, &code1, &arg11, &arg21, &arg31);
1516
1517 *code = code1;
1518 *arg1 = arg11;
1519 if (arg2)
1520 *arg2 = arg21;
1521 /* Ignore arg3 currently. */
1522}
1523
ca3c9092 1524
3b8827a2 1525/* Recognize rotation patterns. Return true if a transformation
1526 applied, otherwise return false.
1527
1528 We are looking for X with unsigned type T with bitsize B, OP being
1529 +, | or ^, some type T2 wider than T and
1530 (X << CNT1) OP (X >> CNT2) iff CNT1 + CNT2 == B
1531 ((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2)) iff CNT1 + CNT2 == B
1532 (X << Y) OP (X >> (B - Y))
1533 (X << (int) Y) OP (X >> (int) (B - Y))
1534 ((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y)))
1535 ((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) (B - Y)))
043ce677 1536 (X << Y) | (X >> ((-Y) & (B - 1)))
1537 (X << (int) Y) | (X >> (int) ((-Y) & (B - 1)))
1538 ((T) ((T2) X << Y)) | ((T) ((T2) X >> ((-Y) & (B - 1))))
1539 ((T) ((T2) X << (int) Y)) | ((T) ((T2) X >> (int) ((-Y) & (B - 1))))
3b8827a2 1540
1541 and transform these into:
1542 X r<< CNT1
1543 X r<< Y
1544
1545 Note, in the patterns with T2 type, the type of OP operands
1546 might be even a signed type, but should have precision B. */
1547
1548static bool
1549simplify_rotate (gimple_stmt_iterator *gsi)
1550{
1551 gimple stmt = gsi_stmt (*gsi);
1552 tree arg[2], rtype, rotcnt = NULL_TREE;
1553 tree def_arg1[2], def_arg2[2];
1554 enum tree_code def_code[2];
1555 tree lhs;
1556 int i;
1557 bool swapped_p = false;
1558 gimple g;
1559
1560 arg[0] = gimple_assign_rhs1 (stmt);
1561 arg[1] = gimple_assign_rhs2 (stmt);
1562 rtype = TREE_TYPE (arg[0]);
1563
1564 /* Only create rotates in complete modes. Other cases are not
1565 expanded properly. */
1566 if (!INTEGRAL_TYPE_P (rtype)
1567 || TYPE_PRECISION (rtype) != GET_MODE_PRECISION (TYPE_MODE (rtype)))
1568 return false;
1569
1570 for (i = 0; i < 2; i++)
1571 defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
1572
1573 /* Look through narrowing conversions. */
1574 if (CONVERT_EXPR_CODE_P (def_code[0])
1575 && CONVERT_EXPR_CODE_P (def_code[1])
1576 && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[0]))
1577 && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[1]))
1578 && TYPE_PRECISION (TREE_TYPE (def_arg1[0]))
1579 == TYPE_PRECISION (TREE_TYPE (def_arg1[1]))
1580 && TYPE_PRECISION (TREE_TYPE (def_arg1[0])) > TYPE_PRECISION (rtype)
1581 && has_single_use (arg[0])
1582 && has_single_use (arg[1]))
1583 {
1584 for (i = 0; i < 2; i++)
1585 {
1586 arg[i] = def_arg1[i];
1587 defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
1588 }
1589 }
1590
1591 /* One operand has to be LSHIFT_EXPR and one RSHIFT_EXPR. */
1592 for (i = 0; i < 2; i++)
1593 if (def_code[i] != LSHIFT_EXPR && def_code[i] != RSHIFT_EXPR)
1594 return false;
1595 else if (!has_single_use (arg[i]))
1596 return false;
1597 if (def_code[0] == def_code[1])
1598 return false;
1599
1600 /* If we've looked through narrowing conversions before, look through
1601 widening conversions from unsigned type with the same precision
1602 as rtype here. */
1603 if (TYPE_PRECISION (TREE_TYPE (def_arg1[0])) != TYPE_PRECISION (rtype))
1604 for (i = 0; i < 2; i++)
1605 {
1606 tree tem;
1607 enum tree_code code;
1608 defcodefor_name (def_arg1[i], &code, &tem, NULL);
1609 if (!CONVERT_EXPR_CODE_P (code)
1610 || !INTEGRAL_TYPE_P (TREE_TYPE (tem))
1611 || TYPE_PRECISION (TREE_TYPE (tem)) != TYPE_PRECISION (rtype))
1612 return false;
1613 def_arg1[i] = tem;
1614 }
1615 /* Both shifts have to use the same first operand. */
1616 if (TREE_CODE (def_arg1[0]) != SSA_NAME || def_arg1[0] != def_arg1[1])
1617 return false;
1618 if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[0])))
1619 return false;
1620
1621 /* CNT1 + CNT2 == B case above. */
e913b5cd 1622 if (tree_fits_uhwi_p (def_arg2[0])
1623 && tree_fits_uhwi_p (def_arg2[1])
aa59f000 1624 && tree_to_uhwi (def_arg2[0])
e913b5cd 1625 + tree_to_uhwi (def_arg2[1]) == TYPE_PRECISION (rtype))
3b8827a2 1626 rotcnt = def_arg2[0];
1627 else if (TREE_CODE (def_arg2[0]) != SSA_NAME
1628 || TREE_CODE (def_arg2[1]) != SSA_NAME)
1629 return false;
1630 else
1631 {
1632 tree cdef_arg1[2], cdef_arg2[2], def_arg2_alt[2];
1633 enum tree_code cdef_code[2];
1634 /* Look through conversion of the shift count argument.
1635 The C/C++ FE cast any shift count argument to integer_type_node.
1636 The only problem might be if the shift count type maximum value
1637 is equal or smaller than number of bits in rtype. */
1638 for (i = 0; i < 2; i++)
1639 {
1640 def_arg2_alt[i] = def_arg2[i];
1641 defcodefor_name (def_arg2[i], &cdef_code[i],
1642 &cdef_arg1[i], &cdef_arg2[i]);
1643 if (CONVERT_EXPR_CODE_P (cdef_code[i])
1644 && INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))
1645 && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
1646 > floor_log2 (TYPE_PRECISION (rtype))
1647 && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
1648 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (cdef_arg1[i]))))
1649 {
1650 def_arg2_alt[i] = cdef_arg1[i];
1651 defcodefor_name (def_arg2_alt[i], &cdef_code[i],
1652 &cdef_arg1[i], &cdef_arg2[i]);
1653 }
1654 }
1655 for (i = 0; i < 2; i++)
1656 /* Check for one shift count being Y and the other B - Y,
1657 with optional casts. */
1658 if (cdef_code[i] == MINUS_EXPR
e913b5cd 1659 && tree_fits_shwi_p (cdef_arg1[i])
1660 && tree_to_shwi (cdef_arg1[i]) == TYPE_PRECISION (rtype)
3b8827a2 1661 && TREE_CODE (cdef_arg2[i]) == SSA_NAME)
1662 {
1663 tree tem;
1664 enum tree_code code;
1665
1666 if (cdef_arg2[i] == def_arg2[1 - i]
1667 || cdef_arg2[i] == def_arg2_alt[1 - i])
1668 {
1669 rotcnt = cdef_arg2[i];
1670 break;
1671 }
1672 defcodefor_name (cdef_arg2[i], &code, &tem, NULL);
1673 if (CONVERT_EXPR_CODE_P (code)
1674 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
1675 && TYPE_PRECISION (TREE_TYPE (tem))
1676 > floor_log2 (TYPE_PRECISION (rtype))
1677 && TYPE_PRECISION (TREE_TYPE (tem))
1678 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
1679 && (tem == def_arg2[1 - i]
1680 || tem == def_arg2_alt[1 - i]))
1681 {
1682 rotcnt = tem;
1683 break;
1684 }
1685 }
1686 /* The above sequence isn't safe for Y being 0,
1687 because then one of the shifts triggers undefined behavior.
1688 This alternative is safe even for rotation count of 0.
1689 One shift count is Y and the other (-Y) & (B - 1). */
1690 else if (cdef_code[i] == BIT_AND_EXPR
e913b5cd 1691 && tree_fits_shwi_p (cdef_arg2[i])
1692 && tree_to_shwi (cdef_arg2[i])
3b8827a2 1693 == TYPE_PRECISION (rtype) - 1
043ce677 1694 && TREE_CODE (cdef_arg1[i]) == SSA_NAME
1695 && gimple_assign_rhs_code (stmt) == BIT_IOR_EXPR)
3b8827a2 1696 {
1697 tree tem;
1698 enum tree_code code;
1699
1700 defcodefor_name (cdef_arg1[i], &code, &tem, NULL);
1701 if (CONVERT_EXPR_CODE_P (code)
1702 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
1703 && TYPE_PRECISION (TREE_TYPE (tem))
1704 > floor_log2 (TYPE_PRECISION (rtype))
1705 && TYPE_PRECISION (TREE_TYPE (tem))
1706 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem))))
1707 defcodefor_name (tem, &code, &tem, NULL);
1708
1709 if (code == NEGATE_EXPR)
1710 {
1711 if (tem == def_arg2[1 - i] || tem == def_arg2_alt[1 - i])
1712 {
1713 rotcnt = tem;
1714 break;
1715 }
1716 defcodefor_name (tem, &code, &tem, NULL);
1717 if (CONVERT_EXPR_CODE_P (code)
1718 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
1719 && TYPE_PRECISION (TREE_TYPE (tem))
1720 > floor_log2 (TYPE_PRECISION (rtype))
1721 && TYPE_PRECISION (TREE_TYPE (tem))
1722 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
1723 && (tem == def_arg2[1 - i]
1724 || tem == def_arg2_alt[1 - i]))
1725 {
1726 rotcnt = tem;
1727 break;
1728 }
1729 }
1730 }
1731 if (rotcnt == NULL_TREE)
1732 return false;
1733 swapped_p = i != 1;
1734 }
1735
1736 if (!useless_type_conversion_p (TREE_TYPE (def_arg2[0]),
1737 TREE_TYPE (rotcnt)))
1738 {
e9cf809e 1739 g = gimple_build_assign (make_ssa_name (TREE_TYPE (def_arg2[0])),
1740 NOP_EXPR, rotcnt);
3b8827a2 1741 gsi_insert_before (gsi, g, GSI_SAME_STMT);
1742 rotcnt = gimple_assign_lhs (g);
1743 }
1744 lhs = gimple_assign_lhs (stmt);
1745 if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
f9e245b2 1746 lhs = make_ssa_name (TREE_TYPE (def_arg1[0]));
e9cf809e 1747 g = gimple_build_assign (lhs,
1748 ((def_code[0] == LSHIFT_EXPR) ^ swapped_p)
1749 ? LROTATE_EXPR : RROTATE_EXPR, def_arg1[0], rotcnt);
3b8827a2 1750 if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
1751 {
1752 gsi_insert_before (gsi, g, GSI_SAME_STMT);
e9cf809e 1753 g = gimple_build_assign (gimple_assign_lhs (stmt), NOP_EXPR, lhs);
3b8827a2 1754 }
1755 gsi_replace (gsi, g, false);
1756 return true;
1757}
1758
173c91d9 1759/* Combine an element access with a shuffle. Returns true if there were
1760 any changes made, else it returns false. */
1761
1762static bool
1763simplify_bitfield_ref (gimple_stmt_iterator *gsi)
1764{
1765 gimple stmt = gsi_stmt (*gsi);
1766 gimple def_stmt;
1767 tree op, op0, op1, op2;
1768 tree elem_type;
1769 unsigned idx, n, size;
1770 enum tree_code code;
1771
1772 op = gimple_assign_rhs1 (stmt);
1773 gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF);
1774
1775 op0 = TREE_OPERAND (op, 0);
1776 if (TREE_CODE (op0) != SSA_NAME
1777 || TREE_CODE (TREE_TYPE (op0)) != VECTOR_TYPE)
1778 return false;
1779
58bf5219 1780 def_stmt = get_prop_source_stmt (op0, false, NULL);
1781 if (!def_stmt || !can_propagate_from (def_stmt))
1782 return false;
1783
1784 op1 = TREE_OPERAND (op, 1);
1785 op2 = TREE_OPERAND (op, 2);
1786 code = gimple_assign_rhs_code (def_stmt);
1787
1788 if (code == CONSTRUCTOR)
1789 {
1790 tree tem = fold_ternary (BIT_FIELD_REF, TREE_TYPE (op),
1791 gimple_assign_rhs1 (def_stmt), op1, op2);
1792 if (!tem || !valid_gimple_rhs_p (tem))
1793 return false;
1794 gimple_assign_set_rhs_from_tree (gsi, tem);
1795 update_stmt (gsi_stmt (*gsi));
1796 return true;
1797 }
1798
173c91d9 1799 elem_type = TREE_TYPE (TREE_TYPE (op0));
1800 if (TREE_TYPE (op) != elem_type)
1801 return false;
1802
f9ae6f95 1803 size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
1804 n = TREE_INT_CST_LOW (op1) / size;
173c91d9 1805 if (n != 1)
1806 return false;
f9ae6f95 1807 idx = TREE_INT_CST_LOW (op2) / size;
173c91d9 1808
173c91d9 1809 if (code == VEC_PERM_EXPR)
1810 {
1811 tree p, m, index, tem;
1812 unsigned nelts;
1813 m = gimple_assign_rhs3 (def_stmt);
1814 if (TREE_CODE (m) != VECTOR_CST)
1815 return false;
1816 nelts = VECTOR_CST_NELTS (m);
f9ae6f95 1817 idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx));
173c91d9 1818 idx %= 2 * nelts;
1819 if (idx < nelts)
1820 {
1821 p = gimple_assign_rhs1 (def_stmt);
1822 }
1823 else
1824 {
1825 p = gimple_assign_rhs2 (def_stmt);
1826 idx -= nelts;
1827 }
1828 index = build_int_cst (TREE_TYPE (TREE_TYPE (m)), idx * size);
1829 tem = build3 (BIT_FIELD_REF, TREE_TYPE (op),
ab54bbbd 1830 unshare_expr (p), op1, index);
173c91d9 1831 gimple_assign_set_rhs1 (stmt, tem);
1832 fold_stmt (gsi);
1833 update_stmt (gsi_stmt (*gsi));
1834 return true;
1835 }
1836
1837 return false;
1838}
1839
496ec2ad 1840/* Determine whether applying the 2 permutations (mask1 then mask2)
1841 gives back one of the input. */
1842
1843static int
1844is_combined_permutation_identity (tree mask1, tree mask2)
1845{
1846 tree mask;
1847 unsigned int nelts, i, j;
1848 bool maybe_identity1 = true;
1849 bool maybe_identity2 = true;
1850
1851 gcc_checking_assert (TREE_CODE (mask1) == VECTOR_CST
1852 && TREE_CODE (mask2) == VECTOR_CST);
1853 mask = fold_ternary (VEC_PERM_EXPR, TREE_TYPE (mask1), mask1, mask1, mask2);
1854 gcc_assert (TREE_CODE (mask) == VECTOR_CST);
1855
1856 nelts = VECTOR_CST_NELTS (mask);
1857 for (i = 0; i < nelts; i++)
1858 {
1859 tree val = VECTOR_CST_ELT (mask, i);
1860 gcc_assert (TREE_CODE (val) == INTEGER_CST);
f9ae6f95 1861 j = TREE_INT_CST_LOW (val) & (2 * nelts - 1);
496ec2ad 1862 if (j == i)
1863 maybe_identity2 = false;
1864 else if (j == i + nelts)
1865 maybe_identity1 = false;
1866 else
1867 return 0;
1868 }
1869 return maybe_identity1 ? 1 : maybe_identity2 ? 2 : 0;
1870}
1871
2b9112d6 1872/* Combine a shuffle with its arguments. Returns 1 if there were any
1873 changes made, 2 if cfg-cleanup needs to run. Else it returns 0. */
496ec2ad 1874
1875static int
1876simplify_permutation (gimple_stmt_iterator *gsi)
1877{
1878 gimple stmt = gsi_stmt (*gsi);
1879 gimple def_stmt;
2b9112d6 1880 tree op0, op1, op2, op3, arg0, arg1;
1881 enum tree_code code;
ab54bbbd 1882 bool single_use_op0 = false;
496ec2ad 1883
2b9112d6 1884 gcc_checking_assert (gimple_assign_rhs_code (stmt) == VEC_PERM_EXPR);
496ec2ad 1885
1886 op0 = gimple_assign_rhs1 (stmt);
1887 op1 = gimple_assign_rhs2 (stmt);
1888 op2 = gimple_assign_rhs3 (stmt);
1889
496ec2ad 1890 if (TREE_CODE (op2) != VECTOR_CST)
1891 return 0;
1892
2b9112d6 1893 if (TREE_CODE (op0) == VECTOR_CST)
1894 {
1895 code = VECTOR_CST;
1896 arg0 = op0;
1897 }
1898 else if (TREE_CODE (op0) == SSA_NAME)
1899 {
ab54bbbd 1900 def_stmt = get_prop_source_stmt (op0, false, &single_use_op0);
1901 if (!def_stmt || !can_propagate_from (def_stmt))
2b9112d6 1902 return 0;
496ec2ad 1903
2b9112d6 1904 code = gimple_assign_rhs_code (def_stmt);
1905 arg0 = gimple_assign_rhs1 (def_stmt);
1906 }
1907 else
496ec2ad 1908 return 0;
1909
496ec2ad 1910 /* Two consecutive shuffles. */
2b9112d6 1911 if (code == VEC_PERM_EXPR)
496ec2ad 1912 {
1913 tree orig;
1914 int ident;
2b9112d6 1915
1916 if (op0 != op1)
1917 return 0;
496ec2ad 1918 op3 = gimple_assign_rhs3 (def_stmt);
1919 if (TREE_CODE (op3) != VECTOR_CST)
1920 return 0;
1921 ident = is_combined_permutation_identity (op3, op2);
1922 if (!ident)
1923 return 0;
1924 orig = (ident == 1) ? gimple_assign_rhs1 (def_stmt)
1925 : gimple_assign_rhs2 (def_stmt);
1926 gimple_assign_set_rhs1 (stmt, unshare_expr (orig));
1927 gimple_assign_set_rhs_code (stmt, TREE_CODE (orig));
1928 gimple_set_num_ops (stmt, 2);
1929 update_stmt (stmt);
1930 return remove_prop_source_from_use (op0) ? 2 : 1;
1931 }
1932
2b9112d6 1933 /* Shuffle of a constructor. */
1934 else if (code == CONSTRUCTOR || code == VECTOR_CST)
1935 {
1936 tree opt;
1937 bool ret = false;
1938 if (op0 != op1)
1939 {
ab54bbbd 1940 if (TREE_CODE (op0) == SSA_NAME && !single_use_op0)
2b9112d6 1941 return 0;
1942
1943 if (TREE_CODE (op1) == VECTOR_CST)
1944 arg1 = op1;
1945 else if (TREE_CODE (op1) == SSA_NAME)
1946 {
1947 enum tree_code code2;
1948
ab54bbbd 1949 gimple def_stmt2 = get_prop_source_stmt (op1, true, NULL);
1950 if (!def_stmt2 || !can_propagate_from (def_stmt2))
2b9112d6 1951 return 0;
1952
1953 code2 = gimple_assign_rhs_code (def_stmt2);
1954 if (code2 != CONSTRUCTOR && code2 != VECTOR_CST)
1955 return 0;
1956 arg1 = gimple_assign_rhs1 (def_stmt2);
1957 }
1958 else
1959 return 0;
1960 }
1961 else
1962 {
1963 /* Already used twice in this statement. */
1964 if (TREE_CODE (op0) == SSA_NAME && num_imm_uses (op0) > 2)
1965 return 0;
1966 arg1 = arg0;
1967 }
9af5ce0c 1968 opt = fold_ternary (VEC_PERM_EXPR, TREE_TYPE (op0), arg0, arg1, op2);
2b9112d6 1969 if (!opt
9af5ce0c 1970 || (TREE_CODE (opt) != CONSTRUCTOR && TREE_CODE (opt) != VECTOR_CST))
2b9112d6 1971 return 0;
1972 gimple_assign_set_rhs_from_tree (gsi, opt);
1973 update_stmt (gsi_stmt (*gsi));
1974 if (TREE_CODE (op0) == SSA_NAME)
1975 ret = remove_prop_source_from_use (op0);
1976 if (op0 != op1 && TREE_CODE (op1) == SSA_NAME)
1977 ret |= remove_prop_source_from_use (op1);
1978 return ret ? 2 : 1;
1979 }
1980
1981 return 0;
496ec2ad 1982}
1983
6a9e13a2 1984/* Recognize a VEC_PERM_EXPR. Returns true if there were any changes. */
1985
1986static bool
1987simplify_vector_constructor (gimple_stmt_iterator *gsi)
1988{
1989 gimple stmt = gsi_stmt (*gsi);
1990 gimple def_stmt;
1991 tree op, op2, orig, type, elem_type;
1992 unsigned elem_size, nelts, i;
1993 enum tree_code code;
1994 constructor_elt *elt;
1995 unsigned char *sel;
1996 bool maybe_ident;
1997
1998 gcc_checking_assert (gimple_assign_rhs_code (stmt) == CONSTRUCTOR);
1999
2000 op = gimple_assign_rhs1 (stmt);
2001 type = TREE_TYPE (op);
2002 gcc_checking_assert (TREE_CODE (type) == VECTOR_TYPE);
2003
2004 nelts = TYPE_VECTOR_SUBPARTS (type);
2005 elem_type = TREE_TYPE (type);
f9ae6f95 2006 elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
6a9e13a2 2007
2008 sel = XALLOCAVEC (unsigned char, nelts);
2009 orig = NULL;
2010 maybe_ident = true;
f1f41a6c 2011 FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
6a9e13a2 2012 {
2013 tree ref, op1;
2014
2015 if (i >= nelts)
2016 return false;
2017
2018 if (TREE_CODE (elt->value) != SSA_NAME)
2019 return false;
ab54bbbd 2020 def_stmt = get_prop_source_stmt (elt->value, false, NULL);
2021 if (!def_stmt)
6a9e13a2 2022 return false;
2023 code = gimple_assign_rhs_code (def_stmt);
2024 if (code != BIT_FIELD_REF)
2025 return false;
2026 op1 = gimple_assign_rhs1 (def_stmt);
2027 ref = TREE_OPERAND (op1, 0);
2028 if (orig)
2029 {
2030 if (ref != orig)
2031 return false;
2032 }
2033 else
2034 {
2035 if (TREE_CODE (ref) != SSA_NAME)
2036 return false;
8a13ba5e 2037 if (!useless_type_conversion_p (type, TREE_TYPE (ref)))
2038 return false;
6a9e13a2 2039 orig = ref;
2040 }
f9ae6f95 2041 if (TREE_INT_CST_LOW (TREE_OPERAND (op1, 1)) != elem_size)
6a9e13a2 2042 return false;
f9ae6f95 2043 sel[i] = TREE_INT_CST_LOW (TREE_OPERAND (op1, 2)) / elem_size;
6a9e13a2 2044 if (sel[i] != i) maybe_ident = false;
2045 }
2046 if (i < nelts)
2047 return false;
2048
2049 if (maybe_ident)
d1938a4b 2050 gimple_assign_set_rhs_from_tree (gsi, orig);
6a9e13a2 2051 else
2052 {
d1938a4b 2053 tree mask_type, *mask_elts;
2054
2055 if (!can_vec_perm_p (TYPE_MODE (type), false, sel))
2056 return false;
2057 mask_type
2058 = build_vector_type (build_nonstandard_integer_type (elem_size, 1),
2059 nelts);
2060 if (GET_MODE_CLASS (TYPE_MODE (mask_type)) != MODE_VECTOR_INT
2061 || GET_MODE_SIZE (TYPE_MODE (mask_type))
2062 != GET_MODE_SIZE (TYPE_MODE (type)))
6a9e13a2 2063 return false;
d1938a4b 2064 mask_elts = XALLOCAVEC (tree, nelts);
2065 for (i = 0; i < nelts; i++)
2066 mask_elts[i] = build_int_cst (TREE_TYPE (mask_type), sel[i]);
2067 op2 = build_vector (mask_type, mask_elts);
806413d2 2068 gimple_assign_set_rhs_with_ops (gsi, VEC_PERM_EXPR, orig, orig, op2);
6a9e13a2 2069 }
2070 update_stmt (gsi_stmt (*gsi));
2071 return true;
2072}
2073
f619ecae 2074
f619ecae 2075/* Primitive "lattice" function for gimple_simplify. */
2076
2077static tree
2078fwprop_ssa_val (tree name)
2079{
2080 /* First valueize NAME. */
2081 if (TREE_CODE (name) == SSA_NAME
2082 && SSA_NAME_VERSION (name) < lattice.length ())
2083 {
2084 tree val = lattice[SSA_NAME_VERSION (name)];
2085 if (val)
2086 name = val;
2087 }
58810b92 2088 /* We continue matching along SSA use-def edges for SSA names
2089 that are not single-use. Currently there are no patterns
2090 that would cause any issues with that. */
f619ecae 2091 return name;
2092}
2093
678b2f5b 2094/* Main entry point for the forward propagation and statement combine
2095 optimizer. */
4ee9c684 2096
65b0537f 2097namespace {
2098
2099const pass_data pass_data_forwprop =
2100{
2101 GIMPLE_PASS, /* type */
2102 "forwprop", /* name */
2103 OPTGROUP_NONE, /* optinfo_flags */
65b0537f 2104 TV_TREE_FORWPROP, /* tv_id */
2105 ( PROP_cfg | PROP_ssa ), /* properties_required */
2106 0, /* properties_provided */
2107 0, /* properties_destroyed */
2108 0, /* todo_flags_start */
8b88439e 2109 TODO_update_ssa, /* todo_flags_finish */
65b0537f 2110};
2111
2112class pass_forwprop : public gimple_opt_pass
2113{
2114public:
2115 pass_forwprop (gcc::context *ctxt)
2116 : gimple_opt_pass (pass_data_forwprop, ctxt)
2117 {}
2118
2119 /* opt_pass methods: */
2120 opt_pass * clone () { return new pass_forwprop (m_ctxt); }
2121 virtual bool gate (function *) { return flag_tree_forwprop; }
2122 virtual unsigned int execute (function *);
2123
2124}; // class pass_forwprop
2125
2126unsigned int
2127pass_forwprop::execute (function *fun)
4ee9c684 2128{
c96420f8 2129 unsigned int todoflags = 0;
4ee9c684 2130
148aa112 2131 cfg_changed = false;
2132
770ae4bb 2133 /* Combine stmts with the stmts defining their operands. Do that
2134 in an order that guarantees visiting SSA defs before SSA uses. */
2135 lattice.create (num_ssa_names);
2136 lattice.quick_grow_cleared (num_ssa_names);
2137 int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (fun));
2138 int postorder_num = inverted_post_order_compute (postorder);
25959a39 2139 auto_vec<gimple, 4> to_fixup;
770ae4bb 2140 to_purge = BITMAP_ALLOC (NULL);
2141 for (int i = 0; i < postorder_num; ++i)
f5c8cff5 2142 {
2f5a3c4a 2143 gimple_stmt_iterator gsi;
770ae4bb 2144 basic_block bb = BASIC_BLOCK_FOR_FN (fun, postorder[i]);
291d763b 2145
678b2f5b 2146 /* Apply forward propagation to all stmts in the basic-block.
2147 Note we update GSI within the loop as necessary. */
75a70cf9 2148 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
291d763b 2149 {
75a70cf9 2150 gimple stmt = gsi_stmt (gsi);
678b2f5b 2151 tree lhs, rhs;
2152 enum tree_code code;
291d763b 2153
678b2f5b 2154 if (!is_gimple_assign (stmt))
291d763b 2155 {
678b2f5b 2156 gsi_next (&gsi);
2157 continue;
2158 }
3a938499 2159
678b2f5b 2160 lhs = gimple_assign_lhs (stmt);
2161 rhs = gimple_assign_rhs1 (stmt);
2162 code = gimple_assign_rhs_code (stmt);
2163 if (TREE_CODE (lhs) != SSA_NAME
2164 || has_zero_uses (lhs))
2165 {
2166 gsi_next (&gsi);
2167 continue;
2168 }
3a938499 2169
678b2f5b 2170 /* If this statement sets an SSA_NAME to an address,
2171 try to propagate the address into the uses of the SSA_NAME. */
2172 if (code == ADDR_EXPR
2173 /* Handle pointer conversions on invariant addresses
2174 as well, as this is valid gimple. */
2175 || (CONVERT_EXPR_CODE_P (code)
2176 && TREE_CODE (rhs) == ADDR_EXPR
2177 && POINTER_TYPE_P (TREE_TYPE (lhs))))
2178 {
2179 tree base = get_base_address (TREE_OPERAND (rhs, 0));
2180 if ((!base
2181 || !DECL_P (base)
2182 || decl_address_invariant_p (base))
2183 && !stmt_references_abnormal_ssa_name (stmt)
bfb89138 2184 && forward_propagate_addr_expr (lhs, rhs, true))
1c4607fd 2185 {
770ae4bb 2186 fwprop_invalidate_lattice (gimple_get_lhs (stmt));
678b2f5b 2187 release_defs (stmt);
678b2f5b 2188 gsi_remove (&gsi, true);
1c4607fd 2189 }
678b2f5b 2190 else
2191 gsi_next (&gsi);
2192 }
cd22a796 2193 else if (code == POINTER_PLUS_EXPR)
678b2f5b 2194 {
cd22a796 2195 tree off = gimple_assign_rhs2 (stmt);
2196 if (TREE_CODE (off) == INTEGER_CST
2197 && can_propagate_from (stmt)
2198 && !simple_iv_increment_p (stmt)
678b2f5b 2199 /* ??? Better adjust the interface to that function
2200 instead of building new trees here. */
2201 && forward_propagate_addr_expr
cd22a796 2202 (lhs,
2203 build1_loc (gimple_location (stmt),
2204 ADDR_EXPR, TREE_TYPE (rhs),
2205 fold_build2 (MEM_REF,
2206 TREE_TYPE (TREE_TYPE (rhs)),
2207 rhs,
2208 fold_convert (ptr_type_node,
bfb89138 2209 off))), true))
ca3c9092 2210 {
770ae4bb 2211 fwprop_invalidate_lattice (gimple_get_lhs (stmt));
678b2f5b 2212 release_defs (stmt);
678b2f5b 2213 gsi_remove (&gsi, true);
ca3c9092 2214 }
678b2f5b 2215 else if (is_gimple_min_invariant (rhs))
6afd0544 2216 {
678b2f5b 2217 /* Make sure to fold &a[0] + off_1 here. */
50aacf4c 2218 fold_stmt_inplace (&gsi);
678b2f5b 2219 update_stmt (stmt);
2220 if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
6afd0544 2221 gsi_next (&gsi);
2222 }
291d763b 2223 else
75a70cf9 2224 gsi_next (&gsi);
291d763b 2225 }
e3c6a1ed 2226 else if (TREE_CODE (TREE_TYPE (lhs)) == COMPLEX_TYPE
2227 && gimple_assign_load_p (stmt)
2228 && !gimple_has_volatile_ops (stmt)
b6d76e68 2229 && (TREE_CODE (gimple_assign_rhs1 (stmt))
2230 != TARGET_MEM_REF)
e3c6a1ed 2231 && !stmt_can_throw_internal (stmt))
2232 {
2233 /* Rewrite loads used only in real/imagpart extractions to
2234 component-wise loads. */
2235 use_operand_p use_p;
2236 imm_use_iterator iter;
2237 bool rewrite = true;
2238 FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
2239 {
2240 gimple use_stmt = USE_STMT (use_p);
2241 if (is_gimple_debug (use_stmt))
2242 continue;
2243 if (!is_gimple_assign (use_stmt)
2244 || (gimple_assign_rhs_code (use_stmt) != REALPART_EXPR
2245 && gimple_assign_rhs_code (use_stmt) != IMAGPART_EXPR))
2246 {
2247 rewrite = false;
2248 break;
2249 }
2250 }
2251 if (rewrite)
2252 {
2253 gimple use_stmt;
2254 FOR_EACH_IMM_USE_STMT (use_stmt, iter, lhs)
2255 {
2256 if (is_gimple_debug (use_stmt))
2257 {
2258 if (gimple_debug_bind_p (use_stmt))
2259 {
2260 gimple_debug_bind_reset_value (use_stmt);
2261 update_stmt (use_stmt);
2262 }
2263 continue;
2264 }
2265
2266 tree new_rhs = build1 (gimple_assign_rhs_code (use_stmt),
2267 TREE_TYPE (TREE_TYPE (rhs)),
2268 unshare_expr (rhs));
2269 gimple new_stmt
2270 = gimple_build_assign (gimple_assign_lhs (use_stmt),
2271 new_rhs);
2272
08110213 2273 location_t loc = gimple_location (use_stmt);
2274 gimple_set_location (new_stmt, loc);
e3c6a1ed 2275 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
2276 unlink_stmt_vdef (use_stmt);
2277 gsi_remove (&gsi2, true);
2278
2279 gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
2280 }
7fb03128 2281
2282 release_defs (stmt);
e3c6a1ed 2283 gsi_remove (&gsi, true);
2284 }
2285 else
2286 gsi_next (&gsi);
2287 }
2288 else if (code == COMPLEX_EXPR)
2289 {
2290 /* Rewrite stores of a single-use complex build expression
2291 to component-wise stores. */
2292 use_operand_p use_p;
2293 gimple use_stmt;
2294 if (single_imm_use (lhs, &use_p, &use_stmt)
2295 && gimple_store_p (use_stmt)
2296 && !gimple_has_volatile_ops (use_stmt)
7fb03128 2297 && is_gimple_assign (use_stmt)
2298 && (TREE_CODE (gimple_assign_lhs (use_stmt))
2299 != TARGET_MEM_REF))
e3c6a1ed 2300 {
2301 tree use_lhs = gimple_assign_lhs (use_stmt);
2302 tree new_lhs = build1 (REALPART_EXPR,
2303 TREE_TYPE (TREE_TYPE (use_lhs)),
2304 unshare_expr (use_lhs));
2305 gimple new_stmt = gimple_build_assign (new_lhs, rhs);
08110213 2306 location_t loc = gimple_location (use_stmt);
2307 gimple_set_location (new_stmt, loc);
e3c6a1ed 2308 gimple_set_vuse (new_stmt, gimple_vuse (use_stmt));
2309 gimple_set_vdef (new_stmt, make_ssa_name (gimple_vop (cfun)));
2310 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2311 gimple_set_vuse (use_stmt, gimple_vdef (new_stmt));
2312 gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt);
2313 gsi_insert_before (&gsi2, new_stmt, GSI_SAME_STMT);
2314
2315 new_lhs = build1 (IMAGPART_EXPR,
2316 TREE_TYPE (TREE_TYPE (use_lhs)),
2317 unshare_expr (use_lhs));
2318 gimple_assign_set_lhs (use_stmt, new_lhs);
2319 gimple_assign_set_rhs1 (use_stmt, gimple_assign_rhs2 (stmt));
2320 update_stmt (use_stmt);
2321
7fb03128 2322 release_defs (stmt);
e3c6a1ed 2323 gsi_remove (&gsi, true);
2324 }
2325 else
2326 gsi_next (&gsi);
2327 }
291d763b 2328 else
75a70cf9 2329 gsi_next (&gsi);
291d763b 2330 }
678b2f5b 2331
2332 /* Combine stmts with the stmts defining their operands.
2333 Note we update GSI within the loop as necessary. */
a7107e58 2334 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
678b2f5b 2335 {
2336 gimple stmt = gsi_stmt (gsi);
770ae4bb 2337 gimple orig_stmt = stmt;
678b2f5b 2338 bool changed = false;
25959a39 2339 bool was_noreturn = (is_gimple_call (stmt)
2340 && gimple_call_noreturn_p (stmt));
678b2f5b 2341
2f5a3c4a 2342 /* Mark stmt as potentially needing revisiting. */
2343 gimple_set_plf (stmt, GF_PLF_1, false);
2344
770ae4bb 2345 if (fold_stmt (&gsi, fwprop_ssa_val))
2346 {
2347 changed = true;
2348 stmt = gsi_stmt (gsi);
2349 if (maybe_clean_or_replace_eh_stmt (orig_stmt, stmt))
2350 bitmap_set_bit (to_purge, bb->index);
25959a39 2351 if (!was_noreturn
2352 && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt))
2353 to_fixup.safe_push (stmt);
770ae4bb 2354 /* Cleanup the CFG if we simplified a condition to
2355 true or false. */
1a91d914 2356 if (gcond *cond = dyn_cast <gcond *> (stmt))
2357 if (gimple_cond_true_p (cond)
2358 || gimple_cond_false_p (cond))
2359 cfg_changed = true;
770ae4bb 2360 update_stmt (stmt);
2361 }
2362
678b2f5b 2363 switch (gimple_code (stmt))
2364 {
2365 case GIMPLE_ASSIGN:
2366 {
2367 tree rhs1 = gimple_assign_rhs1 (stmt);
2368 enum tree_code code = gimple_assign_rhs_code (stmt);
2369
d0eb9b3d 2370 if (code == COND_EXPR
2371 || code == VEC_COND_EXPR)
678b2f5b 2372 {
2373 /* In this case the entire COND_EXPR is in rhs1. */
84debb86 2374 if (forward_propagate_into_cond (&gsi))
11b881f5 2375 {
2376 changed = true;
2377 stmt = gsi_stmt (gsi);
2378 }
678b2f5b 2379 }
2380 else if (TREE_CODE_CLASS (code) == tcc_comparison)
2381 {
6f9714b3 2382 int did_something;
6f9714b3 2383 did_something = forward_propagate_into_comparison (&gsi);
2384 if (did_something == 2)
2385 cfg_changed = true;
6f9714b3 2386 changed = did_something != 0;
678b2f5b 2387 }
3b8827a2 2388 else if ((code == PLUS_EXPR
2389 || code == BIT_IOR_EXPR
2390 || code == BIT_XOR_EXPR)
2391 && simplify_rotate (&gsi))
2392 changed = true;
496ec2ad 2393 else if (code == VEC_PERM_EXPR)
2394 {
2395 int did_something = simplify_permutation (&gsi);
2396 if (did_something == 2)
2397 cfg_changed = true;
2398 changed = did_something != 0;
2399 }
173c91d9 2400 else if (code == BIT_FIELD_REF)
2401 changed = simplify_bitfield_ref (&gsi);
6a9e13a2 2402 else if (code == CONSTRUCTOR
2403 && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
2404 changed = simplify_vector_constructor (&gsi);
678b2f5b 2405 break;
2406 }
2407
2408 case GIMPLE_SWITCH:
1a91d914 2409 changed = simplify_gimple_switch (as_a <gswitch *> (stmt));
678b2f5b 2410 break;
2411
2412 case GIMPLE_COND:
2413 {
1a91d914 2414 int did_something
2415 = forward_propagate_into_gimple_cond (as_a <gcond *> (stmt));
678b2f5b 2416 if (did_something == 2)
2417 cfg_changed = true;
678b2f5b 2418 changed = did_something != 0;
2419 break;
2420 }
2421
2422 case GIMPLE_CALL:
2423 {
2424 tree callee = gimple_call_fndecl (stmt);
2425 if (callee != NULL_TREE
2426 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
2427 changed = simplify_builtin_call (&gsi, callee);
2428 break;
2429 }
2430
2431 default:;
2432 }
2433
a7107e58 2434 if (changed)
2435 {
2436 /* If the stmt changed then re-visit it and the statements
2437 inserted before it. */
2f5a3c4a 2438 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
2439 if (gimple_plf (gsi_stmt (gsi), GF_PLF_1))
2440 break;
2441 if (gsi_end_p (gsi))
a7107e58 2442 gsi = gsi_start_bb (bb);
2443 else
2f5a3c4a 2444 gsi_next (&gsi);
a7107e58 2445 }
2446 else
2447 {
2f5a3c4a 2448 /* Stmt no longer needs to be revisited. */
2449 gimple_set_plf (stmt, GF_PLF_1, true);
770ae4bb 2450
2451 /* Fill up the lattice. */
2452 if (gimple_assign_single_p (stmt))
2453 {
2454 tree lhs = gimple_assign_lhs (stmt);
2455 tree rhs = gimple_assign_rhs1 (stmt);
2456 if (TREE_CODE (lhs) == SSA_NAME)
2457 {
2458 tree val = lhs;
2459 if (TREE_CODE (rhs) == SSA_NAME)
2460 val = fwprop_ssa_val (rhs);
2461 else if (is_gimple_min_invariant (rhs))
2462 val = rhs;
2463 fwprop_set_lattice_val (lhs, val);
2464 }
2465 }
2466
a7107e58 2467 gsi_next (&gsi);
2468 }
678b2f5b 2469 }
f5c8cff5 2470 }
770ae4bb 2471 free (postorder);
2472 lattice.release ();
148aa112 2473
25959a39 2474 /* Fixup stmts that became noreturn calls. This may require splitting
2475 blocks and thus isn't possible during the walk. Do this
2476 in reverse order so we don't inadvertedly remove a stmt we want to
2477 fixup by visiting a dominating now noreturn call first. */
2478 while (!to_fixup.is_empty ())
2479 {
2480 gimple stmt = to_fixup.pop ();
2481 if (dump_file && dump_flags & TDF_DETAILS)
2482 {
2483 fprintf (dump_file, "Fixing up noreturn call ");
2484 print_gimple_stmt (dump_file, stmt, 0, 0);
2485 fprintf (dump_file, "\n");
2486 }
2487 cfg_changed |= fixup_noreturn_call (stmt);
2488 }
2489
770ae4bb 2490 cfg_changed |= gimple_purge_all_dead_eh_edges (to_purge);
2491 BITMAP_FREE (to_purge);
f619ecae 2492
148aa112 2493 if (cfg_changed)
6fa78c7b 2494 todoflags |= TODO_cleanup_cfg;
678b2f5b 2495
c96420f8 2496 return todoflags;
4ee9c684 2497}
2498
cbe8bda8 2499} // anon namespace
2500
2501gimple_opt_pass *
2502make_pass_forwprop (gcc::context *ctxt)
2503{
2504 return new pass_forwprop (ctxt);
2505}