]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/tree-ssa-forwprop.c
* expr.h: Remove prototypes of functions defined in builtins.c.
[thirdparty/gcc.git] / gcc / tree-ssa-forwprop.c
CommitLineData
291d763b 1/* Forward propagation of expressions for single use variables.
3aea1f79 2 Copyright (C) 2004-2014 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"
4ee9c684 24#include "tree.h"
9ed99284 25#include "stor-layout.h"
4ee9c684 26#include "tm_p.h"
27#include "basic-block.h"
e5b1e080 28#include "gimple-pretty-print.h"
bc61cadb 29#include "tree-ssa-alias.h"
30#include "internal-fn.h"
31#include "gimple-fold.h"
32#include "tree-eh.h"
33#include "gimple-expr.h"
34#include "is-a.h"
073c1fd5 35#include "gimple.h"
a8783bee 36#include "gimplify.h"
dcf1a1ec 37#include "gimple-iterator.h"
e795d6e1 38#include "gimplify-me.h"
073c1fd5 39#include "gimple-ssa.h"
40#include "tree-cfg.h"
41#include "tree-phinodes.h"
42#include "ssa-iterators.h"
9ed99284 43#include "stringpool.h"
073c1fd5 44#include "tree-ssanames.h"
9ed99284 45#include "expr.h"
073c1fd5 46#include "tree-dfa.h"
4ee9c684 47#include "tree-pass.h"
291d763b 48#include "langhooks.h"
5adc1066 49#include "flags.h"
27f931ff 50#include "expr.h"
6b42039a 51#include "cfgloop.h"
d1938a4b 52#include "optabs.h"
58bf5219 53#include "tree-ssa-propagate.h"
424a4a92 54#include "tree-ssa-dom.h"
f7715905 55#include "builtins.h"
4ee9c684 56
291d763b 57/* This pass propagates the RHS of assignment statements into use
58 sites of the LHS of the assignment. It's basically a specialized
8f628ee8 59 form of tree combination. It is hoped all of this can disappear
60 when we have a generalized tree combiner.
4ee9c684 61
291d763b 62 One class of common cases we handle is forward propagating a single use
48e1416a 63 variable into a COND_EXPR.
4ee9c684 64
65 bb0:
66 x = a COND b;
67 if (x) goto ... else goto ...
68
69 Will be transformed into:
70
71 bb0:
72 if (a COND b) goto ... else goto ...
48e1416a 73
4ee9c684 74 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
75
76 Or (assuming c1 and c2 are constants):
77
78 bb0:
48e1416a 79 x = a + c1;
4ee9c684 80 if (x EQ/NEQ c2) goto ... else goto ...
81
82 Will be transformed into:
83
84 bb0:
85 if (a EQ/NEQ (c2 - c1)) goto ... else goto ...
86
87 Similarly for x = a - c1.
48e1416a 88
4ee9c684 89 Or
90
91 bb0:
92 x = !a
93 if (x) goto ... else goto ...
94
95 Will be transformed into:
96
97 bb0:
98 if (a == 0) goto ... else goto ...
99
100 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
101 For these cases, we propagate A into all, possibly more than one,
102 COND_EXPRs that use X.
103
f5c8cff5 104 Or
105
106 bb0:
107 x = (typecast) a
108 if (x) goto ... else goto ...
109
110 Will be transformed into:
111
112 bb0:
113 if (a != 0) goto ... else goto ...
114
115 (Assuming a is an integral type and x is a boolean or x is an
116 integral and a is a boolean.)
117
118 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
119 For these cases, we propagate A into all, possibly more than one,
120 COND_EXPRs that use X.
121
4ee9c684 122 In addition to eliminating the variable and the statement which assigns
123 a value to the variable, we may be able to later thread the jump without
e6dfde59 124 adding insane complexity in the dominator optimizer.
4ee9c684 125
f5c8cff5 126 Also note these transformations can cascade. We handle this by having
127 a worklist of COND_EXPR statements to examine. As we make a change to
128 a statement, we put it back on the worklist to examine on the next
129 iteration of the main loop.
130
291d763b 131 A second class of propagation opportunities arises for ADDR_EXPR
132 nodes.
133
134 ptr = &x->y->z;
135 res = *ptr;
136
137 Will get turned into
138
139 res = x->y->z;
140
50f39ec6 141 Or
142 ptr = (type1*)&type2var;
143 res = *ptr
144
145 Will get turned into (if type1 and type2 are the same size
146 and neither have volatile on them):
147 res = VIEW_CONVERT_EXPR<type1>(type2var)
148
291d763b 149 Or
150
151 ptr = &x[0];
152 ptr2 = ptr + <constant>;
153
154 Will get turned into
155
156 ptr2 = &x[constant/elementsize];
157
158 Or
159
160 ptr = &x[0];
161 offset = index * element_size;
162 offset_p = (pointer) offset;
163 ptr2 = ptr + offset_p
164
165 Will get turned into:
166
167 ptr2 = &x[index];
168
1c4607fd 169 Or
170 ssa = (int) decl
171 res = ssa & 1
172
173 Provided that decl has known alignment >= 2, will get turned into
174
175 res = 0
176
8f628ee8 177 We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to
178 allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent
179 {NOT_EXPR,NEG_EXPR}.
291d763b 180
4ee9c684 181 This will (of course) be extended as other needs arise. */
182
bfb89138 183static bool forward_propagate_addr_expr (tree, tree, bool);
148aa112 184
b59e1c90 185/* Set to true if we delete dead edges during the optimization. */
148aa112 186static bool cfg_changed;
187
75a70cf9 188static tree rhs_to_tree (tree type, gimple stmt);
148aa112 189
83a20baf 190/* Get the next statement we can propagate NAME's value into skipping
5adc1066 191 trivial copies. Returns the statement that is suitable as a
192 propagation destination or NULL_TREE if there is no such one.
193 This only returns destinations in a single-use chain. FINAL_NAME_P
194 if non-NULL is written to the ssa name that represents the use. */
a3451973 195
75a70cf9 196static gimple
5adc1066 197get_prop_dest_stmt (tree name, tree *final_name_p)
a3451973 198{
5adc1066 199 use_operand_p use;
75a70cf9 200 gimple use_stmt;
a3451973 201
5adc1066 202 do {
203 /* If name has multiple uses, bail out. */
204 if (!single_imm_use (name, &use, &use_stmt))
75a70cf9 205 return NULL;
a3451973 206
5adc1066 207 /* If this is not a trivial copy, we found it. */
8f0b877f 208 if (!gimple_assign_ssa_name_copy_p (use_stmt)
75a70cf9 209 || gimple_assign_rhs1 (use_stmt) != name)
5adc1066 210 break;
211
212 /* Continue searching uses of the copy destination. */
75a70cf9 213 name = gimple_assign_lhs (use_stmt);
5adc1066 214 } while (1);
215
216 if (final_name_p)
217 *final_name_p = name;
218
219 return use_stmt;
a3451973 220}
221
5adc1066 222/* Get the statement we can propagate from into NAME skipping
223 trivial copies. Returns the statement which defines the
224 propagation source or NULL_TREE if there is no such one.
225 If SINGLE_USE_ONLY is set considers only sources which have
226 a single use chain up to NAME. If SINGLE_USE_P is non-null,
227 it is set to whether the chain to NAME is a single use chain
228 or not. SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set. */
4ee9c684 229
75a70cf9 230static gimple
5adc1066 231get_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
f5c8cff5 232{
5adc1066 233 bool single_use = true;
234
235 do {
75a70cf9 236 gimple def_stmt = SSA_NAME_DEF_STMT (name);
5adc1066 237
238 if (!has_single_use (name))
239 {
240 single_use = false;
241 if (single_use_only)
75a70cf9 242 return NULL;
5adc1066 243 }
244
245 /* If name is defined by a PHI node or is the default def, bail out. */
8f0b877f 246 if (!is_gimple_assign (def_stmt))
75a70cf9 247 return NULL;
5adc1066 248
ab31ca23 249 /* If def_stmt is a simple copy, continue looking. */
250 if (gimple_assign_rhs_code (def_stmt) == SSA_NAME)
251 name = gimple_assign_rhs1 (def_stmt);
252 else
5adc1066 253 {
254 if (!single_use_only && single_use_p)
255 *single_use_p = single_use;
256
ab31ca23 257 return def_stmt;
5adc1066 258 }
5adc1066 259 } while (1);
260}
e6dfde59 261
5adc1066 262/* Checks if the destination ssa name in DEF_STMT can be used as
263 propagation source. Returns true if so, otherwise false. */
e6dfde59 264
5adc1066 265static bool
75a70cf9 266can_propagate_from (gimple def_stmt)
5adc1066 267{
75a70cf9 268 gcc_assert (is_gimple_assign (def_stmt));
8f0b877f 269
484b827b 270 /* If the rhs has side-effects we cannot propagate from it. */
75a70cf9 271 if (gimple_has_volatile_ops (def_stmt))
484b827b 272 return false;
273
274 /* If the rhs is a load we cannot propagate from it. */
75a70cf9 275 if (TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_reference
276 || TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) == tcc_declaration)
484b827b 277 return false;
278
b9e98b8a 279 /* Constants can be always propagated. */
8f0b877f 280 if (gimple_assign_single_p (def_stmt)
281 && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
b9e98b8a 282 return true;
283
75a70cf9 284 /* We cannot propagate ssa names that occur in abnormal phi nodes. */
32cdcc42 285 if (stmt_references_abnormal_ssa_name (def_stmt))
286 return false;
4ee9c684 287
5adc1066 288 /* If the definition is a conversion of a pointer to a function type,
75a70cf9 289 then we can not apply optimizations as some targets require
290 function pointers to be canonicalized and in this case this
291 optimization could eliminate a necessary canonicalization. */
8f0b877f 292 if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
75a70cf9 293 {
294 tree rhs = gimple_assign_rhs1 (def_stmt);
295 if (POINTER_TYPE_P (TREE_TYPE (rhs))
296 && TREE_CODE (TREE_TYPE (TREE_TYPE (rhs))) == FUNCTION_TYPE)
297 return false;
298 }
8f0b877f 299
5adc1066 300 return true;
e6dfde59 301}
302
ff0739e0 303/* Remove a chain of dead statements starting at the definition of
304 NAME. The chain is linked via the first operand of the defining statements.
5d2361b0 305 If NAME was replaced in its only use then this function can be used
ff0739e0 306 to clean up dead stmts. The function handles already released SSA
307 names gracefully.
308 Returns true if cleanup-cfg has to run. */
8f628ee8 309
5adc1066 310static bool
5d2361b0 311remove_prop_source_from_use (tree name)
5adc1066 312{
75a70cf9 313 gimple_stmt_iterator gsi;
314 gimple stmt;
5d2361b0 315 bool cfg_changed = false;
8f628ee8 316
5adc1066 317 do {
5d2361b0 318 basic_block bb;
319
ff0739e0 320 if (SSA_NAME_IN_FREE_LIST (name)
321 || SSA_NAME_IS_DEFAULT_DEF (name)
322 || !has_zero_uses (name))
5d2361b0 323 return cfg_changed;
8f628ee8 324
5adc1066 325 stmt = SSA_NAME_DEF_STMT (name);
ff0739e0 326 if (gimple_code (stmt) == GIMPLE_PHI
327 || gimple_has_side_effects (stmt))
6f9714b3 328 return cfg_changed;
ff0739e0 329
330 bb = gimple_bb (stmt);
6f9714b3 331 gsi = gsi_for_stmt (stmt);
ff0739e0 332 unlink_stmt_vdef (stmt);
13ff78a4 333 if (gsi_remove (&gsi, true))
334 cfg_changed |= gimple_purge_dead_eh_edges (bb);
ff0739e0 335 release_defs (stmt);
8f628ee8 336
ff0739e0 337 name = is_gimple_assign (stmt) ? gimple_assign_rhs1 (stmt) : NULL_TREE;
75a70cf9 338 } while (name && TREE_CODE (name) == SSA_NAME);
8f628ee8 339
5d2361b0 340 return cfg_changed;
5adc1066 341}
8f628ee8 342
75a70cf9 343/* Return the rhs of a gimple_assign STMT in a form of a single tree,
344 converted to type TYPE.
48e1416a 345
75a70cf9 346 This should disappear, but is needed so we can combine expressions and use
347 the fold() interfaces. Long term, we need to develop folding and combine
348 routines that deal with gimple exclusively . */
349
350static tree
351rhs_to_tree (tree type, gimple stmt)
352{
389dd41b 353 location_t loc = gimple_location (stmt);
75a70cf9 354 enum tree_code code = gimple_assign_rhs_code (stmt);
57c45d70 355 if (get_gimple_rhs_class (code) == GIMPLE_TERNARY_RHS)
356 return fold_build3_loc (loc, code, type, gimple_assign_rhs1 (stmt),
357 gimple_assign_rhs2 (stmt),
358 gimple_assign_rhs3 (stmt));
359 else if (get_gimple_rhs_class (code) == GIMPLE_BINARY_RHS)
389dd41b 360 return fold_build2_loc (loc, code, type, gimple_assign_rhs1 (stmt),
fb8ed03f 361 gimple_assign_rhs2 (stmt));
75a70cf9 362 else if (get_gimple_rhs_class (code) == GIMPLE_UNARY_RHS)
fb8ed03f 363 return build1 (code, type, gimple_assign_rhs1 (stmt));
75a70cf9 364 else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS)
365 return gimple_assign_rhs1 (stmt);
366 else
367 gcc_unreachable ();
368}
369
5adc1066 370/* Combine OP0 CODE OP1 in the context of a COND_EXPR. Returns
371 the folded result in a form suitable for COND_EXPR_COND or
372 NULL_TREE, if there is no suitable simplified form. If
373 INVARIANT_ONLY is true only gimple_min_invariant results are
374 considered simplified. */
8f628ee8 375
376static tree
c73fee76 377combine_cond_expr_cond (gimple stmt, enum tree_code code, tree type,
5adc1066 378 tree op0, tree op1, bool invariant_only)
8f628ee8 379{
5adc1066 380 tree t;
8f628ee8 381
5adc1066 382 gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison);
8f628ee8 383
c73fee76 384 fold_defer_overflow_warnings ();
385 t = fold_binary_loc (gimple_location (stmt), code, type, op0, op1);
5adc1066 386 if (!t)
c73fee76 387 {
388 fold_undefer_overflow_warnings (false, NULL, 0);
389 return NULL_TREE;
390 }
8f628ee8 391
5adc1066 392 /* Require that we got a boolean type out if we put one in. */
393 gcc_assert (TREE_CODE (TREE_TYPE (t)) == TREE_CODE (type));
8f628ee8 394
a7392604 395 /* Canonicalize the combined condition for use in a COND_EXPR. */
396 t = canonicalize_cond_expr_cond (t);
8f628ee8 397
5adc1066 398 /* Bail out if we required an invariant but didn't get one. */
75a70cf9 399 if (!t || (invariant_only && !is_gimple_min_invariant (t)))
c73fee76 400 {
401 fold_undefer_overflow_warnings (false, NULL, 0);
402 return NULL_TREE;
403 }
404
405 fold_undefer_overflow_warnings (!gimple_no_warning_p (stmt), stmt, 0);
8f628ee8 406
a7392604 407 return t;
8f628ee8 408}
409
c8126d25 410/* Combine the comparison OP0 CODE OP1 at LOC with the defining statements
411 of its operand. Return a new comparison tree or NULL_TREE if there
412 were no simplifying combines. */
413
414static tree
c73fee76 415forward_propagate_into_comparison_1 (gimple stmt,
678b2f5b 416 enum tree_code code, tree type,
417 tree op0, tree op1)
c8126d25 418{
419 tree tmp = NULL_TREE;
420 tree rhs0 = NULL_TREE, rhs1 = NULL_TREE;
421 bool single_use0_p = false, single_use1_p = false;
422
423 /* For comparisons use the first operand, that is likely to
424 simplify comparisons against constants. */
425 if (TREE_CODE (op0) == SSA_NAME)
426 {
427 gimple def_stmt = get_prop_source_stmt (op0, false, &single_use0_p);
428 if (def_stmt && can_propagate_from (def_stmt))
429 {
430 rhs0 = rhs_to_tree (TREE_TYPE (op1), def_stmt);
c73fee76 431 tmp = combine_cond_expr_cond (stmt, code, type,
c8126d25 432 rhs0, op1, !single_use0_p);
433 if (tmp)
434 return tmp;
435 }
436 }
437
438 /* If that wasn't successful, try the second operand. */
439 if (TREE_CODE (op1) == SSA_NAME)
440 {
441 gimple def_stmt = get_prop_source_stmt (op1, false, &single_use1_p);
442 if (def_stmt && can_propagate_from (def_stmt))
443 {
444 rhs1 = rhs_to_tree (TREE_TYPE (op0), def_stmt);
c73fee76 445 tmp = combine_cond_expr_cond (stmt, code, type,
c8126d25 446 op0, rhs1, !single_use1_p);
447 if (tmp)
448 return tmp;
449 }
450 }
451
452 /* If that wasn't successful either, try both operands. */
453 if (rhs0 != NULL_TREE
454 && rhs1 != NULL_TREE)
c73fee76 455 tmp = combine_cond_expr_cond (stmt, code, type,
c8126d25 456 rhs0, rhs1,
457 !(single_use0_p && single_use1_p));
458
459 return tmp;
460}
461
678b2f5b 462/* Propagate from the ssa name definition statements of the assignment
463 from a comparison at *GSI into the conditional if that simplifies it.
6f9714b3 464 Returns 1 if the stmt was modified and 2 if the CFG needs cleanup,
465 otherwise returns 0. */
c8126d25 466
6f9714b3 467static int
678b2f5b 468forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
c8126d25 469{
678b2f5b 470 gimple stmt = gsi_stmt (*gsi);
471 tree tmp;
6f9714b3 472 bool cfg_changed = false;
56632de0 473 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
6f9714b3 474 tree rhs1 = gimple_assign_rhs1 (stmt);
475 tree rhs2 = gimple_assign_rhs2 (stmt);
c8126d25 476
477 /* Combine the comparison with defining statements. */
c73fee76 478 tmp = forward_propagate_into_comparison_1 (stmt,
678b2f5b 479 gimple_assign_rhs_code (stmt),
56632de0 480 type, rhs1, rhs2);
481 if (tmp && useless_type_conversion_p (type, TREE_TYPE (tmp)))
c8126d25 482 {
678b2f5b 483 gimple_assign_set_rhs_from_tree (gsi, tmp);
50aacf4c 484 fold_stmt (gsi);
485 update_stmt (gsi_stmt (*gsi));
75200312 486
6f9714b3 487 if (TREE_CODE (rhs1) == SSA_NAME)
488 cfg_changed |= remove_prop_source_from_use (rhs1);
489 if (TREE_CODE (rhs2) == SSA_NAME)
490 cfg_changed |= remove_prop_source_from_use (rhs2);
491 return cfg_changed ? 2 : 1;
c8126d25 492 }
493
6f9714b3 494 return 0;
c8126d25 495}
496
5adc1066 497/* Propagate from the ssa name definition statements of COND_EXPR
75a70cf9 498 in GIMPLE_COND statement STMT into the conditional if that simplifies it.
499 Returns zero if no statement was changed, one if there were
500 changes and two if cfg_cleanup needs to run.
48e1416a 501
75a70cf9 502 This must be kept in sync with forward_propagate_into_cond. */
503
504static int
505forward_propagate_into_gimple_cond (gimple stmt)
506{
678b2f5b 507 tree tmp;
508 enum tree_code code = gimple_cond_code (stmt);
6f9714b3 509 bool cfg_changed = false;
510 tree rhs1 = gimple_cond_lhs (stmt);
511 tree rhs2 = gimple_cond_rhs (stmt);
678b2f5b 512
513 /* We can do tree combining on SSA_NAME and comparison expressions. */
514 if (TREE_CODE_CLASS (gimple_cond_code (stmt)) != tcc_comparison)
515 return 0;
516
c73fee76 517 tmp = forward_propagate_into_comparison_1 (stmt, code,
678b2f5b 518 boolean_type_node,
6f9714b3 519 rhs1, rhs2);
678b2f5b 520 if (tmp)
521 {
522 if (dump_file && tmp)
523 {
678b2f5b 524 fprintf (dump_file, " Replaced '");
6f9714b3 525 print_gimple_expr (dump_file, stmt, 0, 0);
678b2f5b 526 fprintf (dump_file, "' with '");
527 print_generic_expr (dump_file, tmp, 0);
528 fprintf (dump_file, "'\n");
529 }
75a70cf9 530
678b2f5b 531 gimple_cond_set_condition_from_tree (stmt, unshare_expr (tmp));
532 update_stmt (stmt);
75a70cf9 533
6f9714b3 534 if (TREE_CODE (rhs1) == SSA_NAME)
535 cfg_changed |= remove_prop_source_from_use (rhs1);
536 if (TREE_CODE (rhs2) == SSA_NAME)
537 cfg_changed |= remove_prop_source_from_use (rhs2);
538 return (cfg_changed || is_gimple_min_invariant (tmp)) ? 2 : 1;
678b2f5b 539 }
75a70cf9 540
10a6edd6 541 /* Canonicalize _Bool == 0 and _Bool != 1 to _Bool != 0 by swapping edges. */
542 if ((TREE_CODE (TREE_TYPE (rhs1)) == BOOLEAN_TYPE
543 || (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
544 && TYPE_PRECISION (TREE_TYPE (rhs1)) == 1))
545 && ((code == EQ_EXPR
546 && integer_zerop (rhs2))
547 || (code == NE_EXPR
548 && integer_onep (rhs2))))
549 {
550 basic_block bb = gimple_bb (stmt);
551 gimple_cond_set_code (stmt, NE_EXPR);
552 gimple_cond_set_rhs (stmt, build_zero_cst (TREE_TYPE (rhs1)));
553 EDGE_SUCC (bb, 0)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
554 EDGE_SUCC (bb, 1)->flags ^= (EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
555 return 1;
556 }
557
6f9714b3 558 return 0;
75a70cf9 559}
560
561
562/* Propagate from the ssa name definition statements of COND_EXPR
563 in the rhs of statement STMT into the conditional if that simplifies it.
8a2caf10 564 Returns true zero if the stmt was changed. */
4ee9c684 565
8a2caf10 566static bool
75a70cf9 567forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
e6dfde59 568{
75a70cf9 569 gimple stmt = gsi_stmt (*gsi_p);
678b2f5b 570 tree tmp = NULL_TREE;
571 tree cond = gimple_assign_rhs1 (stmt);
def3cb70 572 enum tree_code code = gimple_assign_rhs_code (stmt);
10a6edd6 573 bool swap = false;
d080be9e 574
678b2f5b 575 /* We can do tree combining on SSA_NAME and comparison expressions. */
576 if (COMPARISON_CLASS_P (cond))
c73fee76 577 tmp = forward_propagate_into_comparison_1 (stmt, TREE_CODE (cond),
f2c1848b 578 TREE_TYPE (cond),
c8126d25 579 TREE_OPERAND (cond, 0),
580 TREE_OPERAND (cond, 1));
678b2f5b 581 else if (TREE_CODE (cond) == SSA_NAME)
582 {
def3cb70 583 enum tree_code def_code;
8a2caf10 584 tree name = cond;
678b2f5b 585 gimple def_stmt = get_prop_source_stmt (name, true, NULL);
586 if (!def_stmt || !can_propagate_from (def_stmt))
6f9714b3 587 return 0;
5adc1066 588
def3cb70 589 def_code = gimple_assign_rhs_code (def_stmt);
590 if (TREE_CODE_CLASS (def_code) == tcc_comparison)
8a2caf10 591 tmp = fold_build2_loc (gimple_location (def_stmt),
def3cb70 592 def_code,
bc112f18 593 TREE_TYPE (cond),
8a2caf10 594 gimple_assign_rhs1 (def_stmt),
595 gimple_assign_rhs2 (def_stmt));
def3cb70 596 else if (code == COND_EXPR
597 && ((def_code == BIT_NOT_EXPR
598 && TYPE_PRECISION (TREE_TYPE (cond)) == 1)
599 || (def_code == BIT_XOR_EXPR
600 && integer_onep (gimple_assign_rhs2 (def_stmt)))))
10a6edd6 601 {
602 tmp = gimple_assign_rhs1 (def_stmt);
603 swap = true;
604 }
678b2f5b 605 }
5adc1066 606
25f48be0 607 if (tmp
608 && is_gimple_condexpr (tmp))
678b2f5b 609 {
610 if (dump_file && tmp)
611 {
612 fprintf (dump_file, " Replaced '");
613 print_generic_expr (dump_file, cond, 0);
614 fprintf (dump_file, "' with '");
615 print_generic_expr (dump_file, tmp, 0);
616 fprintf (dump_file, "'\n");
617 }
d080be9e 618
def3cb70 619 if ((code == VEC_COND_EXPR) ? integer_all_onesp (tmp)
620 : integer_onep (tmp))
8a2caf10 621 gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs2 (stmt));
622 else if (integer_zerop (tmp))
623 gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
624 else
10a6edd6 625 {
626 gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
627 if (swap)
628 {
629 tree t = gimple_assign_rhs2 (stmt);
630 gimple_assign_set_rhs2 (stmt, gimple_assign_rhs3 (stmt));
631 gimple_assign_set_rhs3 (stmt, t);
632 }
633 }
678b2f5b 634 stmt = gsi_stmt (*gsi_p);
635 update_stmt (stmt);
5adc1066 636
8a2caf10 637 return true;
678b2f5b 638 }
d080be9e 639
6f9714b3 640 return 0;
4ee9c684 641}
642
360b78f3 643/* Propagate from the ssa name definition statements of COND_EXPR
644 values in the rhs of statement STMT into the conditional arms
645 if that simplifies it.
646 Returns true if the stmt was changed. */
647
648static bool
649combine_cond_exprs (gimple_stmt_iterator *gsi_p)
650{
651 gimple stmt = gsi_stmt (*gsi_p);
652 tree cond, val1, val2;
653 bool changed = false;
654
655 cond = gimple_assign_rhs1 (stmt);
656 val1 = gimple_assign_rhs2 (stmt);
657 if (TREE_CODE (val1) == SSA_NAME)
658 {
659 gimple def_stmt = SSA_NAME_DEF_STMT (val1);
660 if (is_gimple_assign (def_stmt)
661 && gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt)
662 && operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0))
663 {
664 val1 = unshare_expr (gimple_assign_rhs2 (def_stmt));
665 gimple_assign_set_rhs2 (stmt, val1);
666 changed = true;
667 }
668 }
669 val2 = gimple_assign_rhs3 (stmt);
670 if (TREE_CODE (val2) == SSA_NAME)
671 {
672 gimple def_stmt = SSA_NAME_DEF_STMT (val2);
673 if (is_gimple_assign (def_stmt)
674 && gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt)
675 && operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0))
676 {
677 val2 = unshare_expr (gimple_assign_rhs3 (def_stmt));
678 gimple_assign_set_rhs3 (stmt, val2);
679 changed = true;
680 }
681 }
682 if (operand_equal_p (val1, val2, 0))
683 {
684 gimple_assign_set_rhs_from_tree (gsi_p, val1);
685 stmt = gsi_stmt (*gsi_p);
686 changed = true;
687 }
688
689 if (changed)
690 update_stmt (stmt);
691
692 return changed;
693}
694
48e1416a 695/* We've just substituted an ADDR_EXPR into stmt. Update all the
148aa112 696 relevant data structures to match. */
697
698static void
75a70cf9 699tidy_after_forward_propagate_addr (gimple stmt)
148aa112 700{
148aa112 701 /* We may have turned a trapping insn into a non-trapping insn. */
702 if (maybe_clean_or_replace_eh_stmt (stmt, stmt)
75a70cf9 703 && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
148aa112 704 cfg_changed = true;
f2fae51f 705
75a70cf9 706 if (TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)
707 recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));
148aa112 708}
709
15ec875c 710/* NAME is a SSA_NAME representing DEF_RHS which is of the form
711 ADDR_EXPR <whatever>.
291d763b 712
3d5cfe81 713 Try to forward propagate the ADDR_EXPR into the use USE_STMT.
291d763b 714 Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
3d5cfe81 715 node or for recovery of array indexing from pointer arithmetic.
75a70cf9 716
6b5a5c42 717 Return true if the propagation was successful (the propagation can
718 be not totally successful, yet things may have been changed). */
291d763b 719
720static bool
75a70cf9 721forward_propagate_addr_expr_1 (tree name, tree def_rhs,
722 gimple_stmt_iterator *use_stmt_gsi,
6776dec8 723 bool single_use_p)
291d763b 724{
75a70cf9 725 tree lhs, rhs, rhs2, array_ref;
75a70cf9 726 gimple use_stmt = gsi_stmt (*use_stmt_gsi);
727 enum tree_code rhs_code;
9e019299 728 bool res = true;
291d763b 729
971c637a 730 gcc_assert (TREE_CODE (def_rhs) == ADDR_EXPR);
291d763b 731
75a70cf9 732 lhs = gimple_assign_lhs (use_stmt);
733 rhs_code = gimple_assign_rhs_code (use_stmt);
734 rhs = gimple_assign_rhs1 (use_stmt);
15ec875c 735
bfb89138 736 /* Do not perform copy-propagation but recurse through copy chains. */
737 if (TREE_CODE (lhs) == SSA_NAME
738 && rhs_code == SSA_NAME)
739 return forward_propagate_addr_expr (lhs, def_rhs, single_use_p);
740
741 /* The use statement could be a conversion. Recurse to the uses of the
742 lhs as copyprop does not copy through pointer to integer to pointer
743 conversions and FRE does not catch all cases either.
744 Treat the case of a single-use name and
6776dec8 745 a conversion to def_rhs type separate, though. */
971c637a 746 if (TREE_CODE (lhs) == SSA_NAME
bfb89138 747 && CONVERT_EXPR_CODE_P (rhs_code))
6776dec8 748 {
bfb89138 749 /* If there is a point in a conversion chain where the types match
750 so we can remove a conversion re-materialize the address here
751 and stop. */
752 if (single_use_p
753 && useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (def_rhs)))
754 {
755 gimple_assign_set_rhs1 (use_stmt, unshare_expr (def_rhs));
756 gimple_assign_set_rhs_code (use_stmt, TREE_CODE (def_rhs));
757 return true;
758 }
759
760 /* Else recurse if the conversion preserves the address value. */
761 if ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
762 || POINTER_TYPE_P (TREE_TYPE (lhs)))
763 && (TYPE_PRECISION (TREE_TYPE (lhs))
764 >= TYPE_PRECISION (TREE_TYPE (def_rhs))))
765 return forward_propagate_addr_expr (lhs, def_rhs, single_use_p);
766
767 return false;
6776dec8 768 }
971c637a 769
bfb89138 770 /* If this isn't a conversion chain from this on we only can propagate
771 into compatible pointer contexts. */
772 if (!types_compatible_p (TREE_TYPE (name), TREE_TYPE (def_rhs)))
773 return false;
774
182cf5a9 775 /* Propagate through constant pointer adjustments. */
776 if (TREE_CODE (lhs) == SSA_NAME
777 && rhs_code == POINTER_PLUS_EXPR
778 && rhs == name
779 && TREE_CODE (gimple_assign_rhs2 (use_stmt)) == INTEGER_CST)
780 {
781 tree new_def_rhs;
782 /* As we come here with non-invariant addresses in def_rhs we need
783 to make sure we can build a valid constant offsetted address
784 for further propagation. Simply rely on fold building that
785 and check after the fact. */
786 new_def_rhs = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (rhs)),
787 def_rhs,
788 fold_convert (ptr_type_node,
789 gimple_assign_rhs2 (use_stmt)));
790 if (TREE_CODE (new_def_rhs) == MEM_REF
f5d03f27 791 && !is_gimple_mem_ref_addr (TREE_OPERAND (new_def_rhs, 0)))
182cf5a9 792 return false;
793 new_def_rhs = build_fold_addr_expr_with_type (new_def_rhs,
794 TREE_TYPE (rhs));
795
796 /* Recurse. If we could propagate into all uses of lhs do not
797 bother to replace into the current use but just pretend we did. */
798 if (TREE_CODE (new_def_rhs) == ADDR_EXPR
bfb89138 799 && forward_propagate_addr_expr (lhs, new_def_rhs, single_use_p))
182cf5a9 800 return true;
801
802 if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (new_def_rhs)))
803 gimple_assign_set_rhs_with_ops (use_stmt_gsi, TREE_CODE (new_def_rhs),
804 new_def_rhs, NULL_TREE);
805 else if (is_gimple_min_invariant (new_def_rhs))
806 gimple_assign_set_rhs_with_ops (use_stmt_gsi, NOP_EXPR,
807 new_def_rhs, NULL_TREE);
808 else
809 return false;
810 gcc_assert (gsi_stmt (*use_stmt_gsi) == use_stmt);
811 update_stmt (use_stmt);
812 return true;
813 }
814
48e1416a 815 /* Now strip away any outer COMPONENT_REF/ARRAY_REF nodes from the LHS.
971c637a 816 ADDR_EXPR will not appear on the LHS. */
d0d1ecb8 817 tree *lhsp = gimple_assign_lhs_ptr (use_stmt);
818 while (handled_component_p (*lhsp))
819 lhsp = &TREE_OPERAND (*lhsp, 0);
820 lhs = *lhsp;
971c637a 821
182cf5a9 822 /* Now see if the LHS node is a MEM_REF using NAME. If so,
971c637a 823 propagate the ADDR_EXPR into the use of NAME and fold the result. */
182cf5a9 824 if (TREE_CODE (lhs) == MEM_REF
9e019299 825 && TREE_OPERAND (lhs, 0) == name)
971c637a 826 {
182cf5a9 827 tree def_rhs_base;
828 HOST_WIDE_INT def_rhs_offset;
829 /* If the address is invariant we can always fold it. */
830 if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0),
831 &def_rhs_offset)))
9e019299 832 {
5de9d3ed 833 offset_int off = mem_ref_offset (lhs);
182cf5a9 834 tree new_ptr;
e913b5cd 835 off += def_rhs_offset;
182cf5a9 836 if (TREE_CODE (def_rhs_base) == MEM_REF)
837 {
cf8f0e63 838 off += mem_ref_offset (def_rhs_base);
182cf5a9 839 new_ptr = TREE_OPERAND (def_rhs_base, 0);
840 }
841 else
842 new_ptr = build_fold_addr_expr (def_rhs_base);
843 TREE_OPERAND (lhs, 0) = new_ptr;
844 TREE_OPERAND (lhs, 1)
e913b5cd 845 = wide_int_to_tree (TREE_TYPE (TREE_OPERAND (lhs, 1)), off);
9e019299 846 tidy_after_forward_propagate_addr (use_stmt);
9e019299 847 /* Continue propagating into the RHS if this was not the only use. */
848 if (single_use_p)
849 return true;
850 }
182cf5a9 851 /* If the LHS is a plain dereference and the value type is the same as
852 that of the pointed-to type of the address we can put the
853 dereferenced address on the LHS preserving the original alias-type. */
d0d1ecb8 854 else if (integer_zerop (TREE_OPERAND (lhs, 1))
855 && ((gimple_assign_lhs (use_stmt) == lhs
856 && useless_type_conversion_p
857 (TREE_TYPE (TREE_OPERAND (def_rhs, 0)),
858 TREE_TYPE (gimple_assign_rhs1 (use_stmt))))
859 || types_compatible_p (TREE_TYPE (lhs),
860 TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
f6e2e4ff 861 /* Don't forward anything into clobber stmts if it would result
862 in the lhs no longer being a MEM_REF. */
863 && (!gimple_clobber_p (use_stmt)
864 || TREE_CODE (TREE_OPERAND (def_rhs, 0)) == MEM_REF))
182cf5a9 865 {
866 tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
98d96c6f 867 tree new_offset, new_base, saved, new_lhs;
182cf5a9 868 while (handled_component_p (*def_rhs_basep))
869 def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
870 saved = *def_rhs_basep;
871 if (TREE_CODE (*def_rhs_basep) == MEM_REF)
872 {
873 new_base = TREE_OPERAND (*def_rhs_basep, 0);
b97e39a0 874 new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (lhs, 1)),
875 TREE_OPERAND (*def_rhs_basep, 1));
182cf5a9 876 }
877 else
878 {
879 new_base = build_fold_addr_expr (*def_rhs_basep);
880 new_offset = TREE_OPERAND (lhs, 1);
881 }
882 *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
883 new_base, new_offset);
2e5dc41c 884 TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (lhs);
31fa5b0d 885 TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (lhs);
2e5dc41c 886 TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (lhs);
98d96c6f 887 new_lhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
d0d1ecb8 888 *lhsp = new_lhs;
98d96c6f 889 TREE_THIS_VOLATILE (new_lhs) = TREE_THIS_VOLATILE (lhs);
31fa5b0d 890 TREE_SIDE_EFFECTS (new_lhs) = TREE_SIDE_EFFECTS (lhs);
182cf5a9 891 *def_rhs_basep = saved;
892 tidy_after_forward_propagate_addr (use_stmt);
893 /* Continue propagating into the RHS if this was not the
894 only use. */
895 if (single_use_p)
896 return true;
897 }
9e019299 898 else
899 /* We can have a struct assignment dereferencing our name twice.
900 Note that we didn't propagate into the lhs to not falsely
901 claim we did when propagating into the rhs. */
902 res = false;
971c637a 903 }
15ec875c 904
631d5db6 905 /* Strip away any outer COMPONENT_REF, ARRAY_REF or ADDR_EXPR
906 nodes from the RHS. */
d0d1ecb8 907 tree *rhsp = gimple_assign_rhs1_ptr (use_stmt);
908 if (TREE_CODE (*rhsp) == ADDR_EXPR)
909 rhsp = &TREE_OPERAND (*rhsp, 0);
910 while (handled_component_p (*rhsp))
911 rhsp = &TREE_OPERAND (*rhsp, 0);
912 rhs = *rhsp;
291d763b 913
182cf5a9 914 /* Now see if the RHS node is a MEM_REF using NAME. If so,
291d763b 915 propagate the ADDR_EXPR into the use of NAME and fold the result. */
182cf5a9 916 if (TREE_CODE (rhs) == MEM_REF
917 && TREE_OPERAND (rhs, 0) == name)
291d763b 918 {
182cf5a9 919 tree def_rhs_base;
920 HOST_WIDE_INT def_rhs_offset;
921 if ((def_rhs_base = get_addr_base_and_unit_offset (TREE_OPERAND (def_rhs, 0),
922 &def_rhs_offset)))
923 {
5de9d3ed 924 offset_int off = mem_ref_offset (rhs);
182cf5a9 925 tree new_ptr;
e913b5cd 926 off += def_rhs_offset;
182cf5a9 927 if (TREE_CODE (def_rhs_base) == MEM_REF)
928 {
cf8f0e63 929 off += mem_ref_offset (def_rhs_base);
182cf5a9 930 new_ptr = TREE_OPERAND (def_rhs_base, 0);
931 }
932 else
933 new_ptr = build_fold_addr_expr (def_rhs_base);
934 TREE_OPERAND (rhs, 0) = new_ptr;
935 TREE_OPERAND (rhs, 1)
e913b5cd 936 = wide_int_to_tree (TREE_TYPE (TREE_OPERAND (rhs, 1)), off);
50aacf4c 937 fold_stmt_inplace (use_stmt_gsi);
182cf5a9 938 tidy_after_forward_propagate_addr (use_stmt);
939 return res;
940 }
2e5dc41c 941 /* If the RHS is a plain dereference and the value type is the same as
182cf5a9 942 that of the pointed-to type of the address we can put the
2e5dc41c 943 dereferenced address on the RHS preserving the original alias-type. */
d0d1ecb8 944 else if (integer_zerop (TREE_OPERAND (rhs, 1))
945 && ((gimple_assign_rhs1 (use_stmt) == rhs
946 && useless_type_conversion_p
947 (TREE_TYPE (gimple_assign_lhs (use_stmt)),
948 TREE_TYPE (TREE_OPERAND (def_rhs, 0))))
949 || types_compatible_p (TREE_TYPE (rhs),
950 TREE_TYPE (TREE_OPERAND (def_rhs, 0)))))
182cf5a9 951 {
952 tree *def_rhs_basep = &TREE_OPERAND (def_rhs, 0);
98d96c6f 953 tree new_offset, new_base, saved, new_rhs;
182cf5a9 954 while (handled_component_p (*def_rhs_basep))
955 def_rhs_basep = &TREE_OPERAND (*def_rhs_basep, 0);
956 saved = *def_rhs_basep;
957 if (TREE_CODE (*def_rhs_basep) == MEM_REF)
958 {
959 new_base = TREE_OPERAND (*def_rhs_basep, 0);
b97e39a0 960 new_offset = fold_convert (TREE_TYPE (TREE_OPERAND (rhs, 1)),
961 TREE_OPERAND (*def_rhs_basep, 1));
182cf5a9 962 }
963 else
964 {
965 new_base = build_fold_addr_expr (*def_rhs_basep);
966 new_offset = TREE_OPERAND (rhs, 1);
967 }
968 *def_rhs_basep = build2 (MEM_REF, TREE_TYPE (*def_rhs_basep),
969 new_base, new_offset);
2e5dc41c 970 TREE_THIS_VOLATILE (*def_rhs_basep) = TREE_THIS_VOLATILE (rhs);
31fa5b0d 971 TREE_SIDE_EFFECTS (*def_rhs_basep) = TREE_SIDE_EFFECTS (rhs);
2e5dc41c 972 TREE_THIS_NOTRAP (*def_rhs_basep) = TREE_THIS_NOTRAP (rhs);
98d96c6f 973 new_rhs = unshare_expr (TREE_OPERAND (def_rhs, 0));
d0d1ecb8 974 *rhsp = new_rhs;
98d96c6f 975 TREE_THIS_VOLATILE (new_rhs) = TREE_THIS_VOLATILE (rhs);
31fa5b0d 976 TREE_SIDE_EFFECTS (new_rhs) = TREE_SIDE_EFFECTS (rhs);
182cf5a9 977 *def_rhs_basep = saved;
50aacf4c 978 fold_stmt_inplace (use_stmt_gsi);
182cf5a9 979 tidy_after_forward_propagate_addr (use_stmt);
980 return res;
981 }
291d763b 982 }
983
971c637a 984 /* If the use of the ADDR_EXPR is not a POINTER_PLUS_EXPR, there
985 is nothing to do. */
75a70cf9 986 if (gimple_assign_rhs_code (use_stmt) != POINTER_PLUS_EXPR
987 || gimple_assign_rhs1 (use_stmt) != name)
971c637a 988 return false;
989
291d763b 990 /* The remaining cases are all for turning pointer arithmetic into
991 array indexing. They only apply when we have the address of
992 element zero in an array. If that is not the case then there
993 is nothing to do. */
15ec875c 994 array_ref = TREE_OPERAND (def_rhs, 0);
182cf5a9 995 if ((TREE_CODE (array_ref) != ARRAY_REF
996 || TREE_CODE (TREE_TYPE (TREE_OPERAND (array_ref, 0))) != ARRAY_TYPE
997 || TREE_CODE (TREE_OPERAND (array_ref, 1)) != INTEGER_CST)
998 && TREE_CODE (TREE_TYPE (array_ref)) != ARRAY_TYPE)
291d763b 999 return false;
1000
75a70cf9 1001 rhs2 = gimple_assign_rhs2 (use_stmt);
704d7315 1002 /* Optimize &x[C1] p+ C2 to &x p+ C3 with C3 = C1 * element_size + C2. */
75a70cf9 1003 if (TREE_CODE (rhs2) == INTEGER_CST)
291d763b 1004 {
704d7315 1005 tree new_rhs = build1_loc (gimple_location (use_stmt),
1006 ADDR_EXPR, TREE_TYPE (def_rhs),
1007 fold_build2 (MEM_REF,
1008 TREE_TYPE (TREE_TYPE (def_rhs)),
1009 unshare_expr (def_rhs),
1010 fold_convert (ptr_type_node,
1011 rhs2)));
1012 gimple_assign_set_rhs_from_tree (use_stmt_gsi, new_rhs);
1013 use_stmt = gsi_stmt (*use_stmt_gsi);
1014 update_stmt (use_stmt);
1015 tidy_after_forward_propagate_addr (use_stmt);
1016 return true;
291d763b 1017 }
1018
291d763b 1019 return false;
1020}
1021
3d5cfe81 1022/* STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.
1023
1024 Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME.
1025 Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
1026 node or for recovery of array indexing from pointer arithmetic.
bfb89138 1027
1028 PARENT_SINGLE_USE_P tells if, when in a recursive invocation, NAME was
1029 the single use in the previous invocation. Pass true when calling
1030 this as toplevel.
1031
3d5cfe81 1032 Returns true, if all uses have been propagated into. */
1033
1034static bool
bfb89138 1035forward_propagate_addr_expr (tree name, tree rhs, bool parent_single_use_p)
3d5cfe81 1036{
3d5cfe81 1037 imm_use_iterator iter;
75a70cf9 1038 gimple use_stmt;
3d5cfe81 1039 bool all = true;
bfb89138 1040 bool single_use_p = parent_single_use_p && has_single_use (name);
3d5cfe81 1041
09aca5bc 1042 FOR_EACH_IMM_USE_STMT (use_stmt, iter, name)
3d5cfe81 1043 {
c96420f8 1044 bool result;
9481f629 1045 tree use_rhs;
3d5cfe81 1046
1047 /* If the use is not in a simple assignment statement, then
1048 there is nothing we can do. */
162efce1 1049 if (!is_gimple_assign (use_stmt))
3d5cfe81 1050 {
688ff29b 1051 if (!is_gimple_debug (use_stmt))
9845d120 1052 all = false;
3d5cfe81 1053 continue;
1054 }
1055
162efce1 1056 gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
1057 result = forward_propagate_addr_expr_1 (name, rhs, &gsi,
1058 single_use_p);
1059 /* If the use has moved to a different statement adjust
1060 the update machinery for the old statement too. */
1061 if (use_stmt != gsi_stmt (gsi))
3d5cfe81 1062 {
162efce1 1063 update_stmt (use_stmt);
1064 use_stmt = gsi_stmt (gsi);
3d5cfe81 1065 }
162efce1 1066 update_stmt (use_stmt);
c96420f8 1067 all &= result;
de6ed584 1068
15ec875c 1069 /* Remove intermediate now unused copy and conversion chains. */
75a70cf9 1070 use_rhs = gimple_assign_rhs1 (use_stmt);
15ec875c 1071 if (result
75a70cf9 1072 && TREE_CODE (gimple_assign_lhs (use_stmt)) == SSA_NAME
7b705d94 1073 && TREE_CODE (use_rhs) == SSA_NAME
1074 && has_zero_uses (gimple_assign_lhs (use_stmt)))
15ec875c 1075 {
75a70cf9 1076 gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
15ec875c 1077 release_defs (use_stmt);
75a70cf9 1078 gsi_remove (&gsi, true);
15ec875c 1079 }
3d5cfe81 1080 }
1081
628ce22b 1082 return all && has_zero_uses (name);
3d5cfe81 1083}
1084
678b2f5b 1085
e3a19533 1086/* Forward propagate the comparison defined in *DEFGSI like
678b2f5b 1087 cond_1 = x CMP y to uses of the form
1088 a_1 = (T')cond_1
1089 a_1 = !cond_1
1090 a_1 = cond_1 != 0
e3a19533 1091 Returns true if stmt is now unused. Advance DEFGSI to the next
1092 statement. */
678b2f5b 1093
1094static bool
e3a19533 1095forward_propagate_comparison (gimple_stmt_iterator *defgsi)
678b2f5b 1096{
e3a19533 1097 gimple stmt = gsi_stmt (*defgsi);
678b2f5b 1098 tree name = gimple_assign_lhs (stmt);
1099 gimple use_stmt;
1100 tree tmp = NULL_TREE;
e5b1e080 1101 gimple_stmt_iterator gsi;
1102 enum tree_code code;
1103 tree lhs;
678b2f5b 1104
1105 /* Don't propagate ssa names that occur in abnormal phis. */
1106 if ((TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
1107 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (stmt)))
1108 || (TREE_CODE (gimple_assign_rhs2 (stmt)) == SSA_NAME
1109 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs2 (stmt))))
e3a19533 1110 goto bailout;
678b2f5b 1111
1112 /* Do not un-cse comparisons. But propagate through copies. */
1113 use_stmt = get_prop_dest_stmt (name, &name);
e5b1e080 1114 if (!use_stmt
1115 || !is_gimple_assign (use_stmt))
e3a19533 1116 goto bailout;
678b2f5b 1117
e5b1e080 1118 code = gimple_assign_rhs_code (use_stmt);
1119 lhs = gimple_assign_lhs (use_stmt);
1120 if (!INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
e3a19533 1121 goto bailout;
678b2f5b 1122
e5b1e080 1123 /* We can propagate the condition into a statement that
1124 computes the logical negation of the comparison result. */
4b5f1658 1125 if ((code == BIT_NOT_EXPR
1126 && TYPE_PRECISION (TREE_TYPE (lhs)) == 1)
1127 || (code == BIT_XOR_EXPR
1128 && integer_onep (gimple_assign_rhs2 (use_stmt))))
e5b1e080 1129 {
1130 tree type = TREE_TYPE (gimple_assign_rhs1 (stmt));
1131 bool nans = HONOR_NANS (TYPE_MODE (type));
1132 enum tree_code inv_code;
1133 inv_code = invert_tree_comparison (gimple_assign_rhs_code (stmt), nans);
1134 if (inv_code == ERROR_MARK)
e3a19533 1135 goto bailout;
678b2f5b 1136
e5b1e080 1137 tmp = build2 (inv_code, TREE_TYPE (lhs), gimple_assign_rhs1 (stmt),
1138 gimple_assign_rhs2 (stmt));
1139 }
1140 else
e3a19533 1141 goto bailout;
678b2f5b 1142
e5b1e080 1143 gsi = gsi_for_stmt (use_stmt);
1144 gimple_assign_set_rhs_from_tree (&gsi, unshare_expr (tmp));
1145 use_stmt = gsi_stmt (gsi);
1146 update_stmt (use_stmt);
678b2f5b 1147
e5b1e080 1148 if (dump_file && (dump_flags & TDF_DETAILS))
1149 {
1150 fprintf (dump_file, " Replaced '");
1151 print_gimple_expr (dump_file, stmt, 0, dump_flags);
1152 fprintf (dump_file, "' with '");
1153 print_gimple_expr (dump_file, use_stmt, 0, dump_flags);
1154 fprintf (dump_file, "'\n");
678b2f5b 1155 }
1156
e3a19533 1157 /* When we remove stmt now the iterator defgsi goes off it's current
1158 sequence, hence advance it now. */
1159 gsi_next (defgsi);
1160
e5b1e080 1161 /* Remove defining statements. */
1162 return remove_prop_source_from_use (name);
e3a19533 1163
1164bailout:
1165 gsi_next (defgsi);
1166 return false;
678b2f5b 1167}
1168
1169
d23e1965 1170/* GSI_P points to a statement which performs a narrowing integral
1171 conversion.
1172
1173 Look for cases like:
1174
1175 t = x & c;
1176 y = (T) t;
1177
1178 Turn them into:
1179
1180 t = x & c;
1181 y = (T) x;
1182
1183 If T is narrower than X's type and C merely masks off bits outside
1184 of (T) and nothing else.
1185
1186 Normally we'd let DCE remove the dead statement. But no DCE runs
1187 after the last forwprop/combine pass, so we remove the obviously
1188 dead code ourselves.
1189
1190 Return TRUE if a change was made, FALSE otherwise. */
1191
1192static bool
1193simplify_conversion_from_bitmask (gimple_stmt_iterator *gsi_p)
1194{
1195 gimple stmt = gsi_stmt (*gsi_p);
1196 gimple rhs_def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (stmt));
1197
1198 /* See if the input for the conversion was set via a BIT_AND_EXPR and
1199 the only use of the BIT_AND_EXPR result is the conversion. */
1200 if (is_gimple_assign (rhs_def_stmt)
1201 && gimple_assign_rhs_code (rhs_def_stmt) == BIT_AND_EXPR
1202 && has_single_use (gimple_assign_lhs (rhs_def_stmt)))
1203 {
1204 tree rhs_def_operand1 = gimple_assign_rhs1 (rhs_def_stmt);
1205 tree rhs_def_operand2 = gimple_assign_rhs2 (rhs_def_stmt);
1206 tree lhs_type = TREE_TYPE (gimple_assign_lhs (stmt));
1207
1208 /* Now verify suitability of the BIT_AND_EXPR's operands.
1209 The first must be an SSA_NAME that we can propagate and the
1210 second must be an integer constant that masks out all the
1211 bits outside the final result's type, but nothing else. */
1212 if (TREE_CODE (rhs_def_operand1) == SSA_NAME
1213 && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand1)
1214 && TREE_CODE (rhs_def_operand2) == INTEGER_CST
1215 && operand_equal_p (rhs_def_operand2,
1216 build_low_bits_mask (TREE_TYPE (rhs_def_operand2),
1217 TYPE_PRECISION (lhs_type)),
1218 0))
1219 {
1220 /* This is an optimizable case. Replace the source operand
1221 in the conversion with the first source operand of the
1222 BIT_AND_EXPR. */
1223 gimple_assign_set_rhs1 (stmt, rhs_def_operand1);
1224 stmt = gsi_stmt (*gsi_p);
1225 update_stmt (stmt);
1226
1227 /* There is no DCE after the last forwprop pass. It's
1228 easy to clean up the first order effects here. */
1229 gimple_stmt_iterator si;
1230 si = gsi_for_stmt (rhs_def_stmt);
1231 gsi_remove (&si, true);
1232 release_defs (rhs_def_stmt);
1233 return true;
1234 }
1235 }
1236
1237 return false;
1238}
1239
1240
3a938499 1241/* If we have lhs = ~x (STMT), look and see if earlier we had x = ~y.
1242 If so, we can change STMT into lhs = y which can later be copy
48e1416a 1243 propagated. Similarly for negation.
3a938499 1244
48e1416a 1245 This could trivially be formulated as a forward propagation
3a938499 1246 to immediate uses. However, we already had an implementation
1247 from DOM which used backward propagation via the use-def links.
1248
1249 It turns out that backward propagation is actually faster as
1250 there's less work to do for each NOT/NEG expression we find.
1251 Backwards propagation needs to look at the statement in a single
1252 backlink. Forward propagation needs to look at potentially more
678b2f5b 1253 than one forward link.
3a938499 1254
678b2f5b 1255 Returns true when the statement was changed. */
1256
1257static bool
75a70cf9 1258simplify_not_neg_expr (gimple_stmt_iterator *gsi_p)
3a938499 1259{
75a70cf9 1260 gimple stmt = gsi_stmt (*gsi_p);
1261 tree rhs = gimple_assign_rhs1 (stmt);
1262 gimple rhs_def_stmt = SSA_NAME_DEF_STMT (rhs);
3a938499 1263
1264 /* See if the RHS_DEF_STMT has the same form as our statement. */
75a70cf9 1265 if (is_gimple_assign (rhs_def_stmt)
1266 && gimple_assign_rhs_code (rhs_def_stmt) == gimple_assign_rhs_code (stmt))
3a938499 1267 {
75a70cf9 1268 tree rhs_def_operand = gimple_assign_rhs1 (rhs_def_stmt);
3a938499 1269
1270 /* Verify that RHS_DEF_OPERAND is a suitable SSA_NAME. */
1271 if (TREE_CODE (rhs_def_operand) == SSA_NAME
1272 && ! SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs_def_operand))
1273 {
75a70cf9 1274 gimple_assign_set_rhs_from_tree (gsi_p, rhs_def_operand);
1275 stmt = gsi_stmt (*gsi_p);
3a938499 1276 update_stmt (stmt);
678b2f5b 1277 return true;
3a938499 1278 }
1279 }
678b2f5b 1280
1281 return false;
3a938499 1282}
3d5cfe81 1283
b59e1c90 1284/* Helper function for simplify_gimple_switch. Remove case labels that
1285 have values outside the range of the new type. */
1286
1287static void
1288simplify_gimple_switch_label_vec (gimple stmt, tree index_type)
1289{
1290 unsigned int branch_num = gimple_switch_num_labels (stmt);
c2078b80 1291 auto_vec<tree> labels (branch_num);
b59e1c90 1292 unsigned int i, len;
1293
1294 /* Collect the existing case labels in a VEC, and preprocess it as if
1295 we are gimplifying a GENERIC SWITCH_EXPR. */
1296 for (i = 1; i < branch_num; i++)
f1f41a6c 1297 labels.quick_push (gimple_switch_label (stmt, i));
b59e1c90 1298 preprocess_case_label_vec_for_gimple (labels, index_type, NULL);
1299
1300 /* If any labels were removed, replace the existing case labels
1301 in the GIMPLE_SWITCH statement with the correct ones.
1302 Note that the type updates were done in-place on the case labels,
1303 so we only have to replace the case labels in the GIMPLE_SWITCH
1304 if the number of labels changed. */
f1f41a6c 1305 len = labels.length ();
b59e1c90 1306 if (len < branch_num - 1)
1307 {
1308 bitmap target_blocks;
1309 edge_iterator ei;
1310 edge e;
1311
1312 /* Corner case: *all* case labels have been removed as being
1313 out-of-range for INDEX_TYPE. Push one label and let the
1314 CFG cleanups deal with this further. */
1315 if (len == 0)
1316 {
1317 tree label, elt;
1318
1319 label = CASE_LABEL (gimple_switch_default_label (stmt));
1320 elt = build_case_label (build_int_cst (index_type, 0), NULL, label);
f1f41a6c 1321 labels.quick_push (elt);
b59e1c90 1322 len = 1;
1323 }
1324
f1f41a6c 1325 for (i = 0; i < labels.length (); i++)
1326 gimple_switch_set_label (stmt, i + 1, labels[i]);
b59e1c90 1327 for (i++ ; i < branch_num; i++)
1328 gimple_switch_set_label (stmt, i, NULL_TREE);
1329 gimple_switch_set_num_labels (stmt, len + 1);
1330
1331 /* Cleanup any edges that are now dead. */
1332 target_blocks = BITMAP_ALLOC (NULL);
1333 for (i = 0; i < gimple_switch_num_labels (stmt); i++)
1334 {
1335 tree elt = gimple_switch_label (stmt, i);
1336 basic_block target = label_to_block (CASE_LABEL (elt));
1337 bitmap_set_bit (target_blocks, target->index);
1338 }
1339 for (ei = ei_start (gimple_bb (stmt)->succs); (e = ei_safe_edge (ei)); )
1340 {
1341 if (! bitmap_bit_p (target_blocks, e->dest->index))
1342 {
1343 remove_edge (e);
1344 cfg_changed = true;
1345 free_dominance_info (CDI_DOMINATORS);
1346 }
1347 else
1348 ei_next (&ei);
1349 }
1350 BITMAP_FREE (target_blocks);
1351 }
b59e1c90 1352}
1353
b5860aba 1354/* STMT is a SWITCH_EXPR for which we attempt to find equivalent forms of
1355 the condition which we may be able to optimize better. */
1356
678b2f5b 1357static bool
75a70cf9 1358simplify_gimple_switch (gimple stmt)
b5860aba 1359{
b5860aba 1360 /* The optimization that we really care about is removing unnecessary
1361 casts. That will let us do much better in propagating the inferred
1362 constant at the switch target. */
00bffa46 1363 tree cond = gimple_switch_index (stmt);
b5860aba 1364 if (TREE_CODE (cond) == SSA_NAME)
1365 {
00bffa46 1366 gimple def_stmt = SSA_NAME_DEF_STMT (cond);
1367 if (gimple_assign_cast_p (def_stmt))
b5860aba 1368 {
00bffa46 1369 tree def = gimple_assign_rhs1 (def_stmt);
1370 if (TREE_CODE (def) != SSA_NAME)
1371 return false;
1372
1373 /* If we have an extension or sign-change that preserves the
1374 values we check against then we can copy the source value into
1375 the switch. */
1376 tree ti = TREE_TYPE (def);
1377 if (INTEGRAL_TYPE_P (ti)
1378 && TYPE_PRECISION (ti) <= TYPE_PRECISION (TREE_TYPE (cond)))
b5860aba 1379 {
00bffa46 1380 size_t n = gimple_switch_num_labels (stmt);
1381 tree min = NULL_TREE, max = NULL_TREE;
1382 if (n > 1)
1383 {
1384 min = CASE_LOW (gimple_switch_label (stmt, 1));
1385 if (CASE_HIGH (gimple_switch_label (stmt, n - 1)))
1386 max = CASE_HIGH (gimple_switch_label (stmt, n - 1));
1387 else
1388 max = CASE_LOW (gimple_switch_label (stmt, n - 1));
1389 }
1390 if ((!min || int_fits_type_p (min, ti))
1391 && (!max || int_fits_type_p (max, ti)))
b5860aba 1392 {
75a70cf9 1393 gimple_switch_set_index (stmt, def);
b59e1c90 1394 simplify_gimple_switch_label_vec (stmt, ti);
b5860aba 1395 update_stmt (stmt);
678b2f5b 1396 return true;
b5860aba 1397 }
1398 }
1399 }
1400 }
678b2f5b 1401
1402 return false;
b5860aba 1403}
1404
27f931ff 1405/* For pointers p2 and p1 return p2 - p1 if the
1406 difference is known and constant, otherwise return NULL. */
1407
1408static tree
1409constant_pointer_difference (tree p1, tree p2)
1410{
1411 int i, j;
1412#define CPD_ITERATIONS 5
1413 tree exps[2][CPD_ITERATIONS];
1414 tree offs[2][CPD_ITERATIONS];
1415 int cnt[2];
1416
1417 for (i = 0; i < 2; i++)
1418 {
1419 tree p = i ? p1 : p2;
1420 tree off = size_zero_node;
1421 gimple stmt;
1422 enum tree_code code;
1423
1424 /* For each of p1 and p2 we need to iterate at least
1425 twice, to handle ADDR_EXPR directly in p1/p2,
1426 SSA_NAME with ADDR_EXPR or POINTER_PLUS_EXPR etc.
1427 on definition's stmt RHS. Iterate a few extra times. */
1428 j = 0;
1429 do
1430 {
1431 if (!POINTER_TYPE_P (TREE_TYPE (p)))
1432 break;
1433 if (TREE_CODE (p) == ADDR_EXPR)
1434 {
1435 tree q = TREE_OPERAND (p, 0);
1436 HOST_WIDE_INT offset;
1437 tree base = get_addr_base_and_unit_offset (q, &offset);
1438 if (base)
1439 {
1440 q = base;
1441 if (offset)
1442 off = size_binop (PLUS_EXPR, off, size_int (offset));
1443 }
1444 if (TREE_CODE (q) == MEM_REF
1445 && TREE_CODE (TREE_OPERAND (q, 0)) == SSA_NAME)
1446 {
1447 p = TREE_OPERAND (q, 0);
1448 off = size_binop (PLUS_EXPR, off,
e913b5cd 1449 wide_int_to_tree (sizetype,
1450 mem_ref_offset (q)));
27f931ff 1451 }
1452 else
1453 {
1454 exps[i][j] = q;
1455 offs[i][j++] = off;
1456 break;
1457 }
1458 }
1459 if (TREE_CODE (p) != SSA_NAME)
1460 break;
1461 exps[i][j] = p;
1462 offs[i][j++] = off;
1463 if (j == CPD_ITERATIONS)
1464 break;
1465 stmt = SSA_NAME_DEF_STMT (p);
1466 if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != p)
1467 break;
1468 code = gimple_assign_rhs_code (stmt);
1469 if (code == POINTER_PLUS_EXPR)
1470 {
1471 if (TREE_CODE (gimple_assign_rhs2 (stmt)) != INTEGER_CST)
1472 break;
1473 off = size_binop (PLUS_EXPR, off, gimple_assign_rhs2 (stmt));
1474 p = gimple_assign_rhs1 (stmt);
1475 }
1476 else if (code == ADDR_EXPR || code == NOP_EXPR)
1477 p = gimple_assign_rhs1 (stmt);
1478 else
1479 break;
1480 }
1481 while (1);
1482 cnt[i] = j;
1483 }
1484
1485 for (i = 0; i < cnt[0]; i++)
1486 for (j = 0; j < cnt[1]; j++)
1487 if (exps[0][i] == exps[1][j])
1488 return size_binop (MINUS_EXPR, offs[0][i], offs[1][j]);
1489
1490 return NULL_TREE;
1491}
1492
1493/* *GSI_P is a GIMPLE_CALL to a builtin function.
1494 Optimize
1495 memcpy (p, "abcd", 4);
1496 memset (p + 4, ' ', 3);
1497 into
1498 memcpy (p, "abcd ", 7);
1499 call if the latter can be stored by pieces during expansion. */
1500
1501static bool
1502simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
1503{
1504 gimple stmt1, stmt2 = gsi_stmt (*gsi_p);
1505 tree vuse = gimple_vuse (stmt2);
1506 if (vuse == NULL)
1507 return false;
1508 stmt1 = SSA_NAME_DEF_STMT (vuse);
1509
1510 switch (DECL_FUNCTION_CODE (callee2))
1511 {
1512 case BUILT_IN_MEMSET:
1513 if (gimple_call_num_args (stmt2) != 3
1514 || gimple_call_lhs (stmt2)
1515 || CHAR_BIT != 8
1516 || BITS_PER_UNIT != 8)
1517 break;
1518 else
1519 {
1520 tree callee1;
1521 tree ptr1, src1, str1, off1, len1, lhs1;
1522 tree ptr2 = gimple_call_arg (stmt2, 0);
1523 tree val2 = gimple_call_arg (stmt2, 1);
1524 tree len2 = gimple_call_arg (stmt2, 2);
1525 tree diff, vdef, new_str_cst;
1526 gimple use_stmt;
1527 unsigned int ptr1_align;
1528 unsigned HOST_WIDE_INT src_len;
1529 char *src_buf;
1530 use_operand_p use_p;
1531
e913b5cd 1532 if (!tree_fits_shwi_p (val2)
1533 || !tree_fits_uhwi_p (len2))
27f931ff 1534 break;
1535 if (is_gimple_call (stmt1))
1536 {
1537 /* If first stmt is a call, it needs to be memcpy
1538 or mempcpy, with string literal as second argument and
1539 constant length. */
1540 callee1 = gimple_call_fndecl (stmt1);
1541 if (callee1 == NULL_TREE
1542 || DECL_BUILT_IN_CLASS (callee1) != BUILT_IN_NORMAL
1543 || gimple_call_num_args (stmt1) != 3)
1544 break;
1545 if (DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMCPY
1546 && DECL_FUNCTION_CODE (callee1) != BUILT_IN_MEMPCPY)
1547 break;
1548 ptr1 = gimple_call_arg (stmt1, 0);
1549 src1 = gimple_call_arg (stmt1, 1);
1550 len1 = gimple_call_arg (stmt1, 2);
1551 lhs1 = gimple_call_lhs (stmt1);
e913b5cd 1552 if (!tree_fits_uhwi_p (len1))
27f931ff 1553 break;
1554 str1 = string_constant (src1, &off1);
1555 if (str1 == NULL_TREE)
1556 break;
e913b5cd 1557 if (!tree_fits_uhwi_p (off1)
27f931ff 1558 || compare_tree_int (off1, TREE_STRING_LENGTH (str1) - 1) > 0
1559 || compare_tree_int (len1, TREE_STRING_LENGTH (str1)
e913b5cd 1560 - tree_to_uhwi (off1)) > 0
27f931ff 1561 || TREE_CODE (TREE_TYPE (str1)) != ARRAY_TYPE
1562 || TYPE_MODE (TREE_TYPE (TREE_TYPE (str1)))
1563 != TYPE_MODE (char_type_node))
1564 break;
1565 }
1566 else if (gimple_assign_single_p (stmt1))
1567 {
1568 /* Otherwise look for length 1 memcpy optimized into
1569 assignment. */
1570 ptr1 = gimple_assign_lhs (stmt1);
1571 src1 = gimple_assign_rhs1 (stmt1);
1572 if (TREE_CODE (ptr1) != MEM_REF
1573 || TYPE_MODE (TREE_TYPE (ptr1)) != TYPE_MODE (char_type_node)
e913b5cd 1574 || !tree_fits_shwi_p (src1))
27f931ff 1575 break;
1576 ptr1 = build_fold_addr_expr (ptr1);
1577 callee1 = NULL_TREE;
1578 len1 = size_one_node;
1579 lhs1 = NULL_TREE;
1580 off1 = size_zero_node;
1581 str1 = NULL_TREE;
1582 }
1583 else
1584 break;
1585
1586 diff = constant_pointer_difference (ptr1, ptr2);
1587 if (diff == NULL && lhs1 != NULL)
1588 {
1589 diff = constant_pointer_difference (lhs1, ptr2);
1590 if (DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY
1591 && diff != NULL)
1592 diff = size_binop (PLUS_EXPR, diff,
1593 fold_convert (sizetype, len1));
1594 }
1595 /* If the difference between the second and first destination pointer
1596 is not constant, or is bigger than memcpy length, bail out. */
1597 if (diff == NULL
e913b5cd 1598 || !tree_fits_uhwi_p (diff)
27f931ff 1599 || tree_int_cst_lt (len1, diff))
1600 break;
1601
1602 /* Use maximum of difference plus memset length and memcpy length
1603 as the new memcpy length, if it is too big, bail out. */
e913b5cd 1604 src_len = tree_to_uhwi (diff);
1605 src_len += tree_to_uhwi (len2);
aa59f000 1606 if (src_len < tree_to_uhwi (len1))
e913b5cd 1607 src_len = tree_to_uhwi (len1);
27f931ff 1608 if (src_len > 1024)
1609 break;
1610
1611 /* If mempcpy value is used elsewhere, bail out, as mempcpy
1612 with bigger length will return different result. */
1613 if (lhs1 != NULL_TREE
1614 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY
1615 && (TREE_CODE (lhs1) != SSA_NAME
1616 || !single_imm_use (lhs1, &use_p, &use_stmt)
1617 || use_stmt != stmt2))
1618 break;
1619
1620 /* If anything reads memory in between memcpy and memset
1621 call, the modified memcpy call might change it. */
1622 vdef = gimple_vdef (stmt1);
1623 if (vdef != NULL
1624 && (!single_imm_use (vdef, &use_p, &use_stmt)
1625 || use_stmt != stmt2))
1626 break;
1627
957d0361 1628 ptr1_align = get_pointer_alignment (ptr1);
27f931ff 1629 /* Construct the new source string literal. */
1630 src_buf = XALLOCAVEC (char, src_len + 1);
1631 if (callee1)
1632 memcpy (src_buf,
e913b5cd 1633 TREE_STRING_POINTER (str1) + tree_to_uhwi (off1),
1634 tree_to_uhwi (len1));
27f931ff 1635 else
e913b5cd 1636 src_buf[0] = tree_to_shwi (src1);
1637 memset (src_buf + tree_to_uhwi (diff),
1638 tree_to_shwi (val2), tree_to_uhwi (len2));
27f931ff 1639 src_buf[src_len] = '\0';
1640 /* Neither builtin_strncpy_read_str nor builtin_memcpy_read_str
1641 handle embedded '\0's. */
1642 if (strlen (src_buf) != src_len)
1643 break;
1644 rtl_profile_for_bb (gimple_bb (stmt2));
1645 /* If the new memcpy wouldn't be emitted by storing the literal
1646 by pieces, this optimization might enlarge .rodata too much,
1647 as commonly used string literals couldn't be shared any
1648 longer. */
1649 if (!can_store_by_pieces (src_len,
1650 builtin_strncpy_read_str,
1651 src_buf, ptr1_align, false))
1652 break;
1653
1654 new_str_cst = build_string_literal (src_len, src_buf);
1655 if (callee1)
1656 {
1657 /* If STMT1 is a mem{,p}cpy call, adjust it and remove
1658 memset call. */
1659 if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
1660 gimple_call_set_lhs (stmt1, NULL_TREE);
1661 gimple_call_set_arg (stmt1, 1, new_str_cst);
1662 gimple_call_set_arg (stmt1, 2,
1663 build_int_cst (TREE_TYPE (len1), src_len));
1664 update_stmt (stmt1);
1665 unlink_stmt_vdef (stmt2);
1666 gsi_remove (gsi_p, true);
1667 release_defs (stmt2);
1668 if (lhs1 && DECL_FUNCTION_CODE (callee1) == BUILT_IN_MEMPCPY)
1669 release_ssa_name (lhs1);
1670 return true;
1671 }
1672 else
1673 {
1674 /* Otherwise, if STMT1 is length 1 memcpy optimized into
1675 assignment, remove STMT1 and change memset call into
1676 memcpy call. */
1677 gimple_stmt_iterator gsi = gsi_for_stmt (stmt1);
1678
7ecb2e7c 1679 if (!is_gimple_val (ptr1))
1680 ptr1 = force_gimple_operand_gsi (gsi_p, ptr1, true, NULL_TREE,
1681 true, GSI_SAME_STMT);
b9a16870 1682 gimple_call_set_fndecl (stmt2,
1683 builtin_decl_explicit (BUILT_IN_MEMCPY));
27f931ff 1684 gimple_call_set_arg (stmt2, 0, ptr1);
1685 gimple_call_set_arg (stmt2, 1, new_str_cst);
1686 gimple_call_set_arg (stmt2, 2,
1687 build_int_cst (TREE_TYPE (len2), src_len));
1688 unlink_stmt_vdef (stmt1);
1689 gsi_remove (&gsi, true);
1690 release_defs (stmt1);
1691 update_stmt (stmt2);
1692 return false;
1693 }
1694 }
1695 break;
1696 default:
1697 break;
1698 }
1699 return false;
1700}
1701
41913fa9 1702/* Checks if expression has type of one-bit precision, or is a known
1703 truth-valued expression. */
1704static bool
1705truth_valued_ssa_name (tree name)
1706{
1707 gimple def;
1708 tree type = TREE_TYPE (name);
1709
1710 if (!INTEGRAL_TYPE_P (type))
1711 return false;
1712 /* Don't check here for BOOLEAN_TYPE as the precision isn't
1713 necessarily one and so ~X is not equal to !X. */
1714 if (TYPE_PRECISION (type) == 1)
1715 return true;
1716 def = SSA_NAME_DEF_STMT (name);
1717 if (is_gimple_assign (def))
1718 return truth_value_p (gimple_assign_rhs_code (def));
1719 return false;
1720}
1721
1722/* Helper routine for simplify_bitwise_binary_1 function.
1723 Return for the SSA name NAME the expression X if it mets condition
1724 NAME = !X. Otherwise return NULL_TREE.
1725 Detected patterns for NAME = !X are:
1726 !X and X == 0 for X with integral type.
1727 X ^ 1, X != 1,or ~X for X with integral type with precision of one. */
1728static tree
1729lookup_logical_inverted_value (tree name)
1730{
1731 tree op1, op2;
1732 enum tree_code code;
1733 gimple def;
1734
1735 /* If name has none-intergal type, or isn't a SSA_NAME, then
1736 return. */
1737 if (TREE_CODE (name) != SSA_NAME
1738 || !INTEGRAL_TYPE_P (TREE_TYPE (name)))
1739 return NULL_TREE;
1740 def = SSA_NAME_DEF_STMT (name);
1741 if (!is_gimple_assign (def))
1742 return NULL_TREE;
1743
1744 code = gimple_assign_rhs_code (def);
1745 op1 = gimple_assign_rhs1 (def);
1746 op2 = NULL_TREE;
1747
1748 /* Get for EQ_EXPR or BIT_XOR_EXPR operation the second operand.
8f4a7578 1749 If CODE isn't an EQ_EXPR, BIT_XOR_EXPR, or BIT_NOT_EXPR, then return. */
41913fa9 1750 if (code == EQ_EXPR || code == NE_EXPR
1751 || code == BIT_XOR_EXPR)
1752 op2 = gimple_assign_rhs2 (def);
1753
1754 switch (code)
1755 {
41913fa9 1756 case BIT_NOT_EXPR:
1757 if (truth_valued_ssa_name (name))
1758 return op1;
1759 break;
1760 case EQ_EXPR:
1761 /* Check if we have X == 0 and X has an integral type. */
1762 if (!INTEGRAL_TYPE_P (TREE_TYPE (op1)))
1763 break;
1764 if (integer_zerop (op2))
1765 return op1;
1766 break;
1767 case NE_EXPR:
1768 /* Check if we have X != 1 and X is a truth-valued. */
1769 if (!INTEGRAL_TYPE_P (TREE_TYPE (op1)))
1770 break;
1771 if (integer_onep (op2) && truth_valued_ssa_name (op1))
1772 return op1;
1773 break;
1774 case BIT_XOR_EXPR:
1775 /* Check if we have X ^ 1 and X is truth valued. */
1776 if (integer_onep (op2) && truth_valued_ssa_name (op1))
1777 return op1;
1778 break;
1779 default:
1780 break;
1781 }
1782
1783 return NULL_TREE;
1784}
1785
1786/* Optimize ARG1 CODE ARG2 to a constant for bitwise binary
1787 operations CODE, if one operand has the logically inverted
1788 value of the other. */
1789static tree
1790simplify_bitwise_binary_1 (enum tree_code code, tree type,
1791 tree arg1, tree arg2)
1792{
1793 tree anot;
1794
1795 /* If CODE isn't a bitwise binary operation, return NULL_TREE. */
1796 if (code != BIT_AND_EXPR && code != BIT_IOR_EXPR
1797 && code != BIT_XOR_EXPR)
1798 return NULL_TREE;
1799
1800 /* First check if operands ARG1 and ARG2 are equal. If so
1801 return NULL_TREE as this optimization is handled fold_stmt. */
1802 if (arg1 == arg2)
1803 return NULL_TREE;
1804 /* See if we have in arguments logical-not patterns. */
1805 if (((anot = lookup_logical_inverted_value (arg1)) == NULL_TREE
1806 || anot != arg2)
1807 && ((anot = lookup_logical_inverted_value (arg2)) == NULL_TREE
1808 || anot != arg1))
1809 return NULL_TREE;
1810
1811 /* X & !X -> 0. */
1812 if (code == BIT_AND_EXPR)
1813 return fold_convert (type, integer_zero_node);
1814 /* X | !X -> 1 and X ^ !X -> 1, if X is truth-valued. */
1815 if (truth_valued_ssa_name (anot))
1816 return fold_convert (type, integer_one_node);
1817
1818 /* ??? Otherwise result is (X != 0 ? X : 1). not handled. */
1819 return NULL_TREE;
1820}
1821
10fbe63d 1822/* Given a ssa_name in NAME see if it was defined by an assignment and
1823 set CODE to be the code and ARG1 to the first operand on the rhs and ARG2
1824 to the second operand on the rhs. */
1825
1826static inline void
1827defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
1828{
1829 gimple def;
1830 enum tree_code code1;
1831 tree arg11;
1832 tree arg21;
1833 tree arg31;
1834 enum gimple_rhs_class grhs_class;
1835
1836 code1 = TREE_CODE (name);
1837 arg11 = name;
1838 arg21 = NULL_TREE;
1839 grhs_class = get_gimple_rhs_class (code1);
1840
1841 if (code1 == SSA_NAME)
1842 {
1843 def = SSA_NAME_DEF_STMT (name);
1844
1845 if (def && is_gimple_assign (def)
1846 && can_propagate_from (def))
1847 {
1848 code1 = gimple_assign_rhs_code (def);
1849 arg11 = gimple_assign_rhs1 (def);
1850 arg21 = gimple_assign_rhs2 (def);
1851 arg31 = gimple_assign_rhs2 (def);
1852 }
1853 }
1854 else if (grhs_class == GIMPLE_TERNARY_RHS
1855 || GIMPLE_BINARY_RHS
1856 || GIMPLE_UNARY_RHS
1857 || GIMPLE_SINGLE_RHS)
1858 extract_ops_from_tree_1 (name, &code1, &arg11, &arg21, &arg31);
1859
1860 *code = code1;
1861 *arg1 = arg11;
1862 if (arg2)
1863 *arg2 = arg21;
1864 /* Ignore arg3 currently. */
1865}
1866
750e47f5 1867/* Return true if a conversion of an operand from type FROM to type TO
1868 should be applied after performing the operation instead. */
1869
1870static bool
1871hoist_conversion_for_bitop_p (tree to, tree from)
1872{
1873 /* That's a good idea if the conversion widens the operand, thus
1874 after hoisting the conversion the operation will be narrower. */
1875 if (TYPE_PRECISION (from) < TYPE_PRECISION (to))
1876 return true;
1877
1878 /* It's also a good idea if the conversion is to a non-integer mode. */
1879 if (GET_MODE_CLASS (TYPE_MODE (to)) != MODE_INT)
1880 return true;
1881
1882 /* Or if the precision of TO is not the same as the precision
1883 of its mode. */
1884 if (TYPE_PRECISION (to) != GET_MODE_PRECISION (TYPE_MODE (to)))
1885 return true;
1886
1887 return false;
1888}
1889
16bc66ec 1890/* GSI points to a statement of the form
1891
1892 result = OP0 CODE OP1
1893
1894 Where OP0 and OP1 are single bit SSA_NAMEs and CODE is either
1895 BIT_AND_EXPR or BIT_IOR_EXPR.
1896
1897 If OP0 is fed by a bitwise negation of another single bit SSA_NAME,
1898 then we can simplify the two statements into a single LT_EXPR or LE_EXPR
1899 when code is BIT_AND_EXPR and BIT_IOR_EXPR respectively.
1900
040f64e5 1901 If a simplification is made, return TRUE, else return FALSE. */
16bc66ec 1902static bool
1903simplify_bitwise_binary_boolean (gimple_stmt_iterator *gsi,
1904 enum tree_code code,
1905 tree op0, tree op1)
1906{
1907 gimple op0_def_stmt = SSA_NAME_DEF_STMT (op0);
1908
1909 if (!is_gimple_assign (op0_def_stmt)
1910 || (gimple_assign_rhs_code (op0_def_stmt) != BIT_NOT_EXPR))
1911 return false;
1912
1913 tree x = gimple_assign_rhs1 (op0_def_stmt);
1914 if (TREE_CODE (x) == SSA_NAME
1915 && INTEGRAL_TYPE_P (TREE_TYPE (x))
1916 && TYPE_PRECISION (TREE_TYPE (x)) == 1
1917 && TYPE_UNSIGNED (TREE_TYPE (x)) == TYPE_UNSIGNED (TREE_TYPE (op1)))
1918 {
1919 enum tree_code newcode;
1920
1921 gimple stmt = gsi_stmt (*gsi);
1922 gimple_assign_set_rhs1 (stmt, x);
1923 gimple_assign_set_rhs2 (stmt, op1);
1924 if (code == BIT_AND_EXPR)
1925 newcode = TYPE_UNSIGNED (TREE_TYPE (x)) ? LT_EXPR : GT_EXPR;
1926 else
1927 newcode = TYPE_UNSIGNED (TREE_TYPE (x)) ? LE_EXPR : GE_EXPR;
1928 gimple_assign_set_rhs_code (stmt, newcode);
1929 update_stmt (stmt);
1930 return true;
1931 }
1932 return false;
1933
1934}
1935
300da094 1936/* Simplify bitwise binary operations.
1937 Return true if a transformation applied, otherwise return false. */
1c4607fd 1938
300da094 1939static bool
1940simplify_bitwise_binary (gimple_stmt_iterator *gsi)
1c4607fd 1941{
300da094 1942 gimple stmt = gsi_stmt (*gsi);
1c4607fd 1943 tree arg1 = gimple_assign_rhs1 (stmt);
1944 tree arg2 = gimple_assign_rhs2 (stmt);
300da094 1945 enum tree_code code = gimple_assign_rhs_code (stmt);
1946 tree res;
10fbe63d 1947 tree def1_arg1, def1_arg2, def2_arg1, def2_arg2;
26f54bd0 1948 enum tree_code def1_code, def2_code;
1c4607fd 1949
10fbe63d 1950 defcodefor_name (arg1, &def1_code, &def1_arg1, &def1_arg2);
1951 defcodefor_name (arg2, &def2_code, &def2_arg1, &def2_arg2);
26f54bd0 1952
750e47f5 1953 /* Try to fold (type) X op CST -> (type) (X op ((type-x) CST))
1954 when profitable. */
25ce0d90 1955 if (TREE_CODE (arg2) == INTEGER_CST
1956 && CONVERT_EXPR_CODE_P (def1_code)
750e47f5 1957 && hoist_conversion_for_bitop_p (TREE_TYPE (arg1), TREE_TYPE (def1_arg1))
105fc895 1958 && INTEGRAL_TYPE_P (TREE_TYPE (def1_arg1))
25ce0d90 1959 && int_fits_type_p (arg2, TREE_TYPE (def1_arg1)))
1960 {
1961 gimple newop;
03d37e4e 1962 tree tem = make_ssa_name (TREE_TYPE (def1_arg1), NULL);
25ce0d90 1963 newop =
1964 gimple_build_assign_with_ops (code, tem, def1_arg1,
1965 fold_convert_loc (gimple_location (stmt),
1966 TREE_TYPE (def1_arg1),
1967 arg2));
4b5f1658 1968 gimple_set_location (newop, gimple_location (stmt));
25ce0d90 1969 gsi_insert_before (gsi, newop, GSI_SAME_STMT);
1970 gimple_assign_set_rhs_with_ops_1 (gsi, NOP_EXPR,
1971 tem, NULL_TREE, NULL_TREE);
1972 update_stmt (gsi_stmt (*gsi));
1973 return true;
1974 }
1975
300da094 1976 /* For bitwise binary operations apply operand conversions to the
1977 binary operation result instead of to the operands. This allows
1978 to combine successive conversions and bitwise binary operations. */
26f54bd0 1979 if (CONVERT_EXPR_CODE_P (def1_code)
1980 && CONVERT_EXPR_CODE_P (def2_code)
1981 && types_compatible_p (TREE_TYPE (def1_arg1), TREE_TYPE (def2_arg1))
750e47f5 1982 && hoist_conversion_for_bitop_p (TREE_TYPE (arg1), TREE_TYPE (def1_arg1)))
1c4607fd 1983 {
26f54bd0 1984 gimple newop;
03d37e4e 1985 tree tem = make_ssa_name (TREE_TYPE (def1_arg1), NULL);
26f54bd0 1986 newop = gimple_build_assign_with_ops (code, tem, def1_arg1, def2_arg1);
4b5f1658 1987 gimple_set_location (newop, gimple_location (stmt));
26f54bd0 1988 gsi_insert_before (gsi, newop, GSI_SAME_STMT);
1989 gimple_assign_set_rhs_with_ops_1 (gsi, NOP_EXPR,
1990 tem, NULL_TREE, NULL_TREE);
1991 update_stmt (gsi_stmt (*gsi));
1992 return true;
1993 }
1994
35967c0f 1995
1996 /* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */
1997 if (def1_code == def2_code
1998 && def1_code == BIT_AND_EXPR
0a3f7203 1999 && operand_equal_for_phi_arg_p (def1_arg2,
2000 def2_arg2))
35967c0f 2001 {
0a3f7203 2002 tree b = def1_arg2;
35967c0f 2003 tree a = def1_arg1;
2004 tree c = def2_arg1;
2005 tree inner = fold_build2 (code, TREE_TYPE (arg2), a, c);
2006 /* If A OP0 C (this usually means C is the same as A) is 0
2007 then fold it down correctly. */
2008 if (integer_zerop (inner))
2009 {
2010 gimple_assign_set_rhs_from_tree (gsi, inner);
2011 update_stmt (stmt);
2012 return true;
2013 }
2014 /* If A OP0 C (this usually means C is the same as A) is a ssa_name
2015 then fold it down correctly. */
2016 else if (TREE_CODE (inner) == SSA_NAME)
2017 {
2018 tree outer = fold_build2 (def1_code, TREE_TYPE (inner),
2019 inner, b);
2020 gimple_assign_set_rhs_from_tree (gsi, outer);
2021 update_stmt (stmt);
2022 return true;
2023 }
2024 else
2025 {
2026 gimple newop;
2027 tree tem;
03d37e4e 2028 tem = make_ssa_name (TREE_TYPE (arg2), NULL);
35967c0f 2029 newop = gimple_build_assign_with_ops (code, tem, a, c);
35967c0f 2030 gimple_set_location (newop, gimple_location (stmt));
2031 /* Make sure to re-process the new stmt as it's walking upwards. */
2032 gsi_insert_before (gsi, newop, GSI_NEW_STMT);
2033 gimple_assign_set_rhs1 (stmt, tem);
2034 gimple_assign_set_rhs2 (stmt, b);
2035 gimple_assign_set_rhs_code (stmt, def1_code);
2036 update_stmt (stmt);
2037 return true;
2038 }
2039 }
2040
26f54bd0 2041 /* (a | CST1) & CST2 -> (a & CST2) | (CST1 & CST2). */
2042 if (code == BIT_AND_EXPR
2043 && def1_code == BIT_IOR_EXPR
2c83a45e 2044 && CONSTANT_CLASS_P (arg2)
2045 && CONSTANT_CLASS_P (def1_arg2))
26f54bd0 2046 {
2047 tree cst = fold_build2 (BIT_AND_EXPR, TREE_TYPE (arg2),
10fbe63d 2048 arg2, def1_arg2);
26f54bd0 2049 tree tem;
2050 gimple newop;
2051 if (integer_zerop (cst))
300da094 2052 {
26f54bd0 2053 gimple_assign_set_rhs1 (stmt, def1_arg1);
2054 update_stmt (stmt);
2055 return true;
300da094 2056 }
03d37e4e 2057 tem = make_ssa_name (TREE_TYPE (arg2), NULL);
26f54bd0 2058 newop = gimple_build_assign_with_ops (BIT_AND_EXPR,
2059 tem, def1_arg1, arg2);
4b5f1658 2060 gimple_set_location (newop, gimple_location (stmt));
26f54bd0 2061 /* Make sure to re-process the new stmt as it's walking upwards. */
2062 gsi_insert_before (gsi, newop, GSI_NEW_STMT);
2063 gimple_assign_set_rhs1 (stmt, tem);
2064 gimple_assign_set_rhs2 (stmt, cst);
2065 gimple_assign_set_rhs_code (stmt, BIT_IOR_EXPR);
2066 update_stmt (stmt);
2067 return true;
2068 }
2069
2070 /* Combine successive equal operations with constants. */
2071 if ((code == BIT_AND_EXPR
2072 || code == BIT_IOR_EXPR
2073 || code == BIT_XOR_EXPR)
2074 && def1_code == code
2c83a45e 2075 && CONSTANT_CLASS_P (arg2)
2076 && CONSTANT_CLASS_P (def1_arg2))
26f54bd0 2077 {
2078 tree cst = fold_build2 (code, TREE_TYPE (arg2),
10fbe63d 2079 arg2, def1_arg2);
26f54bd0 2080 gimple_assign_set_rhs1 (stmt, def1_arg1);
2081 gimple_assign_set_rhs2 (stmt, cst);
2082 update_stmt (stmt);
2083 return true;
1c4607fd 2084 }
300da094 2085
8a5f403f 2086 /* Canonicalize X ^ ~0 to ~X. */
2087 if (code == BIT_XOR_EXPR
8a5f403f 2088 && integer_all_onesp (arg2))
2089 {
2090 gimple_assign_set_rhs_with_ops (gsi, BIT_NOT_EXPR, arg1, NULL_TREE);
2091 gcc_assert (gsi_stmt (*gsi) == stmt);
2092 update_stmt (stmt);
2093 return true;
2094 }
2095
41913fa9 2096 /* Try simple folding for X op !X, and X op X. */
2097 res = simplify_bitwise_binary_1 (code, TREE_TYPE (arg1), arg1, arg2);
2098 if (res != NULL_TREE)
2099 {
2100 gimple_assign_set_rhs_from_tree (gsi, res);
2101 update_stmt (gsi_stmt (*gsi));
2102 return true;
2103 }
2104
10fbe63d 2105 if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR)
2106 {
2107 enum tree_code ocode = code == BIT_AND_EXPR ? BIT_IOR_EXPR : BIT_AND_EXPR;
2108 if (def1_code == ocode)
2109 {
2110 tree x = arg2;
2111 enum tree_code coden;
2112 tree a1, a2;
2113 /* ( X | Y) & X -> X */
2114 /* ( X & Y) | X -> X */
2115 if (x == def1_arg1
2116 || x == def1_arg2)
2117 {
2118 gimple_assign_set_rhs_from_tree (gsi, x);
2119 update_stmt (gsi_stmt (*gsi));
2120 return true;
2121 }
2122
2123 defcodefor_name (def1_arg1, &coden, &a1, &a2);
2124 /* (~X | Y) & X -> X & Y */
2125 /* (~X & Y) | X -> X | Y */
2126 if (coden == BIT_NOT_EXPR && a1 == x)
2127 {
2128 gimple_assign_set_rhs_with_ops (gsi, code,
2129 x, def1_arg2);
2130 gcc_assert (gsi_stmt (*gsi) == stmt);
2131 update_stmt (stmt);
2132 return true;
2133 }
2134 defcodefor_name (def1_arg2, &coden, &a1, &a2);
2135 /* (Y | ~X) & X -> X & Y */
2136 /* (Y & ~X) | X -> X | Y */
2137 if (coden == BIT_NOT_EXPR && a1 == x)
2138 {
2139 gimple_assign_set_rhs_with_ops (gsi, code,
2140 x, def1_arg1);
2141 gcc_assert (gsi_stmt (*gsi) == stmt);
2142 update_stmt (stmt);
2143 return true;
2144 }
2145 }
2146 if (def2_code == ocode)
2147 {
2148 enum tree_code coden;
2149 tree a1;
2150 tree x = arg1;
2151 /* X & ( X | Y) -> X */
2152 /* X | ( X & Y) -> X */
2153 if (x == def2_arg1
2154 || x == def2_arg2)
2155 {
2156 gimple_assign_set_rhs_from_tree (gsi, x);
2157 update_stmt (gsi_stmt (*gsi));
2158 return true;
2159 }
2160 defcodefor_name (def2_arg1, &coden, &a1, NULL);
2161 /* (~X | Y) & X -> X & Y */
2162 /* (~X & Y) | X -> X | Y */
2163 if (coden == BIT_NOT_EXPR && a1 == x)
2164 {
2165 gimple_assign_set_rhs_with_ops (gsi, code,
2166 x, def2_arg2);
2167 gcc_assert (gsi_stmt (*gsi) == stmt);
2168 update_stmt (stmt);
2169 return true;
2170 }
2171 defcodefor_name (def2_arg2, &coden, &a1, NULL);
2172 /* (Y | ~X) & X -> X & Y */
2173 /* (Y & ~X) | X -> X | Y */
2174 if (coden == BIT_NOT_EXPR && a1 == x)
2175 {
2176 gimple_assign_set_rhs_with_ops (gsi, code,
2177 x, def2_arg1);
2178 gcc_assert (gsi_stmt (*gsi) == stmt);
2179 update_stmt (stmt);
2180 return true;
2181 }
2182 }
10fbe63d 2183
16bc66ec 2184 /* If arg1 and arg2 are booleans (or any single bit type)
2185 then try to simplify:
2186
2187 (~X & Y) -> X < Y
2188 (X & ~Y) -> Y < X
2189 (~X | Y) -> X <= Y
2190 (X | ~Y) -> Y <= X
2191
2192 But only do this if our result feeds into a comparison as
2193 this transformation is not always a win, particularly on
2194 targets with and-not instructions. */
2195 if (TREE_CODE (arg1) == SSA_NAME
2196 && TREE_CODE (arg2) == SSA_NAME
2197 && INTEGRAL_TYPE_P (TREE_TYPE (arg1))
2198 && TYPE_PRECISION (TREE_TYPE (arg1)) == 1
2199 && TYPE_PRECISION (TREE_TYPE (arg2)) == 1
2200 && (TYPE_UNSIGNED (TREE_TYPE (arg1))
2201 == TYPE_UNSIGNED (TREE_TYPE (arg2))))
2202 {
2203 use_operand_p use_p;
2204 gimple use_stmt;
2205
2206 if (single_imm_use (gimple_assign_lhs (stmt), &use_p, &use_stmt))
2207 {
2208 if (gimple_code (use_stmt) == GIMPLE_COND
2209 && gimple_cond_lhs (use_stmt) == gimple_assign_lhs (stmt)
2210 && integer_zerop (gimple_cond_rhs (use_stmt))
2211 && gimple_cond_code (use_stmt) == NE_EXPR)
2212 {
2213 if (simplify_bitwise_binary_boolean (gsi, code, arg1, arg2))
2214 return true;
2215 if (simplify_bitwise_binary_boolean (gsi, code, arg2, arg1))
2216 return true;
2217 }
2218 }
2219 }
2220 }
300da094 2221 return false;
1c4607fd 2222}
2223
ca3c9092 2224
3b8827a2 2225/* Recognize rotation patterns. Return true if a transformation
2226 applied, otherwise return false.
2227
2228 We are looking for X with unsigned type T with bitsize B, OP being
2229 +, | or ^, some type T2 wider than T and
2230 (X << CNT1) OP (X >> CNT2) iff CNT1 + CNT2 == B
2231 ((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2)) iff CNT1 + CNT2 == B
2232 (X << Y) OP (X >> (B - Y))
2233 (X << (int) Y) OP (X >> (int) (B - Y))
2234 ((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y)))
2235 ((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) (B - Y)))
043ce677 2236 (X << Y) | (X >> ((-Y) & (B - 1)))
2237 (X << (int) Y) | (X >> (int) ((-Y) & (B - 1)))
2238 ((T) ((T2) X << Y)) | ((T) ((T2) X >> ((-Y) & (B - 1))))
2239 ((T) ((T2) X << (int) Y)) | ((T) ((T2) X >> (int) ((-Y) & (B - 1))))
3b8827a2 2240
2241 and transform these into:
2242 X r<< CNT1
2243 X r<< Y
2244
2245 Note, in the patterns with T2 type, the type of OP operands
2246 might be even a signed type, but should have precision B. */
2247
2248static bool
2249simplify_rotate (gimple_stmt_iterator *gsi)
2250{
2251 gimple stmt = gsi_stmt (*gsi);
2252 tree arg[2], rtype, rotcnt = NULL_TREE;
2253 tree def_arg1[2], def_arg2[2];
2254 enum tree_code def_code[2];
2255 tree lhs;
2256 int i;
2257 bool swapped_p = false;
2258 gimple g;
2259
2260 arg[0] = gimple_assign_rhs1 (stmt);
2261 arg[1] = gimple_assign_rhs2 (stmt);
2262 rtype = TREE_TYPE (arg[0]);
2263
2264 /* Only create rotates in complete modes. Other cases are not
2265 expanded properly. */
2266 if (!INTEGRAL_TYPE_P (rtype)
2267 || TYPE_PRECISION (rtype) != GET_MODE_PRECISION (TYPE_MODE (rtype)))
2268 return false;
2269
2270 for (i = 0; i < 2; i++)
2271 defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
2272
2273 /* Look through narrowing conversions. */
2274 if (CONVERT_EXPR_CODE_P (def_code[0])
2275 && CONVERT_EXPR_CODE_P (def_code[1])
2276 && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[0]))
2277 && INTEGRAL_TYPE_P (TREE_TYPE (def_arg1[1]))
2278 && TYPE_PRECISION (TREE_TYPE (def_arg1[0]))
2279 == TYPE_PRECISION (TREE_TYPE (def_arg1[1]))
2280 && TYPE_PRECISION (TREE_TYPE (def_arg1[0])) > TYPE_PRECISION (rtype)
2281 && has_single_use (arg[0])
2282 && has_single_use (arg[1]))
2283 {
2284 for (i = 0; i < 2; i++)
2285 {
2286 arg[i] = def_arg1[i];
2287 defcodefor_name (arg[i], &def_code[i], &def_arg1[i], &def_arg2[i]);
2288 }
2289 }
2290
2291 /* One operand has to be LSHIFT_EXPR and one RSHIFT_EXPR. */
2292 for (i = 0; i < 2; i++)
2293 if (def_code[i] != LSHIFT_EXPR && def_code[i] != RSHIFT_EXPR)
2294 return false;
2295 else if (!has_single_use (arg[i]))
2296 return false;
2297 if (def_code[0] == def_code[1])
2298 return false;
2299
2300 /* If we've looked through narrowing conversions before, look through
2301 widening conversions from unsigned type with the same precision
2302 as rtype here. */
2303 if (TYPE_PRECISION (TREE_TYPE (def_arg1[0])) != TYPE_PRECISION (rtype))
2304 for (i = 0; i < 2; i++)
2305 {
2306 tree tem;
2307 enum tree_code code;
2308 defcodefor_name (def_arg1[i], &code, &tem, NULL);
2309 if (!CONVERT_EXPR_CODE_P (code)
2310 || !INTEGRAL_TYPE_P (TREE_TYPE (tem))
2311 || TYPE_PRECISION (TREE_TYPE (tem)) != TYPE_PRECISION (rtype))
2312 return false;
2313 def_arg1[i] = tem;
2314 }
2315 /* Both shifts have to use the same first operand. */
2316 if (TREE_CODE (def_arg1[0]) != SSA_NAME || def_arg1[0] != def_arg1[1])
2317 return false;
2318 if (!TYPE_UNSIGNED (TREE_TYPE (def_arg1[0])))
2319 return false;
2320
2321 /* CNT1 + CNT2 == B case above. */
e913b5cd 2322 if (tree_fits_uhwi_p (def_arg2[0])
2323 && tree_fits_uhwi_p (def_arg2[1])
aa59f000 2324 && tree_to_uhwi (def_arg2[0])
e913b5cd 2325 + tree_to_uhwi (def_arg2[1]) == TYPE_PRECISION (rtype))
3b8827a2 2326 rotcnt = def_arg2[0];
2327 else if (TREE_CODE (def_arg2[0]) != SSA_NAME
2328 || TREE_CODE (def_arg2[1]) != SSA_NAME)
2329 return false;
2330 else
2331 {
2332 tree cdef_arg1[2], cdef_arg2[2], def_arg2_alt[2];
2333 enum tree_code cdef_code[2];
2334 /* Look through conversion of the shift count argument.
2335 The C/C++ FE cast any shift count argument to integer_type_node.
2336 The only problem might be if the shift count type maximum value
2337 is equal or smaller than number of bits in rtype. */
2338 for (i = 0; i < 2; i++)
2339 {
2340 def_arg2_alt[i] = def_arg2[i];
2341 defcodefor_name (def_arg2[i], &cdef_code[i],
2342 &cdef_arg1[i], &cdef_arg2[i]);
2343 if (CONVERT_EXPR_CODE_P (cdef_code[i])
2344 && INTEGRAL_TYPE_P (TREE_TYPE (cdef_arg1[i]))
2345 && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
2346 > floor_log2 (TYPE_PRECISION (rtype))
2347 && TYPE_PRECISION (TREE_TYPE (cdef_arg1[i]))
2348 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (cdef_arg1[i]))))
2349 {
2350 def_arg2_alt[i] = cdef_arg1[i];
2351 defcodefor_name (def_arg2_alt[i], &cdef_code[i],
2352 &cdef_arg1[i], &cdef_arg2[i]);
2353 }
2354 }
2355 for (i = 0; i < 2; i++)
2356 /* Check for one shift count being Y and the other B - Y,
2357 with optional casts. */
2358 if (cdef_code[i] == MINUS_EXPR
e913b5cd 2359 && tree_fits_shwi_p (cdef_arg1[i])
2360 && tree_to_shwi (cdef_arg1[i]) == TYPE_PRECISION (rtype)
3b8827a2 2361 && TREE_CODE (cdef_arg2[i]) == SSA_NAME)
2362 {
2363 tree tem;
2364 enum tree_code code;
2365
2366 if (cdef_arg2[i] == def_arg2[1 - i]
2367 || cdef_arg2[i] == def_arg2_alt[1 - i])
2368 {
2369 rotcnt = cdef_arg2[i];
2370 break;
2371 }
2372 defcodefor_name (cdef_arg2[i], &code, &tem, NULL);
2373 if (CONVERT_EXPR_CODE_P (code)
2374 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
2375 && TYPE_PRECISION (TREE_TYPE (tem))
2376 > floor_log2 (TYPE_PRECISION (rtype))
2377 && TYPE_PRECISION (TREE_TYPE (tem))
2378 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
2379 && (tem == def_arg2[1 - i]
2380 || tem == def_arg2_alt[1 - i]))
2381 {
2382 rotcnt = tem;
2383 break;
2384 }
2385 }
2386 /* The above sequence isn't safe for Y being 0,
2387 because then one of the shifts triggers undefined behavior.
2388 This alternative is safe even for rotation count of 0.
2389 One shift count is Y and the other (-Y) & (B - 1). */
2390 else if (cdef_code[i] == BIT_AND_EXPR
e913b5cd 2391 && tree_fits_shwi_p (cdef_arg2[i])
2392 && tree_to_shwi (cdef_arg2[i])
3b8827a2 2393 == TYPE_PRECISION (rtype) - 1
043ce677 2394 && TREE_CODE (cdef_arg1[i]) == SSA_NAME
2395 && gimple_assign_rhs_code (stmt) == BIT_IOR_EXPR)
3b8827a2 2396 {
2397 tree tem;
2398 enum tree_code code;
2399
2400 defcodefor_name (cdef_arg1[i], &code, &tem, NULL);
2401 if (CONVERT_EXPR_CODE_P (code)
2402 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
2403 && TYPE_PRECISION (TREE_TYPE (tem))
2404 > floor_log2 (TYPE_PRECISION (rtype))
2405 && TYPE_PRECISION (TREE_TYPE (tem))
2406 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem))))
2407 defcodefor_name (tem, &code, &tem, NULL);
2408
2409 if (code == NEGATE_EXPR)
2410 {
2411 if (tem == def_arg2[1 - i] || tem == def_arg2_alt[1 - i])
2412 {
2413 rotcnt = tem;
2414 break;
2415 }
2416 defcodefor_name (tem, &code, &tem, NULL);
2417 if (CONVERT_EXPR_CODE_P (code)
2418 && INTEGRAL_TYPE_P (TREE_TYPE (tem))
2419 && TYPE_PRECISION (TREE_TYPE (tem))
2420 > floor_log2 (TYPE_PRECISION (rtype))
2421 && TYPE_PRECISION (TREE_TYPE (tem))
2422 == GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (tem)))
2423 && (tem == def_arg2[1 - i]
2424 || tem == def_arg2_alt[1 - i]))
2425 {
2426 rotcnt = tem;
2427 break;
2428 }
2429 }
2430 }
2431 if (rotcnt == NULL_TREE)
2432 return false;
2433 swapped_p = i != 1;
2434 }
2435
2436 if (!useless_type_conversion_p (TREE_TYPE (def_arg2[0]),
2437 TREE_TYPE (rotcnt)))
2438 {
2439 g = gimple_build_assign_with_ops (NOP_EXPR,
2440 make_ssa_name (TREE_TYPE (def_arg2[0]),
2441 NULL),
2442 rotcnt, NULL_TREE);
2443 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2444 rotcnt = gimple_assign_lhs (g);
2445 }
2446 lhs = gimple_assign_lhs (stmt);
2447 if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
2448 lhs = make_ssa_name (TREE_TYPE (def_arg1[0]), NULL);
2449 g = gimple_build_assign_with_ops (((def_code[0] == LSHIFT_EXPR) ^ swapped_p)
2450 ? LROTATE_EXPR : RROTATE_EXPR,
2451 lhs, def_arg1[0], rotcnt);
2452 if (!useless_type_conversion_p (rtype, TREE_TYPE (def_arg1[0])))
2453 {
2454 gsi_insert_before (gsi, g, GSI_SAME_STMT);
2455 g = gimple_build_assign_with_ops (NOP_EXPR, gimple_assign_lhs (stmt),
2456 lhs, NULL_TREE);
2457 }
2458 gsi_replace (gsi, g, false);
2459 return true;
2460}
2461
ca3c9092 2462/* Perform re-associations of the plus or minus statement STMT that are
b69d1cb6 2463 always permitted. Returns true if the CFG was changed. */
ca3c9092 2464
b69d1cb6 2465static bool
50aacf4c 2466associate_plusminus (gimple_stmt_iterator *gsi)
ca3c9092 2467{
50aacf4c 2468 gimple stmt = gsi_stmt (*gsi);
ca3c9092 2469 tree rhs1 = gimple_assign_rhs1 (stmt);
2470 tree rhs2 = gimple_assign_rhs2 (stmt);
2471 enum tree_code code = gimple_assign_rhs_code (stmt);
ca3c9092 2472 bool changed;
2473
2474 /* We can't reassociate at all for saturating types. */
2475 if (TYPE_SATURATING (TREE_TYPE (rhs1)))
b69d1cb6 2476 return false;
ca3c9092 2477
2478 /* First contract negates. */
2479 do
2480 {
2481 changed = false;
2482
2483 /* A +- (-B) -> A -+ B. */
2484 if (TREE_CODE (rhs2) == SSA_NAME)
2485 {
2486 gimple def_stmt = SSA_NAME_DEF_STMT (rhs2);
2487 if (is_gimple_assign (def_stmt)
32cdcc42 2488 && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR
2489 && can_propagate_from (def_stmt))
ca3c9092 2490 {
2491 code = (code == MINUS_EXPR) ? PLUS_EXPR : MINUS_EXPR;
2492 gimple_assign_set_rhs_code (stmt, code);
2493 rhs2 = gimple_assign_rhs1 (def_stmt);
2494 gimple_assign_set_rhs2 (stmt, rhs2);
2495 gimple_set_modified (stmt, true);
2496 changed = true;
2497 }
2498 }
2499
2500 /* (-A) + B -> B - A. */
2501 if (TREE_CODE (rhs1) == SSA_NAME
2502 && code == PLUS_EXPR)
2503 {
2504 gimple def_stmt = SSA_NAME_DEF_STMT (rhs1);
2505 if (is_gimple_assign (def_stmt)
32cdcc42 2506 && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR
2507 && can_propagate_from (def_stmt))
ca3c9092 2508 {
2509 code = MINUS_EXPR;
2510 gimple_assign_set_rhs_code (stmt, code);
2511 rhs1 = rhs2;
2512 gimple_assign_set_rhs1 (stmt, rhs1);
2513 rhs2 = gimple_assign_rhs1 (def_stmt);
2514 gimple_assign_set_rhs2 (stmt, rhs2);
2515 gimple_set_modified (stmt, true);
2516 changed = true;
2517 }
2518 }
2519 }
2520 while (changed);
2521
2522 /* We can't reassociate floating-point or fixed-point plus or minus
2523 because of saturation to +-Inf. */
2524 if (FLOAT_TYPE_P (TREE_TYPE (rhs1))
2525 || FIXED_POINT_TYPE_P (TREE_TYPE (rhs1)))
2526 goto out;
2527
2528 /* Second match patterns that allow contracting a plus-minus pair
2529 irrespective of overflow issues.
2530
2531 (A +- B) - A -> +- B
2532 (A +- B) -+ B -> A
2533 (CST +- A) +- CST -> CST +- A
2c83a45e 2534 (A +- CST) +- CST -> A +- CST
ca3c9092 2535 ~A + A -> -1
2536 ~A + 1 -> -A
2537 A - (A +- B) -> -+ B
2538 A +- (B +- A) -> +- B
2539 CST +- (CST +- A) -> CST +- A
2540 CST +- (A +- CST) -> CST +- A
2541 A + ~A -> -1
c223850c 2542 (T)(P + A) - (T)P -> (T)A
ca3c9092 2543
2544 via commutating the addition and contracting operations to zero
2545 by reassociation. */
2546
ca3c9092 2547 if (TREE_CODE (rhs1) == SSA_NAME)
2548 {
2549 gimple def_stmt = SSA_NAME_DEF_STMT (rhs1);
32cdcc42 2550 if (is_gimple_assign (def_stmt) && can_propagate_from (def_stmt))
ca3c9092 2551 {
2552 enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
2553 if (def_code == PLUS_EXPR
2554 || def_code == MINUS_EXPR)
2555 {
2556 tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
2557 tree def_rhs2 = gimple_assign_rhs2 (def_stmt);
2558 if (operand_equal_p (def_rhs1, rhs2, 0)
2559 && code == MINUS_EXPR)
2560 {
2561 /* (A +- B) - A -> +- B. */
2562 code = ((def_code == PLUS_EXPR)
2563 ? TREE_CODE (def_rhs2) : NEGATE_EXPR);
2564 rhs1 = def_rhs2;
2565 rhs2 = NULL_TREE;
50aacf4c 2566 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
2567 gcc_assert (gsi_stmt (*gsi) == stmt);
ca3c9092 2568 gimple_set_modified (stmt, true);
2569 }
2570 else if (operand_equal_p (def_rhs2, rhs2, 0)
2571 && code != def_code)
2572 {
2573 /* (A +- B) -+ B -> A. */
2574 code = TREE_CODE (def_rhs1);
2575 rhs1 = def_rhs1;
2576 rhs2 = NULL_TREE;
50aacf4c 2577 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
2578 gcc_assert (gsi_stmt (*gsi) == stmt);
ca3c9092 2579 gimple_set_modified (stmt, true);
2580 }
2c83a45e 2581 else if (CONSTANT_CLASS_P (rhs2)
2582 && CONSTANT_CLASS_P (def_rhs1))
ca3c9092 2583 {
2584 /* (CST +- A) +- CST -> CST +- A. */
2585 tree cst = fold_binary (code, TREE_TYPE (rhs1),
2586 def_rhs1, rhs2);
2587 if (cst && !TREE_OVERFLOW (cst))
2588 {
2589 code = def_code;
2590 gimple_assign_set_rhs_code (stmt, code);
2591 rhs1 = cst;
2592 gimple_assign_set_rhs1 (stmt, rhs1);
2593 rhs2 = def_rhs2;
2594 gimple_assign_set_rhs2 (stmt, rhs2);
2595 gimple_set_modified (stmt, true);
2596 }
2597 }
2c83a45e 2598 else if (CONSTANT_CLASS_P (rhs2)
2599 && CONSTANT_CLASS_P (def_rhs2))
ca3c9092 2600 {
2c83a45e 2601 /* (A +- CST) +- CST -> A +- CST. */
2602 enum tree_code mix = (code == def_code)
2603 ? PLUS_EXPR : MINUS_EXPR;
2604 tree cst = fold_binary (mix, TREE_TYPE (rhs1),
ca3c9092 2605 def_rhs2, rhs2);
2606 if (cst && !TREE_OVERFLOW (cst))
2607 {
2c83a45e 2608 code = def_code;
ca3c9092 2609 gimple_assign_set_rhs_code (stmt, code);
2610 rhs1 = def_rhs1;
2611 gimple_assign_set_rhs1 (stmt, rhs1);
2612 rhs2 = cst;
2613 gimple_assign_set_rhs2 (stmt, rhs2);
2614 gimple_set_modified (stmt, true);
2615 }
2616 }
2617 }
2c83a45e 2618 else if (def_code == BIT_NOT_EXPR && code == PLUS_EXPR)
ca3c9092 2619 {
2620 tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
2c83a45e 2621 if (operand_equal_p (def_rhs1, rhs2, 0))
ca3c9092 2622 {
2623 /* ~A + A -> -1. */
2c83a45e 2624 rhs1 = build_all_ones_cst (TREE_TYPE (rhs2));
ca3c9092 2625 rhs2 = NULL_TREE;
2c83a45e 2626 code = TREE_CODE (rhs1);
50aacf4c 2627 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
2628 gcc_assert (gsi_stmt (*gsi) == stmt);
ca3c9092 2629 gimple_set_modified (stmt, true);
2630 }
2c83a45e 2631 else if ((TREE_CODE (TREE_TYPE (rhs2)) != COMPLEX_TYPE
2632 && integer_onep (rhs2))
2633 || (TREE_CODE (rhs2) == COMPLEX_CST
2634 && integer_onep (TREE_REALPART (rhs2))
2635 && integer_onep (TREE_IMAGPART (rhs2))))
ca3c9092 2636 {
2637 /* ~A + 1 -> -A. */
2638 code = NEGATE_EXPR;
2639 rhs1 = def_rhs1;
2640 rhs2 = NULL_TREE;
50aacf4c 2641 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
2642 gcc_assert (gsi_stmt (*gsi) == stmt);
ca3c9092 2643 gimple_set_modified (stmt, true);
2644 }
2645 }
f0365515 2646 else if (code == MINUS_EXPR
2647 && CONVERT_EXPR_CODE_P (def_code)
2648 && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
c223850c 2649 && TREE_CODE (rhs2) == SSA_NAME)
2650 {
f0365515 2651 /* (T)(P + A) - (T)P -> (T)A. */
c223850c 2652 gimple def_stmt2 = SSA_NAME_DEF_STMT (rhs2);
f0365515 2653 if (is_gimple_assign (def_stmt2)
c223850c 2654 && can_propagate_from (def_stmt2)
2655 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt2))
2656 && TREE_CODE (gimple_assign_rhs1 (def_stmt2)) == SSA_NAME)
2657 {
f0365515 2658 /* Now we have (T)X - (T)P. */
2659 tree p = gimple_assign_rhs1 (def_stmt2);
c223850c 2660 def_stmt2 = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
2661 if (is_gimple_assign (def_stmt2)
f0365515 2662 && can_propagate_from (def_stmt2)
2663 && (gimple_assign_rhs_code (def_stmt2) == POINTER_PLUS_EXPR
2664 || gimple_assign_rhs_code (def_stmt2) == PLUS_EXPR)
2665 && gimple_assign_rhs1 (def_stmt2) == p)
c223850c 2666 {
f0365515 2667 /* And finally (T)(P + A) - (T)P. */
2668 tree a = gimple_assign_rhs2 (def_stmt2);
2669 /* For pointer types, if the conversion of A to the final
2670 type requires a sign- or zero-extension, then we have
2671 to punt - it is not defined which one is correct. */
2672 if (!POINTER_TYPE_P (TREE_TYPE (rhs1))
2673 || TYPE_PRECISION (TREE_TYPE (rhs1))
2674 <= TYPE_PRECISION (TREE_TYPE (a))
2675 || (TREE_CODE (a) == INTEGER_CST
2676 && tree_int_cst_sign_bit (a) == 0))
c223850c 2677 {
2678 if (useless_type_conversion_p (TREE_TYPE (rhs1),
f0365515 2679 TREE_TYPE (a)))
2680 code = TREE_CODE (a);
c223850c 2681 else
f0365515 2682 code = NOP_EXPR;
2683 rhs1 = a;
c223850c 2684 rhs2 = NULL_TREE;
2685 gimple_assign_set_rhs_with_ops (gsi, code, rhs1,
f0365515 2686 rhs2);
c223850c 2687 gcc_assert (gsi_stmt (*gsi) == stmt);
2688 gimple_set_modified (stmt, true);
2689 }
2690 }
2691 }
2692 }
ca3c9092 2693 }
2694 }
2695
2696 if (rhs2 && TREE_CODE (rhs2) == SSA_NAME)
2697 {
2698 gimple def_stmt = SSA_NAME_DEF_STMT (rhs2);
32cdcc42 2699 if (is_gimple_assign (def_stmt) && can_propagate_from (def_stmt))
ca3c9092 2700 {
2701 enum tree_code def_code = gimple_assign_rhs_code (def_stmt);
2702 if (def_code == PLUS_EXPR
2703 || def_code == MINUS_EXPR)
2704 {
2705 tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
2706 tree def_rhs2 = gimple_assign_rhs2 (def_stmt);
2707 if (operand_equal_p (def_rhs1, rhs1, 0)
2708 && code == MINUS_EXPR)
2709 {
2710 /* A - (A +- B) -> -+ B. */
2711 code = ((def_code == PLUS_EXPR)
2712 ? NEGATE_EXPR : TREE_CODE (def_rhs2));
2713 rhs1 = def_rhs2;
2714 rhs2 = NULL_TREE;
50aacf4c 2715 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
2716 gcc_assert (gsi_stmt (*gsi) == stmt);
ca3c9092 2717 gimple_set_modified (stmt, true);
2718 }
2719 else if (operand_equal_p (def_rhs2, rhs1, 0)
2720 && code != def_code)
2721 {
2722 /* A +- (B +- A) -> +- B. */
2723 code = ((code == PLUS_EXPR)
2724 ? TREE_CODE (def_rhs1) : NEGATE_EXPR);
2725 rhs1 = def_rhs1;
2726 rhs2 = NULL_TREE;
50aacf4c 2727 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
2728 gcc_assert (gsi_stmt (*gsi) == stmt);
ca3c9092 2729 gimple_set_modified (stmt, true);
2730 }
2c83a45e 2731 else if (CONSTANT_CLASS_P (rhs1)
2732 && CONSTANT_CLASS_P (def_rhs1))
ca3c9092 2733 {
2734 /* CST +- (CST +- A) -> CST +- A. */
2735 tree cst = fold_binary (code, TREE_TYPE (rhs2),
2736 rhs1, def_rhs1);
2737 if (cst && !TREE_OVERFLOW (cst))
2738 {
2739 code = (code == def_code ? PLUS_EXPR : MINUS_EXPR);
2740 gimple_assign_set_rhs_code (stmt, code);
2741 rhs1 = cst;
2742 gimple_assign_set_rhs1 (stmt, rhs1);
2743 rhs2 = def_rhs2;
2744 gimple_assign_set_rhs2 (stmt, rhs2);
2745 gimple_set_modified (stmt, true);
2746 }
2747 }
2c83a45e 2748 else if (CONSTANT_CLASS_P (rhs1)
2749 && CONSTANT_CLASS_P (def_rhs2))
ca3c9092 2750 {
2751 /* CST +- (A +- CST) -> CST +- A. */
2752 tree cst = fold_binary (def_code == code
2753 ? PLUS_EXPR : MINUS_EXPR,
2754 TREE_TYPE (rhs2),
2755 rhs1, def_rhs2);
2756 if (cst && !TREE_OVERFLOW (cst))
2757 {
2758 rhs1 = cst;
2759 gimple_assign_set_rhs1 (stmt, rhs1);
2760 rhs2 = def_rhs1;
2761 gimple_assign_set_rhs2 (stmt, rhs2);
2762 gimple_set_modified (stmt, true);
2763 }
2764 }
2765 }
2c83a45e 2766 else if (def_code == BIT_NOT_EXPR)
ca3c9092 2767 {
2768 tree def_rhs1 = gimple_assign_rhs1 (def_stmt);
2769 if (code == PLUS_EXPR
2770 && operand_equal_p (def_rhs1, rhs1, 0))
2771 {
2772 /* A + ~A -> -1. */
2c83a45e 2773 rhs1 = build_all_ones_cst (TREE_TYPE (rhs1));
ca3c9092 2774 rhs2 = NULL_TREE;
2c83a45e 2775 code = TREE_CODE (rhs1);
50aacf4c 2776 gimple_assign_set_rhs_with_ops (gsi, code, rhs1, NULL_TREE);
2777 gcc_assert (gsi_stmt (*gsi) == stmt);
ca3c9092 2778 gimple_set_modified (stmt, true);
2779 }
2780 }
2781 }
2782 }
2783
2784out:
2785 if (gimple_modified_p (stmt))
2786 {
50aacf4c 2787 fold_stmt_inplace (gsi);
ca3c9092 2788 update_stmt (stmt);
5a423a75 2789 return true;
ca3c9092 2790 }
b69d1cb6 2791
2792 return false;
ca3c9092 2793}
2794
c9c17332 2795/* Associate operands of a POINTER_PLUS_EXPR assignmen at *GSI. Returns
2796 true if anything changed, false otherwise. */
2797
2798static bool
b904104c 2799associate_pointerplus_align (gimple_stmt_iterator *gsi)
c9c17332 2800{
2801 gimple stmt = gsi_stmt (*gsi);
2802 gimple def_stmt;
2803 tree ptr, rhs, algn;
2804
2805 /* Pattern match
2806 tem = (sizetype) ptr;
2807 tem = tem & algn;
2808 tem = -tem;
2809 ... = ptr p+ tem;
2810 and produce the simpler and easier to analyze with respect to alignment
2811 ... = ptr & ~algn; */
2812 ptr = gimple_assign_rhs1 (stmt);
2813 rhs = gimple_assign_rhs2 (stmt);
2814 if (TREE_CODE (rhs) != SSA_NAME)
2815 return false;
2816 def_stmt = SSA_NAME_DEF_STMT (rhs);
2817 if (!is_gimple_assign (def_stmt)
2818 || gimple_assign_rhs_code (def_stmt) != NEGATE_EXPR)
2819 return false;
2820 rhs = gimple_assign_rhs1 (def_stmt);
2821 if (TREE_CODE (rhs) != SSA_NAME)
2822 return false;
2823 def_stmt = SSA_NAME_DEF_STMT (rhs);
2824 if (!is_gimple_assign (def_stmt)
2825 || gimple_assign_rhs_code (def_stmt) != BIT_AND_EXPR)
2826 return false;
2827 rhs = gimple_assign_rhs1 (def_stmt);
2828 algn = gimple_assign_rhs2 (def_stmt);
2829 if (TREE_CODE (rhs) != SSA_NAME
2830 || TREE_CODE (algn) != INTEGER_CST)
2831 return false;
2832 def_stmt = SSA_NAME_DEF_STMT (rhs);
2833 if (!is_gimple_assign (def_stmt)
2834 || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
2835 return false;
2836 if (gimple_assign_rhs1 (def_stmt) != ptr)
2837 return false;
2838
6da74b21 2839 algn = wide_int_to_tree (TREE_TYPE (ptr), wi::bit_not (algn));
c9c17332 2840 gimple_assign_set_rhs_with_ops (gsi, BIT_AND_EXPR, ptr, algn);
2841 fold_stmt_inplace (gsi);
2842 update_stmt (stmt);
2843
2844 return true;
2845}
2846
b904104c 2847/* Associate operands of a POINTER_PLUS_EXPR assignmen at *GSI. Returns
2848 true if anything changed, false otherwise. */
2849
2850static bool
2851associate_pointerplus_diff (gimple_stmt_iterator *gsi)
2852{
2853 gimple stmt = gsi_stmt (*gsi);
2854 gimple def_stmt;
2855 tree ptr1, rhs;
2856
2857 /* Pattern match
2858 tem1 = (long) ptr1;
2859 tem2 = (long) ptr2;
2860 tem3 = tem2 - tem1;
2861 tem4 = (unsigned long) tem3;
2862 tem5 = ptr1 + tem4;
2863 and produce
2864 tem5 = ptr2; */
2865 ptr1 = gimple_assign_rhs1 (stmt);
2866 rhs = gimple_assign_rhs2 (stmt);
2867 if (TREE_CODE (rhs) != SSA_NAME)
2868 return false;
2869 gimple minus = SSA_NAME_DEF_STMT (rhs);
2870 /* Conditionally look through a sign-changing conversion. */
2871 if (is_gimple_assign (minus)
2872 && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (minus))
2873 && (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (minus)))
2874 == TYPE_PRECISION (TREE_TYPE (rhs)))
2875 && TREE_CODE (gimple_assign_rhs1 (minus)) == SSA_NAME)
2876 minus = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (minus));
2877 if (!is_gimple_assign (minus))
2878 return false;
2879 if (gimple_assign_rhs_code (minus) != MINUS_EXPR)
2880 return false;
2881 rhs = gimple_assign_rhs2 (minus);
2882 if (TREE_CODE (rhs) != SSA_NAME)
2883 return false;
2884 def_stmt = SSA_NAME_DEF_STMT (rhs);
2885 if (!is_gimple_assign (def_stmt)
2886 || ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
2887 || gimple_assign_rhs1 (def_stmt) != ptr1)
2888 return false;
2889 rhs = gimple_assign_rhs1 (minus);
2890 if (TREE_CODE (rhs) != SSA_NAME)
2891 return false;
2892 def_stmt = SSA_NAME_DEF_STMT (rhs);
2893 if (!is_gimple_assign (def_stmt)
2894 || ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
2895 return false;
2896 rhs = gimple_assign_rhs1 (def_stmt);
2897 if (! useless_type_conversion_p (TREE_TYPE (ptr1), TREE_TYPE (rhs)))
2898 return false;
2899
2900 gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (rhs), rhs, NULL_TREE);
2901 update_stmt (stmt);
2902
2903 return true;
2904}
2905
2906/* Associate operands of a POINTER_PLUS_EXPR assignmen at *GSI. Returns
2907 true if anything changed, false otherwise. */
2908
2909static bool
2910associate_pointerplus (gimple_stmt_iterator *gsi)
2911{
2912 gimple stmt = gsi_stmt (*gsi);
2913 gimple def_stmt;
2914 tree ptr, off1, off2;
2915
2916 if (associate_pointerplus_align (gsi)
2917 || associate_pointerplus_diff (gsi))
2918 return true;
2919
2920 /* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */
2921 ptr = gimple_assign_rhs1 (stmt);
2922 off1 = gimple_assign_rhs2 (stmt);
135b982d 2923 if (TREE_CODE (ptr) != SSA_NAME
2924 || !has_single_use (ptr))
b904104c 2925 return false;
2926 def_stmt = SSA_NAME_DEF_STMT (ptr);
2927 if (!is_gimple_assign (def_stmt)
135b982d 2928 || gimple_assign_rhs_code (def_stmt) != POINTER_PLUS_EXPR
2929 || !can_propagate_from (def_stmt))
b904104c 2930 return false;
2931 ptr = gimple_assign_rhs1 (def_stmt);
2932 off2 = gimple_assign_rhs2 (def_stmt);
2933 if (!types_compatible_p (TREE_TYPE (off1), TREE_TYPE (off2)))
2934 return false;
2935
2936 tree off = make_ssa_name (TREE_TYPE (off1), NULL);
2937 gimple ostmt = gimple_build_assign_with_ops (PLUS_EXPR, off, off1, off2);
2938 gsi_insert_before (gsi, ostmt, GSI_SAME_STMT);
2939
2940 gimple_assign_set_rhs_with_ops (gsi, POINTER_PLUS_EXPR, ptr, off);
2941 update_stmt (stmt);
2942
2943 return true;
2944}
2945
6afd0544 2946/* Combine two conversions in a row for the second conversion at *GSI.
89c8f35a 2947 Returns 1 if there were any changes made, 2 if cfg-cleanup needs to
2948 run. Else it returns 0. */
6afd0544 2949
89c8f35a 2950static int
6afd0544 2951combine_conversions (gimple_stmt_iterator *gsi)
2952{
2953 gimple stmt = gsi_stmt (*gsi);
2954 gimple def_stmt;
2955 tree op0, lhs;
2956 enum tree_code code = gimple_assign_rhs_code (stmt);
487282d5 2957 enum tree_code code2;
6afd0544 2958
2959 gcc_checking_assert (CONVERT_EXPR_CODE_P (code)
2960 || code == FLOAT_EXPR
2961 || code == FIX_TRUNC_EXPR);
2962
2963 lhs = gimple_assign_lhs (stmt);
2964 op0 = gimple_assign_rhs1 (stmt);
2965 if (useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0)))
2966 {
2967 gimple_assign_set_rhs_code (stmt, TREE_CODE (op0));
89c8f35a 2968 return 1;
6afd0544 2969 }
2970
2971 if (TREE_CODE (op0) != SSA_NAME)
89c8f35a 2972 return 0;
6afd0544 2973
2974 def_stmt = SSA_NAME_DEF_STMT (op0);
2975 if (!is_gimple_assign (def_stmt))
89c8f35a 2976 return 0;
6afd0544 2977
487282d5 2978 code2 = gimple_assign_rhs_code (def_stmt);
2979
2980 if (CONVERT_EXPR_CODE_P (code2) || code2 == FLOAT_EXPR)
6afd0544 2981 {
2982 tree defop0 = gimple_assign_rhs1 (def_stmt);
2983 tree type = TREE_TYPE (lhs);
2984 tree inside_type = TREE_TYPE (defop0);
2985 tree inter_type = TREE_TYPE (op0);
2986 int inside_int = INTEGRAL_TYPE_P (inside_type);
2987 int inside_ptr = POINTER_TYPE_P (inside_type);
2988 int inside_float = FLOAT_TYPE_P (inside_type);
2989 int inside_vec = TREE_CODE (inside_type) == VECTOR_TYPE;
2990 unsigned int inside_prec = TYPE_PRECISION (inside_type);
2991 int inside_unsignedp = TYPE_UNSIGNED (inside_type);
2992 int inter_int = INTEGRAL_TYPE_P (inter_type);
2993 int inter_ptr = POINTER_TYPE_P (inter_type);
2994 int inter_float = FLOAT_TYPE_P (inter_type);
2995 int inter_vec = TREE_CODE (inter_type) == VECTOR_TYPE;
2996 unsigned int inter_prec = TYPE_PRECISION (inter_type);
2997 int inter_unsignedp = TYPE_UNSIGNED (inter_type);
2998 int final_int = INTEGRAL_TYPE_P (type);
2999 int final_ptr = POINTER_TYPE_P (type);
3000 int final_float = FLOAT_TYPE_P (type);
3001 int final_vec = TREE_CODE (type) == VECTOR_TYPE;
3002 unsigned int final_prec = TYPE_PRECISION (type);
3003 int final_unsignedp = TYPE_UNSIGNED (type);
3004
3aeff048 3005 /* Don't propagate ssa names that occur in abnormal phis. */
3006 if (TREE_CODE (defop0) == SSA_NAME
3007 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (defop0))
3008 return 0;
3009
6afd0544 3010 /* In addition to the cases of two conversions in a row
3011 handled below, if we are converting something to its own
3012 type via an object of identical or wider precision, neither
3013 conversion is needed. */
3014 if (useless_type_conversion_p (type, inside_type)
3015 && (((inter_int || inter_ptr) && final_int)
3016 || (inter_float && final_float))
3017 && inter_prec >= final_prec)
3018 {
3019 gimple_assign_set_rhs1 (stmt, unshare_expr (defop0));
3020 gimple_assign_set_rhs_code (stmt, TREE_CODE (defop0));
3021 update_stmt (stmt);
89c8f35a 3022 return remove_prop_source_from_use (op0) ? 2 : 1;
6afd0544 3023 }
3024
3025 /* Likewise, if the intermediate and initial types are either both
3026 float or both integer, we don't need the middle conversion if the
3027 former is wider than the latter and doesn't change the signedness
3028 (for integers). Avoid this if the final type is a pointer since
3029 then we sometimes need the middle conversion. Likewise if the
3030 final type has a precision not equal to the size of its mode. */
3031 if (((inter_int && inside_int)
3032 || (inter_float && inside_float)
3033 || (inter_vec && inside_vec))
3034 && inter_prec >= inside_prec
3035 && (inter_float || inter_vec
3036 || inter_unsignedp == inside_unsignedp)
51dbf409 3037 && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type))
6afd0544 3038 && TYPE_MODE (type) == TYPE_MODE (inter_type))
3039 && ! final_ptr
3040 && (! final_vec || inter_prec == inside_prec))
3041 {
3042 gimple_assign_set_rhs1 (stmt, defop0);
3043 update_stmt (stmt);
89c8f35a 3044 return remove_prop_source_from_use (op0) ? 2 : 1;
6afd0544 3045 }
3046
3047 /* If we have a sign-extension of a zero-extended value, we can
a6476f88 3048 replace that by a single zero-extension. Likewise if the
3049 final conversion does not change precision we can drop the
3050 intermediate conversion. */
6afd0544 3051 if (inside_int && inter_int && final_int
a6476f88 3052 && ((inside_prec < inter_prec && inter_prec < final_prec
3053 && inside_unsignedp && !inter_unsignedp)
3054 || final_prec == inter_prec))
6afd0544 3055 {
3056 gimple_assign_set_rhs1 (stmt, defop0);
3057 update_stmt (stmt);
89c8f35a 3058 return remove_prop_source_from_use (op0) ? 2 : 1;
6afd0544 3059 }
3060
3061 /* Two conversions in a row are not needed unless:
3062 - some conversion is floating-point (overstrict for now), or
3063 - some conversion is a vector (overstrict for now), or
3064 - the intermediate type is narrower than both initial and
3065 final, or
3066 - the intermediate type and innermost type differ in signedness,
3067 and the outermost type is wider than the intermediate, or
3068 - the initial type is a pointer type and the precisions of the
3069 intermediate and final types differ, or
3070 - the final type is a pointer type and the precisions of the
3071 initial and intermediate types differ. */
3072 if (! inside_float && ! inter_float && ! final_float
3073 && ! inside_vec && ! inter_vec && ! final_vec
3074 && (inter_prec >= inside_prec || inter_prec >= final_prec)
3075 && ! (inside_int && inter_int
3076 && inter_unsignedp != inside_unsignedp
3077 && inter_prec < final_prec)
3078 && ((inter_unsignedp && inter_prec > inside_prec)
3079 == (final_unsignedp && final_prec > inter_prec))
3080 && ! (inside_ptr && inter_prec != final_prec)
3081 && ! (final_ptr && inside_prec != inter_prec)
51dbf409 3082 && ! (final_prec != GET_MODE_PRECISION (TYPE_MODE (type))
6afd0544 3083 && TYPE_MODE (type) == TYPE_MODE (inter_type)))
3084 {
3085 gimple_assign_set_rhs1 (stmt, defop0);
3086 update_stmt (stmt);
89c8f35a 3087 return remove_prop_source_from_use (op0) ? 2 : 1;
6afd0544 3088 }
3089
3090 /* A truncation to an unsigned type should be canonicalized as
3091 bitwise and of a mask. */
3092 if (final_int && inter_int && inside_int
3093 && final_prec == inside_prec
3094 && final_prec > inter_prec
3095 && inter_unsignedp)
3096 {
3097 tree tem;
3098 tem = fold_build2 (BIT_AND_EXPR, inside_type,
3099 defop0,
e913b5cd 3100 wide_int_to_tree
796b6678 3101 (inside_type,
3102 wi::mask (inter_prec, false,
3103 TYPE_PRECISION (inside_type))));
6afd0544 3104 if (!useless_type_conversion_p (type, inside_type))
3105 {
3106 tem = force_gimple_operand_gsi (gsi, tem, true, NULL_TREE, true,
3107 GSI_SAME_STMT);
3108 gimple_assign_set_rhs1 (stmt, tem);
3109 }
3110 else
3111 gimple_assign_set_rhs_from_tree (gsi, tem);
3112 update_stmt (gsi_stmt (*gsi));
89c8f35a 3113 return 1;
6afd0544 3114 }
487282d5 3115
3116 /* If we are converting an integer to a floating-point that can
3117 represent it exactly and back to an integer, we can skip the
3118 floating-point conversion. */
3119 if (inside_int && inter_float && final_int &&
3120 (unsigned) significand_size (TYPE_MODE (inter_type))
3121 >= inside_prec - !inside_unsignedp)
3122 {
3123 if (useless_type_conversion_p (type, inside_type))
3124 {
3125 gimple_assign_set_rhs1 (stmt, unshare_expr (defop0));
3126 gimple_assign_set_rhs_code (stmt, TREE_CODE (defop0));
3127 update_stmt (stmt);
3128 return remove_prop_source_from_use (op0) ? 2 : 1;
3129 }
3130 else
3131 {
3132 gimple_assign_set_rhs1 (stmt, defop0);
3133 gimple_assign_set_rhs_code (stmt, CONVERT_EXPR);
3134 update_stmt (stmt);
3135 return remove_prop_source_from_use (op0) ? 2 : 1;
3136 }
3137 }
6afd0544 3138 }
3139
89c8f35a 3140 return 0;
6afd0544 3141}
3142
dbf51ba1 3143/* Combine VIEW_CONVERT_EXPRs with their defining statement. */
3144
3145static bool
3146simplify_vce (gimple_stmt_iterator *gsi)
3147{
3148 gimple stmt = gsi_stmt (*gsi);
3149 tree type = TREE_TYPE (gimple_assign_lhs (stmt));
3150
3151 /* Drop useless VIEW_CONVERT_EXPRs. */
3152 tree op = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
3153 if (useless_type_conversion_p (type, TREE_TYPE (op)))
3154 {
3155 gimple_assign_set_rhs1 (stmt, op);
3156 update_stmt (stmt);
3157 return true;
3158 }
3159
3160 if (TREE_CODE (op) != SSA_NAME)
3161 return false;
3162
3163 gimple def_stmt = SSA_NAME_DEF_STMT (op);
3164 if (!is_gimple_assign (def_stmt))
3165 return false;
3166
3167 tree def_op = gimple_assign_rhs1 (def_stmt);
3168 switch (gimple_assign_rhs_code (def_stmt))
3169 {
3170 CASE_CONVERT:
3171 /* Strip integral conversions that do not change the precision. */
3172 if ((INTEGRAL_TYPE_P (TREE_TYPE (op))
3173 || POINTER_TYPE_P (TREE_TYPE (op)))
3174 && (INTEGRAL_TYPE_P (TREE_TYPE (def_op))
3175 || POINTER_TYPE_P (TREE_TYPE (def_op)))
3176 && (TYPE_PRECISION (TREE_TYPE (op))
3177 == TYPE_PRECISION (TREE_TYPE (def_op))))
3178 {
3179 TREE_OPERAND (gimple_assign_rhs1 (stmt), 0) = def_op;
3180 update_stmt (stmt);
3181 return true;
3182 }
3183 break;
3184
3185 case VIEW_CONVERT_EXPR:
3186 /* Series of VIEW_CONVERT_EXPRs on register operands can
3187 be contracted. */
3188 if (TREE_CODE (TREE_OPERAND (def_op, 0)) == SSA_NAME)
3189 {
3190 if (useless_type_conversion_p (type,
3191 TREE_TYPE (TREE_OPERAND (def_op, 0))))
3192 gimple_assign_set_rhs1 (stmt, TREE_OPERAND (def_op, 0));
3193 else
3194 TREE_OPERAND (gimple_assign_rhs1 (stmt), 0)
3195 = TREE_OPERAND (def_op, 0);
3196 update_stmt (stmt);
3197 return true;
3198 }
3199
3200 default:;
3201 }
3202
3203 return false;
3204}
3205
173c91d9 3206/* Combine an element access with a shuffle. Returns true if there were
3207 any changes made, else it returns false. */
3208
3209static bool
3210simplify_bitfield_ref (gimple_stmt_iterator *gsi)
3211{
3212 gimple stmt = gsi_stmt (*gsi);
3213 gimple def_stmt;
3214 tree op, op0, op1, op2;
3215 tree elem_type;
3216 unsigned idx, n, size;
3217 enum tree_code code;
3218
3219 op = gimple_assign_rhs1 (stmt);
3220 gcc_checking_assert (TREE_CODE (op) == BIT_FIELD_REF);
3221
3222 op0 = TREE_OPERAND (op, 0);
3223 if (TREE_CODE (op0) != SSA_NAME
3224 || TREE_CODE (TREE_TYPE (op0)) != VECTOR_TYPE)
3225 return false;
3226
58bf5219 3227 def_stmt = get_prop_source_stmt (op0, false, NULL);
3228 if (!def_stmt || !can_propagate_from (def_stmt))
3229 return false;
3230
3231 op1 = TREE_OPERAND (op, 1);
3232 op2 = TREE_OPERAND (op, 2);
3233 code = gimple_assign_rhs_code (def_stmt);
3234
3235 if (code == CONSTRUCTOR)
3236 {
3237 tree tem = fold_ternary (BIT_FIELD_REF, TREE_TYPE (op),
3238 gimple_assign_rhs1 (def_stmt), op1, op2);
3239 if (!tem || !valid_gimple_rhs_p (tem))
3240 return false;
3241 gimple_assign_set_rhs_from_tree (gsi, tem);
3242 update_stmt (gsi_stmt (*gsi));
3243 return true;
3244 }
3245
173c91d9 3246 elem_type = TREE_TYPE (TREE_TYPE (op0));
3247 if (TREE_TYPE (op) != elem_type)
3248 return false;
3249
f9ae6f95 3250 size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
3251 n = TREE_INT_CST_LOW (op1) / size;
173c91d9 3252 if (n != 1)
3253 return false;
f9ae6f95 3254 idx = TREE_INT_CST_LOW (op2) / size;
173c91d9 3255
173c91d9 3256 if (code == VEC_PERM_EXPR)
3257 {
3258 tree p, m, index, tem;
3259 unsigned nelts;
3260 m = gimple_assign_rhs3 (def_stmt);
3261 if (TREE_CODE (m) != VECTOR_CST)
3262 return false;
3263 nelts = VECTOR_CST_NELTS (m);
f9ae6f95 3264 idx = TREE_INT_CST_LOW (VECTOR_CST_ELT (m, idx));
173c91d9 3265 idx %= 2 * nelts;
3266 if (idx < nelts)
3267 {
3268 p = gimple_assign_rhs1 (def_stmt);
3269 }
3270 else
3271 {
3272 p = gimple_assign_rhs2 (def_stmt);
3273 idx -= nelts;
3274 }
3275 index = build_int_cst (TREE_TYPE (TREE_TYPE (m)), idx * size);
3276 tem = build3 (BIT_FIELD_REF, TREE_TYPE (op),
ab54bbbd 3277 unshare_expr (p), op1, index);
173c91d9 3278 gimple_assign_set_rhs1 (stmt, tem);
3279 fold_stmt (gsi);
3280 update_stmt (gsi_stmt (*gsi));
3281 return true;
3282 }
3283
3284 return false;
3285}
3286
496ec2ad 3287/* Determine whether applying the 2 permutations (mask1 then mask2)
3288 gives back one of the input. */
3289
3290static int
3291is_combined_permutation_identity (tree mask1, tree mask2)
3292{
3293 tree mask;
3294 unsigned int nelts, i, j;
3295 bool maybe_identity1 = true;
3296 bool maybe_identity2 = true;
3297
3298 gcc_checking_assert (TREE_CODE (mask1) == VECTOR_CST
3299 && TREE_CODE (mask2) == VECTOR_CST);
3300 mask = fold_ternary (VEC_PERM_EXPR, TREE_TYPE (mask1), mask1, mask1, mask2);
3301 gcc_assert (TREE_CODE (mask) == VECTOR_CST);
3302
3303 nelts = VECTOR_CST_NELTS (mask);
3304 for (i = 0; i < nelts; i++)
3305 {
3306 tree val = VECTOR_CST_ELT (mask, i);
3307 gcc_assert (TREE_CODE (val) == INTEGER_CST);
f9ae6f95 3308 j = TREE_INT_CST_LOW (val) & (2 * nelts - 1);
496ec2ad 3309 if (j == i)
3310 maybe_identity2 = false;
3311 else if (j == i + nelts)
3312 maybe_identity1 = false;
3313 else
3314 return 0;
3315 }
3316 return maybe_identity1 ? 1 : maybe_identity2 ? 2 : 0;
3317}
3318
2b9112d6 3319/* Combine a shuffle with its arguments. Returns 1 if there were any
3320 changes made, 2 if cfg-cleanup needs to run. Else it returns 0. */
496ec2ad 3321
3322static int
3323simplify_permutation (gimple_stmt_iterator *gsi)
3324{
3325 gimple stmt = gsi_stmt (*gsi);
3326 gimple def_stmt;
2b9112d6 3327 tree op0, op1, op2, op3, arg0, arg1;
3328 enum tree_code code;
ab54bbbd 3329 bool single_use_op0 = false;
496ec2ad 3330
2b9112d6 3331 gcc_checking_assert (gimple_assign_rhs_code (stmt) == VEC_PERM_EXPR);
496ec2ad 3332
3333 op0 = gimple_assign_rhs1 (stmt);
3334 op1 = gimple_assign_rhs2 (stmt);
3335 op2 = gimple_assign_rhs3 (stmt);
3336
496ec2ad 3337 if (TREE_CODE (op2) != VECTOR_CST)
3338 return 0;
3339
2b9112d6 3340 if (TREE_CODE (op0) == VECTOR_CST)
3341 {
3342 code = VECTOR_CST;
3343 arg0 = op0;
3344 }
3345 else if (TREE_CODE (op0) == SSA_NAME)
3346 {
ab54bbbd 3347 def_stmt = get_prop_source_stmt (op0, false, &single_use_op0);
3348 if (!def_stmt || !can_propagate_from (def_stmt))
2b9112d6 3349 return 0;
496ec2ad 3350
2b9112d6 3351 code = gimple_assign_rhs_code (def_stmt);
3352 arg0 = gimple_assign_rhs1 (def_stmt);
3353 }
3354 else
496ec2ad 3355 return 0;
3356
496ec2ad 3357 /* Two consecutive shuffles. */
2b9112d6 3358 if (code == VEC_PERM_EXPR)
496ec2ad 3359 {
3360 tree orig;
3361 int ident;
2b9112d6 3362
3363 if (op0 != op1)
3364 return 0;
496ec2ad 3365 op3 = gimple_assign_rhs3 (def_stmt);
3366 if (TREE_CODE (op3) != VECTOR_CST)
3367 return 0;
3368 ident = is_combined_permutation_identity (op3, op2);
3369 if (!ident)
3370 return 0;
3371 orig = (ident == 1) ? gimple_assign_rhs1 (def_stmt)
3372 : gimple_assign_rhs2 (def_stmt);
3373 gimple_assign_set_rhs1 (stmt, unshare_expr (orig));
3374 gimple_assign_set_rhs_code (stmt, TREE_CODE (orig));
3375 gimple_set_num_ops (stmt, 2);
3376 update_stmt (stmt);
3377 return remove_prop_source_from_use (op0) ? 2 : 1;
3378 }
3379
2b9112d6 3380 /* Shuffle of a constructor. */
3381 else if (code == CONSTRUCTOR || code == VECTOR_CST)
3382 {
3383 tree opt;
3384 bool ret = false;
3385 if (op0 != op1)
3386 {
ab54bbbd 3387 if (TREE_CODE (op0) == SSA_NAME && !single_use_op0)
2b9112d6 3388 return 0;
3389
3390 if (TREE_CODE (op1) == VECTOR_CST)
3391 arg1 = op1;
3392 else if (TREE_CODE (op1) == SSA_NAME)
3393 {
3394 enum tree_code code2;
3395
ab54bbbd 3396 gimple def_stmt2 = get_prop_source_stmt (op1, true, NULL);
3397 if (!def_stmt2 || !can_propagate_from (def_stmt2))
2b9112d6 3398 return 0;
3399
3400 code2 = gimple_assign_rhs_code (def_stmt2);
3401 if (code2 != CONSTRUCTOR && code2 != VECTOR_CST)
3402 return 0;
3403 arg1 = gimple_assign_rhs1 (def_stmt2);
3404 }
3405 else
3406 return 0;
3407 }
3408 else
3409 {
3410 /* Already used twice in this statement. */
3411 if (TREE_CODE (op0) == SSA_NAME && num_imm_uses (op0) > 2)
3412 return 0;
3413 arg1 = arg0;
3414 }
9af5ce0c 3415 opt = fold_ternary (VEC_PERM_EXPR, TREE_TYPE (op0), arg0, arg1, op2);
2b9112d6 3416 if (!opt
9af5ce0c 3417 || (TREE_CODE (opt) != CONSTRUCTOR && TREE_CODE (opt) != VECTOR_CST))
2b9112d6 3418 return 0;
3419 gimple_assign_set_rhs_from_tree (gsi, opt);
3420 update_stmt (gsi_stmt (*gsi));
3421 if (TREE_CODE (op0) == SSA_NAME)
3422 ret = remove_prop_source_from_use (op0);
3423 if (op0 != op1 && TREE_CODE (op1) == SSA_NAME)
3424 ret |= remove_prop_source_from_use (op1);
3425 return ret ? 2 : 1;
3426 }
3427
3428 return 0;
496ec2ad 3429}
3430
6a9e13a2 3431/* Recognize a VEC_PERM_EXPR. Returns true if there were any changes. */
3432
3433static bool
3434simplify_vector_constructor (gimple_stmt_iterator *gsi)
3435{
3436 gimple stmt = gsi_stmt (*gsi);
3437 gimple def_stmt;
3438 tree op, op2, orig, type, elem_type;
3439 unsigned elem_size, nelts, i;
3440 enum tree_code code;
3441 constructor_elt *elt;
3442 unsigned char *sel;
3443 bool maybe_ident;
3444
3445 gcc_checking_assert (gimple_assign_rhs_code (stmt) == CONSTRUCTOR);
3446
3447 op = gimple_assign_rhs1 (stmt);
3448 type = TREE_TYPE (op);
3449 gcc_checking_assert (TREE_CODE (type) == VECTOR_TYPE);
3450
3451 nelts = TYPE_VECTOR_SUBPARTS (type);
3452 elem_type = TREE_TYPE (type);
f9ae6f95 3453 elem_size = TREE_INT_CST_LOW (TYPE_SIZE (elem_type));
6a9e13a2 3454
3455 sel = XALLOCAVEC (unsigned char, nelts);
3456 orig = NULL;
3457 maybe_ident = true;
f1f41a6c 3458 FOR_EACH_VEC_SAFE_ELT (CONSTRUCTOR_ELTS (op), i, elt)
6a9e13a2 3459 {
3460 tree ref, op1;
3461
3462 if (i >= nelts)
3463 return false;
3464
3465 if (TREE_CODE (elt->value) != SSA_NAME)
3466 return false;
ab54bbbd 3467 def_stmt = get_prop_source_stmt (elt->value, false, NULL);
3468 if (!def_stmt)
6a9e13a2 3469 return false;
3470 code = gimple_assign_rhs_code (def_stmt);
3471 if (code != BIT_FIELD_REF)
3472 return false;
3473 op1 = gimple_assign_rhs1 (def_stmt);
3474 ref = TREE_OPERAND (op1, 0);
3475 if (orig)
3476 {
3477 if (ref != orig)
3478 return false;
3479 }
3480 else
3481 {
3482 if (TREE_CODE (ref) != SSA_NAME)
3483 return false;
8a13ba5e 3484 if (!useless_type_conversion_p (type, TREE_TYPE (ref)))
3485 return false;
6a9e13a2 3486 orig = ref;
3487 }
f9ae6f95 3488 if (TREE_INT_CST_LOW (TREE_OPERAND (op1, 1)) != elem_size)
6a9e13a2 3489 return false;
f9ae6f95 3490 sel[i] = TREE_INT_CST_LOW (TREE_OPERAND (op1, 2)) / elem_size;
6a9e13a2 3491 if (sel[i] != i) maybe_ident = false;
3492 }
3493 if (i < nelts)
3494 return false;
3495
3496 if (maybe_ident)
d1938a4b 3497 gimple_assign_set_rhs_from_tree (gsi, orig);
6a9e13a2 3498 else
3499 {
d1938a4b 3500 tree mask_type, *mask_elts;
3501
3502 if (!can_vec_perm_p (TYPE_MODE (type), false, sel))
3503 return false;
3504 mask_type
3505 = build_vector_type (build_nonstandard_integer_type (elem_size, 1),
3506 nelts);
3507 if (GET_MODE_CLASS (TYPE_MODE (mask_type)) != MODE_VECTOR_INT
3508 || GET_MODE_SIZE (TYPE_MODE (mask_type))
3509 != GET_MODE_SIZE (TYPE_MODE (type)))
6a9e13a2 3510 return false;
d1938a4b 3511 mask_elts = XALLOCAVEC (tree, nelts);
3512 for (i = 0; i < nelts; i++)
3513 mask_elts[i] = build_int_cst (TREE_TYPE (mask_type), sel[i]);
3514 op2 = build_vector (mask_type, mask_elts);
6a9e13a2 3515 gimple_assign_set_rhs_with_ops_1 (gsi, VEC_PERM_EXPR, orig, orig, op2);
3516 }
3517 update_stmt (gsi_stmt (*gsi));
3518 return true;
3519}
3520
5a423a75 3521/* Simplify multiplications.
3522 Return true if a transformation applied, otherwise return false. */
3523
3524static bool
3525simplify_mult (gimple_stmt_iterator *gsi)
3526{
3527 gimple stmt = gsi_stmt (*gsi);
3528 tree arg1 = gimple_assign_rhs1 (stmt);
3529 tree arg2 = gimple_assign_rhs2 (stmt);
3530
3531 if (TREE_CODE (arg1) != SSA_NAME)
3532 return false;
3533
3534 gimple def_stmt = SSA_NAME_DEF_STMT (arg1);
3535 if (!is_gimple_assign (def_stmt))
3536 return false;
3537
3538 /* Look through a sign-changing conversion. */
3539 if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
3540 {
3541 if (TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (def_stmt)))
3542 != TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))
3543 || TREE_CODE (gimple_assign_rhs1 (def_stmt)) != SSA_NAME)
3544 return false;
3545 def_stmt = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def_stmt));
3546 if (!is_gimple_assign (def_stmt))
3547 return false;
3548 }
3549
3550 if (gimple_assign_rhs_code (def_stmt) == EXACT_DIV_EXPR)
3551 {
3552 if (operand_equal_p (gimple_assign_rhs2 (def_stmt), arg2, 0))
3553 {
3554 tree res = gimple_assign_rhs1 (def_stmt);
3555 if (useless_type_conversion_p (TREE_TYPE (arg1), TREE_TYPE (res)))
3556 gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (res), res,
3557 NULL_TREE);
3558 else
3559 gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, res, NULL_TREE);
3560 gcc_assert (gsi_stmt (*gsi) == stmt);
3561 update_stmt (stmt);
3562 return true;
3563 }
3564 }
3565
3566 return false;
3567}
678b2f5b 3568/* Main entry point for the forward propagation and statement combine
3569 optimizer. */
4ee9c684 3570
65b0537f 3571namespace {
3572
3573const pass_data pass_data_forwprop =
3574{
3575 GIMPLE_PASS, /* type */
3576 "forwprop", /* name */
3577 OPTGROUP_NONE, /* optinfo_flags */
3578 true, /* has_execute */
3579 TV_TREE_FORWPROP, /* tv_id */
3580 ( PROP_cfg | PROP_ssa ), /* properties_required */
3581 0, /* properties_provided */
3582 0, /* properties_destroyed */
3583 0, /* todo_flags_start */
8b88439e 3584 TODO_update_ssa, /* todo_flags_finish */
65b0537f 3585};
3586
3587class pass_forwprop : public gimple_opt_pass
3588{
3589public:
3590 pass_forwprop (gcc::context *ctxt)
3591 : gimple_opt_pass (pass_data_forwprop, ctxt)
3592 {}
3593
3594 /* opt_pass methods: */
3595 opt_pass * clone () { return new pass_forwprop (m_ctxt); }
3596 virtual bool gate (function *) { return flag_tree_forwprop; }
3597 virtual unsigned int execute (function *);
3598
3599}; // class pass_forwprop
3600
3601unsigned int
3602pass_forwprop::execute (function *fun)
4ee9c684 3603{
f5c8cff5 3604 basic_block bb;
c96420f8 3605 unsigned int todoflags = 0;
4ee9c684 3606
148aa112 3607 cfg_changed = false;
3608
65b0537f 3609 FOR_EACH_BB_FN (bb, fun)
f5c8cff5 3610 {
2f5a3c4a 3611 gimple_stmt_iterator gsi;
291d763b 3612
678b2f5b 3613 /* Apply forward propagation to all stmts in the basic-block.
3614 Note we update GSI within the loop as necessary. */
75a70cf9 3615 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
291d763b 3616 {
75a70cf9 3617 gimple stmt = gsi_stmt (gsi);
678b2f5b 3618 tree lhs, rhs;
3619 enum tree_code code;
291d763b 3620
678b2f5b 3621 if (!is_gimple_assign (stmt))
291d763b 3622 {
678b2f5b 3623 gsi_next (&gsi);
3624 continue;
3625 }
3a938499 3626
678b2f5b 3627 lhs = gimple_assign_lhs (stmt);
3628 rhs = gimple_assign_rhs1 (stmt);
3629 code = gimple_assign_rhs_code (stmt);
3630 if (TREE_CODE (lhs) != SSA_NAME
3631 || has_zero_uses (lhs))
3632 {
3633 gsi_next (&gsi);
3634 continue;
3635 }
3a938499 3636
678b2f5b 3637 /* If this statement sets an SSA_NAME to an address,
3638 try to propagate the address into the uses of the SSA_NAME. */
3639 if (code == ADDR_EXPR
3640 /* Handle pointer conversions on invariant addresses
3641 as well, as this is valid gimple. */
3642 || (CONVERT_EXPR_CODE_P (code)
3643 && TREE_CODE (rhs) == ADDR_EXPR
3644 && POINTER_TYPE_P (TREE_TYPE (lhs))))
3645 {
3646 tree base = get_base_address (TREE_OPERAND (rhs, 0));
3647 if ((!base
3648 || !DECL_P (base)
3649 || decl_address_invariant_p (base))
3650 && !stmt_references_abnormal_ssa_name (stmt)
bfb89138 3651 && forward_propagate_addr_expr (lhs, rhs, true))
1c4607fd 3652 {
678b2f5b 3653 release_defs (stmt);
678b2f5b 3654 gsi_remove (&gsi, true);
1c4607fd 3655 }
678b2f5b 3656 else
3657 gsi_next (&gsi);
3658 }
cd22a796 3659 else if (code == POINTER_PLUS_EXPR)
678b2f5b 3660 {
cd22a796 3661 tree off = gimple_assign_rhs2 (stmt);
3662 if (TREE_CODE (off) == INTEGER_CST
3663 && can_propagate_from (stmt)
3664 && !simple_iv_increment_p (stmt)
678b2f5b 3665 /* ??? Better adjust the interface to that function
3666 instead of building new trees here. */
3667 && forward_propagate_addr_expr
cd22a796 3668 (lhs,
3669 build1_loc (gimple_location (stmt),
3670 ADDR_EXPR, TREE_TYPE (rhs),
3671 fold_build2 (MEM_REF,
3672 TREE_TYPE (TREE_TYPE (rhs)),
3673 rhs,
3674 fold_convert (ptr_type_node,
bfb89138 3675 off))), true))
ca3c9092 3676 {
678b2f5b 3677 release_defs (stmt);
678b2f5b 3678 gsi_remove (&gsi, true);
ca3c9092 3679 }
678b2f5b 3680 else if (is_gimple_min_invariant (rhs))
6afd0544 3681 {
678b2f5b 3682 /* Make sure to fold &a[0] + off_1 here. */
50aacf4c 3683 fold_stmt_inplace (&gsi);
678b2f5b 3684 update_stmt (stmt);
3685 if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
6afd0544 3686 gsi_next (&gsi);
3687 }
291d763b 3688 else
75a70cf9 3689 gsi_next (&gsi);
291d763b 3690 }
678b2f5b 3691 else if (TREE_CODE_CLASS (code) == tcc_comparison)
b5860aba 3692 {
e3a19533 3693 if (forward_propagate_comparison (&gsi))
65b0537f 3694 cfg_changed = true;
b5860aba 3695 }
291d763b 3696 else
75a70cf9 3697 gsi_next (&gsi);
291d763b 3698 }
678b2f5b 3699
3700 /* Combine stmts with the stmts defining their operands.
3701 Note we update GSI within the loop as necessary. */
a7107e58 3702 for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);)
678b2f5b 3703 {
3704 gimple stmt = gsi_stmt (gsi);
3705 bool changed = false;
3706
2f5a3c4a 3707 /* Mark stmt as potentially needing revisiting. */
3708 gimple_set_plf (stmt, GF_PLF_1, false);
3709
678b2f5b 3710 switch (gimple_code (stmt))
3711 {
3712 case GIMPLE_ASSIGN:
3713 {
3714 tree rhs1 = gimple_assign_rhs1 (stmt);
3715 enum tree_code code = gimple_assign_rhs_code (stmt);
3716
3717 if ((code == BIT_NOT_EXPR
3718 || code == NEGATE_EXPR)
3719 && TREE_CODE (rhs1) == SSA_NAME)
3720 changed = simplify_not_neg_expr (&gsi);
360b78f3 3721 else if (code == COND_EXPR
3722 || code == VEC_COND_EXPR)
678b2f5b 3723 {
3724 /* In this case the entire COND_EXPR is in rhs1. */
11b881f5 3725 if (forward_propagate_into_cond (&gsi)
3726 || combine_cond_exprs (&gsi))
3727 {
3728 changed = true;
3729 stmt = gsi_stmt (gsi);
3730 }
678b2f5b 3731 }
3732 else if (TREE_CODE_CLASS (code) == tcc_comparison)
3733 {
6f9714b3 3734 int did_something;
6f9714b3 3735 did_something = forward_propagate_into_comparison (&gsi);
3736 if (did_something == 2)
3737 cfg_changed = true;
6f9714b3 3738 changed = did_something != 0;
678b2f5b 3739 }
3b8827a2 3740 else if ((code == PLUS_EXPR
3741 || code == BIT_IOR_EXPR
3742 || code == BIT_XOR_EXPR)
3743 && simplify_rotate (&gsi))
3744 changed = true;
678b2f5b 3745 else if (code == BIT_AND_EXPR
3746 || code == BIT_IOR_EXPR
3747 || code == BIT_XOR_EXPR)
3748 changed = simplify_bitwise_binary (&gsi);
5a423a75 3749 else if (code == MULT_EXPR)
3750 {
3751 changed = simplify_mult (&gsi);
3752 if (changed
3753 && maybe_clean_or_replace_eh_stmt (stmt, stmt)
3754 && gimple_purge_dead_eh_edges (bb))
3755 cfg_changed = true;
3756 }
678b2f5b 3757 else if (code == PLUS_EXPR
3758 || code == MINUS_EXPR)
5a423a75 3759 {
3760 changed = associate_plusminus (&gsi);
3761 if (changed
3762 && maybe_clean_or_replace_eh_stmt (stmt, stmt)
3763 && gimple_purge_dead_eh_edges (bb))
3764 cfg_changed = true;
3765 }
c9c17332 3766 else if (code == POINTER_PLUS_EXPR)
3767 changed = associate_pointerplus (&gsi);
678b2f5b 3768 else if (CONVERT_EXPR_CODE_P (code)
3769 || code == FLOAT_EXPR
3770 || code == FIX_TRUNC_EXPR)
89c8f35a 3771 {
3772 int did_something = combine_conversions (&gsi);
3773 if (did_something == 2)
3774 cfg_changed = true;
d23e1965 3775
3776 /* If we have a narrowing conversion to an integral
3777 type that is fed by a BIT_AND_EXPR, we might be
3778 able to remove the BIT_AND_EXPR if it merely
3779 masks off bits outside the final type (and nothing
3780 else. */
3781 if (! did_something)
3782 {
3783 tree outer_type = TREE_TYPE (gimple_assign_lhs (stmt));
3784 tree inner_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
4c0d6cf7 3785 if (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME
3786 && INTEGRAL_TYPE_P (outer_type)
d23e1965 3787 && INTEGRAL_TYPE_P (inner_type)
3788 && (TYPE_PRECISION (outer_type)
3789 <= TYPE_PRECISION (inner_type)))
3790 did_something = simplify_conversion_from_bitmask (&gsi);
3791 }
3792
89c8f35a 3793 changed = did_something != 0;
3794 }
dbf51ba1 3795 else if (code == VIEW_CONVERT_EXPR)
3796 changed = simplify_vce (&gsi);
496ec2ad 3797 else if (code == VEC_PERM_EXPR)
3798 {
3799 int did_something = simplify_permutation (&gsi);
3800 if (did_something == 2)
3801 cfg_changed = true;
3802 changed = did_something != 0;
3803 }
173c91d9 3804 else if (code == BIT_FIELD_REF)
3805 changed = simplify_bitfield_ref (&gsi);
6a9e13a2 3806 else if (code == CONSTRUCTOR
3807 && TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
3808 changed = simplify_vector_constructor (&gsi);
678b2f5b 3809 break;
3810 }
3811
3812 case GIMPLE_SWITCH:
3813 changed = simplify_gimple_switch (stmt);
3814 break;
3815
3816 case GIMPLE_COND:
3817 {
3818 int did_something;
678b2f5b 3819 did_something = forward_propagate_into_gimple_cond (stmt);
3820 if (did_something == 2)
3821 cfg_changed = true;
678b2f5b 3822 changed = did_something != 0;
3823 break;
3824 }
3825
3826 case GIMPLE_CALL:
3827 {
3828 tree callee = gimple_call_fndecl (stmt);
3829 if (callee != NULL_TREE
3830 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
3831 changed = simplify_builtin_call (&gsi, callee);
3832 break;
3833 }
3834
3835 default:;
3836 }
3837
a7107e58 3838 if (changed)
3839 {
3840 /* If the stmt changed then re-visit it and the statements
3841 inserted before it. */
2f5a3c4a 3842 for (; !gsi_end_p (gsi); gsi_prev (&gsi))
3843 if (gimple_plf (gsi_stmt (gsi), GF_PLF_1))
3844 break;
3845 if (gsi_end_p (gsi))
a7107e58 3846 gsi = gsi_start_bb (bb);
3847 else
2f5a3c4a 3848 gsi_next (&gsi);
a7107e58 3849 }
3850 else
3851 {
2f5a3c4a 3852 /* Stmt no longer needs to be revisited. */
3853 gimple_set_plf (stmt, GF_PLF_1, true);
a7107e58 3854 gsi_next (&gsi);
3855 }
678b2f5b 3856 }
f5c8cff5 3857 }
148aa112 3858
3859 if (cfg_changed)
6fa78c7b 3860 todoflags |= TODO_cleanup_cfg;
678b2f5b 3861
c96420f8 3862 return todoflags;
4ee9c684 3863}
3864
cbe8bda8 3865} // anon namespace
3866
3867gimple_opt_pass *
3868make_pass_forwprop (gcc::context *ctxt)
3869{
3870 return new pass_forwprop (ctxt);
3871}