comparison gcc/tree-ssa-phiopt.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Optimization of PHI nodes by converting them into straightline code. 1 /* Optimization of PHI nodes by converting them into straightline code.
2 Copyright (C) 2004-2018 Free Software Foundation, Inc. 2 Copyright (C) 2004-2020 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it 6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the 7 under the terms of the GNU General Public License as published by the
42 #include "domwalk.h" 42 #include "domwalk.h"
43 #include "cfgloop.h" 43 #include "cfgloop.h"
44 #include "tree-data-ref.h" 44 #include "tree-data-ref.h"
45 #include "tree-scalar-evolution.h" 45 #include "tree-scalar-evolution.h"
46 #include "tree-inline.h" 46 #include "tree-inline.h"
47 #include "params.h"
48 #include "case-cfn-macros.h" 47 #include "case-cfn-macros.h"
49 48
50 static unsigned int tree_ssa_phiopt_worker (bool, bool, bool); 49 static unsigned int tree_ssa_phiopt_worker (bool, bool, bool);
50 static bool two_value_replacement (basic_block, basic_block, edge, gphi *,
51 tree, tree);
51 static bool conditional_replacement (basic_block, basic_block, 52 static bool conditional_replacement (basic_block, basic_block,
52 edge, edge, gphi *, tree, tree); 53 edge, edge, gphi *, tree, tree);
53 static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree, 54 static gphi *factor_out_conditional_conversion (edge, edge, gphi *, tree, tree,
54 gimple *); 55 gimple *);
55 static int value_replacement (basic_block, basic_block, 56 static int value_replacement (basic_block, basic_block,
330 arg1 = gimple_phi_arg_def (phi, e2->dest_idx); 331 arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
331 gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE); 332 gcc_assert (arg0 != NULL_TREE && arg1 != NULL_TREE);
332 } 333 }
333 334
334 /* Do the replacement of conditional if it can be done. */ 335 /* Do the replacement of conditional if it can be done. */
335 if (!early_p 336 if (two_value_replacement (bb, bb1, e2, phi, arg0, arg1))
336 && conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) 337 cfgchanged = true;
338 else if (!early_p
339 && conditional_replacement (bb, bb1, e1, e2, phi,
340 arg0, arg1))
337 cfgchanged = true; 341 cfgchanged = true;
338 else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) 342 else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
339 cfgchanged = true; 343 cfgchanged = true;
340 else if (!early_p 344 else if (!early_p
341 && cond_removal_in_popcount_pattern (bb, bb1, e1, e2, 345 && cond_removal_in_popcount_pattern (bb, bb1, e1, e2,
421 gimple *arg0_def_stmt = NULL, *arg1_def_stmt = NULL, *new_stmt; 425 gimple *arg0_def_stmt = NULL, *arg1_def_stmt = NULL, *new_stmt;
422 tree new_arg0 = NULL_TREE, new_arg1 = NULL_TREE; 426 tree new_arg0 = NULL_TREE, new_arg1 = NULL_TREE;
423 tree temp, result; 427 tree temp, result;
424 gphi *newphi; 428 gphi *newphi;
425 gimple_stmt_iterator gsi, gsi_for_def; 429 gimple_stmt_iterator gsi, gsi_for_def;
426 source_location locus = gimple_location (phi); 430 location_t locus = gimple_location (phi);
427 enum tree_code convert_code; 431 enum tree_code convert_code;
428 432
429 /* Handle only PHI statements with two arguments. TODO: If all 433 /* Handle only PHI statements with two arguments. TODO: If all
430 other arguments to PHI are INTEGER_CST or if their defining 434 other arguments to PHI are INTEGER_CST or if their defining
431 statement have the same unary operation, we can handle more 435 statement have the same unary operation, we can handle more
497 && gimple_bb (arg0_def_stmt) == e0->src) 501 && gimple_bb (arg0_def_stmt) == e0->src)
498 { 502 {
499 gsi = gsi_for_stmt (arg0_def_stmt); 503 gsi = gsi_for_stmt (arg0_def_stmt);
500 gsi_prev_nondebug (&gsi); 504 gsi_prev_nondebug (&gsi);
501 if (!gsi_end_p (gsi)) 505 if (!gsi_end_p (gsi))
502 return NULL; 506 {
507 if (gassign *assign
508 = dyn_cast <gassign *> (gsi_stmt (gsi)))
509 {
510 tree lhs = gimple_assign_lhs (assign);
511 enum tree_code ass_code
512 = gimple_assign_rhs_code (assign);
513 if (ass_code != MAX_EXPR && ass_code != MIN_EXPR)
514 return NULL;
515 if (lhs != gimple_assign_rhs1 (arg0_def_stmt))
516 return NULL;
517 gsi_prev_nondebug (&gsi);
518 if (!gsi_end_p (gsi))
519 return NULL;
520 }
521 else
522 return NULL;
523 }
503 gsi = gsi_for_stmt (arg0_def_stmt); 524 gsi = gsi_for_stmt (arg0_def_stmt);
504 gsi_next_nondebug (&gsi); 525 gsi_next_nondebug (&gsi);
505 if (!gsi_end_p (gsi)) 526 if (!gsi_end_p (gsi))
506 return NULL; 527 return NULL;
507 } 528 }
570 gsi = gsi_for_stmt (phi); 591 gsi = gsi_for_stmt (phi);
571 gsi_remove (&gsi, true); 592 gsi_remove (&gsi, true);
572 return newphi; 593 return newphi;
573 } 594 }
574 595
596 /* Optimize
597 # x_5 in range [cst1, cst2] where cst2 = cst1 + 1
598 if (x_5 op cstN) # where op is == or != and N is 1 or 2
599 goto bb3;
600 else
601 goto bb4;
602 bb3:
603 bb4:
604 # r_6 = PHI<cst3(2), cst4(3)> # where cst3 == cst4 + 1 or cst4 == cst3 + 1
605
606 to r_6 = x_5 + (min (cst3, cst4) - cst1) or
607 r_6 = (min (cst3, cst4) + cst1) - x_5 depending on op, N and which
608 of cst3 and cst4 is smaller. */
609
610 static bool
611 two_value_replacement (basic_block cond_bb, basic_block middle_bb,
612 edge e1, gphi *phi, tree arg0, tree arg1)
613 {
614 /* Only look for adjacent integer constants. */
615 if (!INTEGRAL_TYPE_P (TREE_TYPE (arg0))
616 || !INTEGRAL_TYPE_P (TREE_TYPE (arg1))
617 || TREE_CODE (arg0) != INTEGER_CST
618 || TREE_CODE (arg1) != INTEGER_CST
619 || (tree_int_cst_lt (arg0, arg1)
620 ? wi::to_widest (arg0) + 1 != wi::to_widest (arg1)
621 : wi::to_widest (arg1) + 1 != wi::to_widest (arg0)))
622 return false;
623
624 if (!empty_block_p (middle_bb))
625 return false;
626
627 gimple *stmt = last_stmt (cond_bb);
628 tree lhs = gimple_cond_lhs (stmt);
629 tree rhs = gimple_cond_rhs (stmt);
630
631 if (TREE_CODE (lhs) != SSA_NAME
632 || !INTEGRAL_TYPE_P (TREE_TYPE (lhs))
633 || TREE_CODE (TREE_TYPE (lhs)) == BOOLEAN_TYPE
634 || TREE_CODE (rhs) != INTEGER_CST)
635 return false;
636
637 switch (gimple_cond_code (stmt))
638 {
639 case EQ_EXPR:
640 case NE_EXPR:
641 break;
642 default:
643 return false;
644 }
645
646 wide_int min, max;
647 if (get_range_info (lhs, &min, &max) != VR_RANGE
648 || min + 1 != max
649 || (wi::to_wide (rhs) != min
650 && wi::to_wide (rhs) != max))
651 return false;
652
653 /* We need to know which is the true edge and which is the false
654 edge so that we know when to invert the condition below. */
655 edge true_edge, false_edge;
656 extract_true_false_edges_from_block (cond_bb, &true_edge, &false_edge);
657 if ((gimple_cond_code (stmt) == EQ_EXPR)
658 ^ (wi::to_wide (rhs) == max)
659 ^ (e1 == false_edge))
660 std::swap (arg0, arg1);
661
662 tree type;
663 if (TYPE_PRECISION (TREE_TYPE (lhs)) == TYPE_PRECISION (TREE_TYPE (arg0)))
664 {
665 /* Avoid performing the arithmetics in bool type which has different
666 semantics, otherwise prefer unsigned types from the two with
667 the same precision. */
668 if (TREE_CODE (TREE_TYPE (arg0)) == BOOLEAN_TYPE
669 || !TYPE_UNSIGNED (TREE_TYPE (arg0)))
670 type = TREE_TYPE (lhs);
671 else
672 type = TREE_TYPE (arg0);
673 }
674 else if (TYPE_PRECISION (TREE_TYPE (lhs)) > TYPE_PRECISION (TREE_TYPE (arg0)))
675 type = TREE_TYPE (lhs);
676 else
677 type = TREE_TYPE (arg0);
678
679 min = wide_int::from (min, TYPE_PRECISION (type),
680 TYPE_SIGN (TREE_TYPE (lhs)));
681 wide_int a = wide_int::from (wi::to_wide (arg0), TYPE_PRECISION (type),
682 TYPE_SIGN (TREE_TYPE (arg0)));
683 enum tree_code code;
684 wi::overflow_type ovf;
685 if (tree_int_cst_lt (arg0, arg1))
686 {
687 code = PLUS_EXPR;
688 a -= min;
689 if (!TYPE_UNSIGNED (type))
690 {
691 /* lhs is known to be in range [min, min+1] and we want to add a
692 to it. Check if that operation can overflow for those 2 values
693 and if yes, force unsigned type. */
694 wi::add (min + (wi::neg_p (a) ? 0 : 1), a, SIGNED, &ovf);
695 if (ovf)
696 type = unsigned_type_for (type);
697 }
698 }
699 else
700 {
701 code = MINUS_EXPR;
702 a += min;
703 if (!TYPE_UNSIGNED (type))
704 {
705 /* lhs is known to be in range [min, min+1] and we want to subtract
706 it from a. Check if that operation can overflow for those 2
707 values and if yes, force unsigned type. */
708 wi::sub (a, min + (wi::neg_p (min) ? 0 : 1), SIGNED, &ovf);
709 if (ovf)
710 type = unsigned_type_for (type);
711 }
712 }
713
714 tree arg = wide_int_to_tree (type, a);
715 gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
716 if (!useless_type_conversion_p (type, TREE_TYPE (lhs)))
717 lhs = gimplify_build1 (&gsi, NOP_EXPR, type, lhs);
718 tree new_rhs;
719 if (code == PLUS_EXPR)
720 new_rhs = gimplify_build2 (&gsi, PLUS_EXPR, type, lhs, arg);
721 else
722 new_rhs = gimplify_build2 (&gsi, MINUS_EXPR, type, arg, lhs);
723 if (!useless_type_conversion_p (TREE_TYPE (arg0), type))
724 new_rhs = gimplify_build1 (&gsi, NOP_EXPR, TREE_TYPE (arg0), new_rhs);
725
726 replace_phi_edge_with_variable (cond_bb, e1, phi, new_rhs);
727
728 /* Note that we optimized this PHI. */
729 return true;
730 }
731
575 /* The function conditional_replacement does the main work of doing the 732 /* The function conditional_replacement does the main work of doing the
576 conditional replacement. Return true if the replacement is done. 733 conditional replacement. Return true if the replacement is done.
577 Otherwise return false. 734 Otherwise return false.
578 BB is the basic block where the replacement is going to be done on. ARG0 735 BB is the basic block where the replacement is going to be done on. ARG0
579 is argument 0 from PHI. Likewise for ARG1. */ 736 is argument 0 from PHI. Likewise for ARG1. */
667 new_var = force_gimple_operand_gsi (&gsi, cond, true, NULL, true, 824 new_var = force_gimple_operand_gsi (&gsi, cond, true, NULL, true,
668 GSI_SAME_STMT); 825 GSI_SAME_STMT);
669 826
670 if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var))) 827 if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var)))
671 { 828 {
672 source_location locus_0, locus_1; 829 location_t locus_0, locus_1;
673 830
674 new_var2 = make_ssa_name (TREE_TYPE (result)); 831 new_var2 = make_ssa_name (TREE_TYPE (result));
675 new_stmt = gimple_build_assign (new_var2, CONVERT_EXPR, new_var); 832 new_stmt = gimple_build_assign (new_var2, CONVERT_EXPR, new_var);
676 gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); 833 gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
677 new_var = new_var2; 834 new_var = new_var2;
1202 static bool 1359 static bool
1203 minmax_replacement (basic_block cond_bb, basic_block middle_bb, 1360 minmax_replacement (basic_block cond_bb, basic_block middle_bb,
1204 edge e0, edge e1, gimple *phi, 1361 edge e0, edge e1, gimple *phi,
1205 tree arg0, tree arg1) 1362 tree arg0, tree arg1)
1206 { 1363 {
1207 tree result, type; 1364 tree result, type, rhs;
1208 gcond *cond; 1365 gcond *cond;
1209 gassign *new_stmt; 1366 gassign *new_stmt;
1210 edge true_edge, false_edge; 1367 edge true_edge, false_edge;
1211 enum tree_code cmp, minmax, ass_code; 1368 enum tree_code cmp, minmax, ass_code;
1212 tree smaller, alt_smaller, larger, alt_larger, arg_true, arg_false; 1369 tree smaller, alt_smaller, larger, alt_larger, arg_true, arg_false;
1218 if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type)) 1375 if (HONOR_NANS (type) || HONOR_SIGNED_ZEROS (type))
1219 return false; 1376 return false;
1220 1377
1221 cond = as_a <gcond *> (last_stmt (cond_bb)); 1378 cond = as_a <gcond *> (last_stmt (cond_bb));
1222 cmp = gimple_cond_code (cond); 1379 cmp = gimple_cond_code (cond);
1380 rhs = gimple_cond_rhs (cond);
1381
1382 /* Turn EQ/NE of extreme values to order comparisons. */
1383 if ((cmp == NE_EXPR || cmp == EQ_EXPR)
1384 && TREE_CODE (rhs) == INTEGER_CST
1385 && INTEGRAL_TYPE_P (TREE_TYPE (rhs)))
1386 {
1387 if (wi::eq_p (wi::to_wide (rhs), wi::min_value (TREE_TYPE (rhs))))
1388 {
1389 cmp = (cmp == EQ_EXPR) ? LT_EXPR : GE_EXPR;
1390 rhs = wide_int_to_tree (TREE_TYPE (rhs),
1391 wi::min_value (TREE_TYPE (rhs)) + 1);
1392 }
1393 else if (wi::eq_p (wi::to_wide (rhs), wi::max_value (TREE_TYPE (rhs))))
1394 {
1395 cmp = (cmp == EQ_EXPR) ? GT_EXPR : LE_EXPR;
1396 rhs = wide_int_to_tree (TREE_TYPE (rhs),
1397 wi::max_value (TREE_TYPE (rhs)) - 1);
1398 }
1399 }
1223 1400
1224 /* This transformation is only valid for order comparisons. Record which 1401 /* This transformation is only valid for order comparisons. Record which
1225 operand is smaller/larger if the result of the comparison is true. */ 1402 operand is smaller/larger if the result of the comparison is true. */
1226 alt_smaller = NULL_TREE; 1403 alt_smaller = NULL_TREE;
1227 alt_larger = NULL_TREE; 1404 alt_larger = NULL_TREE;
1228 if (cmp == LT_EXPR || cmp == LE_EXPR) 1405 if (cmp == LT_EXPR || cmp == LE_EXPR)
1229 { 1406 {
1230 smaller = gimple_cond_lhs (cond); 1407 smaller = gimple_cond_lhs (cond);
1231 larger = gimple_cond_rhs (cond); 1408 larger = rhs;
1232 /* If we have smaller < CST it is equivalent to smaller <= CST-1. 1409 /* If we have smaller < CST it is equivalent to smaller <= CST-1.
1233 Likewise smaller <= CST is equivalent to smaller < CST+1. */ 1410 Likewise smaller <= CST is equivalent to smaller < CST+1. */
1234 if (TREE_CODE (larger) == INTEGER_CST) 1411 if (TREE_CODE (larger) == INTEGER_CST
1412 && INTEGRAL_TYPE_P (TREE_TYPE (larger)))
1235 { 1413 {
1236 if (cmp == LT_EXPR) 1414 if (cmp == LT_EXPR)
1237 { 1415 {
1238 wi::overflow_type overflow; 1416 wi::overflow_type overflow;
1239 wide_int alt = wi::sub (wi::to_wide (larger), 1, 1417 wide_int alt = wi::sub (wi::to_wide (larger), 1,
1253 } 1431 }
1254 } 1432 }
1255 } 1433 }
1256 else if (cmp == GT_EXPR || cmp == GE_EXPR) 1434 else if (cmp == GT_EXPR || cmp == GE_EXPR)
1257 { 1435 {
1258 smaller = gimple_cond_rhs (cond); 1436 smaller = rhs;
1259 larger = gimple_cond_lhs (cond); 1437 larger = gimple_cond_lhs (cond);
1260 /* If we have larger > CST it is equivalent to larger >= CST+1. 1438 /* If we have larger > CST it is equivalent to larger >= CST+1.
1261 Likewise larger >= CST is equivalent to larger > CST-1. */ 1439 Likewise larger >= CST is equivalent to larger > CST-1. */
1262 if (TREE_CODE (smaller) == INTEGER_CST) 1440 if (TREE_CODE (smaller) == INTEGER_CST
1441 && INTEGRAL_TYPE_P (TREE_TYPE (smaller)))
1263 { 1442 {
1264 wi::overflow_type overflow; 1443 wi::overflow_type overflow;
1265 if (cmp == GT_EXPR) 1444 if (cmp == GT_EXPR)
1266 { 1445 {
1267 wide_int alt = wi::add (wi::to_wide (smaller), 1, 1446 wide_int alt = wi::add (wi::to_wide (smaller), 1,
1690 1869
1691 /* OTHER_BLOCK must have only one executable statement which must have the 1870 /* OTHER_BLOCK must have only one executable statement which must have the
1692 form arg0 = -arg1 or arg1 = -arg0. */ 1871 form arg0 = -arg1 or arg1 = -arg0. */
1693 1872
1694 assign = last_and_only_stmt (middle_bb); 1873 assign = last_and_only_stmt (middle_bb);
1695 /* If we did not find the proper negation assignment, then we can not 1874 /* If we did not find the proper negation assignment, then we cannot
1696 optimize. */ 1875 optimize. */
1697 if (assign == NULL) 1876 if (assign == NULL)
1698 return false; 1877 return false;
1699 1878
1700 /* If we got here, then we have found the only executable statement 1879 /* If we got here, then we have found the only executable statement
1701 in OTHER_BLOCK. If it is anything other than arg = -arg1 or 1880 in OTHER_BLOCK. If it is anything other than arg = -arg1 or
1702 arg1 = -arg0, then we can not optimize. */ 1881 arg1 = -arg0, then we cannot optimize. */
1703 if (gimple_code (assign) != GIMPLE_ASSIGN) 1882 if (gimple_code (assign) != GIMPLE_ASSIGN)
1704 return false; 1883 return false;
1705 1884
1706 lhs = gimple_assign_lhs (assign); 1885 lhs = gimple_assign_lhs (assign);
1707 1886
2017 JOIN_BB: 2196 JOIN_BB:
2018 some more 2197 some more
2019 2198
2020 We check that MIDDLE_BB contains only one store, that that store 2199 We check that MIDDLE_BB contains only one store, that that store
2021 doesn't trap (not via NOTRAP, but via checking if an access to the same 2200 doesn't trap (not via NOTRAP, but via checking if an access to the same
2022 memory location dominates us) and that the store has a "simple" RHS. */ 2201 memory location dominates us, or the store is to a local addressable
2202 object) and that the store has a "simple" RHS. */
2023 2203
2024 static bool 2204 static bool
2025 cond_store_replacement (basic_block middle_bb, basic_block join_bb, 2205 cond_store_replacement (basic_block middle_bb, basic_block join_bb,
2026 edge e0, edge e1, hash_set<tree> *nontrap) 2206 edge e0, edge e1, hash_set<tree> *nontrap)
2027 { 2207 {
2028 gimple *assign = last_and_only_stmt (middle_bb); 2208 gimple *assign = last_and_only_stmt (middle_bb);
2029 tree lhs, rhs, name, name2; 2209 tree lhs, rhs, name, name2;
2030 gphi *newphi; 2210 gphi *newphi;
2031 gassign *new_stmt; 2211 gassign *new_stmt;
2032 gimple_stmt_iterator gsi; 2212 gimple_stmt_iterator gsi;
2033 source_location locus; 2213 location_t locus;
2034 2214
2035 /* Check if middle_bb contains of only one store. */ 2215 /* Check if middle_bb contains of only one store. */
2036 if (!assign 2216 if (!assign
2037 || !gimple_assign_single_p (assign) 2217 || !gimple_assign_single_p (assign)
2038 || gimple_has_volatile_ops (assign)) 2218 || gimple_has_volatile_ops (assign))
2039 return false; 2219 return false;
2040 2220
2221 /* And no PHI nodes so all uses in the single stmt are also
2222 available where we insert to. */
2223 if (!gimple_seq_empty_p (phi_nodes (middle_bb)))
2224 return false;
2225
2041 locus = gimple_location (assign); 2226 locus = gimple_location (assign);
2042 lhs = gimple_assign_lhs (assign); 2227 lhs = gimple_assign_lhs (assign);
2043 rhs = gimple_assign_rhs1 (assign); 2228 rhs = gimple_assign_rhs1 (assign);
2044 if (TREE_CODE (lhs) != MEM_REF 2229 if ((TREE_CODE (lhs) != MEM_REF
2045 || TREE_CODE (TREE_OPERAND (lhs, 0)) != SSA_NAME 2230 && TREE_CODE (lhs) != ARRAY_REF
2231 && TREE_CODE (lhs) != COMPONENT_REF)
2046 || !is_gimple_reg_type (TREE_TYPE (lhs))) 2232 || !is_gimple_reg_type (TREE_TYPE (lhs)))
2047 return false; 2233 return false;
2048 2234
2049 /* Prove that we can move the store down. We could also check 2235 /* Prove that we can move the store down. We could also check
2050 TREE_THIS_NOTRAP here, but in that case we also could move stores, 2236 TREE_THIS_NOTRAP here, but in that case we also could move stores,
2051 whose value is not available readily, which we want to avoid. */ 2237 whose value is not available readily, which we want to avoid. */
2052 if (!nontrap->contains (lhs)) 2238 if (!nontrap->contains (lhs))
2053 return false; 2239 {
2240 /* If LHS is a local variable without address-taken, we could
2241 always safely move down the store. */
2242 tree base = get_base_address (lhs);
2243 if (!auto_var_p (base) || TREE_ADDRESSABLE (base))
2244 return false;
2245 }
2054 2246
2055 /* Now we've checked the constraints, so do the transformation: 2247 /* Now we've checked the constraints, so do the transformation:
2056 1) Remove the single store. */ 2248 1) Remove the single store. */
2057 gsi = gsi_for_stmt (assign); 2249 gsi = gsi_for_stmt (assign);
2058 unlink_stmt_vdef (assign); 2250 unlink_stmt_vdef (assign);
2078 /* 2) Insert a load from the memory of the store to the temporary 2270 /* 2) Insert a load from the memory of the store to the temporary
2079 on the edge which did not contain the store. */ 2271 on the edge which did not contain the store. */
2080 name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore"); 2272 name = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
2081 new_stmt = gimple_build_assign (name, lhs); 2273 new_stmt = gimple_build_assign (name, lhs);
2082 gimple_set_location (new_stmt, locus); 2274 gimple_set_location (new_stmt, locus);
2275 lhs = unshare_expr (lhs);
2276 /* Set TREE_NO_WARNING on the rhs of the load to avoid uninit
2277 warnings. */
2278 TREE_NO_WARNING (gimple_assign_rhs1 (new_stmt)) = 1;
2083 gsi_insert_on_edge (e1, new_stmt); 2279 gsi_insert_on_edge (e1, new_stmt);
2084 2280
2085 /* 3) Create a PHI node at the join block, with one argument 2281 /* 3) Create a PHI node at the join block, with one argument
2086 holding the old RHS, and the other holding the temporary 2282 holding the old RHS, and the other holding the temporary
2087 where we stored the old memory contents. */ 2283 where we stored the old memory contents. */
2088 name2 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore"); 2284 name2 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "cstore");
2089 newphi = create_phi_node (name2, join_bb); 2285 newphi = create_phi_node (name2, join_bb);
2090 add_phi_arg (newphi, rhs, e0, locus); 2286 add_phi_arg (newphi, rhs, e0, locus);
2091 add_phi_arg (newphi, name, e1, locus); 2287 add_phi_arg (newphi, name, e1, locus);
2092 2288
2093 lhs = unshare_expr (lhs);
2094 new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi)); 2289 new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
2095 2290
2096 /* 4) Insert that PHI node. */ 2291 /* 4) Insert that PHI node. */
2097 gsi = gsi_after_labels (join_bb); 2292 gsi = gsi_after_labels (join_bb);
2098 if (gsi_end_p (gsi)) 2293 if (gsi_end_p (gsi))
2100 gsi = gsi_last_bb (join_bb); 2295 gsi = gsi_last_bb (join_bb);
2101 gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT); 2296 gsi_insert_after (&gsi, new_stmt, GSI_NEW_STMT);
2102 } 2297 }
2103 else 2298 else
2104 gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT); 2299 gsi_insert_before (&gsi, new_stmt, GSI_NEW_STMT);
2300
2301 if (dump_file && (dump_flags & TDF_DETAILS))
2302 {
2303 fprintf (dump_file, "\nConditional store replacement happened!");
2304 fprintf (dump_file, "\nReplaced the store with a load.");
2305 fprintf (dump_file, "\nInserted a new PHI statement in joint block:\n");
2306 print_gimple_stmt (dump_file, new_stmt, 0, TDF_VOPS|TDF_MEMSYMS);
2307 }
2105 2308
2106 return true; 2309 return true;
2107 } 2310 }
2108 2311
2109 /* Do the main work of conditional store replacement. */ 2312 /* Do the main work of conditional store replacement. */
2112 cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, 2315 cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb,
2113 basic_block join_bb, gimple *then_assign, 2316 basic_block join_bb, gimple *then_assign,
2114 gimple *else_assign) 2317 gimple *else_assign)
2115 { 2318 {
2116 tree lhs_base, lhs, then_rhs, else_rhs, name; 2319 tree lhs_base, lhs, then_rhs, else_rhs, name;
2117 source_location then_locus, else_locus; 2320 location_t then_locus, else_locus;
2118 gimple_stmt_iterator gsi; 2321 gimple_stmt_iterator gsi;
2119 gphi *newphi; 2322 gphi *newphi;
2120 gassign *new_stmt; 2323 gassign *new_stmt;
2121 2324
2122 if (then_assign == NULL 2325 if (then_assign == NULL
2267 if (else_assign) 2470 if (else_assign)
2268 return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb, 2471 return cond_if_else_store_replacement_1 (then_bb, else_bb, join_bb,
2269 then_assign, else_assign); 2472 then_assign, else_assign);
2270 } 2473 }
2271 2474
2272 if (MAX_STORES_TO_SINK == 0) 2475 /* If either vectorization or if-conversion is disabled then do
2476 not sink any stores. */
2477 if (param_max_stores_to_sink == 0
2478 || (!flag_tree_loop_vectorize && !flag_tree_slp_vectorize)
2479 || !flag_tree_loop_if_convert)
2273 return false; 2480 return false;
2274 2481
2275 /* Find data references. */ 2482 /* Find data references. */
2276 then_datarefs.create (1); 2483 then_datarefs.create (1);
2277 else_datarefs.create (1); 2484 else_datarefs.create (1);
2324 else_stores.safe_push (else_store); 2531 else_stores.safe_push (else_store);
2325 } 2532 }
2326 2533
2327 /* No pairs of stores found. */ 2534 /* No pairs of stores found. */
2328 if (!then_stores.length () 2535 if (!then_stores.length ()
2329 || then_stores.length () > (unsigned) MAX_STORES_TO_SINK) 2536 || then_stores.length () > (unsigned) param_max_stores_to_sink)
2330 { 2537 {
2331 free_data_refs (then_datarefs); 2538 free_data_refs (then_datarefs);
2332 free_data_refs (else_datarefs); 2539 free_data_refs (else_datarefs);
2333 return false; 2540 return false;
2334 } 2541 }
2454 2661
2455 static void 2662 static void
2456 hoist_adjacent_loads (basic_block bb0, basic_block bb1, 2663 hoist_adjacent_loads (basic_block bb0, basic_block bb1,
2457 basic_block bb2, basic_block bb3) 2664 basic_block bb2, basic_block bb3)
2458 { 2665 {
2459 int param_align = PARAM_VALUE (PARAM_L1_CACHE_LINE_SIZE); 2666 int param_align = param_l1_cache_line_size;
2460 unsigned param_align_bits = (unsigned) (param_align * BITS_PER_UNIT); 2667 unsigned param_align_bits = (unsigned) (param_align * BITS_PER_UNIT);
2461 gphi_iterator gsi; 2668 gphi_iterator gsi;
2462 2669
2463 /* Walk the phis in bb3 looking for an opportunity. We are looking 2670 /* Walk the phis in bb3 looking for an opportunity. We are looking
2464 for phis of two SSA names, one each of which is defined in bb1 and 2671 for phis of two SSA names, one each of which is defined in bb1 and
2604 2811
2605 static bool 2812 static bool
2606 gate_hoist_loads (void) 2813 gate_hoist_loads (void)
2607 { 2814 {
2608 return (flag_hoist_adjacent_loads == 1 2815 return (flag_hoist_adjacent_loads == 1
2609 && PARAM_VALUE (PARAM_L1_CACHE_LINE_SIZE) 2816 && param_l1_cache_line_size
2610 && HAVE_conditional_move); 2817 && HAVE_conditional_move);
2611 } 2818 }
2612 2819
2613 /* This pass tries to replaces an if-then-else block with an 2820 /* This pass tries to replaces an if-then-else block with an
2614 assignment. We have four kinds of transformations. Some of these 2821 assignment. We have four kinds of transformations. Some of these