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