1*e4b17023SJohn Marino /* Tail call optimization on trees. 2*e4b17023SJohn Marino Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 3*e4b17023SJohn Marino Free Software Foundation, Inc. 4*e4b17023SJohn Marino 5*e4b17023SJohn Marino This file is part of GCC. 6*e4b17023SJohn Marino 7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify 8*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by 9*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option) 10*e4b17023SJohn Marino any later version. 11*e4b17023SJohn Marino 12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, 13*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of 14*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15*e4b17023SJohn Marino GNU General Public License for more details. 16*e4b17023SJohn Marino 17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License 18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see 19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */ 20*e4b17023SJohn Marino 21*e4b17023SJohn Marino #include "config.h" 22*e4b17023SJohn Marino #include "system.h" 23*e4b17023SJohn Marino #include "coretypes.h" 24*e4b17023SJohn Marino #include "tm.h" 25*e4b17023SJohn Marino #include "tree.h" 26*e4b17023SJohn Marino #include "tm_p.h" 27*e4b17023SJohn Marino #include "basic-block.h" 28*e4b17023SJohn Marino #include "function.h" 29*e4b17023SJohn Marino #include "tree-flow.h" 30*e4b17023SJohn Marino #include "tree-dump.h" 31*e4b17023SJohn Marino #include "gimple-pretty-print.h" 32*e4b17023SJohn Marino #include "except.h" 33*e4b17023SJohn Marino #include "tree-pass.h" 34*e4b17023SJohn Marino #include "flags.h" 35*e4b17023SJohn Marino #include "langhooks.h" 36*e4b17023SJohn Marino #include "dbgcnt.h" 37*e4b17023SJohn Marino #include "target.h" 38*e4b17023SJohn Marino #include "common/common-target.h" 39*e4b17023SJohn Marino 40*e4b17023SJohn Marino /* The file implements the tail recursion elimination. It is also used to 41*e4b17023SJohn Marino analyze the tail calls in general, passing the results to the rtl level 42*e4b17023SJohn Marino where they are used for sibcall optimization. 43*e4b17023SJohn Marino 44*e4b17023SJohn Marino In addition to the standard tail recursion elimination, we handle the most 45*e4b17023SJohn Marino trivial cases of making the call tail recursive by creating accumulators. 46*e4b17023SJohn Marino For example the following function 47*e4b17023SJohn Marino 48*e4b17023SJohn Marino int sum (int n) 49*e4b17023SJohn Marino { 50*e4b17023SJohn Marino if (n > 0) 51*e4b17023SJohn Marino return n + sum (n - 1); 52*e4b17023SJohn Marino else 53*e4b17023SJohn Marino return 0; 54*e4b17023SJohn Marino } 55*e4b17023SJohn Marino 56*e4b17023SJohn Marino is transformed into 57*e4b17023SJohn Marino 58*e4b17023SJohn Marino int sum (int n) 59*e4b17023SJohn Marino { 60*e4b17023SJohn Marino int acc = 0; 61*e4b17023SJohn Marino 62*e4b17023SJohn Marino while (n > 0) 63*e4b17023SJohn Marino acc += n--; 64*e4b17023SJohn Marino 65*e4b17023SJohn Marino return acc; 66*e4b17023SJohn Marino } 67*e4b17023SJohn Marino 68*e4b17023SJohn Marino To do this, we maintain two accumulators (a_acc and m_acc) that indicate 69*e4b17023SJohn Marino when we reach the return x statement, we should return a_acc + x * m_acc 70*e4b17023SJohn Marino instead. They are initially initialized to 0 and 1, respectively, 71*e4b17023SJohn Marino so the semantics of the function is obviously preserved. If we are 72*e4b17023SJohn Marino guaranteed that the value of the accumulator never change, we 73*e4b17023SJohn Marino omit the accumulator. 74*e4b17023SJohn Marino 75*e4b17023SJohn Marino There are three cases how the function may exit. The first one is 76*e4b17023SJohn Marino handled in adjust_return_value, the other two in adjust_accumulator_values 77*e4b17023SJohn Marino (the second case is actually a special case of the third one and we 78*e4b17023SJohn Marino present it separately just for clarity): 79*e4b17023SJohn Marino 80*e4b17023SJohn Marino 1) Just return x, where x is not in any of the remaining special shapes. 81*e4b17023SJohn Marino We rewrite this to a gimple equivalent of return m_acc * x + a_acc. 82*e4b17023SJohn Marino 83*e4b17023SJohn Marino 2) return f (...), where f is the current function, is rewritten in a 84*e4b17023SJohn Marino classical tail-recursion elimination way, into assignment of arguments 85*e4b17023SJohn Marino and jump to the start of the function. Values of the accumulators 86*e4b17023SJohn Marino are unchanged. 87*e4b17023SJohn Marino 88*e4b17023SJohn Marino 3) return a + m * f(...), where a and m do not depend on call to f. 89*e4b17023SJohn Marino To preserve the semantics described before we want this to be rewritten 90*e4b17023SJohn Marino in such a way that we finally return 91*e4b17023SJohn Marino 92*e4b17023SJohn Marino a_acc + (a + m * f(...)) * m_acc = (a_acc + a * m_acc) + (m * m_acc) * f(...). 93*e4b17023SJohn Marino 94*e4b17023SJohn Marino I.e. we increase a_acc by a * m_acc, multiply m_acc by m and 95*e4b17023SJohn Marino eliminate the tail call to f. Special cases when the value is just 96*e4b17023SJohn Marino added or just multiplied are obtained by setting a = 0 or m = 1. 97*e4b17023SJohn Marino 98*e4b17023SJohn Marino TODO -- it is possible to do similar tricks for other operations. */ 99*e4b17023SJohn Marino 100*e4b17023SJohn Marino /* A structure that describes the tailcall. */ 101*e4b17023SJohn Marino 102*e4b17023SJohn Marino struct tailcall 103*e4b17023SJohn Marino { 104*e4b17023SJohn Marino /* The iterator pointing to the call statement. */ 105*e4b17023SJohn Marino gimple_stmt_iterator call_gsi; 106*e4b17023SJohn Marino 107*e4b17023SJohn Marino /* True if it is a call to the current function. */ 108*e4b17023SJohn Marino bool tail_recursion; 109*e4b17023SJohn Marino 110*e4b17023SJohn Marino /* The return value of the caller is mult * f + add, where f is the return 111*e4b17023SJohn Marino value of the call. */ 112*e4b17023SJohn Marino tree mult, add; 113*e4b17023SJohn Marino 114*e4b17023SJohn Marino /* Next tailcall in the chain. */ 115*e4b17023SJohn Marino struct tailcall *next; 116*e4b17023SJohn Marino }; 117*e4b17023SJohn Marino 118*e4b17023SJohn Marino /* The variables holding the value of multiplicative and additive 119*e4b17023SJohn Marino accumulator. */ 120*e4b17023SJohn Marino static tree m_acc, a_acc; 121*e4b17023SJohn Marino 122*e4b17023SJohn Marino static bool suitable_for_tail_opt_p (void); 123*e4b17023SJohn Marino static bool optimize_tail_call (struct tailcall *, bool); 124*e4b17023SJohn Marino static void eliminate_tail_call (struct tailcall *); 125*e4b17023SJohn Marino static void find_tail_calls (basic_block, struct tailcall **); 126*e4b17023SJohn Marino 127*e4b17023SJohn Marino /* Returns false when the function is not suitable for tail call optimization 128*e4b17023SJohn Marino from some reason (e.g. if it takes variable number of arguments). */ 129*e4b17023SJohn Marino 130*e4b17023SJohn Marino static bool 131*e4b17023SJohn Marino suitable_for_tail_opt_p (void) 132*e4b17023SJohn Marino { 133*e4b17023SJohn Marino if (cfun->stdarg) 134*e4b17023SJohn Marino return false; 135*e4b17023SJohn Marino 136*e4b17023SJohn Marino return true; 137*e4b17023SJohn Marino } 138*e4b17023SJohn Marino /* Returns false when the function is not suitable for tail call optimization 139*e4b17023SJohn Marino from some reason (e.g. if it takes variable number of arguments). 140*e4b17023SJohn Marino This test must pass in addition to suitable_for_tail_opt_p in order to make 141*e4b17023SJohn Marino tail call discovery happen. */ 142*e4b17023SJohn Marino 143*e4b17023SJohn Marino static bool 144*e4b17023SJohn Marino suitable_for_tail_call_opt_p (void) 145*e4b17023SJohn Marino { 146*e4b17023SJohn Marino tree param; 147*e4b17023SJohn Marino 148*e4b17023SJohn Marino /* alloca (until we have stack slot life analysis) inhibits 149*e4b17023SJohn Marino sibling call optimizations, but not tail recursion. */ 150*e4b17023SJohn Marino if (cfun->calls_alloca) 151*e4b17023SJohn Marino return false; 152*e4b17023SJohn Marino 153*e4b17023SJohn Marino /* If we are using sjlj exceptions, we may need to add a call to 154*e4b17023SJohn Marino _Unwind_SjLj_Unregister at exit of the function. Which means 155*e4b17023SJohn Marino that we cannot do any sibcall transformations. */ 156*e4b17023SJohn Marino if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ 157*e4b17023SJohn Marino && current_function_has_exception_handlers ()) 158*e4b17023SJohn Marino return false; 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino /* Any function that calls setjmp might have longjmp called from 161*e4b17023SJohn Marino any called function. ??? We really should represent this 162*e4b17023SJohn Marino properly in the CFG so that this needn't be special cased. */ 163*e4b17023SJohn Marino if (cfun->calls_setjmp) 164*e4b17023SJohn Marino return false; 165*e4b17023SJohn Marino 166*e4b17023SJohn Marino /* ??? It is OK if the argument of a function is taken in some cases, 167*e4b17023SJohn Marino but not in all cases. See PR15387 and PR19616. Revisit for 4.1. */ 168*e4b17023SJohn Marino for (param = DECL_ARGUMENTS (current_function_decl); 169*e4b17023SJohn Marino param; 170*e4b17023SJohn Marino param = DECL_CHAIN (param)) 171*e4b17023SJohn Marino if (TREE_ADDRESSABLE (param)) 172*e4b17023SJohn Marino return false; 173*e4b17023SJohn Marino 174*e4b17023SJohn Marino return true; 175*e4b17023SJohn Marino } 176*e4b17023SJohn Marino 177*e4b17023SJohn Marino /* Checks whether the expression EXPR in stmt AT is independent of the 178*e4b17023SJohn Marino statement pointed to by GSI (in a sense that we already know EXPR's value 179*e4b17023SJohn Marino at GSI). We use the fact that we are only called from the chain of 180*e4b17023SJohn Marino basic blocks that have only single successor. Returns the expression 181*e4b17023SJohn Marino containing the value of EXPR at GSI. */ 182*e4b17023SJohn Marino 183*e4b17023SJohn Marino static tree 184*e4b17023SJohn Marino independent_of_stmt_p (tree expr, gimple at, gimple_stmt_iterator gsi) 185*e4b17023SJohn Marino { 186*e4b17023SJohn Marino basic_block bb, call_bb, at_bb; 187*e4b17023SJohn Marino edge e; 188*e4b17023SJohn Marino edge_iterator ei; 189*e4b17023SJohn Marino 190*e4b17023SJohn Marino if (is_gimple_min_invariant (expr)) 191*e4b17023SJohn Marino return expr; 192*e4b17023SJohn Marino 193*e4b17023SJohn Marino if (TREE_CODE (expr) != SSA_NAME) 194*e4b17023SJohn Marino return NULL_TREE; 195*e4b17023SJohn Marino 196*e4b17023SJohn Marino /* Mark the blocks in the chain leading to the end. */ 197*e4b17023SJohn Marino at_bb = gimple_bb (at); 198*e4b17023SJohn Marino call_bb = gimple_bb (gsi_stmt (gsi)); 199*e4b17023SJohn Marino for (bb = call_bb; bb != at_bb; bb = single_succ (bb)) 200*e4b17023SJohn Marino bb->aux = &bb->aux; 201*e4b17023SJohn Marino bb->aux = &bb->aux; 202*e4b17023SJohn Marino 203*e4b17023SJohn Marino while (1) 204*e4b17023SJohn Marino { 205*e4b17023SJohn Marino at = SSA_NAME_DEF_STMT (expr); 206*e4b17023SJohn Marino bb = gimple_bb (at); 207*e4b17023SJohn Marino 208*e4b17023SJohn Marino /* The default definition or defined before the chain. */ 209*e4b17023SJohn Marino if (!bb || !bb->aux) 210*e4b17023SJohn Marino break; 211*e4b17023SJohn Marino 212*e4b17023SJohn Marino if (bb == call_bb) 213*e4b17023SJohn Marino { 214*e4b17023SJohn Marino for (; !gsi_end_p (gsi); gsi_next (&gsi)) 215*e4b17023SJohn Marino if (gsi_stmt (gsi) == at) 216*e4b17023SJohn Marino break; 217*e4b17023SJohn Marino 218*e4b17023SJohn Marino if (!gsi_end_p (gsi)) 219*e4b17023SJohn Marino expr = NULL_TREE; 220*e4b17023SJohn Marino break; 221*e4b17023SJohn Marino } 222*e4b17023SJohn Marino 223*e4b17023SJohn Marino if (gimple_code (at) != GIMPLE_PHI) 224*e4b17023SJohn Marino { 225*e4b17023SJohn Marino expr = NULL_TREE; 226*e4b17023SJohn Marino break; 227*e4b17023SJohn Marino } 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds) 230*e4b17023SJohn Marino if (e->src->aux) 231*e4b17023SJohn Marino break; 232*e4b17023SJohn Marino gcc_assert (e); 233*e4b17023SJohn Marino 234*e4b17023SJohn Marino expr = PHI_ARG_DEF_FROM_EDGE (at, e); 235*e4b17023SJohn Marino if (TREE_CODE (expr) != SSA_NAME) 236*e4b17023SJohn Marino { 237*e4b17023SJohn Marino /* The value is a constant. */ 238*e4b17023SJohn Marino break; 239*e4b17023SJohn Marino } 240*e4b17023SJohn Marino } 241*e4b17023SJohn Marino 242*e4b17023SJohn Marino /* Unmark the blocks. */ 243*e4b17023SJohn Marino for (bb = call_bb; bb != at_bb; bb = single_succ (bb)) 244*e4b17023SJohn Marino bb->aux = NULL; 245*e4b17023SJohn Marino bb->aux = NULL; 246*e4b17023SJohn Marino 247*e4b17023SJohn Marino return expr; 248*e4b17023SJohn Marino } 249*e4b17023SJohn Marino 250*e4b17023SJohn Marino /* Simulates the effect of an assignment STMT on the return value of the tail 251*e4b17023SJohn Marino recursive CALL passed in ASS_VAR. M and A are the multiplicative and the 252*e4b17023SJohn Marino additive factor for the real return value. */ 253*e4b17023SJohn Marino 254*e4b17023SJohn Marino static bool 255*e4b17023SJohn Marino process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m, 256*e4b17023SJohn Marino tree *a, tree *ass_var) 257*e4b17023SJohn Marino { 258*e4b17023SJohn Marino tree op0, op1 = NULL_TREE, non_ass_var = NULL_TREE; 259*e4b17023SJohn Marino tree dest = gimple_assign_lhs (stmt); 260*e4b17023SJohn Marino enum tree_code code = gimple_assign_rhs_code (stmt); 261*e4b17023SJohn Marino enum gimple_rhs_class rhs_class = get_gimple_rhs_class (code); 262*e4b17023SJohn Marino tree src_var = gimple_assign_rhs1 (stmt); 263*e4b17023SJohn Marino 264*e4b17023SJohn Marino /* See if this is a simple copy operation of an SSA name to the function 265*e4b17023SJohn Marino result. In that case we may have a simple tail call. Ignore type 266*e4b17023SJohn Marino conversions that can never produce extra code between the function 267*e4b17023SJohn Marino call and the function return. */ 268*e4b17023SJohn Marino if ((rhs_class == GIMPLE_SINGLE_RHS || gimple_assign_cast_p (stmt)) 269*e4b17023SJohn Marino && (TREE_CODE (src_var) == SSA_NAME)) 270*e4b17023SJohn Marino { 271*e4b17023SJohn Marino /* Reject a tailcall if the type conversion might need 272*e4b17023SJohn Marino additional code. */ 273*e4b17023SJohn Marino if (gimple_assign_cast_p (stmt) 274*e4b17023SJohn Marino && TYPE_MODE (TREE_TYPE (dest)) != TYPE_MODE (TREE_TYPE (src_var))) 275*e4b17023SJohn Marino return false; 276*e4b17023SJohn Marino 277*e4b17023SJohn Marino if (src_var != *ass_var) 278*e4b17023SJohn Marino return false; 279*e4b17023SJohn Marino 280*e4b17023SJohn Marino *ass_var = dest; 281*e4b17023SJohn Marino return true; 282*e4b17023SJohn Marino } 283*e4b17023SJohn Marino 284*e4b17023SJohn Marino switch (rhs_class) 285*e4b17023SJohn Marino { 286*e4b17023SJohn Marino case GIMPLE_BINARY_RHS: 287*e4b17023SJohn Marino op1 = gimple_assign_rhs2 (stmt); 288*e4b17023SJohn Marino 289*e4b17023SJohn Marino /* Fall through. */ 290*e4b17023SJohn Marino 291*e4b17023SJohn Marino case GIMPLE_UNARY_RHS: 292*e4b17023SJohn Marino op0 = gimple_assign_rhs1 (stmt); 293*e4b17023SJohn Marino break; 294*e4b17023SJohn Marino 295*e4b17023SJohn Marino default: 296*e4b17023SJohn Marino return false; 297*e4b17023SJohn Marino } 298*e4b17023SJohn Marino 299*e4b17023SJohn Marino /* Accumulator optimizations will reverse the order of operations. 300*e4b17023SJohn Marino We can only do that for floating-point types if we're assuming 301*e4b17023SJohn Marino that addition and multiplication are associative. */ 302*e4b17023SJohn Marino if (!flag_associative_math) 303*e4b17023SJohn Marino if (FLOAT_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl)))) 304*e4b17023SJohn Marino return false; 305*e4b17023SJohn Marino 306*e4b17023SJohn Marino if (rhs_class == GIMPLE_UNARY_RHS) 307*e4b17023SJohn Marino ; 308*e4b17023SJohn Marino else if (op0 == *ass_var 309*e4b17023SJohn Marino && (non_ass_var = independent_of_stmt_p (op1, stmt, call))) 310*e4b17023SJohn Marino ; 311*e4b17023SJohn Marino else if (op1 == *ass_var 312*e4b17023SJohn Marino && (non_ass_var = independent_of_stmt_p (op0, stmt, call))) 313*e4b17023SJohn Marino ; 314*e4b17023SJohn Marino else 315*e4b17023SJohn Marino return false; 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino switch (code) 318*e4b17023SJohn Marino { 319*e4b17023SJohn Marino case PLUS_EXPR: 320*e4b17023SJohn Marino *a = non_ass_var; 321*e4b17023SJohn Marino *ass_var = dest; 322*e4b17023SJohn Marino return true; 323*e4b17023SJohn Marino 324*e4b17023SJohn Marino case MULT_EXPR: 325*e4b17023SJohn Marino *m = non_ass_var; 326*e4b17023SJohn Marino *ass_var = dest; 327*e4b17023SJohn Marino return true; 328*e4b17023SJohn Marino 329*e4b17023SJohn Marino case NEGATE_EXPR: 330*e4b17023SJohn Marino if (FLOAT_TYPE_P (TREE_TYPE (op0))) 331*e4b17023SJohn Marino *m = build_real (TREE_TYPE (op0), dconstm1); 332*e4b17023SJohn Marino else 333*e4b17023SJohn Marino *m = build_int_cst (TREE_TYPE (op0), -1); 334*e4b17023SJohn Marino 335*e4b17023SJohn Marino *ass_var = dest; 336*e4b17023SJohn Marino return true; 337*e4b17023SJohn Marino 338*e4b17023SJohn Marino case MINUS_EXPR: 339*e4b17023SJohn Marino if (*ass_var == op0) 340*e4b17023SJohn Marino *a = fold_build1 (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var); 341*e4b17023SJohn Marino else 342*e4b17023SJohn Marino { 343*e4b17023SJohn Marino if (FLOAT_TYPE_P (TREE_TYPE (non_ass_var))) 344*e4b17023SJohn Marino *m = build_real (TREE_TYPE (non_ass_var), dconstm1); 345*e4b17023SJohn Marino else 346*e4b17023SJohn Marino *m = build_int_cst (TREE_TYPE (non_ass_var), -1); 347*e4b17023SJohn Marino 348*e4b17023SJohn Marino *a = fold_build1 (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var); 349*e4b17023SJohn Marino } 350*e4b17023SJohn Marino 351*e4b17023SJohn Marino *ass_var = dest; 352*e4b17023SJohn Marino return true; 353*e4b17023SJohn Marino 354*e4b17023SJohn Marino /* TODO -- Handle POINTER_PLUS_EXPR. */ 355*e4b17023SJohn Marino 356*e4b17023SJohn Marino default: 357*e4b17023SJohn Marino return false; 358*e4b17023SJohn Marino } 359*e4b17023SJohn Marino } 360*e4b17023SJohn Marino 361*e4b17023SJohn Marino /* Propagate VAR through phis on edge E. */ 362*e4b17023SJohn Marino 363*e4b17023SJohn Marino static tree 364*e4b17023SJohn Marino propagate_through_phis (tree var, edge e) 365*e4b17023SJohn Marino { 366*e4b17023SJohn Marino basic_block dest = e->dest; 367*e4b17023SJohn Marino gimple_stmt_iterator gsi; 368*e4b17023SJohn Marino 369*e4b17023SJohn Marino for (gsi = gsi_start_phis (dest); !gsi_end_p (gsi); gsi_next (&gsi)) 370*e4b17023SJohn Marino { 371*e4b17023SJohn Marino gimple phi = gsi_stmt (gsi); 372*e4b17023SJohn Marino if (PHI_ARG_DEF_FROM_EDGE (phi, e) == var) 373*e4b17023SJohn Marino return PHI_RESULT (phi); 374*e4b17023SJohn Marino } 375*e4b17023SJohn Marino return var; 376*e4b17023SJohn Marino } 377*e4b17023SJohn Marino 378*e4b17023SJohn Marino /* Finds tailcalls falling into basic block BB. The list of found tailcalls is 379*e4b17023SJohn Marino added to the start of RET. */ 380*e4b17023SJohn Marino 381*e4b17023SJohn Marino static void 382*e4b17023SJohn Marino find_tail_calls (basic_block bb, struct tailcall **ret) 383*e4b17023SJohn Marino { 384*e4b17023SJohn Marino tree ass_var = NULL_TREE, ret_var, func, param; 385*e4b17023SJohn Marino gimple stmt, call = NULL; 386*e4b17023SJohn Marino gimple_stmt_iterator gsi, agsi; 387*e4b17023SJohn Marino bool tail_recursion; 388*e4b17023SJohn Marino struct tailcall *nw; 389*e4b17023SJohn Marino edge e; 390*e4b17023SJohn Marino tree m, a; 391*e4b17023SJohn Marino basic_block abb; 392*e4b17023SJohn Marino size_t idx; 393*e4b17023SJohn Marino tree var; 394*e4b17023SJohn Marino referenced_var_iterator rvi; 395*e4b17023SJohn Marino 396*e4b17023SJohn Marino if (!single_succ_p (bb)) 397*e4b17023SJohn Marino return; 398*e4b17023SJohn Marino 399*e4b17023SJohn Marino for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) 400*e4b17023SJohn Marino { 401*e4b17023SJohn Marino stmt = gsi_stmt (gsi); 402*e4b17023SJohn Marino 403*e4b17023SJohn Marino /* Ignore labels, returns, clobbers and debug stmts. */ 404*e4b17023SJohn Marino if (gimple_code (stmt) == GIMPLE_LABEL 405*e4b17023SJohn Marino || gimple_code (stmt) == GIMPLE_RETURN 406*e4b17023SJohn Marino || gimple_clobber_p (stmt) 407*e4b17023SJohn Marino || is_gimple_debug (stmt)) 408*e4b17023SJohn Marino continue; 409*e4b17023SJohn Marino 410*e4b17023SJohn Marino /* Check for a call. */ 411*e4b17023SJohn Marino if (is_gimple_call (stmt)) 412*e4b17023SJohn Marino { 413*e4b17023SJohn Marino call = stmt; 414*e4b17023SJohn Marino ass_var = gimple_call_lhs (stmt); 415*e4b17023SJohn Marino break; 416*e4b17023SJohn Marino } 417*e4b17023SJohn Marino 418*e4b17023SJohn Marino /* If the statement references memory or volatile operands, fail. */ 419*e4b17023SJohn Marino if (gimple_references_memory_p (stmt) 420*e4b17023SJohn Marino || gimple_has_volatile_ops (stmt)) 421*e4b17023SJohn Marino return; 422*e4b17023SJohn Marino } 423*e4b17023SJohn Marino 424*e4b17023SJohn Marino if (gsi_end_p (gsi)) 425*e4b17023SJohn Marino { 426*e4b17023SJohn Marino edge_iterator ei; 427*e4b17023SJohn Marino /* Recurse to the predecessors. */ 428*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds) 429*e4b17023SJohn Marino find_tail_calls (e->src, ret); 430*e4b17023SJohn Marino 431*e4b17023SJohn Marino return; 432*e4b17023SJohn Marino } 433*e4b17023SJohn Marino 434*e4b17023SJohn Marino /* If the LHS of our call is not just a simple register, we can't 435*e4b17023SJohn Marino transform this into a tail or sibling call. This situation happens, 436*e4b17023SJohn Marino in (e.g.) "*p = foo()" where foo returns a struct. In this case 437*e4b17023SJohn Marino we won't have a temporary here, but we need to carry out the side 438*e4b17023SJohn Marino effect anyway, so tailcall is impossible. 439*e4b17023SJohn Marino 440*e4b17023SJohn Marino ??? In some situations (when the struct is returned in memory via 441*e4b17023SJohn Marino invisible argument) we could deal with this, e.g. by passing 'p' 442*e4b17023SJohn Marino itself as that argument to foo, but it's too early to do this here, 443*e4b17023SJohn Marino and expand_call() will not handle it anyway. If it ever can, then 444*e4b17023SJohn Marino we need to revisit this here, to allow that situation. */ 445*e4b17023SJohn Marino if (ass_var && !is_gimple_reg (ass_var)) 446*e4b17023SJohn Marino return; 447*e4b17023SJohn Marino 448*e4b17023SJohn Marino /* We found the call, check whether it is suitable. */ 449*e4b17023SJohn Marino tail_recursion = false; 450*e4b17023SJohn Marino func = gimple_call_fndecl (call); 451*e4b17023SJohn Marino if (func == current_function_decl) 452*e4b17023SJohn Marino { 453*e4b17023SJohn Marino tree arg; 454*e4b17023SJohn Marino 455*e4b17023SJohn Marino for (param = DECL_ARGUMENTS (func), idx = 0; 456*e4b17023SJohn Marino param && idx < gimple_call_num_args (call); 457*e4b17023SJohn Marino param = DECL_CHAIN (param), idx ++) 458*e4b17023SJohn Marino { 459*e4b17023SJohn Marino arg = gimple_call_arg (call, idx); 460*e4b17023SJohn Marino if (param != arg) 461*e4b17023SJohn Marino { 462*e4b17023SJohn Marino /* Make sure there are no problems with copying. The parameter 463*e4b17023SJohn Marino have a copyable type and the two arguments must have reasonably 464*e4b17023SJohn Marino equivalent types. The latter requirement could be relaxed if 465*e4b17023SJohn Marino we emitted a suitable type conversion statement. */ 466*e4b17023SJohn Marino if (!is_gimple_reg_type (TREE_TYPE (param)) 467*e4b17023SJohn Marino || !useless_type_conversion_p (TREE_TYPE (param), 468*e4b17023SJohn Marino TREE_TYPE (arg))) 469*e4b17023SJohn Marino break; 470*e4b17023SJohn Marino 471*e4b17023SJohn Marino /* The parameter should be a real operand, so that phi node 472*e4b17023SJohn Marino created for it at the start of the function has the meaning 473*e4b17023SJohn Marino of copying the value. This test implies is_gimple_reg_type 474*e4b17023SJohn Marino from the previous condition, however this one could be 475*e4b17023SJohn Marino relaxed by being more careful with copying the new value 476*e4b17023SJohn Marino of the parameter (emitting appropriate GIMPLE_ASSIGN and 477*e4b17023SJohn Marino updating the virtual operands). */ 478*e4b17023SJohn Marino if (!is_gimple_reg (param)) 479*e4b17023SJohn Marino break; 480*e4b17023SJohn Marino } 481*e4b17023SJohn Marino } 482*e4b17023SJohn Marino if (idx == gimple_call_num_args (call) && !param) 483*e4b17023SJohn Marino tail_recursion = true; 484*e4b17023SJohn Marino } 485*e4b17023SJohn Marino 486*e4b17023SJohn Marino /* Make sure the tail invocation of this function does not refer 487*e4b17023SJohn Marino to local variables. */ 488*e4b17023SJohn Marino FOR_EACH_REFERENCED_VAR (cfun, var, rvi) 489*e4b17023SJohn Marino { 490*e4b17023SJohn Marino if (TREE_CODE (var) != PARM_DECL 491*e4b17023SJohn Marino && auto_var_in_fn_p (var, cfun->decl) 492*e4b17023SJohn Marino && (ref_maybe_used_by_stmt_p (call, var) 493*e4b17023SJohn Marino || call_may_clobber_ref_p (call, var))) 494*e4b17023SJohn Marino return; 495*e4b17023SJohn Marino } 496*e4b17023SJohn Marino 497*e4b17023SJohn Marino /* Now check the statements after the call. None of them has virtual 498*e4b17023SJohn Marino operands, so they may only depend on the call through its return 499*e4b17023SJohn Marino value. The return value should also be dependent on each of them, 500*e4b17023SJohn Marino since we are running after dce. */ 501*e4b17023SJohn Marino m = NULL_TREE; 502*e4b17023SJohn Marino a = NULL_TREE; 503*e4b17023SJohn Marino 504*e4b17023SJohn Marino abb = bb; 505*e4b17023SJohn Marino agsi = gsi; 506*e4b17023SJohn Marino while (1) 507*e4b17023SJohn Marino { 508*e4b17023SJohn Marino tree tmp_a = NULL_TREE; 509*e4b17023SJohn Marino tree tmp_m = NULL_TREE; 510*e4b17023SJohn Marino gsi_next (&agsi); 511*e4b17023SJohn Marino 512*e4b17023SJohn Marino while (gsi_end_p (agsi)) 513*e4b17023SJohn Marino { 514*e4b17023SJohn Marino ass_var = propagate_through_phis (ass_var, single_succ_edge (abb)); 515*e4b17023SJohn Marino abb = single_succ (abb); 516*e4b17023SJohn Marino agsi = gsi_start_bb (abb); 517*e4b17023SJohn Marino } 518*e4b17023SJohn Marino 519*e4b17023SJohn Marino stmt = gsi_stmt (agsi); 520*e4b17023SJohn Marino 521*e4b17023SJohn Marino if (gimple_code (stmt) == GIMPLE_LABEL) 522*e4b17023SJohn Marino continue; 523*e4b17023SJohn Marino 524*e4b17023SJohn Marino if (gimple_code (stmt) == GIMPLE_RETURN) 525*e4b17023SJohn Marino break; 526*e4b17023SJohn Marino 527*e4b17023SJohn Marino if (gimple_clobber_p (stmt)) 528*e4b17023SJohn Marino continue; 529*e4b17023SJohn Marino 530*e4b17023SJohn Marino if (is_gimple_debug (stmt)) 531*e4b17023SJohn Marino continue; 532*e4b17023SJohn Marino 533*e4b17023SJohn Marino if (gimple_code (stmt) != GIMPLE_ASSIGN) 534*e4b17023SJohn Marino return; 535*e4b17023SJohn Marino 536*e4b17023SJohn Marino /* This is a gimple assign. */ 537*e4b17023SJohn Marino if (! process_assignment (stmt, gsi, &tmp_m, &tmp_a, &ass_var)) 538*e4b17023SJohn Marino return; 539*e4b17023SJohn Marino 540*e4b17023SJohn Marino if (tmp_a) 541*e4b17023SJohn Marino { 542*e4b17023SJohn Marino tree type = TREE_TYPE (tmp_a); 543*e4b17023SJohn Marino if (a) 544*e4b17023SJohn Marino a = fold_build2 (PLUS_EXPR, type, fold_convert (type, a), tmp_a); 545*e4b17023SJohn Marino else 546*e4b17023SJohn Marino a = tmp_a; 547*e4b17023SJohn Marino } 548*e4b17023SJohn Marino if (tmp_m) 549*e4b17023SJohn Marino { 550*e4b17023SJohn Marino tree type = TREE_TYPE (tmp_m); 551*e4b17023SJohn Marino if (m) 552*e4b17023SJohn Marino m = fold_build2 (MULT_EXPR, type, fold_convert (type, m), tmp_m); 553*e4b17023SJohn Marino else 554*e4b17023SJohn Marino m = tmp_m; 555*e4b17023SJohn Marino 556*e4b17023SJohn Marino if (a) 557*e4b17023SJohn Marino a = fold_build2 (MULT_EXPR, type, fold_convert (type, a), tmp_m); 558*e4b17023SJohn Marino } 559*e4b17023SJohn Marino } 560*e4b17023SJohn Marino 561*e4b17023SJohn Marino /* See if this is a tail call we can handle. */ 562*e4b17023SJohn Marino ret_var = gimple_return_retval (stmt); 563*e4b17023SJohn Marino 564*e4b17023SJohn Marino /* We may proceed if there either is no return value, or the return value 565*e4b17023SJohn Marino is identical to the call's return. */ 566*e4b17023SJohn Marino if (ret_var 567*e4b17023SJohn Marino && (ret_var != ass_var)) 568*e4b17023SJohn Marino return; 569*e4b17023SJohn Marino 570*e4b17023SJohn Marino /* If this is not a tail recursive call, we cannot handle addends or 571*e4b17023SJohn Marino multiplicands. */ 572*e4b17023SJohn Marino if (!tail_recursion && (m || a)) 573*e4b17023SJohn Marino return; 574*e4b17023SJohn Marino 575*e4b17023SJohn Marino nw = XNEW (struct tailcall); 576*e4b17023SJohn Marino 577*e4b17023SJohn Marino nw->call_gsi = gsi; 578*e4b17023SJohn Marino 579*e4b17023SJohn Marino nw->tail_recursion = tail_recursion; 580*e4b17023SJohn Marino 581*e4b17023SJohn Marino nw->mult = m; 582*e4b17023SJohn Marino nw->add = a; 583*e4b17023SJohn Marino 584*e4b17023SJohn Marino nw->next = *ret; 585*e4b17023SJohn Marino *ret = nw; 586*e4b17023SJohn Marino } 587*e4b17023SJohn Marino 588*e4b17023SJohn Marino /* Helper to insert PHI_ARGH to the phi of VAR in the destination of edge E. */ 589*e4b17023SJohn Marino 590*e4b17023SJohn Marino static void 591*e4b17023SJohn Marino add_successor_phi_arg (edge e, tree var, tree phi_arg) 592*e4b17023SJohn Marino { 593*e4b17023SJohn Marino gimple_stmt_iterator gsi; 594*e4b17023SJohn Marino 595*e4b17023SJohn Marino for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) 596*e4b17023SJohn Marino if (PHI_RESULT (gsi_stmt (gsi)) == var) 597*e4b17023SJohn Marino break; 598*e4b17023SJohn Marino 599*e4b17023SJohn Marino gcc_assert (!gsi_end_p (gsi)); 600*e4b17023SJohn Marino add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION); 601*e4b17023SJohn Marino } 602*e4b17023SJohn Marino 603*e4b17023SJohn Marino /* Creates a GIMPLE statement which computes the operation specified by 604*e4b17023SJohn Marino CODE, OP0 and OP1 to a new variable with name LABEL and inserts the 605*e4b17023SJohn Marino statement in the position specified by GSI and UPDATE. Returns the 606*e4b17023SJohn Marino tree node of the statement's result. */ 607*e4b17023SJohn Marino 608*e4b17023SJohn Marino static tree 609*e4b17023SJohn Marino adjust_return_value_with_ops (enum tree_code code, const char *label, 610*e4b17023SJohn Marino tree acc, tree op1, gimple_stmt_iterator gsi) 611*e4b17023SJohn Marino { 612*e4b17023SJohn Marino 613*e4b17023SJohn Marino tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl)); 614*e4b17023SJohn Marino tree tmp = create_tmp_reg (ret_type, label); 615*e4b17023SJohn Marino gimple stmt; 616*e4b17023SJohn Marino tree result; 617*e4b17023SJohn Marino 618*e4b17023SJohn Marino add_referenced_var (tmp); 619*e4b17023SJohn Marino 620*e4b17023SJohn Marino if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1))) 621*e4b17023SJohn Marino stmt = gimple_build_assign_with_ops (code, tmp, acc, op1); 622*e4b17023SJohn Marino else 623*e4b17023SJohn Marino { 624*e4b17023SJohn Marino tree rhs = fold_convert (TREE_TYPE (acc), 625*e4b17023SJohn Marino fold_build2 (code, 626*e4b17023SJohn Marino TREE_TYPE (op1), 627*e4b17023SJohn Marino fold_convert (TREE_TYPE (op1), acc), 628*e4b17023SJohn Marino op1)); 629*e4b17023SJohn Marino rhs = force_gimple_operand_gsi (&gsi, rhs, 630*e4b17023SJohn Marino false, NULL, true, GSI_CONTINUE_LINKING); 631*e4b17023SJohn Marino stmt = gimple_build_assign (NULL_TREE, rhs); 632*e4b17023SJohn Marino } 633*e4b17023SJohn Marino 634*e4b17023SJohn Marino result = make_ssa_name (tmp, stmt); 635*e4b17023SJohn Marino gimple_assign_set_lhs (stmt, result); 636*e4b17023SJohn Marino update_stmt (stmt); 637*e4b17023SJohn Marino gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); 638*e4b17023SJohn Marino return result; 639*e4b17023SJohn Marino } 640*e4b17023SJohn Marino 641*e4b17023SJohn Marino /* Creates a new GIMPLE statement that adjusts the value of accumulator ACC by 642*e4b17023SJohn Marino the computation specified by CODE and OP1 and insert the statement 643*e4b17023SJohn Marino at the position specified by GSI as a new statement. Returns new SSA name 644*e4b17023SJohn Marino of updated accumulator. */ 645*e4b17023SJohn Marino 646*e4b17023SJohn Marino static tree 647*e4b17023SJohn Marino update_accumulator_with_ops (enum tree_code code, tree acc, tree op1, 648*e4b17023SJohn Marino gimple_stmt_iterator gsi) 649*e4b17023SJohn Marino { 650*e4b17023SJohn Marino gimple stmt; 651*e4b17023SJohn Marino tree var; 652*e4b17023SJohn Marino if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1))) 653*e4b17023SJohn Marino stmt = gimple_build_assign_with_ops (code, SSA_NAME_VAR (acc), acc, op1); 654*e4b17023SJohn Marino else 655*e4b17023SJohn Marino { 656*e4b17023SJohn Marino tree rhs = fold_convert (TREE_TYPE (acc), 657*e4b17023SJohn Marino fold_build2 (code, 658*e4b17023SJohn Marino TREE_TYPE (op1), 659*e4b17023SJohn Marino fold_convert (TREE_TYPE (op1), acc), 660*e4b17023SJohn Marino op1)); 661*e4b17023SJohn Marino rhs = force_gimple_operand_gsi (&gsi, rhs, 662*e4b17023SJohn Marino false, NULL, false, GSI_CONTINUE_LINKING); 663*e4b17023SJohn Marino stmt = gimple_build_assign (NULL_TREE, rhs); 664*e4b17023SJohn Marino } 665*e4b17023SJohn Marino var = make_ssa_name (SSA_NAME_VAR (acc), stmt); 666*e4b17023SJohn Marino gimple_assign_set_lhs (stmt, var); 667*e4b17023SJohn Marino update_stmt (stmt); 668*e4b17023SJohn Marino gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); 669*e4b17023SJohn Marino return var; 670*e4b17023SJohn Marino } 671*e4b17023SJohn Marino 672*e4b17023SJohn Marino /* Adjust the accumulator values according to A and M after GSI, and update 673*e4b17023SJohn Marino the phi nodes on edge BACK. */ 674*e4b17023SJohn Marino 675*e4b17023SJohn Marino static void 676*e4b17023SJohn Marino adjust_accumulator_values (gimple_stmt_iterator gsi, tree m, tree a, edge back) 677*e4b17023SJohn Marino { 678*e4b17023SJohn Marino tree var, a_acc_arg, m_acc_arg; 679*e4b17023SJohn Marino 680*e4b17023SJohn Marino if (m) 681*e4b17023SJohn Marino m = force_gimple_operand_gsi (&gsi, m, true, NULL, true, GSI_SAME_STMT); 682*e4b17023SJohn Marino if (a) 683*e4b17023SJohn Marino a = force_gimple_operand_gsi (&gsi, a, true, NULL, true, GSI_SAME_STMT); 684*e4b17023SJohn Marino 685*e4b17023SJohn Marino a_acc_arg = a_acc; 686*e4b17023SJohn Marino m_acc_arg = m_acc; 687*e4b17023SJohn Marino if (a) 688*e4b17023SJohn Marino { 689*e4b17023SJohn Marino if (m_acc) 690*e4b17023SJohn Marino { 691*e4b17023SJohn Marino if (integer_onep (a)) 692*e4b17023SJohn Marino var = m_acc; 693*e4b17023SJohn Marino else 694*e4b17023SJohn Marino var = adjust_return_value_with_ops (MULT_EXPR, "acc_tmp", m_acc, 695*e4b17023SJohn Marino a, gsi); 696*e4b17023SJohn Marino } 697*e4b17023SJohn Marino else 698*e4b17023SJohn Marino var = a; 699*e4b17023SJohn Marino 700*e4b17023SJohn Marino a_acc_arg = update_accumulator_with_ops (PLUS_EXPR, a_acc, var, gsi); 701*e4b17023SJohn Marino } 702*e4b17023SJohn Marino 703*e4b17023SJohn Marino if (m) 704*e4b17023SJohn Marino m_acc_arg = update_accumulator_with_ops (MULT_EXPR, m_acc, m, gsi); 705*e4b17023SJohn Marino 706*e4b17023SJohn Marino if (a_acc) 707*e4b17023SJohn Marino add_successor_phi_arg (back, a_acc, a_acc_arg); 708*e4b17023SJohn Marino 709*e4b17023SJohn Marino if (m_acc) 710*e4b17023SJohn Marino add_successor_phi_arg (back, m_acc, m_acc_arg); 711*e4b17023SJohn Marino } 712*e4b17023SJohn Marino 713*e4b17023SJohn Marino /* Adjust value of the return at the end of BB according to M and A 714*e4b17023SJohn Marino accumulators. */ 715*e4b17023SJohn Marino 716*e4b17023SJohn Marino static void 717*e4b17023SJohn Marino adjust_return_value (basic_block bb, tree m, tree a) 718*e4b17023SJohn Marino { 719*e4b17023SJohn Marino tree retval; 720*e4b17023SJohn Marino gimple ret_stmt = gimple_seq_last_stmt (bb_seq (bb)); 721*e4b17023SJohn Marino gimple_stmt_iterator gsi = gsi_last_bb (bb); 722*e4b17023SJohn Marino 723*e4b17023SJohn Marino gcc_assert (gimple_code (ret_stmt) == GIMPLE_RETURN); 724*e4b17023SJohn Marino 725*e4b17023SJohn Marino retval = gimple_return_retval (ret_stmt); 726*e4b17023SJohn Marino if (!retval || retval == error_mark_node) 727*e4b17023SJohn Marino return; 728*e4b17023SJohn Marino 729*e4b17023SJohn Marino if (m) 730*e4b17023SJohn Marino retval = adjust_return_value_with_ops (MULT_EXPR, "mul_tmp", m_acc, retval, 731*e4b17023SJohn Marino gsi); 732*e4b17023SJohn Marino if (a) 733*e4b17023SJohn Marino retval = adjust_return_value_with_ops (PLUS_EXPR, "acc_tmp", a_acc, retval, 734*e4b17023SJohn Marino gsi); 735*e4b17023SJohn Marino gimple_return_set_retval (ret_stmt, retval); 736*e4b17023SJohn Marino update_stmt (ret_stmt); 737*e4b17023SJohn Marino } 738*e4b17023SJohn Marino 739*e4b17023SJohn Marino /* Subtract COUNT and FREQUENCY from the basic block and it's 740*e4b17023SJohn Marino outgoing edge. */ 741*e4b17023SJohn Marino static void 742*e4b17023SJohn Marino decrease_profile (basic_block bb, gcov_type count, int frequency) 743*e4b17023SJohn Marino { 744*e4b17023SJohn Marino edge e; 745*e4b17023SJohn Marino bb->count -= count; 746*e4b17023SJohn Marino if (bb->count < 0) 747*e4b17023SJohn Marino bb->count = 0; 748*e4b17023SJohn Marino bb->frequency -= frequency; 749*e4b17023SJohn Marino if (bb->frequency < 0) 750*e4b17023SJohn Marino bb->frequency = 0; 751*e4b17023SJohn Marino if (!single_succ_p (bb)) 752*e4b17023SJohn Marino { 753*e4b17023SJohn Marino gcc_assert (!EDGE_COUNT (bb->succs)); 754*e4b17023SJohn Marino return; 755*e4b17023SJohn Marino } 756*e4b17023SJohn Marino e = single_succ_edge (bb); 757*e4b17023SJohn Marino e->count -= count; 758*e4b17023SJohn Marino if (e->count < 0) 759*e4b17023SJohn Marino e->count = 0; 760*e4b17023SJohn Marino } 761*e4b17023SJohn Marino 762*e4b17023SJohn Marino /* Returns true if argument PARAM of the tail recursive call needs to be copied 763*e4b17023SJohn Marino when the call is eliminated. */ 764*e4b17023SJohn Marino 765*e4b17023SJohn Marino static bool 766*e4b17023SJohn Marino arg_needs_copy_p (tree param) 767*e4b17023SJohn Marino { 768*e4b17023SJohn Marino tree def; 769*e4b17023SJohn Marino 770*e4b17023SJohn Marino if (!is_gimple_reg (param) || !var_ann (param)) 771*e4b17023SJohn Marino return false; 772*e4b17023SJohn Marino 773*e4b17023SJohn Marino /* Parameters that are only defined but never used need not be copied. */ 774*e4b17023SJohn Marino def = gimple_default_def (cfun, param); 775*e4b17023SJohn Marino if (!def) 776*e4b17023SJohn Marino return false; 777*e4b17023SJohn Marino 778*e4b17023SJohn Marino return true; 779*e4b17023SJohn Marino } 780*e4b17023SJohn Marino 781*e4b17023SJohn Marino /* Eliminates tail call described by T. TMP_VARS is a list of 782*e4b17023SJohn Marino temporary variables used to copy the function arguments. */ 783*e4b17023SJohn Marino 784*e4b17023SJohn Marino static void 785*e4b17023SJohn Marino eliminate_tail_call (struct tailcall *t) 786*e4b17023SJohn Marino { 787*e4b17023SJohn Marino tree param, rslt; 788*e4b17023SJohn Marino gimple stmt, call; 789*e4b17023SJohn Marino tree arg; 790*e4b17023SJohn Marino size_t idx; 791*e4b17023SJohn Marino basic_block bb, first; 792*e4b17023SJohn Marino edge e; 793*e4b17023SJohn Marino gimple phi; 794*e4b17023SJohn Marino gimple_stmt_iterator gsi; 795*e4b17023SJohn Marino gimple orig_stmt; 796*e4b17023SJohn Marino 797*e4b17023SJohn Marino stmt = orig_stmt = gsi_stmt (t->call_gsi); 798*e4b17023SJohn Marino bb = gsi_bb (t->call_gsi); 799*e4b17023SJohn Marino 800*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS)) 801*e4b17023SJohn Marino { 802*e4b17023SJohn Marino fprintf (dump_file, "Eliminated tail recursion in bb %d : ", 803*e4b17023SJohn Marino bb->index); 804*e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM); 805*e4b17023SJohn Marino fprintf (dump_file, "\n"); 806*e4b17023SJohn Marino } 807*e4b17023SJohn Marino 808*e4b17023SJohn Marino gcc_assert (is_gimple_call (stmt)); 809*e4b17023SJohn Marino 810*e4b17023SJohn Marino first = single_succ (ENTRY_BLOCK_PTR); 811*e4b17023SJohn Marino 812*e4b17023SJohn Marino /* Remove the code after call_gsi that will become unreachable. The 813*e4b17023SJohn Marino possibly unreachable code in other blocks is removed later in 814*e4b17023SJohn Marino cfg cleanup. */ 815*e4b17023SJohn Marino gsi = t->call_gsi; 816*e4b17023SJohn Marino gsi_next (&gsi); 817*e4b17023SJohn Marino while (!gsi_end_p (gsi)) 818*e4b17023SJohn Marino { 819*e4b17023SJohn Marino gimple t = gsi_stmt (gsi); 820*e4b17023SJohn Marino /* Do not remove the return statement, so that redirect_edge_and_branch 821*e4b17023SJohn Marino sees how the block ends. */ 822*e4b17023SJohn Marino if (gimple_code (t) == GIMPLE_RETURN) 823*e4b17023SJohn Marino break; 824*e4b17023SJohn Marino 825*e4b17023SJohn Marino gsi_remove (&gsi, true); 826*e4b17023SJohn Marino release_defs (t); 827*e4b17023SJohn Marino } 828*e4b17023SJohn Marino 829*e4b17023SJohn Marino /* Number of executions of function has reduced by the tailcall. */ 830*e4b17023SJohn Marino e = single_succ_edge (gsi_bb (t->call_gsi)); 831*e4b17023SJohn Marino decrease_profile (EXIT_BLOCK_PTR, e->count, EDGE_FREQUENCY (e)); 832*e4b17023SJohn Marino decrease_profile (ENTRY_BLOCK_PTR, e->count, EDGE_FREQUENCY (e)); 833*e4b17023SJohn Marino if (e->dest != EXIT_BLOCK_PTR) 834*e4b17023SJohn Marino decrease_profile (e->dest, e->count, EDGE_FREQUENCY (e)); 835*e4b17023SJohn Marino 836*e4b17023SJohn Marino /* Replace the call by a jump to the start of function. */ 837*e4b17023SJohn Marino e = redirect_edge_and_branch (single_succ_edge (gsi_bb (t->call_gsi)), 838*e4b17023SJohn Marino first); 839*e4b17023SJohn Marino gcc_assert (e); 840*e4b17023SJohn Marino PENDING_STMT (e) = NULL; 841*e4b17023SJohn Marino 842*e4b17023SJohn Marino /* Add phi node entries for arguments. The ordering of the phi nodes should 843*e4b17023SJohn Marino be the same as the ordering of the arguments. */ 844*e4b17023SJohn Marino for (param = DECL_ARGUMENTS (current_function_decl), 845*e4b17023SJohn Marino idx = 0, gsi = gsi_start_phis (first); 846*e4b17023SJohn Marino param; 847*e4b17023SJohn Marino param = DECL_CHAIN (param), idx++) 848*e4b17023SJohn Marino { 849*e4b17023SJohn Marino if (!arg_needs_copy_p (param)) 850*e4b17023SJohn Marino continue; 851*e4b17023SJohn Marino 852*e4b17023SJohn Marino arg = gimple_call_arg (stmt, idx); 853*e4b17023SJohn Marino phi = gsi_stmt (gsi); 854*e4b17023SJohn Marino gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi))); 855*e4b17023SJohn Marino 856*e4b17023SJohn Marino add_phi_arg (phi, arg, e, gimple_location (stmt)); 857*e4b17023SJohn Marino gsi_next (&gsi); 858*e4b17023SJohn Marino } 859*e4b17023SJohn Marino 860*e4b17023SJohn Marino /* Update the values of accumulators. */ 861*e4b17023SJohn Marino adjust_accumulator_values (t->call_gsi, t->mult, t->add, e); 862*e4b17023SJohn Marino 863*e4b17023SJohn Marino call = gsi_stmt (t->call_gsi); 864*e4b17023SJohn Marino rslt = gimple_call_lhs (call); 865*e4b17023SJohn Marino if (rslt != NULL_TREE) 866*e4b17023SJohn Marino { 867*e4b17023SJohn Marino /* Result of the call will no longer be defined. So adjust the 868*e4b17023SJohn Marino SSA_NAME_DEF_STMT accordingly. */ 869*e4b17023SJohn Marino SSA_NAME_DEF_STMT (rslt) = gimple_build_nop (); 870*e4b17023SJohn Marino } 871*e4b17023SJohn Marino 872*e4b17023SJohn Marino gsi_remove (&t->call_gsi, true); 873*e4b17023SJohn Marino release_defs (call); 874*e4b17023SJohn Marino } 875*e4b17023SJohn Marino 876*e4b17023SJohn Marino /* Add phi nodes for the virtual operands defined in the function to the 877*e4b17023SJohn Marino header of the loop created by tail recursion elimination. 878*e4b17023SJohn Marino 879*e4b17023SJohn Marino Originally, we used to add phi nodes only for call clobbered variables, 880*e4b17023SJohn Marino as the value of the non-call clobbered ones obviously cannot be used 881*e4b17023SJohn Marino or changed within the recursive call. However, the local variables 882*e4b17023SJohn Marino from multiple calls now share the same location, so the virtual ssa form 883*e4b17023SJohn Marino requires us to say that the location dies on further iterations of the loop, 884*e4b17023SJohn Marino which requires adding phi nodes. 885*e4b17023SJohn Marino */ 886*e4b17023SJohn Marino static void 887*e4b17023SJohn Marino add_virtual_phis (void) 888*e4b17023SJohn Marino { 889*e4b17023SJohn Marino referenced_var_iterator rvi; 890*e4b17023SJohn Marino tree var; 891*e4b17023SJohn Marino 892*e4b17023SJohn Marino /* The problematic part is that there is no way how to know what 893*e4b17023SJohn Marino to put into phi nodes (there in fact does not have to be such 894*e4b17023SJohn Marino ssa name available). A solution would be to have an artificial 895*e4b17023SJohn Marino use/kill for all virtual operands in EXIT node. Unless we have 896*e4b17023SJohn Marino this, we cannot do much better than to rebuild the ssa form for 897*e4b17023SJohn Marino possibly affected virtual ssa names from scratch. */ 898*e4b17023SJohn Marino 899*e4b17023SJohn Marino FOR_EACH_REFERENCED_VAR (cfun, var, rvi) 900*e4b17023SJohn Marino { 901*e4b17023SJohn Marino if (!is_gimple_reg (var) && gimple_default_def (cfun, var) != NULL_TREE) 902*e4b17023SJohn Marino mark_sym_for_renaming (var); 903*e4b17023SJohn Marino } 904*e4b17023SJohn Marino } 905*e4b17023SJohn Marino 906*e4b17023SJohn Marino /* Optimizes the tailcall described by T. If OPT_TAILCALLS is true, also 907*e4b17023SJohn Marino mark the tailcalls for the sibcall optimization. */ 908*e4b17023SJohn Marino 909*e4b17023SJohn Marino static bool 910*e4b17023SJohn Marino optimize_tail_call (struct tailcall *t, bool opt_tailcalls) 911*e4b17023SJohn Marino { 912*e4b17023SJohn Marino if (t->tail_recursion) 913*e4b17023SJohn Marino { 914*e4b17023SJohn Marino eliminate_tail_call (t); 915*e4b17023SJohn Marino return true; 916*e4b17023SJohn Marino } 917*e4b17023SJohn Marino 918*e4b17023SJohn Marino if (opt_tailcalls) 919*e4b17023SJohn Marino { 920*e4b17023SJohn Marino gimple stmt = gsi_stmt (t->call_gsi); 921*e4b17023SJohn Marino 922*e4b17023SJohn Marino gimple_call_set_tail (stmt, true); 923*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS)) 924*e4b17023SJohn Marino { 925*e4b17023SJohn Marino fprintf (dump_file, "Found tail call "); 926*e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, dump_flags); 927*e4b17023SJohn Marino fprintf (dump_file, " in bb %i\n", (gsi_bb (t->call_gsi))->index); 928*e4b17023SJohn Marino } 929*e4b17023SJohn Marino } 930*e4b17023SJohn Marino 931*e4b17023SJohn Marino return false; 932*e4b17023SJohn Marino } 933*e4b17023SJohn Marino 934*e4b17023SJohn Marino /* Creates a tail-call accumulator of the same type as the return type of the 935*e4b17023SJohn Marino current function. LABEL is the name used to creating the temporary 936*e4b17023SJohn Marino variable for the accumulator. The accumulator will be inserted in the 937*e4b17023SJohn Marino phis of a basic block BB with single predecessor with an initial value 938*e4b17023SJohn Marino INIT converted to the current function return type. */ 939*e4b17023SJohn Marino 940*e4b17023SJohn Marino static tree 941*e4b17023SJohn Marino create_tailcall_accumulator (const char *label, basic_block bb, tree init) 942*e4b17023SJohn Marino { 943*e4b17023SJohn Marino tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl)); 944*e4b17023SJohn Marino tree tmp = create_tmp_reg (ret_type, label); 945*e4b17023SJohn Marino gimple phi; 946*e4b17023SJohn Marino 947*e4b17023SJohn Marino add_referenced_var (tmp); 948*e4b17023SJohn Marino phi = create_phi_node (tmp, bb); 949*e4b17023SJohn Marino /* RET_TYPE can be a float when -ffast-maths is enabled. */ 950*e4b17023SJohn Marino add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb), 951*e4b17023SJohn Marino UNKNOWN_LOCATION); 952*e4b17023SJohn Marino return PHI_RESULT (phi); 953*e4b17023SJohn Marino } 954*e4b17023SJohn Marino 955*e4b17023SJohn Marino /* Optimizes tail calls in the function, turning the tail recursion 956*e4b17023SJohn Marino into iteration. */ 957*e4b17023SJohn Marino 958*e4b17023SJohn Marino static unsigned int 959*e4b17023SJohn Marino tree_optimize_tail_calls_1 (bool opt_tailcalls) 960*e4b17023SJohn Marino { 961*e4b17023SJohn Marino edge e; 962*e4b17023SJohn Marino bool phis_constructed = false; 963*e4b17023SJohn Marino struct tailcall *tailcalls = NULL, *act, *next; 964*e4b17023SJohn Marino bool changed = false; 965*e4b17023SJohn Marino basic_block first = single_succ (ENTRY_BLOCK_PTR); 966*e4b17023SJohn Marino tree param; 967*e4b17023SJohn Marino gimple stmt; 968*e4b17023SJohn Marino edge_iterator ei; 969*e4b17023SJohn Marino 970*e4b17023SJohn Marino if (!suitable_for_tail_opt_p ()) 971*e4b17023SJohn Marino return 0; 972*e4b17023SJohn Marino if (opt_tailcalls) 973*e4b17023SJohn Marino opt_tailcalls = suitable_for_tail_call_opt_p (); 974*e4b17023SJohn Marino 975*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) 976*e4b17023SJohn Marino { 977*e4b17023SJohn Marino /* Only traverse the normal exits, i.e. those that end with return 978*e4b17023SJohn Marino statement. */ 979*e4b17023SJohn Marino stmt = last_stmt (e->src); 980*e4b17023SJohn Marino 981*e4b17023SJohn Marino if (stmt 982*e4b17023SJohn Marino && gimple_code (stmt) == GIMPLE_RETURN) 983*e4b17023SJohn Marino find_tail_calls (e->src, &tailcalls); 984*e4b17023SJohn Marino } 985*e4b17023SJohn Marino 986*e4b17023SJohn Marino /* Construct the phi nodes and accumulators if necessary. */ 987*e4b17023SJohn Marino a_acc = m_acc = NULL_TREE; 988*e4b17023SJohn Marino for (act = tailcalls; act; act = act->next) 989*e4b17023SJohn Marino { 990*e4b17023SJohn Marino if (!act->tail_recursion) 991*e4b17023SJohn Marino continue; 992*e4b17023SJohn Marino 993*e4b17023SJohn Marino if (!phis_constructed) 994*e4b17023SJohn Marino { 995*e4b17023SJohn Marino /* Ensure that there is only one predecessor of the block 996*e4b17023SJohn Marino or if there are existing degenerate PHI nodes. */ 997*e4b17023SJohn Marino if (!single_pred_p (first) 998*e4b17023SJohn Marino || !gimple_seq_empty_p (phi_nodes (first))) 999*e4b17023SJohn Marino first = split_edge (single_succ_edge (ENTRY_BLOCK_PTR)); 1000*e4b17023SJohn Marino 1001*e4b17023SJohn Marino /* Copy the args if needed. */ 1002*e4b17023SJohn Marino for (param = DECL_ARGUMENTS (current_function_decl); 1003*e4b17023SJohn Marino param; 1004*e4b17023SJohn Marino param = DECL_CHAIN (param)) 1005*e4b17023SJohn Marino if (arg_needs_copy_p (param)) 1006*e4b17023SJohn Marino { 1007*e4b17023SJohn Marino tree name = gimple_default_def (cfun, param); 1008*e4b17023SJohn Marino tree new_name = make_ssa_name (param, SSA_NAME_DEF_STMT (name)); 1009*e4b17023SJohn Marino gimple phi; 1010*e4b17023SJohn Marino 1011*e4b17023SJohn Marino set_default_def (param, new_name); 1012*e4b17023SJohn Marino phi = create_phi_node (name, first); 1013*e4b17023SJohn Marino SSA_NAME_DEF_STMT (name) = phi; 1014*e4b17023SJohn Marino add_phi_arg (phi, new_name, single_pred_edge (first), 1015*e4b17023SJohn Marino EXPR_LOCATION (param)); 1016*e4b17023SJohn Marino } 1017*e4b17023SJohn Marino phis_constructed = true; 1018*e4b17023SJohn Marino } 1019*e4b17023SJohn Marino 1020*e4b17023SJohn Marino if (act->add && !a_acc) 1021*e4b17023SJohn Marino a_acc = create_tailcall_accumulator ("add_acc", first, 1022*e4b17023SJohn Marino integer_zero_node); 1023*e4b17023SJohn Marino 1024*e4b17023SJohn Marino if (act->mult && !m_acc) 1025*e4b17023SJohn Marino m_acc = create_tailcall_accumulator ("mult_acc", first, 1026*e4b17023SJohn Marino integer_one_node); 1027*e4b17023SJohn Marino } 1028*e4b17023SJohn Marino 1029*e4b17023SJohn Marino if (a_acc || m_acc) 1030*e4b17023SJohn Marino { 1031*e4b17023SJohn Marino /* When the tail call elimination using accumulators is performed, 1032*e4b17023SJohn Marino statements adding the accumulated value are inserted at all exits. 1033*e4b17023SJohn Marino This turns all other tail calls to non-tail ones. */ 1034*e4b17023SJohn Marino opt_tailcalls = false; 1035*e4b17023SJohn Marino } 1036*e4b17023SJohn Marino 1037*e4b17023SJohn Marino for (; tailcalls; tailcalls = next) 1038*e4b17023SJohn Marino { 1039*e4b17023SJohn Marino next = tailcalls->next; 1040*e4b17023SJohn Marino changed |= optimize_tail_call (tailcalls, opt_tailcalls); 1041*e4b17023SJohn Marino free (tailcalls); 1042*e4b17023SJohn Marino } 1043*e4b17023SJohn Marino 1044*e4b17023SJohn Marino if (a_acc || m_acc) 1045*e4b17023SJohn Marino { 1046*e4b17023SJohn Marino /* Modify the remaining return statements. */ 1047*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) 1048*e4b17023SJohn Marino { 1049*e4b17023SJohn Marino stmt = last_stmt (e->src); 1050*e4b17023SJohn Marino 1051*e4b17023SJohn Marino if (stmt 1052*e4b17023SJohn Marino && gimple_code (stmt) == GIMPLE_RETURN) 1053*e4b17023SJohn Marino adjust_return_value (e->src, m_acc, a_acc); 1054*e4b17023SJohn Marino } 1055*e4b17023SJohn Marino } 1056*e4b17023SJohn Marino 1057*e4b17023SJohn Marino if (changed) 1058*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS); 1059*e4b17023SJohn Marino 1060*e4b17023SJohn Marino if (phis_constructed) 1061*e4b17023SJohn Marino add_virtual_phis (); 1062*e4b17023SJohn Marino if (changed) 1063*e4b17023SJohn Marino return TODO_cleanup_cfg | TODO_update_ssa_only_virtuals; 1064*e4b17023SJohn Marino return 0; 1065*e4b17023SJohn Marino } 1066*e4b17023SJohn Marino 1067*e4b17023SJohn Marino static unsigned int 1068*e4b17023SJohn Marino execute_tail_recursion (void) 1069*e4b17023SJohn Marino { 1070*e4b17023SJohn Marino return tree_optimize_tail_calls_1 (false); 1071*e4b17023SJohn Marino } 1072*e4b17023SJohn Marino 1073*e4b17023SJohn Marino static bool 1074*e4b17023SJohn Marino gate_tail_calls (void) 1075*e4b17023SJohn Marino { 1076*e4b17023SJohn Marino return flag_optimize_sibling_calls != 0 && dbg_cnt (tail_call); 1077*e4b17023SJohn Marino } 1078*e4b17023SJohn Marino 1079*e4b17023SJohn Marino static unsigned int 1080*e4b17023SJohn Marino execute_tail_calls (void) 1081*e4b17023SJohn Marino { 1082*e4b17023SJohn Marino return tree_optimize_tail_calls_1 (true); 1083*e4b17023SJohn Marino } 1084*e4b17023SJohn Marino 1085*e4b17023SJohn Marino struct gimple_opt_pass pass_tail_recursion = 1086*e4b17023SJohn Marino { 1087*e4b17023SJohn Marino { 1088*e4b17023SJohn Marino GIMPLE_PASS, 1089*e4b17023SJohn Marino "tailr", /* name */ 1090*e4b17023SJohn Marino gate_tail_calls, /* gate */ 1091*e4b17023SJohn Marino execute_tail_recursion, /* execute */ 1092*e4b17023SJohn Marino NULL, /* sub */ 1093*e4b17023SJohn Marino NULL, /* next */ 1094*e4b17023SJohn Marino 0, /* static_pass_number */ 1095*e4b17023SJohn Marino TV_NONE, /* tv_id */ 1096*e4b17023SJohn Marino PROP_cfg | PROP_ssa, /* properties_required */ 1097*e4b17023SJohn Marino 0, /* properties_provided */ 1098*e4b17023SJohn Marino 0, /* properties_destroyed */ 1099*e4b17023SJohn Marino 0, /* todo_flags_start */ 1100*e4b17023SJohn Marino TODO_verify_ssa /* todo_flags_finish */ 1101*e4b17023SJohn Marino } 1102*e4b17023SJohn Marino }; 1103*e4b17023SJohn Marino 1104*e4b17023SJohn Marino struct gimple_opt_pass pass_tail_calls = 1105*e4b17023SJohn Marino { 1106*e4b17023SJohn Marino { 1107*e4b17023SJohn Marino GIMPLE_PASS, 1108*e4b17023SJohn Marino "tailc", /* name */ 1109*e4b17023SJohn Marino gate_tail_calls, /* gate */ 1110*e4b17023SJohn Marino execute_tail_calls, /* execute */ 1111*e4b17023SJohn Marino NULL, /* sub */ 1112*e4b17023SJohn Marino NULL, /* next */ 1113*e4b17023SJohn Marino 0, /* static_pass_number */ 1114*e4b17023SJohn Marino TV_NONE, /* tv_id */ 1115*e4b17023SJohn Marino PROP_cfg | PROP_ssa, /* properties_required */ 1116*e4b17023SJohn Marino 0, /* properties_provided */ 1117*e4b17023SJohn Marino 0, /* properties_destroyed */ 1118*e4b17023SJohn Marino 0, /* todo_flags_start */ 1119*e4b17023SJohn Marino TODO_verify_ssa /* todo_flags_finish */ 1120*e4b17023SJohn Marino } 1121*e4b17023SJohn Marino }; 1122