1*38fd1498Szrj /* SSA Dominator optimizations for trees 2*38fd1498Szrj Copyright (C) 2001-2018 Free Software Foundation, Inc. 3*38fd1498Szrj Contributed by Diego Novillo <dnovillo@redhat.com> 4*38fd1498Szrj 5*38fd1498Szrj This file is part of GCC. 6*38fd1498Szrj 7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify 8*38fd1498Szrj it under the terms of the GNU General Public License as published by 9*38fd1498Szrj the Free Software Foundation; either version 3, or (at your option) 10*38fd1498Szrj any later version. 11*38fd1498Szrj 12*38fd1498Szrj GCC is distributed in the hope that it will be useful, 13*38fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of 14*38fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*38fd1498Szrj GNU General Public License for more details. 16*38fd1498Szrj 17*38fd1498Szrj You should have received a copy of the GNU General Public License 18*38fd1498Szrj along with GCC; see the file COPYING3. If not see 19*38fd1498Szrj <http://www.gnu.org/licenses/>. */ 20*38fd1498Szrj 21*38fd1498Szrj #include "config.h" 22*38fd1498Szrj #include "system.h" 23*38fd1498Szrj #include "coretypes.h" 24*38fd1498Szrj #include "backend.h" 25*38fd1498Szrj #include "tree.h" 26*38fd1498Szrj #include "gimple.h" 27*38fd1498Szrj #include "tree-pass.h" 28*38fd1498Szrj #include "ssa.h" 29*38fd1498Szrj #include "gimple-pretty-print.h" 30*38fd1498Szrj #include "fold-const.h" 31*38fd1498Szrj #include "cfganal.h" 32*38fd1498Szrj #include "cfgloop.h" 33*38fd1498Szrj #include "gimple-fold.h" 34*38fd1498Szrj #include "tree-eh.h" 35*38fd1498Szrj #include "tree-inline.h" 36*38fd1498Szrj #include "gimple-iterator.h" 37*38fd1498Szrj #include "tree-cfg.h" 38*38fd1498Szrj #include "tree-into-ssa.h" 39*38fd1498Szrj #include "domwalk.h" 40*38fd1498Szrj #include "tree-ssa-propagate.h" 41*38fd1498Szrj #include "tree-ssa-threadupdate.h" 42*38fd1498Szrj #include "params.h" 43*38fd1498Szrj #include "tree-ssa-scopedtables.h" 44*38fd1498Szrj #include "tree-ssa-threadedge.h" 45*38fd1498Szrj #include "tree-ssa-dom.h" 46*38fd1498Szrj #include "gimplify.h" 47*38fd1498Szrj #include "tree-cfgcleanup.h" 48*38fd1498Szrj #include "dbgcnt.h" 49*38fd1498Szrj #include "alloc-pool.h" 50*38fd1498Szrj #include "tree-vrp.h" 51*38fd1498Szrj #include "vr-values.h" 52*38fd1498Szrj #include "gimple-ssa-evrp-analyze.h" 53*38fd1498Szrj 54*38fd1498Szrj /* This file implements optimizations on the dominator tree. */ 55*38fd1498Szrj 56*38fd1498Szrj /* Structure for recording edge equivalences. 57*38fd1498Szrj 58*38fd1498Szrj Computing and storing the edge equivalences instead of creating 59*38fd1498Szrj them on-demand can save significant amounts of time, particularly 60*38fd1498Szrj for pathological cases involving switch statements. 61*38fd1498Szrj 62*38fd1498Szrj These structures live for a single iteration of the dominator 63*38fd1498Szrj optimizer in the edge's AUX field. At the end of an iteration we 64*38fd1498Szrj free each of these structures. */ 65*38fd1498Szrj class edge_info 66*38fd1498Szrj { 67*38fd1498Szrj public: 68*38fd1498Szrj typedef std::pair <tree, tree> equiv_pair; 69*38fd1498Szrj edge_info (edge); 70*38fd1498Szrj ~edge_info (); 71*38fd1498Szrj 72*38fd1498Szrj /* Record a simple LHS = RHS equivalence. This may trigger 73*38fd1498Szrj calls to derive_equivalences. */ 74*38fd1498Szrj void record_simple_equiv (tree, tree); 75*38fd1498Szrj 76*38fd1498Szrj /* If traversing this edge creates simple equivalences, we store 77*38fd1498Szrj them as LHS/RHS pairs within this vector. */ 78*38fd1498Szrj vec<equiv_pair> simple_equivalences; 79*38fd1498Szrj 80*38fd1498Szrj /* Traversing an edge may also indicate one or more particular conditions 81*38fd1498Szrj are true or false. */ 82*38fd1498Szrj vec<cond_equivalence> cond_equivalences; 83*38fd1498Szrj 84*38fd1498Szrj private: 85*38fd1498Szrj /* Derive equivalences by walking the use-def chains. */ 86*38fd1498Szrj void derive_equivalences (tree, tree, int); 87*38fd1498Szrj }; 88*38fd1498Szrj 89*38fd1498Szrj /* Track whether or not we have changed the control flow graph. */ 90*38fd1498Szrj static bool cfg_altered; 91*38fd1498Szrj 92*38fd1498Szrj /* Bitmap of blocks that have had EH statements cleaned. We should 93*38fd1498Szrj remove their dead edges eventually. */ 94*38fd1498Szrj static bitmap need_eh_cleanup; 95*38fd1498Szrj static vec<gimple *> need_noreturn_fixup; 96*38fd1498Szrj 97*38fd1498Szrj /* Statistics for dominator optimizations. */ 98*38fd1498Szrj struct opt_stats_d 99*38fd1498Szrj { 100*38fd1498Szrj long num_stmts; 101*38fd1498Szrj long num_exprs_considered; 102*38fd1498Szrj long num_re; 103*38fd1498Szrj long num_const_prop; 104*38fd1498Szrj long num_copy_prop; 105*38fd1498Szrj }; 106*38fd1498Szrj 107*38fd1498Szrj static struct opt_stats_d opt_stats; 108*38fd1498Szrj 109*38fd1498Szrj /* Local functions. */ 110*38fd1498Szrj static void record_equality (tree, tree, class const_and_copies *); 111*38fd1498Szrj static void record_equivalences_from_phis (basic_block); 112*38fd1498Szrj static void record_equivalences_from_incoming_edge (basic_block, 113*38fd1498Szrj class const_and_copies *, 114*38fd1498Szrj class avail_exprs_stack *); 115*38fd1498Szrj static void eliminate_redundant_computations (gimple_stmt_iterator *, 116*38fd1498Szrj class const_and_copies *, 117*38fd1498Szrj class avail_exprs_stack *); 118*38fd1498Szrj static void record_equivalences_from_stmt (gimple *, int, 119*38fd1498Szrj class avail_exprs_stack *); 120*38fd1498Szrj static void dump_dominator_optimization_stats (FILE *file, 121*38fd1498Szrj hash_table<expr_elt_hasher> *); 122*38fd1498Szrj 123*38fd1498Szrj /* Constructor for EDGE_INFO. An EDGE_INFO instance is always 124*38fd1498Szrj associated with an edge E. */ 125*38fd1498Szrj 126*38fd1498Szrj edge_info::edge_info (edge e) 127*38fd1498Szrj { 128*38fd1498Szrj /* Free the old one associated with E, if it exists and 129*38fd1498Szrj associate our new object with E. */ 130*38fd1498Szrj free_dom_edge_info (e); 131*38fd1498Szrj e->aux = this; 132*38fd1498Szrj 133*38fd1498Szrj /* And initialize the embedded vectors. */ 134*38fd1498Szrj simple_equivalences = vNULL; 135*38fd1498Szrj cond_equivalences = vNULL; 136*38fd1498Szrj } 137*38fd1498Szrj 138*38fd1498Szrj /* Destructor just needs to release the vectors. */ 139*38fd1498Szrj 140*38fd1498Szrj edge_info::~edge_info (void) 141*38fd1498Szrj { 142*38fd1498Szrj this->cond_equivalences.release (); 143*38fd1498Szrj this->simple_equivalences.release (); 144*38fd1498Szrj } 145*38fd1498Szrj 146*38fd1498Szrj /* NAME is known to have the value VALUE, which must be a constant. 147*38fd1498Szrj 148*38fd1498Szrj Walk through its use-def chain to see if there are other equivalences 149*38fd1498Szrj we might be able to derive. 150*38fd1498Szrj 151*38fd1498Szrj RECURSION_LIMIT controls how far back we recurse through the use-def 152*38fd1498Szrj chains. */ 153*38fd1498Szrj 154*38fd1498Szrj void 155*38fd1498Szrj edge_info::derive_equivalences (tree name, tree value, int recursion_limit) 156*38fd1498Szrj { 157*38fd1498Szrj if (TREE_CODE (name) != SSA_NAME || TREE_CODE (value) != INTEGER_CST) 158*38fd1498Szrj return; 159*38fd1498Szrj 160*38fd1498Szrj /* This records the equivalence for the toplevel object. Do 161*38fd1498Szrj this before checking the recursion limit. */ 162*38fd1498Szrj simple_equivalences.safe_push (equiv_pair (name, value)); 163*38fd1498Szrj 164*38fd1498Szrj /* Limit how far up the use-def chains we are willing to walk. */ 165*38fd1498Szrj if (recursion_limit == 0) 166*38fd1498Szrj return; 167*38fd1498Szrj 168*38fd1498Szrj /* We can walk up the use-def chains to potentially find more 169*38fd1498Szrj equivalences. */ 170*38fd1498Szrj gimple *def_stmt = SSA_NAME_DEF_STMT (name); 171*38fd1498Szrj if (is_gimple_assign (def_stmt)) 172*38fd1498Szrj { 173*38fd1498Szrj /* We know the result of DEF_STMT was zero. See if that allows 174*38fd1498Szrj us to deduce anything about the SSA_NAMEs used on the RHS. */ 175*38fd1498Szrj enum tree_code code = gimple_assign_rhs_code (def_stmt); 176*38fd1498Szrj switch (code) 177*38fd1498Szrj { 178*38fd1498Szrj case BIT_IOR_EXPR: 179*38fd1498Szrj if (integer_zerop (value)) 180*38fd1498Szrj { 181*38fd1498Szrj tree rhs1 = gimple_assign_rhs1 (def_stmt); 182*38fd1498Szrj tree rhs2 = gimple_assign_rhs2 (def_stmt); 183*38fd1498Szrj 184*38fd1498Szrj value = build_zero_cst (TREE_TYPE (rhs1)); 185*38fd1498Szrj derive_equivalences (rhs1, value, recursion_limit - 1); 186*38fd1498Szrj value = build_zero_cst (TREE_TYPE (rhs2)); 187*38fd1498Szrj derive_equivalences (rhs2, value, recursion_limit - 1); 188*38fd1498Szrj } 189*38fd1498Szrj break; 190*38fd1498Szrj 191*38fd1498Szrj /* We know the result of DEF_STMT was one. See if that allows 192*38fd1498Szrj us to deduce anything about the SSA_NAMEs used on the RHS. */ 193*38fd1498Szrj case BIT_AND_EXPR: 194*38fd1498Szrj if (!integer_zerop (value)) 195*38fd1498Szrj { 196*38fd1498Szrj tree rhs1 = gimple_assign_rhs1 (def_stmt); 197*38fd1498Szrj tree rhs2 = gimple_assign_rhs2 (def_stmt); 198*38fd1498Szrj 199*38fd1498Szrj /* If either operand has a boolean range, then we 200*38fd1498Szrj know its value must be one, otherwise we just know it 201*38fd1498Szrj is nonzero. The former is clearly useful, I haven't 202*38fd1498Szrj seen cases where the latter is helpful yet. */ 203*38fd1498Szrj if (TREE_CODE (rhs1) == SSA_NAME) 204*38fd1498Szrj { 205*38fd1498Szrj if (ssa_name_has_boolean_range (rhs1)) 206*38fd1498Szrj { 207*38fd1498Szrj value = build_one_cst (TREE_TYPE (rhs1)); 208*38fd1498Szrj derive_equivalences (rhs1, value, recursion_limit - 1); 209*38fd1498Szrj } 210*38fd1498Szrj } 211*38fd1498Szrj if (TREE_CODE (rhs2) == SSA_NAME) 212*38fd1498Szrj { 213*38fd1498Szrj if (ssa_name_has_boolean_range (rhs2)) 214*38fd1498Szrj { 215*38fd1498Szrj value = build_one_cst (TREE_TYPE (rhs2)); 216*38fd1498Szrj derive_equivalences (rhs2, value, recursion_limit - 1); 217*38fd1498Szrj } 218*38fd1498Szrj } 219*38fd1498Szrj } 220*38fd1498Szrj break; 221*38fd1498Szrj 222*38fd1498Szrj /* If LHS is an SSA_NAME and RHS is a constant integer and LHS was 223*38fd1498Szrj set via a widening type conversion, then we may be able to record 224*38fd1498Szrj additional equivalences. */ 225*38fd1498Szrj case NOP_EXPR: 226*38fd1498Szrj case CONVERT_EXPR: 227*38fd1498Szrj { 228*38fd1498Szrj tree rhs = gimple_assign_rhs1 (def_stmt); 229*38fd1498Szrj tree rhs_type = TREE_TYPE (rhs); 230*38fd1498Szrj if (INTEGRAL_TYPE_P (rhs_type) 231*38fd1498Szrj && (TYPE_PRECISION (TREE_TYPE (name)) 232*38fd1498Szrj >= TYPE_PRECISION (rhs_type)) 233*38fd1498Szrj && int_fits_type_p (value, rhs_type)) 234*38fd1498Szrj derive_equivalences (rhs, 235*38fd1498Szrj fold_convert (rhs_type, value), 236*38fd1498Szrj recursion_limit - 1); 237*38fd1498Szrj break; 238*38fd1498Szrj } 239*38fd1498Szrj 240*38fd1498Szrj /* We can invert the operation of these codes trivially if 241*38fd1498Szrj one of the RHS operands is a constant to produce a known 242*38fd1498Szrj value for the other RHS operand. */ 243*38fd1498Szrj case POINTER_PLUS_EXPR: 244*38fd1498Szrj case PLUS_EXPR: 245*38fd1498Szrj { 246*38fd1498Szrj tree rhs1 = gimple_assign_rhs1 (def_stmt); 247*38fd1498Szrj tree rhs2 = gimple_assign_rhs2 (def_stmt); 248*38fd1498Szrj 249*38fd1498Szrj /* If either argument is a constant, then we can compute 250*38fd1498Szrj a constant value for the nonconstant argument. */ 251*38fd1498Szrj if (TREE_CODE (rhs1) == INTEGER_CST 252*38fd1498Szrj && TREE_CODE (rhs2) == SSA_NAME) 253*38fd1498Szrj derive_equivalences (rhs2, 254*38fd1498Szrj fold_binary (MINUS_EXPR, TREE_TYPE (rhs1), 255*38fd1498Szrj value, rhs1), 256*38fd1498Szrj recursion_limit - 1); 257*38fd1498Szrj else if (TREE_CODE (rhs2) == INTEGER_CST 258*38fd1498Szrj && TREE_CODE (rhs1) == SSA_NAME) 259*38fd1498Szrj derive_equivalences (rhs1, 260*38fd1498Szrj fold_binary (MINUS_EXPR, TREE_TYPE (rhs1), 261*38fd1498Szrj value, rhs2), 262*38fd1498Szrj recursion_limit - 1); 263*38fd1498Szrj break; 264*38fd1498Szrj } 265*38fd1498Szrj 266*38fd1498Szrj /* If one of the operands is a constant, then we can compute 267*38fd1498Szrj the value of the other operand. If both operands are 268*38fd1498Szrj SSA_NAMEs, then they must be equal if the result is zero. */ 269*38fd1498Szrj case MINUS_EXPR: 270*38fd1498Szrj { 271*38fd1498Szrj tree rhs1 = gimple_assign_rhs1 (def_stmt); 272*38fd1498Szrj tree rhs2 = gimple_assign_rhs2 (def_stmt); 273*38fd1498Szrj 274*38fd1498Szrj /* If either argument is a constant, then we can compute 275*38fd1498Szrj a constant value for the nonconstant argument. */ 276*38fd1498Szrj if (TREE_CODE (rhs1) == INTEGER_CST 277*38fd1498Szrj && TREE_CODE (rhs2) == SSA_NAME) 278*38fd1498Szrj derive_equivalences (rhs2, 279*38fd1498Szrj fold_binary (MINUS_EXPR, TREE_TYPE (rhs1), 280*38fd1498Szrj rhs1, value), 281*38fd1498Szrj recursion_limit - 1); 282*38fd1498Szrj else if (TREE_CODE (rhs2) == INTEGER_CST 283*38fd1498Szrj && TREE_CODE (rhs1) == SSA_NAME) 284*38fd1498Szrj derive_equivalences (rhs1, 285*38fd1498Szrj fold_binary (PLUS_EXPR, TREE_TYPE (rhs1), 286*38fd1498Szrj value, rhs2), 287*38fd1498Szrj recursion_limit - 1); 288*38fd1498Szrj else if (integer_zerop (value)) 289*38fd1498Szrj { 290*38fd1498Szrj tree cond = build2 (EQ_EXPR, boolean_type_node, 291*38fd1498Szrj gimple_assign_rhs1 (def_stmt), 292*38fd1498Szrj gimple_assign_rhs2 (def_stmt)); 293*38fd1498Szrj tree inverted = invert_truthvalue (cond); 294*38fd1498Szrj record_conditions (&this->cond_equivalences, cond, inverted); 295*38fd1498Szrj } 296*38fd1498Szrj break; 297*38fd1498Szrj } 298*38fd1498Szrj 299*38fd1498Szrj 300*38fd1498Szrj case EQ_EXPR: 301*38fd1498Szrj case NE_EXPR: 302*38fd1498Szrj { 303*38fd1498Szrj if ((code == EQ_EXPR && integer_onep (value)) 304*38fd1498Szrj || (code == NE_EXPR && integer_zerop (value))) 305*38fd1498Szrj { 306*38fd1498Szrj tree rhs1 = gimple_assign_rhs1 (def_stmt); 307*38fd1498Szrj tree rhs2 = gimple_assign_rhs2 (def_stmt); 308*38fd1498Szrj 309*38fd1498Szrj /* If either argument is a constant, then record the 310*38fd1498Szrj other argument as being the same as that constant. 311*38fd1498Szrj 312*38fd1498Szrj If neither operand is a constant, then we have a 313*38fd1498Szrj conditional name == name equivalence. */ 314*38fd1498Szrj if (TREE_CODE (rhs1) == INTEGER_CST) 315*38fd1498Szrj derive_equivalences (rhs2, rhs1, recursion_limit - 1); 316*38fd1498Szrj else if (TREE_CODE (rhs2) == INTEGER_CST) 317*38fd1498Szrj derive_equivalences (rhs1, rhs2, recursion_limit - 1); 318*38fd1498Szrj } 319*38fd1498Szrj else 320*38fd1498Szrj { 321*38fd1498Szrj tree cond = build2 (code, boolean_type_node, 322*38fd1498Szrj gimple_assign_rhs1 (def_stmt), 323*38fd1498Szrj gimple_assign_rhs2 (def_stmt)); 324*38fd1498Szrj tree inverted = invert_truthvalue (cond); 325*38fd1498Szrj if (integer_zerop (value)) 326*38fd1498Szrj std::swap (cond, inverted); 327*38fd1498Szrj record_conditions (&this->cond_equivalences, cond, inverted); 328*38fd1498Szrj } 329*38fd1498Szrj break; 330*38fd1498Szrj } 331*38fd1498Szrj 332*38fd1498Szrj /* For BIT_NOT and NEGATE, we can just apply the operation to the 333*38fd1498Szrj VALUE to get the new equivalence. It will always be a constant 334*38fd1498Szrj so we can recurse. */ 335*38fd1498Szrj case BIT_NOT_EXPR: 336*38fd1498Szrj case NEGATE_EXPR: 337*38fd1498Szrj { 338*38fd1498Szrj tree rhs = gimple_assign_rhs1 (def_stmt); 339*38fd1498Szrj tree res = fold_build1 (code, TREE_TYPE (rhs), value); 340*38fd1498Szrj derive_equivalences (rhs, res, recursion_limit - 1); 341*38fd1498Szrj break; 342*38fd1498Szrj } 343*38fd1498Szrj 344*38fd1498Szrj default: 345*38fd1498Szrj { 346*38fd1498Szrj if (TREE_CODE_CLASS (code) == tcc_comparison) 347*38fd1498Szrj { 348*38fd1498Szrj tree cond = build2 (code, boolean_type_node, 349*38fd1498Szrj gimple_assign_rhs1 (def_stmt), 350*38fd1498Szrj gimple_assign_rhs2 (def_stmt)); 351*38fd1498Szrj tree inverted = invert_truthvalue (cond); 352*38fd1498Szrj if (integer_zerop (value)) 353*38fd1498Szrj std::swap (cond, inverted); 354*38fd1498Szrj record_conditions (&this->cond_equivalences, cond, inverted); 355*38fd1498Szrj break; 356*38fd1498Szrj } 357*38fd1498Szrj break; 358*38fd1498Szrj } 359*38fd1498Szrj } 360*38fd1498Szrj } 361*38fd1498Szrj } 362*38fd1498Szrj 363*38fd1498Szrj void 364*38fd1498Szrj edge_info::record_simple_equiv (tree lhs, tree rhs) 365*38fd1498Szrj { 366*38fd1498Szrj /* If the RHS is a constant, then we may be able to derive 367*38fd1498Szrj further equivalences. Else just record the name = name 368*38fd1498Szrj equivalence. */ 369*38fd1498Szrj if (TREE_CODE (rhs) == INTEGER_CST) 370*38fd1498Szrj derive_equivalences (lhs, rhs, 4); 371*38fd1498Szrj else 372*38fd1498Szrj simple_equivalences.safe_push (equiv_pair (lhs, rhs)); 373*38fd1498Szrj } 374*38fd1498Szrj 375*38fd1498Szrj /* Free the edge_info data attached to E, if it exists. */ 376*38fd1498Szrj 377*38fd1498Szrj void 378*38fd1498Szrj free_dom_edge_info (edge e) 379*38fd1498Szrj { 380*38fd1498Szrj class edge_info *edge_info = (struct edge_info *)e->aux; 381*38fd1498Szrj 382*38fd1498Szrj if (edge_info) 383*38fd1498Szrj delete edge_info; 384*38fd1498Szrj } 385*38fd1498Szrj 386*38fd1498Szrj /* Free all EDGE_INFO structures associated with edges in the CFG. 387*38fd1498Szrj If a particular edge can be threaded, copy the redirection 388*38fd1498Szrj target from the EDGE_INFO structure into the edge's AUX field 389*38fd1498Szrj as required by code to update the CFG and SSA graph for 390*38fd1498Szrj jump threading. */ 391*38fd1498Szrj 392*38fd1498Szrj static void 393*38fd1498Szrj free_all_edge_infos (void) 394*38fd1498Szrj { 395*38fd1498Szrj basic_block bb; 396*38fd1498Szrj edge_iterator ei; 397*38fd1498Szrj edge e; 398*38fd1498Szrj 399*38fd1498Szrj FOR_EACH_BB_FN (bb, cfun) 400*38fd1498Szrj { 401*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->preds) 402*38fd1498Szrj { 403*38fd1498Szrj free_dom_edge_info (e); 404*38fd1498Szrj e->aux = NULL; 405*38fd1498Szrj } 406*38fd1498Szrj } 407*38fd1498Szrj } 408*38fd1498Szrj 409*38fd1498Szrj /* We have finished optimizing BB, record any information implied by 410*38fd1498Szrj taking a specific outgoing edge from BB. */ 411*38fd1498Szrj 412*38fd1498Szrj static void 413*38fd1498Szrj record_edge_info (basic_block bb) 414*38fd1498Szrj { 415*38fd1498Szrj gimple_stmt_iterator gsi = gsi_last_bb (bb); 416*38fd1498Szrj class edge_info *edge_info; 417*38fd1498Szrj 418*38fd1498Szrj if (! gsi_end_p (gsi)) 419*38fd1498Szrj { 420*38fd1498Szrj gimple *stmt = gsi_stmt (gsi); 421*38fd1498Szrj location_t loc = gimple_location (stmt); 422*38fd1498Szrj 423*38fd1498Szrj if (gimple_code (stmt) == GIMPLE_SWITCH) 424*38fd1498Szrj { 425*38fd1498Szrj gswitch *switch_stmt = as_a <gswitch *> (stmt); 426*38fd1498Szrj tree index = gimple_switch_index (switch_stmt); 427*38fd1498Szrj 428*38fd1498Szrj if (TREE_CODE (index) == SSA_NAME) 429*38fd1498Szrj { 430*38fd1498Szrj int i; 431*38fd1498Szrj int n_labels = gimple_switch_num_labels (switch_stmt); 432*38fd1498Szrj tree *info = XCNEWVEC (tree, last_basic_block_for_fn (cfun)); 433*38fd1498Szrj edge e; 434*38fd1498Szrj edge_iterator ei; 435*38fd1498Szrj 436*38fd1498Szrj for (i = 0; i < n_labels; i++) 437*38fd1498Szrj { 438*38fd1498Szrj tree label = gimple_switch_label (switch_stmt, i); 439*38fd1498Szrj basic_block target_bb = label_to_block (CASE_LABEL (label)); 440*38fd1498Szrj if (CASE_HIGH (label) 441*38fd1498Szrj || !CASE_LOW (label) 442*38fd1498Szrj || info[target_bb->index]) 443*38fd1498Szrj info[target_bb->index] = error_mark_node; 444*38fd1498Szrj else 445*38fd1498Szrj info[target_bb->index] = label; 446*38fd1498Szrj } 447*38fd1498Szrj 448*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs) 449*38fd1498Szrj { 450*38fd1498Szrj basic_block target_bb = e->dest; 451*38fd1498Szrj tree label = info[target_bb->index]; 452*38fd1498Szrj 453*38fd1498Szrj if (label != NULL && label != error_mark_node) 454*38fd1498Szrj { 455*38fd1498Szrj tree x = fold_convert_loc (loc, TREE_TYPE (index), 456*38fd1498Szrj CASE_LOW (label)); 457*38fd1498Szrj edge_info = new class edge_info (e); 458*38fd1498Szrj edge_info->record_simple_equiv (index, x); 459*38fd1498Szrj } 460*38fd1498Szrj } 461*38fd1498Szrj free (info); 462*38fd1498Szrj } 463*38fd1498Szrj } 464*38fd1498Szrj 465*38fd1498Szrj /* A COND_EXPR may create equivalences too. */ 466*38fd1498Szrj if (gimple_code (stmt) == GIMPLE_COND) 467*38fd1498Szrj { 468*38fd1498Szrj edge true_edge; 469*38fd1498Szrj edge false_edge; 470*38fd1498Szrj 471*38fd1498Szrj tree op0 = gimple_cond_lhs (stmt); 472*38fd1498Szrj tree op1 = gimple_cond_rhs (stmt); 473*38fd1498Szrj enum tree_code code = gimple_cond_code (stmt); 474*38fd1498Szrj 475*38fd1498Szrj extract_true_false_edges_from_block (bb, &true_edge, &false_edge); 476*38fd1498Szrj 477*38fd1498Szrj /* Special case comparing booleans against a constant as we 478*38fd1498Szrj know the value of OP0 on both arms of the branch. i.e., we 479*38fd1498Szrj can record an equivalence for OP0 rather than COND. 480*38fd1498Szrj 481*38fd1498Szrj However, don't do this if the constant isn't zero or one. 482*38fd1498Szrj Such conditionals will get optimized more thoroughly during 483*38fd1498Szrj the domwalk. */ 484*38fd1498Szrj if ((code == EQ_EXPR || code == NE_EXPR) 485*38fd1498Szrj && TREE_CODE (op0) == SSA_NAME 486*38fd1498Szrj && ssa_name_has_boolean_range (op0) 487*38fd1498Szrj && is_gimple_min_invariant (op1) 488*38fd1498Szrj && (integer_zerop (op1) || integer_onep (op1))) 489*38fd1498Szrj { 490*38fd1498Szrj tree true_val = constant_boolean_node (true, TREE_TYPE (op0)); 491*38fd1498Szrj tree false_val = constant_boolean_node (false, TREE_TYPE (op0)); 492*38fd1498Szrj 493*38fd1498Szrj if (code == EQ_EXPR) 494*38fd1498Szrj { 495*38fd1498Szrj edge_info = new class edge_info (true_edge); 496*38fd1498Szrj edge_info->record_simple_equiv (op0, 497*38fd1498Szrj (integer_zerop (op1) 498*38fd1498Szrj ? false_val : true_val)); 499*38fd1498Szrj edge_info = new class edge_info (false_edge); 500*38fd1498Szrj edge_info->record_simple_equiv (op0, 501*38fd1498Szrj (integer_zerop (op1) 502*38fd1498Szrj ? true_val : false_val)); 503*38fd1498Szrj } 504*38fd1498Szrj else 505*38fd1498Szrj { 506*38fd1498Szrj edge_info = new class edge_info (true_edge); 507*38fd1498Szrj edge_info->record_simple_equiv (op0, 508*38fd1498Szrj (integer_zerop (op1) 509*38fd1498Szrj ? true_val : false_val)); 510*38fd1498Szrj edge_info = new class edge_info (false_edge); 511*38fd1498Szrj edge_info->record_simple_equiv (op0, 512*38fd1498Szrj (integer_zerop (op1) 513*38fd1498Szrj ? false_val : true_val)); 514*38fd1498Szrj } 515*38fd1498Szrj } 516*38fd1498Szrj /* This can show up in the IL as a result of copy propagation 517*38fd1498Szrj it will eventually be canonicalized, but we have to cope 518*38fd1498Szrj with this case within the pass. */ 519*38fd1498Szrj else if (is_gimple_min_invariant (op0) 520*38fd1498Szrj && TREE_CODE (op1) == SSA_NAME) 521*38fd1498Szrj { 522*38fd1498Szrj tree cond = build2 (code, boolean_type_node, op0, op1); 523*38fd1498Szrj tree inverted = invert_truthvalue_loc (loc, cond); 524*38fd1498Szrj bool can_infer_simple_equiv 525*38fd1498Szrj = !(HONOR_SIGNED_ZEROS (op0) 526*38fd1498Szrj && real_zerop (op0)); 527*38fd1498Szrj struct edge_info *edge_info; 528*38fd1498Szrj 529*38fd1498Szrj edge_info = new class edge_info (true_edge); 530*38fd1498Szrj record_conditions (&edge_info->cond_equivalences, cond, inverted); 531*38fd1498Szrj 532*38fd1498Szrj if (can_infer_simple_equiv && code == EQ_EXPR) 533*38fd1498Szrj edge_info->record_simple_equiv (op1, op0); 534*38fd1498Szrj 535*38fd1498Szrj edge_info = new class edge_info (false_edge); 536*38fd1498Szrj record_conditions (&edge_info->cond_equivalences, inverted, cond); 537*38fd1498Szrj 538*38fd1498Szrj if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR) 539*38fd1498Szrj edge_info->record_simple_equiv (op1, op0); 540*38fd1498Szrj } 541*38fd1498Szrj 542*38fd1498Szrj else if (TREE_CODE (op0) == SSA_NAME 543*38fd1498Szrj && (TREE_CODE (op1) == SSA_NAME 544*38fd1498Szrj || is_gimple_min_invariant (op1))) 545*38fd1498Szrj { 546*38fd1498Szrj tree cond = build2 (code, boolean_type_node, op0, op1); 547*38fd1498Szrj tree inverted = invert_truthvalue_loc (loc, cond); 548*38fd1498Szrj bool can_infer_simple_equiv 549*38fd1498Szrj = !(HONOR_SIGNED_ZEROS (op1) 550*38fd1498Szrj && (TREE_CODE (op1) == SSA_NAME || real_zerop (op1))); 551*38fd1498Szrj struct edge_info *edge_info; 552*38fd1498Szrj 553*38fd1498Szrj edge_info = new class edge_info (true_edge); 554*38fd1498Szrj record_conditions (&edge_info->cond_equivalences, cond, inverted); 555*38fd1498Szrj 556*38fd1498Szrj if (can_infer_simple_equiv && code == EQ_EXPR) 557*38fd1498Szrj edge_info->record_simple_equiv (op0, op1); 558*38fd1498Szrj 559*38fd1498Szrj edge_info = new class edge_info (false_edge); 560*38fd1498Szrj record_conditions (&edge_info->cond_equivalences, inverted, cond); 561*38fd1498Szrj 562*38fd1498Szrj if (can_infer_simple_equiv && TREE_CODE (inverted) == EQ_EXPR) 563*38fd1498Szrj edge_info->record_simple_equiv (op0, op1); 564*38fd1498Szrj } 565*38fd1498Szrj } 566*38fd1498Szrj } 567*38fd1498Szrj } 568*38fd1498Szrj 569*38fd1498Szrj 570*38fd1498Szrj class dom_opt_dom_walker : public dom_walker 571*38fd1498Szrj { 572*38fd1498Szrj public: 573*38fd1498Szrj dom_opt_dom_walker (cdi_direction direction, 574*38fd1498Szrj class const_and_copies *const_and_copies, 575*38fd1498Szrj class avail_exprs_stack *avail_exprs_stack, 576*38fd1498Szrj gcond *dummy_cond) 577*38fd1498Szrj : dom_walker (direction, REACHABLE_BLOCKS), 578*38fd1498Szrj m_const_and_copies (const_and_copies), 579*38fd1498Szrj m_avail_exprs_stack (avail_exprs_stack), 580*38fd1498Szrj m_dummy_cond (dummy_cond) { } 581*38fd1498Szrj 582*38fd1498Szrj virtual edge before_dom_children (basic_block); 583*38fd1498Szrj virtual void after_dom_children (basic_block); 584*38fd1498Szrj 585*38fd1498Szrj private: 586*38fd1498Szrj 587*38fd1498Szrj /* Unwindable equivalences, both const/copy and expression varieties. */ 588*38fd1498Szrj class const_and_copies *m_const_and_copies; 589*38fd1498Szrj class avail_exprs_stack *m_avail_exprs_stack; 590*38fd1498Szrj 591*38fd1498Szrj /* VRP data. */ 592*38fd1498Szrj class evrp_range_analyzer evrp_range_analyzer; 593*38fd1498Szrj 594*38fd1498Szrj /* Dummy condition to avoid creating lots of throw away statements. */ 595*38fd1498Szrj gcond *m_dummy_cond; 596*38fd1498Szrj 597*38fd1498Szrj /* Optimize a single statement within a basic block using the 598*38fd1498Szrj various tables mantained by DOM. Returns the taken edge if 599*38fd1498Szrj the statement is a conditional with a statically determined 600*38fd1498Szrj value. */ 601*38fd1498Szrj edge optimize_stmt (basic_block, gimple_stmt_iterator); 602*38fd1498Szrj }; 603*38fd1498Szrj 604*38fd1498Szrj /* Jump threading, redundancy elimination and const/copy propagation. 605*38fd1498Szrj 606*38fd1498Szrj This pass may expose new symbols that need to be renamed into SSA. For 607*38fd1498Szrj every new symbol exposed, its corresponding bit will be set in 608*38fd1498Szrj VARS_TO_RENAME. */ 609*38fd1498Szrj 610*38fd1498Szrj namespace { 611*38fd1498Szrj 612*38fd1498Szrj const pass_data pass_data_dominator = 613*38fd1498Szrj { 614*38fd1498Szrj GIMPLE_PASS, /* type */ 615*38fd1498Szrj "dom", /* name */ 616*38fd1498Szrj OPTGROUP_NONE, /* optinfo_flags */ 617*38fd1498Szrj TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */ 618*38fd1498Szrj ( PROP_cfg | PROP_ssa ), /* properties_required */ 619*38fd1498Szrj 0, /* properties_provided */ 620*38fd1498Szrj 0, /* properties_destroyed */ 621*38fd1498Szrj 0, /* todo_flags_start */ 622*38fd1498Szrj ( TODO_cleanup_cfg | TODO_update_ssa ), /* todo_flags_finish */ 623*38fd1498Szrj }; 624*38fd1498Szrj 625*38fd1498Szrj class pass_dominator : public gimple_opt_pass 626*38fd1498Szrj { 627*38fd1498Szrj public: 628*38fd1498Szrj pass_dominator (gcc::context *ctxt) 629*38fd1498Szrj : gimple_opt_pass (pass_data_dominator, ctxt), 630*38fd1498Szrj may_peel_loop_headers_p (false) 631*38fd1498Szrj {} 632*38fd1498Szrj 633*38fd1498Szrj /* opt_pass methods: */ 634*38fd1498Szrj opt_pass * clone () { return new pass_dominator (m_ctxt); } 635*38fd1498Szrj void set_pass_param (unsigned int n, bool param) 636*38fd1498Szrj { 637*38fd1498Szrj gcc_assert (n == 0); 638*38fd1498Szrj may_peel_loop_headers_p = param; 639*38fd1498Szrj } 640*38fd1498Szrj virtual bool gate (function *) { return flag_tree_dom != 0; } 641*38fd1498Szrj virtual unsigned int execute (function *); 642*38fd1498Szrj 643*38fd1498Szrj private: 644*38fd1498Szrj /* This flag is used to prevent loops from being peeled repeatedly in jump 645*38fd1498Szrj threading; it will be removed once we preserve loop structures throughout 646*38fd1498Szrj the compilation -- we will be able to mark the affected loops directly in 647*38fd1498Szrj jump threading, and avoid peeling them next time. */ 648*38fd1498Szrj bool may_peel_loop_headers_p; 649*38fd1498Szrj }; // class pass_dominator 650*38fd1498Szrj 651*38fd1498Szrj unsigned int 652*38fd1498Szrj pass_dominator::execute (function *fun) 653*38fd1498Szrj { 654*38fd1498Szrj memset (&opt_stats, 0, sizeof (opt_stats)); 655*38fd1498Szrj 656*38fd1498Szrj /* Create our hash tables. */ 657*38fd1498Szrj hash_table<expr_elt_hasher> *avail_exprs 658*38fd1498Szrj = new hash_table<expr_elt_hasher> (1024); 659*38fd1498Szrj class avail_exprs_stack *avail_exprs_stack 660*38fd1498Szrj = new class avail_exprs_stack (avail_exprs); 661*38fd1498Szrj class const_and_copies *const_and_copies = new class const_and_copies (); 662*38fd1498Szrj need_eh_cleanup = BITMAP_ALLOC (NULL); 663*38fd1498Szrj need_noreturn_fixup.create (0); 664*38fd1498Szrj 665*38fd1498Szrj calculate_dominance_info (CDI_DOMINATORS); 666*38fd1498Szrj cfg_altered = false; 667*38fd1498Szrj 668*38fd1498Szrj /* We need to know loop structures in order to avoid destroying them 669*38fd1498Szrj in jump threading. Note that we still can e.g. thread through loop 670*38fd1498Szrj headers to an exit edge, or through loop header to the loop body, assuming 671*38fd1498Szrj that we update the loop info. 672*38fd1498Szrj 673*38fd1498Szrj TODO: We don't need to set LOOPS_HAVE_PREHEADERS generally, but due 674*38fd1498Szrj to several overly conservative bail-outs in jump threading, case 675*38fd1498Szrj gcc.dg/tree-ssa/pr21417.c can't be threaded if loop preheader is 676*38fd1498Szrj missing. We should improve jump threading in future then 677*38fd1498Szrj LOOPS_HAVE_PREHEADERS won't be needed here. */ 678*38fd1498Szrj loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES); 679*38fd1498Szrj 680*38fd1498Szrj /* Initialize the value-handle array. */ 681*38fd1498Szrj threadedge_initialize_values (); 682*38fd1498Szrj 683*38fd1498Szrj /* We need accurate information regarding back edges in the CFG 684*38fd1498Szrj for jump threading; this may include back edges that are not part of 685*38fd1498Szrj a single loop. */ 686*38fd1498Szrj mark_dfs_back_edges (); 687*38fd1498Szrj 688*38fd1498Szrj /* We want to create the edge info structures before the dominator walk 689*38fd1498Szrj so that they'll be in place for the jump threader, particularly when 690*38fd1498Szrj threading through a join block. 691*38fd1498Szrj 692*38fd1498Szrj The conditions will be lazily updated with global equivalences as 693*38fd1498Szrj we reach them during the dominator walk. */ 694*38fd1498Szrj basic_block bb; 695*38fd1498Szrj FOR_EACH_BB_FN (bb, fun) 696*38fd1498Szrj record_edge_info (bb); 697*38fd1498Szrj 698*38fd1498Szrj gcond *dummy_cond = gimple_build_cond (NE_EXPR, integer_zero_node, 699*38fd1498Szrj integer_zero_node, NULL, NULL); 700*38fd1498Szrj 701*38fd1498Szrj /* Recursively walk the dominator tree optimizing statements. */ 702*38fd1498Szrj dom_opt_dom_walker walker (CDI_DOMINATORS, const_and_copies, 703*38fd1498Szrj avail_exprs_stack, dummy_cond); 704*38fd1498Szrj walker.walk (fun->cfg->x_entry_block_ptr); 705*38fd1498Szrj 706*38fd1498Szrj /* Look for blocks where we cleared EDGE_EXECUTABLE on an outgoing 707*38fd1498Szrj edge. When found, remove jump threads which contain any outgoing 708*38fd1498Szrj edge from the affected block. */ 709*38fd1498Szrj if (cfg_altered) 710*38fd1498Szrj { 711*38fd1498Szrj FOR_EACH_BB_FN (bb, fun) 712*38fd1498Szrj { 713*38fd1498Szrj edge_iterator ei; 714*38fd1498Szrj edge e; 715*38fd1498Szrj 716*38fd1498Szrj /* First see if there are any edges without EDGE_EXECUTABLE 717*38fd1498Szrj set. */ 718*38fd1498Szrj bool found = false; 719*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs) 720*38fd1498Szrj { 721*38fd1498Szrj if ((e->flags & EDGE_EXECUTABLE) == 0) 722*38fd1498Szrj { 723*38fd1498Szrj found = true; 724*38fd1498Szrj break; 725*38fd1498Szrj } 726*38fd1498Szrj } 727*38fd1498Szrj 728*38fd1498Szrj /* If there were any such edges found, then remove jump threads 729*38fd1498Szrj containing any edge leaving BB. */ 730*38fd1498Szrj if (found) 731*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs) 732*38fd1498Szrj remove_jump_threads_including (e); 733*38fd1498Szrj } 734*38fd1498Szrj } 735*38fd1498Szrj 736*38fd1498Szrj { 737*38fd1498Szrj gimple_stmt_iterator gsi; 738*38fd1498Szrj basic_block bb; 739*38fd1498Szrj FOR_EACH_BB_FN (bb, fun) 740*38fd1498Szrj { 741*38fd1498Szrj for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 742*38fd1498Szrj update_stmt_if_modified (gsi_stmt (gsi)); 743*38fd1498Szrj } 744*38fd1498Szrj } 745*38fd1498Szrj 746*38fd1498Szrj /* If we exposed any new variables, go ahead and put them into 747*38fd1498Szrj SSA form now, before we handle jump threading. This simplifies 748*38fd1498Szrj interactions between rewriting of _DECL nodes into SSA form 749*38fd1498Szrj and rewriting SSA_NAME nodes into SSA form after block 750*38fd1498Szrj duplication and CFG manipulation. */ 751*38fd1498Szrj update_ssa (TODO_update_ssa); 752*38fd1498Szrj 753*38fd1498Szrj free_all_edge_infos (); 754*38fd1498Szrj 755*38fd1498Szrj /* Thread jumps, creating duplicate blocks as needed. */ 756*38fd1498Szrj cfg_altered |= thread_through_all_blocks (may_peel_loop_headers_p); 757*38fd1498Szrj 758*38fd1498Szrj if (cfg_altered) 759*38fd1498Szrj free_dominance_info (CDI_DOMINATORS); 760*38fd1498Szrj 761*38fd1498Szrj /* Removal of statements may make some EH edges dead. Purge 762*38fd1498Szrj such edges from the CFG as needed. */ 763*38fd1498Szrj if (!bitmap_empty_p (need_eh_cleanup)) 764*38fd1498Szrj { 765*38fd1498Szrj unsigned i; 766*38fd1498Szrj bitmap_iterator bi; 767*38fd1498Szrj 768*38fd1498Szrj /* Jump threading may have created forwarder blocks from blocks 769*38fd1498Szrj needing EH cleanup; the new successor of these blocks, which 770*38fd1498Szrj has inherited from the original block, needs the cleanup. 771*38fd1498Szrj Don't clear bits in the bitmap, as that can break the bitmap 772*38fd1498Szrj iterator. */ 773*38fd1498Szrj EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi) 774*38fd1498Szrj { 775*38fd1498Szrj basic_block bb = BASIC_BLOCK_FOR_FN (fun, i); 776*38fd1498Szrj if (bb == NULL) 777*38fd1498Szrj continue; 778*38fd1498Szrj while (single_succ_p (bb) 779*38fd1498Szrj && (single_succ_edge (bb)->flags & EDGE_EH) == 0) 780*38fd1498Szrj bb = single_succ (bb); 781*38fd1498Szrj if (bb == EXIT_BLOCK_PTR_FOR_FN (fun)) 782*38fd1498Szrj continue; 783*38fd1498Szrj if ((unsigned) bb->index != i) 784*38fd1498Szrj bitmap_set_bit (need_eh_cleanup, bb->index); 785*38fd1498Szrj } 786*38fd1498Szrj 787*38fd1498Szrj gimple_purge_all_dead_eh_edges (need_eh_cleanup); 788*38fd1498Szrj bitmap_clear (need_eh_cleanup); 789*38fd1498Szrj } 790*38fd1498Szrj 791*38fd1498Szrj /* Fixup stmts that became noreturn calls. This may require splitting 792*38fd1498Szrj blocks and thus isn't possible during the dominator walk or before 793*38fd1498Szrj jump threading finished. Do this in reverse order so we don't 794*38fd1498Szrj inadvertedly remove a stmt we want to fixup by visiting a dominating 795*38fd1498Szrj now noreturn call first. */ 796*38fd1498Szrj while (!need_noreturn_fixup.is_empty ()) 797*38fd1498Szrj { 798*38fd1498Szrj gimple *stmt = need_noreturn_fixup.pop (); 799*38fd1498Szrj if (dump_file && dump_flags & TDF_DETAILS) 800*38fd1498Szrj { 801*38fd1498Szrj fprintf (dump_file, "Fixing up noreturn call "); 802*38fd1498Szrj print_gimple_stmt (dump_file, stmt, 0); 803*38fd1498Szrj fprintf (dump_file, "\n"); 804*38fd1498Szrj } 805*38fd1498Szrj fixup_noreturn_call (stmt); 806*38fd1498Szrj } 807*38fd1498Szrj 808*38fd1498Szrj statistics_counter_event (fun, "Redundant expressions eliminated", 809*38fd1498Szrj opt_stats.num_re); 810*38fd1498Szrj statistics_counter_event (fun, "Constants propagated", 811*38fd1498Szrj opt_stats.num_const_prop); 812*38fd1498Szrj statistics_counter_event (fun, "Copies propagated", 813*38fd1498Szrj opt_stats.num_copy_prop); 814*38fd1498Szrj 815*38fd1498Szrj /* Debugging dumps. */ 816*38fd1498Szrj if (dump_file && (dump_flags & TDF_STATS)) 817*38fd1498Szrj dump_dominator_optimization_stats (dump_file, avail_exprs); 818*38fd1498Szrj 819*38fd1498Szrj loop_optimizer_finalize (); 820*38fd1498Szrj 821*38fd1498Szrj /* Delete our main hashtable. */ 822*38fd1498Szrj delete avail_exprs; 823*38fd1498Szrj avail_exprs = NULL; 824*38fd1498Szrj 825*38fd1498Szrj /* Free asserted bitmaps and stacks. */ 826*38fd1498Szrj BITMAP_FREE (need_eh_cleanup); 827*38fd1498Szrj need_noreturn_fixup.release (); 828*38fd1498Szrj delete avail_exprs_stack; 829*38fd1498Szrj delete const_and_copies; 830*38fd1498Szrj 831*38fd1498Szrj /* Free the value-handle array. */ 832*38fd1498Szrj threadedge_finalize_values (); 833*38fd1498Szrj 834*38fd1498Szrj return 0; 835*38fd1498Szrj } 836*38fd1498Szrj 837*38fd1498Szrj } // anon namespace 838*38fd1498Szrj 839*38fd1498Szrj gimple_opt_pass * 840*38fd1498Szrj make_pass_dominator (gcc::context *ctxt) 841*38fd1498Szrj { 842*38fd1498Szrj return new pass_dominator (ctxt); 843*38fd1498Szrj } 844*38fd1498Szrj 845*38fd1498Szrj /* A hack until we remove threading from tree-vrp.c and bring the 846*38fd1498Szrj simplification routine into the dom_opt_dom_walker class. */ 847*38fd1498Szrj static class vr_values *x_vr_values; 848*38fd1498Szrj 849*38fd1498Szrj /* A trivial wrapper so that we can present the generic jump 850*38fd1498Szrj threading code with a simple API for simplifying statements. */ 851*38fd1498Szrj static tree 852*38fd1498Szrj simplify_stmt_for_jump_threading (gimple *stmt, 853*38fd1498Szrj gimple *within_stmt ATTRIBUTE_UNUSED, 854*38fd1498Szrj class avail_exprs_stack *avail_exprs_stack, 855*38fd1498Szrj basic_block bb ATTRIBUTE_UNUSED) 856*38fd1498Szrj { 857*38fd1498Szrj /* First query our hash table to see if the the expression is available 858*38fd1498Szrj there. A non-NULL return value will be either a constant or another 859*38fd1498Szrj SSA_NAME. */ 860*38fd1498Szrj tree cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, false, true); 861*38fd1498Szrj if (cached_lhs) 862*38fd1498Szrj return cached_lhs; 863*38fd1498Szrj 864*38fd1498Szrj /* If the hash table query failed, query VRP information. This is 865*38fd1498Szrj essentially the same as tree-vrp's simplification routine. The 866*38fd1498Szrj copy in tree-vrp is scheduled for removal in gcc-9. */ 867*38fd1498Szrj if (gcond *cond_stmt = dyn_cast <gcond *> (stmt)) 868*38fd1498Szrj { 869*38fd1498Szrj cached_lhs 870*38fd1498Szrj = x_vr_values->vrp_evaluate_conditional (gimple_cond_code (cond_stmt), 871*38fd1498Szrj gimple_cond_lhs (cond_stmt), 872*38fd1498Szrj gimple_cond_rhs (cond_stmt), 873*38fd1498Szrj within_stmt); 874*38fd1498Szrj return cached_lhs; 875*38fd1498Szrj } 876*38fd1498Szrj 877*38fd1498Szrj if (gswitch *switch_stmt = dyn_cast <gswitch *> (stmt)) 878*38fd1498Szrj { 879*38fd1498Szrj tree op = gimple_switch_index (switch_stmt); 880*38fd1498Szrj if (TREE_CODE (op) != SSA_NAME) 881*38fd1498Szrj return NULL_TREE; 882*38fd1498Szrj 883*38fd1498Szrj value_range *vr = x_vr_values->get_value_range (op); 884*38fd1498Szrj if ((vr->type != VR_RANGE && vr->type != VR_ANTI_RANGE) 885*38fd1498Szrj || symbolic_range_p (vr)) 886*38fd1498Szrj return NULL_TREE; 887*38fd1498Szrj 888*38fd1498Szrj if (vr->type == VR_RANGE) 889*38fd1498Szrj { 890*38fd1498Szrj size_t i, j; 891*38fd1498Szrj 892*38fd1498Szrj find_case_label_range (switch_stmt, vr->min, vr->max, &i, &j); 893*38fd1498Szrj 894*38fd1498Szrj if (i == j) 895*38fd1498Szrj { 896*38fd1498Szrj tree label = gimple_switch_label (switch_stmt, i); 897*38fd1498Szrj 898*38fd1498Szrj if (CASE_HIGH (label) != NULL_TREE 899*38fd1498Szrj ? (tree_int_cst_compare (CASE_LOW (label), vr->min) <= 0 900*38fd1498Szrj && tree_int_cst_compare (CASE_HIGH (label), vr->max) >= 0) 901*38fd1498Szrj : (tree_int_cst_equal (CASE_LOW (label), vr->min) 902*38fd1498Szrj && tree_int_cst_equal (vr->min, vr->max))) 903*38fd1498Szrj return label; 904*38fd1498Szrj 905*38fd1498Szrj if (i > j) 906*38fd1498Szrj return gimple_switch_label (switch_stmt, 0); 907*38fd1498Szrj } 908*38fd1498Szrj } 909*38fd1498Szrj 910*38fd1498Szrj if (vr->type == VR_ANTI_RANGE) 911*38fd1498Szrj { 912*38fd1498Szrj unsigned n = gimple_switch_num_labels (switch_stmt); 913*38fd1498Szrj tree min_label = gimple_switch_label (switch_stmt, 1); 914*38fd1498Szrj tree max_label = gimple_switch_label (switch_stmt, n - 1); 915*38fd1498Szrj 916*38fd1498Szrj /* The default label will be taken only if the anti-range of the 917*38fd1498Szrj operand is entirely outside the bounds of all the (non-default) 918*38fd1498Szrj case labels. */ 919*38fd1498Szrj if (tree_int_cst_compare (vr->min, CASE_LOW (min_label)) <= 0 920*38fd1498Szrj && (CASE_HIGH (max_label) != NULL_TREE 921*38fd1498Szrj ? tree_int_cst_compare (vr->max, CASE_HIGH (max_label)) >= 0 922*38fd1498Szrj : tree_int_cst_compare (vr->max, CASE_LOW (max_label)) >= 0)) 923*38fd1498Szrj return gimple_switch_label (switch_stmt, 0); 924*38fd1498Szrj } 925*38fd1498Szrj return NULL_TREE; 926*38fd1498Szrj } 927*38fd1498Szrj 928*38fd1498Szrj if (gassign *assign_stmt = dyn_cast <gassign *> (stmt)) 929*38fd1498Szrj { 930*38fd1498Szrj tree lhs = gimple_assign_lhs (assign_stmt); 931*38fd1498Szrj if (TREE_CODE (lhs) == SSA_NAME 932*38fd1498Szrj && (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) 933*38fd1498Szrj || POINTER_TYPE_P (TREE_TYPE (lhs))) 934*38fd1498Szrj && stmt_interesting_for_vrp (stmt)) 935*38fd1498Szrj { 936*38fd1498Szrj edge dummy_e; 937*38fd1498Szrj tree dummy_tree; 938*38fd1498Szrj value_range new_vr = VR_INITIALIZER; 939*38fd1498Szrj x_vr_values->extract_range_from_stmt (stmt, &dummy_e, 940*38fd1498Szrj &dummy_tree, &new_vr); 941*38fd1498Szrj if (range_int_cst_singleton_p (&new_vr)) 942*38fd1498Szrj return new_vr.min; 943*38fd1498Szrj } 944*38fd1498Szrj } 945*38fd1498Szrj return NULL; 946*38fd1498Szrj } 947*38fd1498Szrj 948*38fd1498Szrj /* Valueize hook for gimple_fold_stmt_to_constant_1. */ 949*38fd1498Szrj 950*38fd1498Szrj static tree 951*38fd1498Szrj dom_valueize (tree t) 952*38fd1498Szrj { 953*38fd1498Szrj if (TREE_CODE (t) == SSA_NAME) 954*38fd1498Szrj { 955*38fd1498Szrj tree tem = SSA_NAME_VALUE (t); 956*38fd1498Szrj if (tem) 957*38fd1498Szrj return tem; 958*38fd1498Szrj } 959*38fd1498Szrj return t; 960*38fd1498Szrj } 961*38fd1498Szrj 962*38fd1498Szrj /* We have just found an equivalence for LHS on an edge E. 963*38fd1498Szrj Look backwards to other uses of LHS and see if we can derive 964*38fd1498Szrj additional equivalences that are valid on edge E. */ 965*38fd1498Szrj static void 966*38fd1498Szrj back_propagate_equivalences (tree lhs, edge e, 967*38fd1498Szrj class const_and_copies *const_and_copies) 968*38fd1498Szrj { 969*38fd1498Szrj use_operand_p use_p; 970*38fd1498Szrj imm_use_iterator iter; 971*38fd1498Szrj bitmap domby = NULL; 972*38fd1498Szrj basic_block dest = e->dest; 973*38fd1498Szrj 974*38fd1498Szrj /* Iterate over the uses of LHS to see if any dominate E->dest. 975*38fd1498Szrj If so, they may create useful equivalences too. 976*38fd1498Szrj 977*38fd1498Szrj ??? If the code gets re-organized to a worklist to catch more 978*38fd1498Szrj indirect opportunities and it is made to handle PHIs then this 979*38fd1498Szrj should only consider use_stmts in basic-blocks we have already visited. */ 980*38fd1498Szrj FOR_EACH_IMM_USE_FAST (use_p, iter, lhs) 981*38fd1498Szrj { 982*38fd1498Szrj gimple *use_stmt = USE_STMT (use_p); 983*38fd1498Szrj 984*38fd1498Szrj /* Often the use is in DEST, which we trivially know we can't use. 985*38fd1498Szrj This is cheaper than the dominator set tests below. */ 986*38fd1498Szrj if (dest == gimple_bb (use_stmt)) 987*38fd1498Szrj continue; 988*38fd1498Szrj 989*38fd1498Szrj /* Filter out statements that can never produce a useful 990*38fd1498Szrj equivalence. */ 991*38fd1498Szrj tree lhs2 = gimple_get_lhs (use_stmt); 992*38fd1498Szrj if (!lhs2 || TREE_CODE (lhs2) != SSA_NAME) 993*38fd1498Szrj continue; 994*38fd1498Szrj 995*38fd1498Szrj /* Profiling has shown the domination tests here can be fairly 996*38fd1498Szrj expensive. We get significant improvements by building the 997*38fd1498Szrj set of blocks that dominate BB. We can then just test 998*38fd1498Szrj for set membership below. 999*38fd1498Szrj 1000*38fd1498Szrj We also initialize the set lazily since often the only uses 1001*38fd1498Szrj are going to be in the same block as DEST. */ 1002*38fd1498Szrj if (!domby) 1003*38fd1498Szrj { 1004*38fd1498Szrj domby = BITMAP_ALLOC (NULL); 1005*38fd1498Szrj basic_block bb = get_immediate_dominator (CDI_DOMINATORS, dest); 1006*38fd1498Szrj while (bb) 1007*38fd1498Szrj { 1008*38fd1498Szrj bitmap_set_bit (domby, bb->index); 1009*38fd1498Szrj bb = get_immediate_dominator (CDI_DOMINATORS, bb); 1010*38fd1498Szrj } 1011*38fd1498Szrj } 1012*38fd1498Szrj 1013*38fd1498Szrj /* This tests if USE_STMT does not dominate DEST. */ 1014*38fd1498Szrj if (!bitmap_bit_p (domby, gimple_bb (use_stmt)->index)) 1015*38fd1498Szrj continue; 1016*38fd1498Szrj 1017*38fd1498Szrj /* At this point USE_STMT dominates DEST and may result in a 1018*38fd1498Szrj useful equivalence. Try to simplify its RHS to a constant 1019*38fd1498Szrj or SSA_NAME. */ 1020*38fd1498Szrj tree res = gimple_fold_stmt_to_constant_1 (use_stmt, dom_valueize, 1021*38fd1498Szrj no_follow_ssa_edges); 1022*38fd1498Szrj if (res && (TREE_CODE (res) == SSA_NAME || is_gimple_min_invariant (res))) 1023*38fd1498Szrj record_equality (lhs2, res, const_and_copies); 1024*38fd1498Szrj } 1025*38fd1498Szrj 1026*38fd1498Szrj if (domby) 1027*38fd1498Szrj BITMAP_FREE (domby); 1028*38fd1498Szrj } 1029*38fd1498Szrj 1030*38fd1498Szrj /* Record into CONST_AND_COPIES and AVAIL_EXPRS_STACK any equivalences implied 1031*38fd1498Szrj by traversing edge E (which are cached in E->aux). 1032*38fd1498Szrj 1033*38fd1498Szrj Callers are responsible for managing the unwinding markers. */ 1034*38fd1498Szrj void 1035*38fd1498Szrj record_temporary_equivalences (edge e, 1036*38fd1498Szrj class const_and_copies *const_and_copies, 1037*38fd1498Szrj class avail_exprs_stack *avail_exprs_stack) 1038*38fd1498Szrj { 1039*38fd1498Szrj int i; 1040*38fd1498Szrj class edge_info *edge_info = (class edge_info *) e->aux; 1041*38fd1498Szrj 1042*38fd1498Szrj /* If we have info associated with this edge, record it into 1043*38fd1498Szrj our equivalence tables. */ 1044*38fd1498Szrj if (edge_info) 1045*38fd1498Szrj { 1046*38fd1498Szrj cond_equivalence *eq; 1047*38fd1498Szrj /* If we have 0 = COND or 1 = COND equivalences, record them 1048*38fd1498Szrj into our expression hash tables. */ 1049*38fd1498Szrj for (i = 0; edge_info->cond_equivalences.iterate (i, &eq); ++i) 1050*38fd1498Szrj avail_exprs_stack->record_cond (eq); 1051*38fd1498Szrj 1052*38fd1498Szrj edge_info::equiv_pair *seq; 1053*38fd1498Szrj for (i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i) 1054*38fd1498Szrj { 1055*38fd1498Szrj tree lhs = seq->first; 1056*38fd1498Szrj if (!lhs || TREE_CODE (lhs) != SSA_NAME) 1057*38fd1498Szrj continue; 1058*38fd1498Szrj 1059*38fd1498Szrj /* Record the simple NAME = VALUE equivalence. */ 1060*38fd1498Szrj tree rhs = seq->second; 1061*38fd1498Szrj 1062*38fd1498Szrj /* If this is a SSA_NAME = SSA_NAME equivalence and one operand is 1063*38fd1498Szrj cheaper to compute than the other, then set up the equivalence 1064*38fd1498Szrj such that we replace the expensive one with the cheap one. 1065*38fd1498Szrj 1066*38fd1498Szrj If they are the same cost to compute, then do not record 1067*38fd1498Szrj anything. */ 1068*38fd1498Szrj if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME) 1069*38fd1498Szrj { 1070*38fd1498Szrj gimple *rhs_def = SSA_NAME_DEF_STMT (rhs); 1071*38fd1498Szrj int rhs_cost = estimate_num_insns (rhs_def, &eni_size_weights); 1072*38fd1498Szrj 1073*38fd1498Szrj gimple *lhs_def = SSA_NAME_DEF_STMT (lhs); 1074*38fd1498Szrj int lhs_cost = estimate_num_insns (lhs_def, &eni_size_weights); 1075*38fd1498Szrj 1076*38fd1498Szrj if (rhs_cost > lhs_cost) 1077*38fd1498Szrj record_equality (rhs, lhs, const_and_copies); 1078*38fd1498Szrj else if (rhs_cost < lhs_cost) 1079*38fd1498Szrj record_equality (lhs, rhs, const_and_copies); 1080*38fd1498Szrj } 1081*38fd1498Szrj else 1082*38fd1498Szrj record_equality (lhs, rhs, const_and_copies); 1083*38fd1498Szrj 1084*38fd1498Szrj 1085*38fd1498Szrj /* Any equivalence found for LHS may result in additional 1086*38fd1498Szrj equivalences for other uses of LHS that we have already 1087*38fd1498Szrj processed. */ 1088*38fd1498Szrj back_propagate_equivalences (lhs, e, const_and_copies); 1089*38fd1498Szrj } 1090*38fd1498Szrj } 1091*38fd1498Szrj } 1092*38fd1498Szrj 1093*38fd1498Szrj /* PHI nodes can create equivalences too. 1094*38fd1498Szrj 1095*38fd1498Szrj Ignoring any alternatives which are the same as the result, if 1096*38fd1498Szrj all the alternatives are equal, then the PHI node creates an 1097*38fd1498Szrj equivalence. */ 1098*38fd1498Szrj 1099*38fd1498Szrj static void 1100*38fd1498Szrj record_equivalences_from_phis (basic_block bb) 1101*38fd1498Szrj { 1102*38fd1498Szrj gphi_iterator gsi; 1103*38fd1498Szrj 1104*38fd1498Szrj for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 1105*38fd1498Szrj { 1106*38fd1498Szrj gphi *phi = gsi.phi (); 1107*38fd1498Szrj 1108*38fd1498Szrj tree lhs = gimple_phi_result (phi); 1109*38fd1498Szrj tree rhs = NULL; 1110*38fd1498Szrj size_t i; 1111*38fd1498Szrj 1112*38fd1498Szrj for (i = 0; i < gimple_phi_num_args (phi); i++) 1113*38fd1498Szrj { 1114*38fd1498Szrj tree t = gimple_phi_arg_def (phi, i); 1115*38fd1498Szrj 1116*38fd1498Szrj /* Ignore alternatives which are the same as our LHS. Since 1117*38fd1498Szrj LHS is a PHI_RESULT, it is known to be a SSA_NAME, so we 1118*38fd1498Szrj can simply compare pointers. */ 1119*38fd1498Szrj if (lhs == t) 1120*38fd1498Szrj continue; 1121*38fd1498Szrj 1122*38fd1498Szrj /* If the associated edge is not marked as executable, then it 1123*38fd1498Szrj can be ignored. */ 1124*38fd1498Szrj if ((gimple_phi_arg_edge (phi, i)->flags & EDGE_EXECUTABLE) == 0) 1125*38fd1498Szrj continue; 1126*38fd1498Szrj 1127*38fd1498Szrj t = dom_valueize (t); 1128*38fd1498Szrj 1129*38fd1498Szrj /* If T is an SSA_NAME and its associated edge is a backedge, 1130*38fd1498Szrj then quit as we can not utilize this equivalence. */ 1131*38fd1498Szrj if (TREE_CODE (t) == SSA_NAME 1132*38fd1498Szrj && (gimple_phi_arg_edge (phi, i)->flags & EDGE_DFS_BACK)) 1133*38fd1498Szrj break; 1134*38fd1498Szrj 1135*38fd1498Szrj /* If we have not processed an alternative yet, then set 1136*38fd1498Szrj RHS to this alternative. */ 1137*38fd1498Szrj if (rhs == NULL) 1138*38fd1498Szrj rhs = t; 1139*38fd1498Szrj /* If we have processed an alternative (stored in RHS), then 1140*38fd1498Szrj see if it is equal to this one. If it isn't, then stop 1141*38fd1498Szrj the search. */ 1142*38fd1498Szrj else if (! operand_equal_for_phi_arg_p (rhs, t)) 1143*38fd1498Szrj break; 1144*38fd1498Szrj } 1145*38fd1498Szrj 1146*38fd1498Szrj /* If we had no interesting alternatives, then all the RHS alternatives 1147*38fd1498Szrj must have been the same as LHS. */ 1148*38fd1498Szrj if (!rhs) 1149*38fd1498Szrj rhs = lhs; 1150*38fd1498Szrj 1151*38fd1498Szrj /* If we managed to iterate through each PHI alternative without 1152*38fd1498Szrj breaking out of the loop, then we have a PHI which may create 1153*38fd1498Szrj a useful equivalence. We do not need to record unwind data for 1154*38fd1498Szrj this, since this is a true assignment and not an equivalence 1155*38fd1498Szrj inferred from a comparison. All uses of this ssa name are dominated 1156*38fd1498Szrj by this assignment, so unwinding just costs time and space. */ 1157*38fd1498Szrj if (i == gimple_phi_num_args (phi) 1158*38fd1498Szrj && may_propagate_copy (lhs, rhs)) 1159*38fd1498Szrj set_ssa_name_value (lhs, rhs); 1160*38fd1498Szrj } 1161*38fd1498Szrj } 1162*38fd1498Szrj 1163*38fd1498Szrj /* Record any equivalences created by the incoming edge to BB into 1164*38fd1498Szrj CONST_AND_COPIES and AVAIL_EXPRS_STACK. If BB has more than one 1165*38fd1498Szrj incoming edge, then no equivalence is created. */ 1166*38fd1498Szrj 1167*38fd1498Szrj static void 1168*38fd1498Szrj record_equivalences_from_incoming_edge (basic_block bb, 1169*38fd1498Szrj class const_and_copies *const_and_copies, 1170*38fd1498Szrj class avail_exprs_stack *avail_exprs_stack) 1171*38fd1498Szrj { 1172*38fd1498Szrj edge e; 1173*38fd1498Szrj basic_block parent; 1174*38fd1498Szrj 1175*38fd1498Szrj /* If our parent block ended with a control statement, then we may be 1176*38fd1498Szrj able to record some equivalences based on which outgoing edge from 1177*38fd1498Szrj the parent was followed. */ 1178*38fd1498Szrj parent = get_immediate_dominator (CDI_DOMINATORS, bb); 1179*38fd1498Szrj 1180*38fd1498Szrj e = single_pred_edge_ignoring_loop_edges (bb, true); 1181*38fd1498Szrj 1182*38fd1498Szrj /* If we had a single incoming edge from our parent block, then enter 1183*38fd1498Szrj any data associated with the edge into our tables. */ 1184*38fd1498Szrj if (e && e->src == parent) 1185*38fd1498Szrj record_temporary_equivalences (e, const_and_copies, avail_exprs_stack); 1186*38fd1498Szrj } 1187*38fd1498Szrj 1188*38fd1498Szrj /* Dump statistics for the hash table HTAB. */ 1189*38fd1498Szrj 1190*38fd1498Szrj static void 1191*38fd1498Szrj htab_statistics (FILE *file, const hash_table<expr_elt_hasher> &htab) 1192*38fd1498Szrj { 1193*38fd1498Szrj fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n", 1194*38fd1498Szrj (long) htab.size (), 1195*38fd1498Szrj (long) htab.elements (), 1196*38fd1498Szrj htab.collisions ()); 1197*38fd1498Szrj } 1198*38fd1498Szrj 1199*38fd1498Szrj /* Dump SSA statistics on FILE. */ 1200*38fd1498Szrj 1201*38fd1498Szrj static void 1202*38fd1498Szrj dump_dominator_optimization_stats (FILE *file, 1203*38fd1498Szrj hash_table<expr_elt_hasher> *avail_exprs) 1204*38fd1498Szrj { 1205*38fd1498Szrj fprintf (file, "Total number of statements: %6ld\n\n", 1206*38fd1498Szrj opt_stats.num_stmts); 1207*38fd1498Szrj fprintf (file, "Exprs considered for dominator optimizations: %6ld\n", 1208*38fd1498Szrj opt_stats.num_exprs_considered); 1209*38fd1498Szrj 1210*38fd1498Szrj fprintf (file, "\nHash table statistics:\n"); 1211*38fd1498Szrj 1212*38fd1498Szrj fprintf (file, " avail_exprs: "); 1213*38fd1498Szrj htab_statistics (file, *avail_exprs); 1214*38fd1498Szrj } 1215*38fd1498Szrj 1216*38fd1498Szrj 1217*38fd1498Szrj /* Similarly, but assume that X and Y are the two operands of an EQ_EXPR. 1218*38fd1498Szrj This constrains the cases in which we may treat this as assignment. */ 1219*38fd1498Szrj 1220*38fd1498Szrj static void 1221*38fd1498Szrj record_equality (tree x, tree y, class const_and_copies *const_and_copies) 1222*38fd1498Szrj { 1223*38fd1498Szrj tree prev_x = NULL, prev_y = NULL; 1224*38fd1498Szrj 1225*38fd1498Szrj if (tree_swap_operands_p (x, y)) 1226*38fd1498Szrj std::swap (x, y); 1227*38fd1498Szrj 1228*38fd1498Szrj /* Most of the time tree_swap_operands_p does what we want. But there 1229*38fd1498Szrj are cases where we know one operand is better for copy propagation than 1230*38fd1498Szrj the other. Given no other code cares about ordering of equality 1231*38fd1498Szrj comparison operators for that purpose, we just handle the special cases 1232*38fd1498Szrj here. */ 1233*38fd1498Szrj if (TREE_CODE (x) == SSA_NAME && TREE_CODE (y) == SSA_NAME) 1234*38fd1498Szrj { 1235*38fd1498Szrj /* If one operand is a single use operand, then make it 1236*38fd1498Szrj X. This will preserve its single use properly and if this 1237*38fd1498Szrj conditional is eliminated, the computation of X can be 1238*38fd1498Szrj eliminated as well. */ 1239*38fd1498Szrj if (has_single_use (y) && ! has_single_use (x)) 1240*38fd1498Szrj std::swap (x, y); 1241*38fd1498Szrj } 1242*38fd1498Szrj if (TREE_CODE (x) == SSA_NAME) 1243*38fd1498Szrj prev_x = SSA_NAME_VALUE (x); 1244*38fd1498Szrj if (TREE_CODE (y) == SSA_NAME) 1245*38fd1498Szrj prev_y = SSA_NAME_VALUE (y); 1246*38fd1498Szrj 1247*38fd1498Szrj /* If one of the previous values is invariant, or invariant in more loops 1248*38fd1498Szrj (by depth), then use that. 1249*38fd1498Szrj Otherwise it doesn't matter which value we choose, just so 1250*38fd1498Szrj long as we canonicalize on one value. */ 1251*38fd1498Szrj if (is_gimple_min_invariant (y)) 1252*38fd1498Szrj ; 1253*38fd1498Szrj else if (is_gimple_min_invariant (x)) 1254*38fd1498Szrj prev_x = x, x = y, y = prev_x, prev_x = prev_y; 1255*38fd1498Szrj else if (prev_x && is_gimple_min_invariant (prev_x)) 1256*38fd1498Szrj x = y, y = prev_x, prev_x = prev_y; 1257*38fd1498Szrj else if (prev_y) 1258*38fd1498Szrj y = prev_y; 1259*38fd1498Szrj 1260*38fd1498Szrj /* After the swapping, we must have one SSA_NAME. */ 1261*38fd1498Szrj if (TREE_CODE (x) != SSA_NAME) 1262*38fd1498Szrj return; 1263*38fd1498Szrj 1264*38fd1498Szrj /* For IEEE, -0.0 == 0.0, so we don't necessarily know the sign of a 1265*38fd1498Szrj variable compared against zero. If we're honoring signed zeros, 1266*38fd1498Szrj then we cannot record this value unless we know that the value is 1267*38fd1498Szrj nonzero. */ 1268*38fd1498Szrj if (HONOR_SIGNED_ZEROS (x) 1269*38fd1498Szrj && (TREE_CODE (y) != REAL_CST 1270*38fd1498Szrj || real_equal (&dconst0, &TREE_REAL_CST (y)))) 1271*38fd1498Szrj return; 1272*38fd1498Szrj 1273*38fd1498Szrj const_and_copies->record_const_or_copy (x, y, prev_x); 1274*38fd1498Szrj } 1275*38fd1498Szrj 1276*38fd1498Szrj /* Returns true when STMT is a simple iv increment. It detects the 1277*38fd1498Szrj following situation: 1278*38fd1498Szrj 1279*38fd1498Szrj i_1 = phi (..., i_k) 1280*38fd1498Szrj [...] 1281*38fd1498Szrj i_j = i_{j-1} for each j : 2 <= j <= k-1 1282*38fd1498Szrj [...] 1283*38fd1498Szrj i_k = i_{k-1} +/- ... */ 1284*38fd1498Szrj 1285*38fd1498Szrj bool 1286*38fd1498Szrj simple_iv_increment_p (gimple *stmt) 1287*38fd1498Szrj { 1288*38fd1498Szrj enum tree_code code; 1289*38fd1498Szrj tree lhs, preinc; 1290*38fd1498Szrj gimple *phi; 1291*38fd1498Szrj size_t i; 1292*38fd1498Szrj 1293*38fd1498Szrj if (gimple_code (stmt) != GIMPLE_ASSIGN) 1294*38fd1498Szrj return false; 1295*38fd1498Szrj 1296*38fd1498Szrj lhs = gimple_assign_lhs (stmt); 1297*38fd1498Szrj if (TREE_CODE (lhs) != SSA_NAME) 1298*38fd1498Szrj return false; 1299*38fd1498Szrj 1300*38fd1498Szrj code = gimple_assign_rhs_code (stmt); 1301*38fd1498Szrj if (code != PLUS_EXPR 1302*38fd1498Szrj && code != MINUS_EXPR 1303*38fd1498Szrj && code != POINTER_PLUS_EXPR) 1304*38fd1498Szrj return false; 1305*38fd1498Szrj 1306*38fd1498Szrj preinc = gimple_assign_rhs1 (stmt); 1307*38fd1498Szrj if (TREE_CODE (preinc) != SSA_NAME) 1308*38fd1498Szrj return false; 1309*38fd1498Szrj 1310*38fd1498Szrj phi = SSA_NAME_DEF_STMT (preinc); 1311*38fd1498Szrj while (gimple_code (phi) != GIMPLE_PHI) 1312*38fd1498Szrj { 1313*38fd1498Szrj /* Follow trivial copies, but not the DEF used in a back edge, 1314*38fd1498Szrj so that we don't prevent coalescing. */ 1315*38fd1498Szrj if (!gimple_assign_ssa_name_copy_p (phi)) 1316*38fd1498Szrj return false; 1317*38fd1498Szrj preinc = gimple_assign_rhs1 (phi); 1318*38fd1498Szrj phi = SSA_NAME_DEF_STMT (preinc); 1319*38fd1498Szrj } 1320*38fd1498Szrj 1321*38fd1498Szrj for (i = 0; i < gimple_phi_num_args (phi); i++) 1322*38fd1498Szrj if (gimple_phi_arg_def (phi, i) == lhs) 1323*38fd1498Szrj return true; 1324*38fd1498Szrj 1325*38fd1498Szrj return false; 1326*38fd1498Szrj } 1327*38fd1498Szrj 1328*38fd1498Szrj /* Propagate know values from SSA_NAME_VALUE into the PHI nodes of the 1329*38fd1498Szrj successors of BB. */ 1330*38fd1498Szrj 1331*38fd1498Szrj static void 1332*38fd1498Szrj cprop_into_successor_phis (basic_block bb, 1333*38fd1498Szrj class const_and_copies *const_and_copies) 1334*38fd1498Szrj { 1335*38fd1498Szrj edge e; 1336*38fd1498Szrj edge_iterator ei; 1337*38fd1498Szrj 1338*38fd1498Szrj FOR_EACH_EDGE (e, ei, bb->succs) 1339*38fd1498Szrj { 1340*38fd1498Szrj int indx; 1341*38fd1498Szrj gphi_iterator gsi; 1342*38fd1498Szrj 1343*38fd1498Szrj /* If this is an abnormal edge, then we do not want to copy propagate 1344*38fd1498Szrj into the PHI alternative associated with this edge. */ 1345*38fd1498Szrj if (e->flags & EDGE_ABNORMAL) 1346*38fd1498Szrj continue; 1347*38fd1498Szrj 1348*38fd1498Szrj gsi = gsi_start_phis (e->dest); 1349*38fd1498Szrj if (gsi_end_p (gsi)) 1350*38fd1498Szrj continue; 1351*38fd1498Szrj 1352*38fd1498Szrj /* We may have an equivalence associated with this edge. While 1353*38fd1498Szrj we can not propagate it into non-dominated blocks, we can 1354*38fd1498Szrj propagate them into PHIs in non-dominated blocks. */ 1355*38fd1498Szrj 1356*38fd1498Szrj /* Push the unwind marker so we can reset the const and copies 1357*38fd1498Szrj table back to its original state after processing this edge. */ 1358*38fd1498Szrj const_and_copies->push_marker (); 1359*38fd1498Szrj 1360*38fd1498Szrj /* Extract and record any simple NAME = VALUE equivalences. 1361*38fd1498Szrj 1362*38fd1498Szrj Don't bother with [01] = COND equivalences, they're not useful 1363*38fd1498Szrj here. */ 1364*38fd1498Szrj class edge_info *edge_info = (class edge_info *) e->aux; 1365*38fd1498Szrj 1366*38fd1498Szrj if (edge_info) 1367*38fd1498Szrj { 1368*38fd1498Szrj edge_info::equiv_pair *seq; 1369*38fd1498Szrj for (int i = 0; edge_info->simple_equivalences.iterate (i, &seq); ++i) 1370*38fd1498Szrj { 1371*38fd1498Szrj tree lhs = seq->first; 1372*38fd1498Szrj tree rhs = seq->second; 1373*38fd1498Szrj 1374*38fd1498Szrj if (lhs && TREE_CODE (lhs) == SSA_NAME) 1375*38fd1498Szrj const_and_copies->record_const_or_copy (lhs, rhs); 1376*38fd1498Szrj } 1377*38fd1498Szrj 1378*38fd1498Szrj } 1379*38fd1498Szrj 1380*38fd1498Szrj indx = e->dest_idx; 1381*38fd1498Szrj for ( ; !gsi_end_p (gsi); gsi_next (&gsi)) 1382*38fd1498Szrj { 1383*38fd1498Szrj tree new_val; 1384*38fd1498Szrj use_operand_p orig_p; 1385*38fd1498Szrj tree orig_val; 1386*38fd1498Szrj gphi *phi = gsi.phi (); 1387*38fd1498Szrj 1388*38fd1498Szrj /* The alternative may be associated with a constant, so verify 1389*38fd1498Szrj it is an SSA_NAME before doing anything with it. */ 1390*38fd1498Szrj orig_p = gimple_phi_arg_imm_use_ptr (phi, indx); 1391*38fd1498Szrj orig_val = get_use_from_ptr (orig_p); 1392*38fd1498Szrj if (TREE_CODE (orig_val) != SSA_NAME) 1393*38fd1498Szrj continue; 1394*38fd1498Szrj 1395*38fd1498Szrj /* If we have *ORIG_P in our constant/copy table, then replace 1396*38fd1498Szrj ORIG_P with its value in our constant/copy table. */ 1397*38fd1498Szrj new_val = SSA_NAME_VALUE (orig_val); 1398*38fd1498Szrj if (new_val 1399*38fd1498Szrj && new_val != orig_val 1400*38fd1498Szrj && may_propagate_copy (orig_val, new_val)) 1401*38fd1498Szrj propagate_value (orig_p, new_val); 1402*38fd1498Szrj } 1403*38fd1498Szrj 1404*38fd1498Szrj const_and_copies->pop_to_marker (); 1405*38fd1498Szrj } 1406*38fd1498Szrj } 1407*38fd1498Szrj 1408*38fd1498Szrj edge 1409*38fd1498Szrj dom_opt_dom_walker::before_dom_children (basic_block bb) 1410*38fd1498Szrj { 1411*38fd1498Szrj gimple_stmt_iterator gsi; 1412*38fd1498Szrj 1413*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 1414*38fd1498Szrj fprintf (dump_file, "\n\nOptimizing block #%d\n\n", bb->index); 1415*38fd1498Szrj 1416*38fd1498Szrj evrp_range_analyzer.enter (bb); 1417*38fd1498Szrj 1418*38fd1498Szrj /* Push a marker on the stacks of local information so that we know how 1419*38fd1498Szrj far to unwind when we finalize this block. */ 1420*38fd1498Szrj m_avail_exprs_stack->push_marker (); 1421*38fd1498Szrj m_const_and_copies->push_marker (); 1422*38fd1498Szrj 1423*38fd1498Szrj record_equivalences_from_incoming_edge (bb, m_const_and_copies, 1424*38fd1498Szrj m_avail_exprs_stack); 1425*38fd1498Szrj 1426*38fd1498Szrj /* PHI nodes can create equivalences too. */ 1427*38fd1498Szrj record_equivalences_from_phis (bb); 1428*38fd1498Szrj 1429*38fd1498Szrj /* Create equivalences from redundant PHIs. PHIs are only truly 1430*38fd1498Szrj redundant when they exist in the same block, so push another 1431*38fd1498Szrj marker and unwind right afterwards. */ 1432*38fd1498Szrj m_avail_exprs_stack->push_marker (); 1433*38fd1498Szrj for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 1434*38fd1498Szrj eliminate_redundant_computations (&gsi, m_const_and_copies, 1435*38fd1498Szrj m_avail_exprs_stack); 1436*38fd1498Szrj m_avail_exprs_stack->pop_to_marker (); 1437*38fd1498Szrj 1438*38fd1498Szrj edge taken_edge = NULL; 1439*38fd1498Szrj for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 1440*38fd1498Szrj { 1441*38fd1498Szrj evrp_range_analyzer.record_ranges_from_stmt (gsi_stmt (gsi), false); 1442*38fd1498Szrj taken_edge = this->optimize_stmt (bb, gsi); 1443*38fd1498Szrj } 1444*38fd1498Szrj 1445*38fd1498Szrj /* Now prepare to process dominated blocks. */ 1446*38fd1498Szrj record_edge_info (bb); 1447*38fd1498Szrj cprop_into_successor_phis (bb, m_const_and_copies); 1448*38fd1498Szrj if (taken_edge && !dbg_cnt (dom_unreachable_edges)) 1449*38fd1498Szrj return NULL; 1450*38fd1498Szrj 1451*38fd1498Szrj return taken_edge; 1452*38fd1498Szrj } 1453*38fd1498Szrj 1454*38fd1498Szrj /* We have finished processing the dominator children of BB, perform 1455*38fd1498Szrj any finalization actions in preparation for leaving this node in 1456*38fd1498Szrj the dominator tree. */ 1457*38fd1498Szrj 1458*38fd1498Szrj void 1459*38fd1498Szrj dom_opt_dom_walker::after_dom_children (basic_block bb) 1460*38fd1498Szrj { 1461*38fd1498Szrj x_vr_values = evrp_range_analyzer.get_vr_values (); 1462*38fd1498Szrj thread_outgoing_edges (bb, m_dummy_cond, m_const_and_copies, 1463*38fd1498Szrj m_avail_exprs_stack, 1464*38fd1498Szrj &evrp_range_analyzer, 1465*38fd1498Szrj simplify_stmt_for_jump_threading); 1466*38fd1498Szrj x_vr_values = NULL; 1467*38fd1498Szrj 1468*38fd1498Szrj /* These remove expressions local to BB from the tables. */ 1469*38fd1498Szrj m_avail_exprs_stack->pop_to_marker (); 1470*38fd1498Szrj m_const_and_copies->pop_to_marker (); 1471*38fd1498Szrj evrp_range_analyzer.leave (bb); 1472*38fd1498Szrj } 1473*38fd1498Szrj 1474*38fd1498Szrj /* Search for redundant computations in STMT. If any are found, then 1475*38fd1498Szrj replace them with the variable holding the result of the computation. 1476*38fd1498Szrj 1477*38fd1498Szrj If safe, record this expression into AVAIL_EXPRS_STACK and 1478*38fd1498Szrj CONST_AND_COPIES. */ 1479*38fd1498Szrj 1480*38fd1498Szrj static void 1481*38fd1498Szrj eliminate_redundant_computations (gimple_stmt_iterator* gsi, 1482*38fd1498Szrj class const_and_copies *const_and_copies, 1483*38fd1498Szrj class avail_exprs_stack *avail_exprs_stack) 1484*38fd1498Szrj { 1485*38fd1498Szrj tree expr_type; 1486*38fd1498Szrj tree cached_lhs; 1487*38fd1498Szrj tree def; 1488*38fd1498Szrj bool insert = true; 1489*38fd1498Szrj bool assigns_var_p = false; 1490*38fd1498Szrj 1491*38fd1498Szrj gimple *stmt = gsi_stmt (*gsi); 1492*38fd1498Szrj 1493*38fd1498Szrj if (gimple_code (stmt) == GIMPLE_PHI) 1494*38fd1498Szrj def = gimple_phi_result (stmt); 1495*38fd1498Szrj else 1496*38fd1498Szrj def = gimple_get_lhs (stmt); 1497*38fd1498Szrj 1498*38fd1498Szrj /* Certain expressions on the RHS can be optimized away, but can not 1499*38fd1498Szrj themselves be entered into the hash tables. */ 1500*38fd1498Szrj if (! def 1501*38fd1498Szrj || TREE_CODE (def) != SSA_NAME 1502*38fd1498Szrj || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def) 1503*38fd1498Szrj || gimple_vdef (stmt) 1504*38fd1498Szrj /* Do not record equivalences for increments of ivs. This would create 1505*38fd1498Szrj overlapping live ranges for a very questionable gain. */ 1506*38fd1498Szrj || simple_iv_increment_p (stmt)) 1507*38fd1498Szrj insert = false; 1508*38fd1498Szrj 1509*38fd1498Szrj /* Check if the expression has been computed before. */ 1510*38fd1498Szrj cached_lhs = avail_exprs_stack->lookup_avail_expr (stmt, insert, true); 1511*38fd1498Szrj 1512*38fd1498Szrj opt_stats.num_exprs_considered++; 1513*38fd1498Szrj 1514*38fd1498Szrj /* Get the type of the expression we are trying to optimize. */ 1515*38fd1498Szrj if (is_gimple_assign (stmt)) 1516*38fd1498Szrj { 1517*38fd1498Szrj expr_type = TREE_TYPE (gimple_assign_lhs (stmt)); 1518*38fd1498Szrj assigns_var_p = true; 1519*38fd1498Szrj } 1520*38fd1498Szrj else if (gimple_code (stmt) == GIMPLE_COND) 1521*38fd1498Szrj expr_type = boolean_type_node; 1522*38fd1498Szrj else if (is_gimple_call (stmt)) 1523*38fd1498Szrj { 1524*38fd1498Szrj gcc_assert (gimple_call_lhs (stmt)); 1525*38fd1498Szrj expr_type = TREE_TYPE (gimple_call_lhs (stmt)); 1526*38fd1498Szrj assigns_var_p = true; 1527*38fd1498Szrj } 1528*38fd1498Szrj else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt)) 1529*38fd1498Szrj expr_type = TREE_TYPE (gimple_switch_index (swtch_stmt)); 1530*38fd1498Szrj else if (gimple_code (stmt) == GIMPLE_PHI) 1531*38fd1498Szrj /* We can't propagate into a phi, so the logic below doesn't apply. 1532*38fd1498Szrj Instead record an equivalence between the cached LHS and the 1533*38fd1498Szrj PHI result of this statement, provided they are in the same block. 1534*38fd1498Szrj This should be sufficient to kill the redundant phi. */ 1535*38fd1498Szrj { 1536*38fd1498Szrj if (def && cached_lhs) 1537*38fd1498Szrj const_and_copies->record_const_or_copy (def, cached_lhs); 1538*38fd1498Szrj return; 1539*38fd1498Szrj } 1540*38fd1498Szrj else 1541*38fd1498Szrj gcc_unreachable (); 1542*38fd1498Szrj 1543*38fd1498Szrj if (!cached_lhs) 1544*38fd1498Szrj return; 1545*38fd1498Szrj 1546*38fd1498Szrj /* It is safe to ignore types here since we have already done 1547*38fd1498Szrj type checking in the hashing and equality routines. In fact 1548*38fd1498Szrj type checking here merely gets in the way of constant 1549*38fd1498Szrj propagation. Also, make sure that it is safe to propagate 1550*38fd1498Szrj CACHED_LHS into the expression in STMT. */ 1551*38fd1498Szrj if ((TREE_CODE (cached_lhs) != SSA_NAME 1552*38fd1498Szrj && (assigns_var_p 1553*38fd1498Szrj || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))) 1554*38fd1498Szrj || may_propagate_copy_into_stmt (stmt, cached_lhs)) 1555*38fd1498Szrj { 1556*38fd1498Szrj gcc_checking_assert (TREE_CODE (cached_lhs) == SSA_NAME 1557*38fd1498Szrj || is_gimple_min_invariant (cached_lhs)); 1558*38fd1498Szrj 1559*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 1560*38fd1498Szrj { 1561*38fd1498Szrj fprintf (dump_file, " Replaced redundant expr '"); 1562*38fd1498Szrj print_gimple_expr (dump_file, stmt, 0, dump_flags); 1563*38fd1498Szrj fprintf (dump_file, "' with '"); 1564*38fd1498Szrj print_generic_expr (dump_file, cached_lhs, dump_flags); 1565*38fd1498Szrj fprintf (dump_file, "'\n"); 1566*38fd1498Szrj } 1567*38fd1498Szrj 1568*38fd1498Szrj opt_stats.num_re++; 1569*38fd1498Szrj 1570*38fd1498Szrj if (assigns_var_p 1571*38fd1498Szrj && !useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs))) 1572*38fd1498Szrj cached_lhs = fold_convert (expr_type, cached_lhs); 1573*38fd1498Szrj 1574*38fd1498Szrj propagate_tree_value_into_stmt (gsi, cached_lhs); 1575*38fd1498Szrj 1576*38fd1498Szrj /* Since it is always necessary to mark the result as modified, 1577*38fd1498Szrj perhaps we should move this into propagate_tree_value_into_stmt 1578*38fd1498Szrj itself. */ 1579*38fd1498Szrj gimple_set_modified (gsi_stmt (*gsi), true); 1580*38fd1498Szrj } 1581*38fd1498Szrj } 1582*38fd1498Szrj 1583*38fd1498Szrj /* STMT, a GIMPLE_ASSIGN, may create certain equivalences, in either 1584*38fd1498Szrj the available expressions table or the const_and_copies table. 1585*38fd1498Szrj Detect and record those equivalences into AVAIL_EXPRS_STACK. 1586*38fd1498Szrj 1587*38fd1498Szrj We handle only very simple copy equivalences here. The heavy 1588*38fd1498Szrj lifing is done by eliminate_redundant_computations. */ 1589*38fd1498Szrj 1590*38fd1498Szrj static void 1591*38fd1498Szrj record_equivalences_from_stmt (gimple *stmt, int may_optimize_p, 1592*38fd1498Szrj class avail_exprs_stack *avail_exprs_stack) 1593*38fd1498Szrj { 1594*38fd1498Szrj tree lhs; 1595*38fd1498Szrj enum tree_code lhs_code; 1596*38fd1498Szrj 1597*38fd1498Szrj gcc_assert (is_gimple_assign (stmt)); 1598*38fd1498Szrj 1599*38fd1498Szrj lhs = gimple_assign_lhs (stmt); 1600*38fd1498Szrj lhs_code = TREE_CODE (lhs); 1601*38fd1498Szrj 1602*38fd1498Szrj if (lhs_code == SSA_NAME 1603*38fd1498Szrj && gimple_assign_single_p (stmt)) 1604*38fd1498Szrj { 1605*38fd1498Szrj tree rhs = gimple_assign_rhs1 (stmt); 1606*38fd1498Szrj 1607*38fd1498Szrj /* If the RHS of the assignment is a constant or another variable that 1608*38fd1498Szrj may be propagated, register it in the CONST_AND_COPIES table. We 1609*38fd1498Szrj do not need to record unwind data for this, since this is a true 1610*38fd1498Szrj assignment and not an equivalence inferred from a comparison. All 1611*38fd1498Szrj uses of this ssa name are dominated by this assignment, so unwinding 1612*38fd1498Szrj just costs time and space. */ 1613*38fd1498Szrj if (may_optimize_p 1614*38fd1498Szrj && (TREE_CODE (rhs) == SSA_NAME 1615*38fd1498Szrj || is_gimple_min_invariant (rhs))) 1616*38fd1498Szrj { 1617*38fd1498Szrj rhs = dom_valueize (rhs); 1618*38fd1498Szrj 1619*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 1620*38fd1498Szrj { 1621*38fd1498Szrj fprintf (dump_file, "==== ASGN "); 1622*38fd1498Szrj print_generic_expr (dump_file, lhs); 1623*38fd1498Szrj fprintf (dump_file, " = "); 1624*38fd1498Szrj print_generic_expr (dump_file, rhs); 1625*38fd1498Szrj fprintf (dump_file, "\n"); 1626*38fd1498Szrj } 1627*38fd1498Szrj 1628*38fd1498Szrj set_ssa_name_value (lhs, rhs); 1629*38fd1498Szrj } 1630*38fd1498Szrj } 1631*38fd1498Szrj 1632*38fd1498Szrj /* Make sure we can propagate &x + CST. */ 1633*38fd1498Szrj if (lhs_code == SSA_NAME 1634*38fd1498Szrj && gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR 1635*38fd1498Szrj && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR 1636*38fd1498Szrj && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST) 1637*38fd1498Szrj { 1638*38fd1498Szrj tree op0 = gimple_assign_rhs1 (stmt); 1639*38fd1498Szrj tree op1 = gimple_assign_rhs2 (stmt); 1640*38fd1498Szrj tree new_rhs 1641*38fd1498Szrj = build_fold_addr_expr (fold_build2 (MEM_REF, 1642*38fd1498Szrj TREE_TYPE (TREE_TYPE (op0)), 1643*38fd1498Szrj unshare_expr (op0), 1644*38fd1498Szrj fold_convert (ptr_type_node, 1645*38fd1498Szrj op1))); 1646*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 1647*38fd1498Szrj { 1648*38fd1498Szrj fprintf (dump_file, "==== ASGN "); 1649*38fd1498Szrj print_generic_expr (dump_file, lhs); 1650*38fd1498Szrj fprintf (dump_file, " = "); 1651*38fd1498Szrj print_generic_expr (dump_file, new_rhs); 1652*38fd1498Szrj fprintf (dump_file, "\n"); 1653*38fd1498Szrj } 1654*38fd1498Szrj 1655*38fd1498Szrj set_ssa_name_value (lhs, new_rhs); 1656*38fd1498Szrj } 1657*38fd1498Szrj 1658*38fd1498Szrj /* A memory store, even an aliased store, creates a useful 1659*38fd1498Szrj equivalence. By exchanging the LHS and RHS, creating suitable 1660*38fd1498Szrj vops and recording the result in the available expression table, 1661*38fd1498Szrj we may be able to expose more redundant loads. */ 1662*38fd1498Szrj if (!gimple_has_volatile_ops (stmt) 1663*38fd1498Szrj && gimple_references_memory_p (stmt) 1664*38fd1498Szrj && gimple_assign_single_p (stmt) 1665*38fd1498Szrj && (TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME 1666*38fd1498Szrj || is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) 1667*38fd1498Szrj && !is_gimple_reg (lhs)) 1668*38fd1498Szrj { 1669*38fd1498Szrj tree rhs = gimple_assign_rhs1 (stmt); 1670*38fd1498Szrj gassign *new_stmt; 1671*38fd1498Szrj 1672*38fd1498Szrj /* Build a new statement with the RHS and LHS exchanged. */ 1673*38fd1498Szrj if (TREE_CODE (rhs) == SSA_NAME) 1674*38fd1498Szrj { 1675*38fd1498Szrj /* NOTE tuples. The call to gimple_build_assign below replaced 1676*38fd1498Szrj a call to build_gimple_modify_stmt, which did not set the 1677*38fd1498Szrj SSA_NAME_DEF_STMT on the LHS of the assignment. Doing so 1678*38fd1498Szrj may cause an SSA validation failure, as the LHS may be a 1679*38fd1498Szrj default-initialized name and should have no definition. I'm 1680*38fd1498Szrj a bit dubious of this, as the artificial statement that we 1681*38fd1498Szrj generate here may in fact be ill-formed, but it is simply 1682*38fd1498Szrj used as an internal device in this pass, and never becomes 1683*38fd1498Szrj part of the CFG. */ 1684*38fd1498Szrj gimple *defstmt = SSA_NAME_DEF_STMT (rhs); 1685*38fd1498Szrj new_stmt = gimple_build_assign (rhs, lhs); 1686*38fd1498Szrj SSA_NAME_DEF_STMT (rhs) = defstmt; 1687*38fd1498Szrj } 1688*38fd1498Szrj else 1689*38fd1498Szrj new_stmt = gimple_build_assign (rhs, lhs); 1690*38fd1498Szrj 1691*38fd1498Szrj gimple_set_vuse (new_stmt, gimple_vdef (stmt)); 1692*38fd1498Szrj 1693*38fd1498Szrj /* Finally enter the statement into the available expression 1694*38fd1498Szrj table. */ 1695*38fd1498Szrj avail_exprs_stack->lookup_avail_expr (new_stmt, true, true); 1696*38fd1498Szrj } 1697*38fd1498Szrj } 1698*38fd1498Szrj 1699*38fd1498Szrj /* Replace *OP_P in STMT with any known equivalent value for *OP_P from 1700*38fd1498Szrj CONST_AND_COPIES. */ 1701*38fd1498Szrj 1702*38fd1498Szrj static void 1703*38fd1498Szrj cprop_operand (gimple *stmt, use_operand_p op_p) 1704*38fd1498Szrj { 1705*38fd1498Szrj tree val; 1706*38fd1498Szrj tree op = USE_FROM_PTR (op_p); 1707*38fd1498Szrj 1708*38fd1498Szrj /* If the operand has a known constant value or it is known to be a 1709*38fd1498Szrj copy of some other variable, use the value or copy stored in 1710*38fd1498Szrj CONST_AND_COPIES. */ 1711*38fd1498Szrj val = SSA_NAME_VALUE (op); 1712*38fd1498Szrj if (val && val != op) 1713*38fd1498Szrj { 1714*38fd1498Szrj /* Do not replace hard register operands in asm statements. */ 1715*38fd1498Szrj if (gimple_code (stmt) == GIMPLE_ASM 1716*38fd1498Szrj && !may_propagate_copy_into_asm (op)) 1717*38fd1498Szrj return; 1718*38fd1498Szrj 1719*38fd1498Szrj /* Certain operands are not allowed to be copy propagated due 1720*38fd1498Szrj to their interaction with exception handling and some GCC 1721*38fd1498Szrj extensions. */ 1722*38fd1498Szrj if (!may_propagate_copy (op, val)) 1723*38fd1498Szrj return; 1724*38fd1498Szrj 1725*38fd1498Szrj /* Do not propagate copies into BIVs. 1726*38fd1498Szrj See PR23821 and PR62217 for how this can disturb IV and 1727*38fd1498Szrj number of iteration analysis. */ 1728*38fd1498Szrj if (TREE_CODE (val) != INTEGER_CST) 1729*38fd1498Szrj { 1730*38fd1498Szrj gimple *def = SSA_NAME_DEF_STMT (op); 1731*38fd1498Szrj if (gimple_code (def) == GIMPLE_PHI 1732*38fd1498Szrj && gimple_bb (def)->loop_father->header == gimple_bb (def)) 1733*38fd1498Szrj return; 1734*38fd1498Szrj } 1735*38fd1498Szrj 1736*38fd1498Szrj /* Dump details. */ 1737*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 1738*38fd1498Szrj { 1739*38fd1498Szrj fprintf (dump_file, " Replaced '"); 1740*38fd1498Szrj print_generic_expr (dump_file, op, dump_flags); 1741*38fd1498Szrj fprintf (dump_file, "' with %s '", 1742*38fd1498Szrj (TREE_CODE (val) != SSA_NAME ? "constant" : "variable")); 1743*38fd1498Szrj print_generic_expr (dump_file, val, dump_flags); 1744*38fd1498Szrj fprintf (dump_file, "'\n"); 1745*38fd1498Szrj } 1746*38fd1498Szrj 1747*38fd1498Szrj if (TREE_CODE (val) != SSA_NAME) 1748*38fd1498Szrj opt_stats.num_const_prop++; 1749*38fd1498Szrj else 1750*38fd1498Szrj opt_stats.num_copy_prop++; 1751*38fd1498Szrj 1752*38fd1498Szrj propagate_value (op_p, val); 1753*38fd1498Szrj 1754*38fd1498Szrj /* And note that we modified this statement. This is now 1755*38fd1498Szrj safe, even if we changed virtual operands since we will 1756*38fd1498Szrj rescan the statement and rewrite its operands again. */ 1757*38fd1498Szrj gimple_set_modified (stmt, true); 1758*38fd1498Szrj } 1759*38fd1498Szrj } 1760*38fd1498Szrj 1761*38fd1498Szrj /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current 1762*38fd1498Szrj known value for that SSA_NAME (or NULL if no value is known). 1763*38fd1498Szrj 1764*38fd1498Szrj Propagate values from CONST_AND_COPIES into the uses, vuses and 1765*38fd1498Szrj vdef_ops of STMT. */ 1766*38fd1498Szrj 1767*38fd1498Szrj static void 1768*38fd1498Szrj cprop_into_stmt (gimple *stmt) 1769*38fd1498Szrj { 1770*38fd1498Szrj use_operand_p op_p; 1771*38fd1498Szrj ssa_op_iter iter; 1772*38fd1498Szrj tree last_copy_propagated_op = NULL; 1773*38fd1498Szrj 1774*38fd1498Szrj FOR_EACH_SSA_USE_OPERAND (op_p, stmt, iter, SSA_OP_USE) 1775*38fd1498Szrj { 1776*38fd1498Szrj tree old_op = USE_FROM_PTR (op_p); 1777*38fd1498Szrj 1778*38fd1498Szrj /* If we have A = B and B = A in the copy propagation tables 1779*38fd1498Szrj (due to an equality comparison), avoid substituting B for A 1780*38fd1498Szrj then A for B in the trivially discovered cases. This allows 1781*38fd1498Szrj optimization of statements were A and B appear as input 1782*38fd1498Szrj operands. */ 1783*38fd1498Szrj if (old_op != last_copy_propagated_op) 1784*38fd1498Szrj { 1785*38fd1498Szrj cprop_operand (stmt, op_p); 1786*38fd1498Szrj 1787*38fd1498Szrj tree new_op = USE_FROM_PTR (op_p); 1788*38fd1498Szrj if (new_op != old_op && TREE_CODE (new_op) == SSA_NAME) 1789*38fd1498Szrj last_copy_propagated_op = new_op; 1790*38fd1498Szrj } 1791*38fd1498Szrj } 1792*38fd1498Szrj } 1793*38fd1498Szrj 1794*38fd1498Szrj /* If STMT contains a relational test, try to convert it into an 1795*38fd1498Szrj equality test if there is only a single value which can ever 1796*38fd1498Szrj make the test true. 1797*38fd1498Szrj 1798*38fd1498Szrj For example, if the expression hash table contains: 1799*38fd1498Szrj 1800*38fd1498Szrj TRUE = (i <= 1) 1801*38fd1498Szrj 1802*38fd1498Szrj And we have a test within statement of i >= 1, then we can safely 1803*38fd1498Szrj rewrite the test as i == 1 since there only a single value where 1804*38fd1498Szrj the test is true. 1805*38fd1498Szrj 1806*38fd1498Szrj This is similar to code in VRP. */ 1807*38fd1498Szrj 1808*38fd1498Szrj static void 1809*38fd1498Szrj test_for_singularity (gimple *stmt, gcond *dummy_cond, 1810*38fd1498Szrj avail_exprs_stack *avail_exprs_stack) 1811*38fd1498Szrj { 1812*38fd1498Szrj /* We want to support gimple conditionals as well as assignments 1813*38fd1498Szrj where the RHS contains a conditional. */ 1814*38fd1498Szrj if (is_gimple_assign (stmt) || gimple_code (stmt) == GIMPLE_COND) 1815*38fd1498Szrj { 1816*38fd1498Szrj enum tree_code code = ERROR_MARK; 1817*38fd1498Szrj tree lhs, rhs; 1818*38fd1498Szrj 1819*38fd1498Szrj /* Extract the condition of interest from both forms we support. */ 1820*38fd1498Szrj if (is_gimple_assign (stmt)) 1821*38fd1498Szrj { 1822*38fd1498Szrj code = gimple_assign_rhs_code (stmt); 1823*38fd1498Szrj lhs = gimple_assign_rhs1 (stmt); 1824*38fd1498Szrj rhs = gimple_assign_rhs2 (stmt); 1825*38fd1498Szrj } 1826*38fd1498Szrj else if (gimple_code (stmt) == GIMPLE_COND) 1827*38fd1498Szrj { 1828*38fd1498Szrj code = gimple_cond_code (as_a <gcond *> (stmt)); 1829*38fd1498Szrj lhs = gimple_cond_lhs (as_a <gcond *> (stmt)); 1830*38fd1498Szrj rhs = gimple_cond_rhs (as_a <gcond *> (stmt)); 1831*38fd1498Szrj } 1832*38fd1498Szrj 1833*38fd1498Szrj /* We're looking for a relational test using LE/GE. Also note we can 1834*38fd1498Szrj canonicalize LT/GT tests against constants into LE/GT tests. */ 1835*38fd1498Szrj if (code == LE_EXPR || code == GE_EXPR 1836*38fd1498Szrj || ((code == LT_EXPR || code == GT_EXPR) 1837*38fd1498Szrj && TREE_CODE (rhs) == INTEGER_CST)) 1838*38fd1498Szrj { 1839*38fd1498Szrj /* For LT_EXPR and GT_EXPR, canonicalize to LE_EXPR and GE_EXPR. */ 1840*38fd1498Szrj if (code == LT_EXPR) 1841*38fd1498Szrj rhs = fold_build2 (MINUS_EXPR, TREE_TYPE (rhs), 1842*38fd1498Szrj rhs, build_int_cst (TREE_TYPE (rhs), 1)); 1843*38fd1498Szrj 1844*38fd1498Szrj if (code == GT_EXPR) 1845*38fd1498Szrj rhs = fold_build2 (PLUS_EXPR, TREE_TYPE (rhs), 1846*38fd1498Szrj rhs, build_int_cst (TREE_TYPE (rhs), 1)); 1847*38fd1498Szrj 1848*38fd1498Szrj /* Determine the code we want to check for in the hash table. */ 1849*38fd1498Szrj enum tree_code test_code; 1850*38fd1498Szrj if (code == GE_EXPR || code == GT_EXPR) 1851*38fd1498Szrj test_code = LE_EXPR; 1852*38fd1498Szrj else 1853*38fd1498Szrj test_code = GE_EXPR; 1854*38fd1498Szrj 1855*38fd1498Szrj /* Update the dummy statement so we can query the hash tables. */ 1856*38fd1498Szrj gimple_cond_set_code (dummy_cond, test_code); 1857*38fd1498Szrj gimple_cond_set_lhs (dummy_cond, lhs); 1858*38fd1498Szrj gimple_cond_set_rhs (dummy_cond, rhs); 1859*38fd1498Szrj tree cached_lhs 1860*38fd1498Szrj = avail_exprs_stack->lookup_avail_expr (dummy_cond, false, false); 1861*38fd1498Szrj 1862*38fd1498Szrj /* If the lookup returned 1 (true), then the expression we 1863*38fd1498Szrj queried was in the hash table. As a result there is only 1864*38fd1498Szrj one value that makes the original conditional true. Update 1865*38fd1498Szrj STMT accordingly. */ 1866*38fd1498Szrj if (cached_lhs && integer_onep (cached_lhs)) 1867*38fd1498Szrj { 1868*38fd1498Szrj if (is_gimple_assign (stmt)) 1869*38fd1498Szrj { 1870*38fd1498Szrj gimple_assign_set_rhs_code (stmt, EQ_EXPR); 1871*38fd1498Szrj gimple_assign_set_rhs2 (stmt, rhs); 1872*38fd1498Szrj gimple_set_modified (stmt, true); 1873*38fd1498Szrj } 1874*38fd1498Szrj else 1875*38fd1498Szrj { 1876*38fd1498Szrj gimple_set_modified (stmt, true); 1877*38fd1498Szrj gimple_cond_set_code (as_a <gcond *> (stmt), EQ_EXPR); 1878*38fd1498Szrj gimple_cond_set_rhs (as_a <gcond *> (stmt), rhs); 1879*38fd1498Szrj gimple_set_modified (stmt, true); 1880*38fd1498Szrj } 1881*38fd1498Szrj } 1882*38fd1498Szrj } 1883*38fd1498Szrj } 1884*38fd1498Szrj } 1885*38fd1498Szrj 1886*38fd1498Szrj /* Optimize the statement in block BB pointed to by iterator SI. 1887*38fd1498Szrj 1888*38fd1498Szrj We try to perform some simplistic global redundancy elimination and 1889*38fd1498Szrj constant propagation: 1890*38fd1498Szrj 1891*38fd1498Szrj 1- To detect global redundancy, we keep track of expressions that have 1892*38fd1498Szrj been computed in this block and its dominators. If we find that the 1893*38fd1498Szrj same expression is computed more than once, we eliminate repeated 1894*38fd1498Szrj computations by using the target of the first one. 1895*38fd1498Szrj 1896*38fd1498Szrj 2- Constant values and copy assignments. This is used to do very 1897*38fd1498Szrj simplistic constant and copy propagation. When a constant or copy 1898*38fd1498Szrj assignment is found, we map the value on the RHS of the assignment to 1899*38fd1498Szrj the variable in the LHS in the CONST_AND_COPIES table. 1900*38fd1498Szrj 1901*38fd1498Szrj 3- Very simple redundant store elimination is performed. 1902*38fd1498Szrj 1903*38fd1498Szrj 4- We can simpify a condition to a constant or from a relational 1904*38fd1498Szrj condition to an equality condition. */ 1905*38fd1498Szrj 1906*38fd1498Szrj edge 1907*38fd1498Szrj dom_opt_dom_walker::optimize_stmt (basic_block bb, gimple_stmt_iterator si) 1908*38fd1498Szrj { 1909*38fd1498Szrj gimple *stmt, *old_stmt; 1910*38fd1498Szrj bool may_optimize_p; 1911*38fd1498Szrj bool modified_p = false; 1912*38fd1498Szrj bool was_noreturn; 1913*38fd1498Szrj edge retval = NULL; 1914*38fd1498Szrj 1915*38fd1498Szrj old_stmt = stmt = gsi_stmt (si); 1916*38fd1498Szrj was_noreturn = is_gimple_call (stmt) && gimple_call_noreturn_p (stmt); 1917*38fd1498Szrj 1918*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 1919*38fd1498Szrj { 1920*38fd1498Szrj fprintf (dump_file, "Optimizing statement "); 1921*38fd1498Szrj print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); 1922*38fd1498Szrj } 1923*38fd1498Szrj 1924*38fd1498Szrj update_stmt_if_modified (stmt); 1925*38fd1498Szrj opt_stats.num_stmts++; 1926*38fd1498Szrj 1927*38fd1498Szrj /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */ 1928*38fd1498Szrj cprop_into_stmt (stmt); 1929*38fd1498Szrj 1930*38fd1498Szrj /* If the statement has been modified with constant replacements, 1931*38fd1498Szrj fold its RHS before checking for redundant computations. */ 1932*38fd1498Szrj if (gimple_modified_p (stmt)) 1933*38fd1498Szrj { 1934*38fd1498Szrj tree rhs = NULL; 1935*38fd1498Szrj 1936*38fd1498Szrj /* Try to fold the statement making sure that STMT is kept 1937*38fd1498Szrj up to date. */ 1938*38fd1498Szrj if (fold_stmt (&si)) 1939*38fd1498Szrj { 1940*38fd1498Szrj stmt = gsi_stmt (si); 1941*38fd1498Szrj gimple_set_modified (stmt, true); 1942*38fd1498Szrj 1943*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 1944*38fd1498Szrj { 1945*38fd1498Szrj fprintf (dump_file, " Folded to: "); 1946*38fd1498Szrj print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); 1947*38fd1498Szrj } 1948*38fd1498Szrj } 1949*38fd1498Szrj 1950*38fd1498Szrj /* We only need to consider cases that can yield a gimple operand. */ 1951*38fd1498Szrj if (gimple_assign_single_p (stmt)) 1952*38fd1498Szrj rhs = gimple_assign_rhs1 (stmt); 1953*38fd1498Szrj else if (gimple_code (stmt) == GIMPLE_GOTO) 1954*38fd1498Szrj rhs = gimple_goto_dest (stmt); 1955*38fd1498Szrj else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt)) 1956*38fd1498Szrj /* This should never be an ADDR_EXPR. */ 1957*38fd1498Szrj rhs = gimple_switch_index (swtch_stmt); 1958*38fd1498Szrj 1959*38fd1498Szrj if (rhs && TREE_CODE (rhs) == ADDR_EXPR) 1960*38fd1498Szrj recompute_tree_invariant_for_addr_expr (rhs); 1961*38fd1498Szrj 1962*38fd1498Szrj /* Indicate that maybe_clean_or_replace_eh_stmt needs to be called, 1963*38fd1498Szrj even if fold_stmt updated the stmt already and thus cleared 1964*38fd1498Szrj gimple_modified_p flag on it. */ 1965*38fd1498Szrj modified_p = true; 1966*38fd1498Szrj } 1967*38fd1498Szrj 1968*38fd1498Szrj /* Check for redundant computations. Do this optimization only 1969*38fd1498Szrj for assignments that have no volatile ops and conditionals. */ 1970*38fd1498Szrj may_optimize_p = (!gimple_has_side_effects (stmt) 1971*38fd1498Szrj && (is_gimple_assign (stmt) 1972*38fd1498Szrj || (is_gimple_call (stmt) 1973*38fd1498Szrj && gimple_call_lhs (stmt) != NULL_TREE) 1974*38fd1498Szrj || gimple_code (stmt) == GIMPLE_COND 1975*38fd1498Szrj || gimple_code (stmt) == GIMPLE_SWITCH)); 1976*38fd1498Szrj 1977*38fd1498Szrj if (may_optimize_p) 1978*38fd1498Szrj { 1979*38fd1498Szrj if (gimple_code (stmt) == GIMPLE_CALL) 1980*38fd1498Szrj { 1981*38fd1498Szrj /* Resolve __builtin_constant_p. If it hasn't been 1982*38fd1498Szrj folded to integer_one_node by now, it's fairly 1983*38fd1498Szrj certain that the value simply isn't constant. */ 1984*38fd1498Szrj tree callee = gimple_call_fndecl (stmt); 1985*38fd1498Szrj if (callee 1986*38fd1498Szrj && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL 1987*38fd1498Szrj && DECL_FUNCTION_CODE (callee) == BUILT_IN_CONSTANT_P) 1988*38fd1498Szrj { 1989*38fd1498Szrj propagate_tree_value_into_stmt (&si, integer_zero_node); 1990*38fd1498Szrj stmt = gsi_stmt (si); 1991*38fd1498Szrj } 1992*38fd1498Szrj } 1993*38fd1498Szrj 1994*38fd1498Szrj if (gimple_code (stmt) == GIMPLE_COND) 1995*38fd1498Szrj { 1996*38fd1498Szrj tree lhs = gimple_cond_lhs (stmt); 1997*38fd1498Szrj tree rhs = gimple_cond_rhs (stmt); 1998*38fd1498Szrj 1999*38fd1498Szrj /* If the LHS has a range [0..1] and the RHS has a range ~[0..1], 2000*38fd1498Szrj then this conditional is computable at compile time. We can just 2001*38fd1498Szrj shove either 0 or 1 into the LHS, mark the statement as modified 2002*38fd1498Szrj and all the right things will just happen below. 2003*38fd1498Szrj 2004*38fd1498Szrj Note this would apply to any case where LHS has a range 2005*38fd1498Szrj narrower than its type implies and RHS is outside that 2006*38fd1498Szrj narrower range. Future work. */ 2007*38fd1498Szrj if (TREE_CODE (lhs) == SSA_NAME 2008*38fd1498Szrj && ssa_name_has_boolean_range (lhs) 2009*38fd1498Szrj && TREE_CODE (rhs) == INTEGER_CST 2010*38fd1498Szrj && ! (integer_zerop (rhs) || integer_onep (rhs))) 2011*38fd1498Szrj { 2012*38fd1498Szrj gimple_cond_set_lhs (as_a <gcond *> (stmt), 2013*38fd1498Szrj fold_convert (TREE_TYPE (lhs), 2014*38fd1498Szrj integer_zero_node)); 2015*38fd1498Szrj gimple_set_modified (stmt, true); 2016*38fd1498Szrj } 2017*38fd1498Szrj else if (TREE_CODE (lhs) == SSA_NAME) 2018*38fd1498Szrj { 2019*38fd1498Szrj /* Exploiting EVRP data is not yet fully integrated into DOM 2020*38fd1498Szrj but we need to do something for this case to avoid regressing 2021*38fd1498Szrj udr4.f90 and new1.C which have unexecutable blocks with 2022*38fd1498Szrj undefined behavior that get diagnosed if they're left in the 2023*38fd1498Szrj IL because we've attached range information to new 2024*38fd1498Szrj SSA_NAMES. */ 2025*38fd1498Szrj update_stmt_if_modified (stmt); 2026*38fd1498Szrj edge taken_edge = NULL; 2027*38fd1498Szrj evrp_range_analyzer.vrp_visit_cond_stmt (as_a <gcond *> (stmt), 2028*38fd1498Szrj &taken_edge); 2029*38fd1498Szrj if (taken_edge) 2030*38fd1498Szrj { 2031*38fd1498Szrj if (taken_edge->flags & EDGE_TRUE_VALUE) 2032*38fd1498Szrj gimple_cond_make_true (as_a <gcond *> (stmt)); 2033*38fd1498Szrj else if (taken_edge->flags & EDGE_FALSE_VALUE) 2034*38fd1498Szrj gimple_cond_make_false (as_a <gcond *> (stmt)); 2035*38fd1498Szrj else 2036*38fd1498Szrj gcc_unreachable (); 2037*38fd1498Szrj gimple_set_modified (stmt, true); 2038*38fd1498Szrj update_stmt (stmt); 2039*38fd1498Szrj cfg_altered = true; 2040*38fd1498Szrj return taken_edge; 2041*38fd1498Szrj } 2042*38fd1498Szrj } 2043*38fd1498Szrj } 2044*38fd1498Szrj 2045*38fd1498Szrj update_stmt_if_modified (stmt); 2046*38fd1498Szrj eliminate_redundant_computations (&si, m_const_and_copies, 2047*38fd1498Szrj m_avail_exprs_stack); 2048*38fd1498Szrj stmt = gsi_stmt (si); 2049*38fd1498Szrj 2050*38fd1498Szrj /* Perform simple redundant store elimination. */ 2051*38fd1498Szrj if (gimple_assign_single_p (stmt) 2052*38fd1498Szrj && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME) 2053*38fd1498Szrj { 2054*38fd1498Szrj tree lhs = gimple_assign_lhs (stmt); 2055*38fd1498Szrj tree rhs = gimple_assign_rhs1 (stmt); 2056*38fd1498Szrj tree cached_lhs; 2057*38fd1498Szrj gassign *new_stmt; 2058*38fd1498Szrj rhs = dom_valueize (rhs); 2059*38fd1498Szrj /* Build a new statement with the RHS and LHS exchanged. */ 2060*38fd1498Szrj if (TREE_CODE (rhs) == SSA_NAME) 2061*38fd1498Szrj { 2062*38fd1498Szrj gimple *defstmt = SSA_NAME_DEF_STMT (rhs); 2063*38fd1498Szrj new_stmt = gimple_build_assign (rhs, lhs); 2064*38fd1498Szrj SSA_NAME_DEF_STMT (rhs) = defstmt; 2065*38fd1498Szrj } 2066*38fd1498Szrj else 2067*38fd1498Szrj new_stmt = gimple_build_assign (rhs, lhs); 2068*38fd1498Szrj gimple_set_vuse (new_stmt, gimple_vuse (stmt)); 2069*38fd1498Szrj cached_lhs = m_avail_exprs_stack->lookup_avail_expr (new_stmt, false, 2070*38fd1498Szrj false); 2071*38fd1498Szrj if (cached_lhs && operand_equal_p (rhs, cached_lhs, 0)) 2072*38fd1498Szrj { 2073*38fd1498Szrj basic_block bb = gimple_bb (stmt); 2074*38fd1498Szrj unlink_stmt_vdef (stmt); 2075*38fd1498Szrj if (gsi_remove (&si, true)) 2076*38fd1498Szrj { 2077*38fd1498Szrj bitmap_set_bit (need_eh_cleanup, bb->index); 2078*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 2079*38fd1498Szrj fprintf (dump_file, " Flagged to clear EH edges.\n"); 2080*38fd1498Szrj } 2081*38fd1498Szrj release_defs (stmt); 2082*38fd1498Szrj return retval; 2083*38fd1498Szrj } 2084*38fd1498Szrj } 2085*38fd1498Szrj 2086*38fd1498Szrj /* If this statement was not redundant, we may still be able to simplify 2087*38fd1498Szrj it, which may in turn allow other part of DOM or other passes to do 2088*38fd1498Szrj a better job. */ 2089*38fd1498Szrj test_for_singularity (stmt, m_dummy_cond, m_avail_exprs_stack); 2090*38fd1498Szrj } 2091*38fd1498Szrj 2092*38fd1498Szrj /* Record any additional equivalences created by this statement. */ 2093*38fd1498Szrj if (is_gimple_assign (stmt)) 2094*38fd1498Szrj record_equivalences_from_stmt (stmt, may_optimize_p, m_avail_exprs_stack); 2095*38fd1498Szrj 2096*38fd1498Szrj /* If STMT is a COND_EXPR or SWITCH_EXPR and it was modified, then we may 2097*38fd1498Szrj know where it goes. */ 2098*38fd1498Szrj if (gimple_modified_p (stmt) || modified_p) 2099*38fd1498Szrj { 2100*38fd1498Szrj tree val = NULL; 2101*38fd1498Szrj 2102*38fd1498Szrj if (gimple_code (stmt) == GIMPLE_COND) 2103*38fd1498Szrj val = fold_binary_loc (gimple_location (stmt), 2104*38fd1498Szrj gimple_cond_code (stmt), boolean_type_node, 2105*38fd1498Szrj gimple_cond_lhs (stmt), 2106*38fd1498Szrj gimple_cond_rhs (stmt)); 2107*38fd1498Szrj else if (gswitch *swtch_stmt = dyn_cast <gswitch *> (stmt)) 2108*38fd1498Szrj val = gimple_switch_index (swtch_stmt); 2109*38fd1498Szrj 2110*38fd1498Szrj if (val && TREE_CODE (val) == INTEGER_CST) 2111*38fd1498Szrj { 2112*38fd1498Szrj retval = find_taken_edge (bb, val); 2113*38fd1498Szrj if (retval) 2114*38fd1498Szrj { 2115*38fd1498Szrj /* Fix the condition to be either true or false. */ 2116*38fd1498Szrj if (gimple_code (stmt) == GIMPLE_COND) 2117*38fd1498Szrj { 2118*38fd1498Szrj if (integer_zerop (val)) 2119*38fd1498Szrj gimple_cond_make_false (as_a <gcond *> (stmt)); 2120*38fd1498Szrj else if (integer_onep (val)) 2121*38fd1498Szrj gimple_cond_make_true (as_a <gcond *> (stmt)); 2122*38fd1498Szrj else 2123*38fd1498Szrj gcc_unreachable (); 2124*38fd1498Szrj 2125*38fd1498Szrj gimple_set_modified (stmt, true); 2126*38fd1498Szrj } 2127*38fd1498Szrj 2128*38fd1498Szrj /* Further simplifications may be possible. */ 2129*38fd1498Szrj cfg_altered = true; 2130*38fd1498Szrj } 2131*38fd1498Szrj } 2132*38fd1498Szrj 2133*38fd1498Szrj update_stmt_if_modified (stmt); 2134*38fd1498Szrj 2135*38fd1498Szrj /* If we simplified a statement in such a way as to be shown that it 2136*38fd1498Szrj cannot trap, update the eh information and the cfg to match. */ 2137*38fd1498Szrj if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) 2138*38fd1498Szrj { 2139*38fd1498Szrj bitmap_set_bit (need_eh_cleanup, bb->index); 2140*38fd1498Szrj if (dump_file && (dump_flags & TDF_DETAILS)) 2141*38fd1498Szrj fprintf (dump_file, " Flagged to clear EH edges.\n"); 2142*38fd1498Szrj } 2143*38fd1498Szrj 2144*38fd1498Szrj if (!was_noreturn 2145*38fd1498Szrj && is_gimple_call (stmt) && gimple_call_noreturn_p (stmt)) 2146*38fd1498Szrj need_noreturn_fixup.safe_push (stmt); 2147*38fd1498Szrj } 2148*38fd1498Szrj return retval; 2149*38fd1498Szrj } 2150