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