1*e4b17023SJohn Marino /* Tree inlining. 2*e4b17023SJohn Marino Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 3*e4b17023SJohn Marino 2012 Free Software Foundation, Inc. 4*e4b17023SJohn Marino Contributed by Alexandre Oliva <aoliva@redhat.com> 5*e4b17023SJohn Marino 6*e4b17023SJohn Marino This file is part of GCC. 7*e4b17023SJohn Marino 8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify 9*e4b17023SJohn Marino it under the terms of the GNU General Public License as published by 10*e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option) 11*e4b17023SJohn Marino any later version. 12*e4b17023SJohn Marino 13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, 14*e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of 15*e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*e4b17023SJohn Marino GNU General Public License for more details. 17*e4b17023SJohn Marino 18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License 19*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see 20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */ 21*e4b17023SJohn Marino 22*e4b17023SJohn Marino #include "config.h" 23*e4b17023SJohn Marino #include "system.h" 24*e4b17023SJohn Marino #include "coretypes.h" 25*e4b17023SJohn Marino #include "tm.h" 26*e4b17023SJohn Marino #include "diagnostic-core.h" 27*e4b17023SJohn Marino #include "tree.h" 28*e4b17023SJohn Marino #include "tree-inline.h" 29*e4b17023SJohn Marino #include "flags.h" 30*e4b17023SJohn Marino #include "params.h" 31*e4b17023SJohn Marino #include "input.h" 32*e4b17023SJohn Marino #include "insn-config.h" 33*e4b17023SJohn Marino #include "hashtab.h" 34*e4b17023SJohn Marino #include "langhooks.h" 35*e4b17023SJohn Marino #include "basic-block.h" 36*e4b17023SJohn Marino #include "tree-iterator.h" 37*e4b17023SJohn Marino #include "cgraph.h" 38*e4b17023SJohn Marino #include "intl.h" 39*e4b17023SJohn Marino #include "tree-mudflap.h" 40*e4b17023SJohn Marino #include "tree-flow.h" 41*e4b17023SJohn Marino #include "function.h" 42*e4b17023SJohn Marino #include "tree-flow.h" 43*e4b17023SJohn Marino #include "tree-pretty-print.h" 44*e4b17023SJohn Marino #include "except.h" 45*e4b17023SJohn Marino #include "debug.h" 46*e4b17023SJohn Marino #include "pointer-set.h" 47*e4b17023SJohn Marino #include "ipa-prop.h" 48*e4b17023SJohn Marino #include "value-prof.h" 49*e4b17023SJohn Marino #include "tree-pass.h" 50*e4b17023SJohn Marino #include "target.h" 51*e4b17023SJohn Marino #include "integrate.h" 52*e4b17023SJohn Marino 53*e4b17023SJohn Marino #include "rtl.h" /* FIXME: For asm_str_count. */ 54*e4b17023SJohn Marino 55*e4b17023SJohn Marino /* I'm not real happy about this, but we need to handle gimple and 56*e4b17023SJohn Marino non-gimple trees. */ 57*e4b17023SJohn Marino #include "gimple.h" 58*e4b17023SJohn Marino 59*e4b17023SJohn Marino /* Inlining, Cloning, Versioning, Parallelization 60*e4b17023SJohn Marino 61*e4b17023SJohn Marino Inlining: a function body is duplicated, but the PARM_DECLs are 62*e4b17023SJohn Marino remapped into VAR_DECLs, and non-void RETURN_EXPRs become 63*e4b17023SJohn Marino MODIFY_EXPRs that store to a dedicated returned-value variable. 64*e4b17023SJohn Marino The duplicated eh_region info of the copy will later be appended 65*e4b17023SJohn Marino to the info for the caller; the eh_region info in copied throwing 66*e4b17023SJohn Marino statements and RESX statements are adjusted accordingly. 67*e4b17023SJohn Marino 68*e4b17023SJohn Marino Cloning: (only in C++) We have one body for a con/de/structor, and 69*e4b17023SJohn Marino multiple function decls, each with a unique parameter list. 70*e4b17023SJohn Marino Duplicate the body, using the given splay tree; some parameters 71*e4b17023SJohn Marino will become constants (like 0 or 1). 72*e4b17023SJohn Marino 73*e4b17023SJohn Marino Versioning: a function body is duplicated and the result is a new 74*e4b17023SJohn Marino function rather than into blocks of an existing function as with 75*e4b17023SJohn Marino inlining. Some parameters will become constants. 76*e4b17023SJohn Marino 77*e4b17023SJohn Marino Parallelization: a region of a function is duplicated resulting in 78*e4b17023SJohn Marino a new function. Variables may be replaced with complex expressions 79*e4b17023SJohn Marino to enable shared variable semantics. 80*e4b17023SJohn Marino 81*e4b17023SJohn Marino All of these will simultaneously lookup any callgraph edges. If 82*e4b17023SJohn Marino we're going to inline the duplicated function body, and the given 83*e4b17023SJohn Marino function has some cloned callgraph nodes (one for each place this 84*e4b17023SJohn Marino function will be inlined) those callgraph edges will be duplicated. 85*e4b17023SJohn Marino If we're cloning the body, those callgraph edges will be 86*e4b17023SJohn Marino updated to point into the new body. (Note that the original 87*e4b17023SJohn Marino callgraph node and edge list will not be altered.) 88*e4b17023SJohn Marino 89*e4b17023SJohn Marino See the CALL_EXPR handling case in copy_tree_body_r (). */ 90*e4b17023SJohn Marino 91*e4b17023SJohn Marino /* To Do: 92*e4b17023SJohn Marino 93*e4b17023SJohn Marino o In order to make inlining-on-trees work, we pessimized 94*e4b17023SJohn Marino function-local static constants. In particular, they are now 95*e4b17023SJohn Marino always output, even when not addressed. Fix this by treating 96*e4b17023SJohn Marino function-local static constants just like global static 97*e4b17023SJohn Marino constants; the back-end already knows not to output them if they 98*e4b17023SJohn Marino are not needed. 99*e4b17023SJohn Marino 100*e4b17023SJohn Marino o Provide heuristics to clamp inlining of recursive template 101*e4b17023SJohn Marino calls? */ 102*e4b17023SJohn Marino 103*e4b17023SJohn Marino 104*e4b17023SJohn Marino /* Weights that estimate_num_insns uses to estimate the size of the 105*e4b17023SJohn Marino produced code. */ 106*e4b17023SJohn Marino 107*e4b17023SJohn Marino eni_weights eni_size_weights; 108*e4b17023SJohn Marino 109*e4b17023SJohn Marino /* Weights that estimate_num_insns uses to estimate the time necessary 110*e4b17023SJohn Marino to execute the produced code. */ 111*e4b17023SJohn Marino 112*e4b17023SJohn Marino eni_weights eni_time_weights; 113*e4b17023SJohn Marino 114*e4b17023SJohn Marino /* Prototypes. */ 115*e4b17023SJohn Marino 116*e4b17023SJohn Marino static tree declare_return_variable (copy_body_data *, tree, tree, basic_block); 117*e4b17023SJohn Marino static void remap_block (tree *, copy_body_data *); 118*e4b17023SJohn Marino static void copy_bind_expr (tree *, int *, copy_body_data *); 119*e4b17023SJohn Marino static tree mark_local_for_remap_r (tree *, int *, void *); 120*e4b17023SJohn Marino static void unsave_expr_1 (tree); 121*e4b17023SJohn Marino static tree unsave_r (tree *, int *, void *); 122*e4b17023SJohn Marino static void declare_inline_vars (tree, tree); 123*e4b17023SJohn Marino static void remap_save_expr (tree *, void *, int *); 124*e4b17023SJohn Marino static void prepend_lexical_block (tree current_block, tree new_block); 125*e4b17023SJohn Marino static tree copy_decl_to_var (tree, copy_body_data *); 126*e4b17023SJohn Marino static tree copy_result_decl_to_var (tree, copy_body_data *); 127*e4b17023SJohn Marino static tree copy_decl_maybe_to_var (tree, copy_body_data *); 128*e4b17023SJohn Marino static gimple remap_gimple_stmt (gimple, copy_body_data *); 129*e4b17023SJohn Marino static bool delete_unreachable_blocks_update_callgraph (copy_body_data *id); 130*e4b17023SJohn Marino 131*e4b17023SJohn Marino /* Insert a tree->tree mapping for ID. Despite the name suggests 132*e4b17023SJohn Marino that the trees should be variables, it is used for more than that. */ 133*e4b17023SJohn Marino 134*e4b17023SJohn Marino void 135*e4b17023SJohn Marino insert_decl_map (copy_body_data *id, tree key, tree value) 136*e4b17023SJohn Marino { 137*e4b17023SJohn Marino *pointer_map_insert (id->decl_map, key) = value; 138*e4b17023SJohn Marino 139*e4b17023SJohn Marino /* Always insert an identity map as well. If we see this same new 140*e4b17023SJohn Marino node again, we won't want to duplicate it a second time. */ 141*e4b17023SJohn Marino if (key != value) 142*e4b17023SJohn Marino *pointer_map_insert (id->decl_map, value) = value; 143*e4b17023SJohn Marino } 144*e4b17023SJohn Marino 145*e4b17023SJohn Marino /* Insert a tree->tree mapping for ID. This is only used for 146*e4b17023SJohn Marino variables. */ 147*e4b17023SJohn Marino 148*e4b17023SJohn Marino static void 149*e4b17023SJohn Marino insert_debug_decl_map (copy_body_data *id, tree key, tree value) 150*e4b17023SJohn Marino { 151*e4b17023SJohn Marino if (!gimple_in_ssa_p (id->src_cfun)) 152*e4b17023SJohn Marino return; 153*e4b17023SJohn Marino 154*e4b17023SJohn Marino if (!MAY_HAVE_DEBUG_STMTS) 155*e4b17023SJohn Marino return; 156*e4b17023SJohn Marino 157*e4b17023SJohn Marino if (!target_for_debug_bind (key)) 158*e4b17023SJohn Marino return; 159*e4b17023SJohn Marino 160*e4b17023SJohn Marino gcc_assert (TREE_CODE (key) == PARM_DECL); 161*e4b17023SJohn Marino gcc_assert (TREE_CODE (value) == VAR_DECL); 162*e4b17023SJohn Marino 163*e4b17023SJohn Marino if (!id->debug_map) 164*e4b17023SJohn Marino id->debug_map = pointer_map_create (); 165*e4b17023SJohn Marino 166*e4b17023SJohn Marino *pointer_map_insert (id->debug_map, key) = value; 167*e4b17023SJohn Marino } 168*e4b17023SJohn Marino 169*e4b17023SJohn Marino /* If nonzero, we're remapping the contents of inlined debug 170*e4b17023SJohn Marino statements. If negative, an error has occurred, such as a 171*e4b17023SJohn Marino reference to a variable that isn't available in the inlined 172*e4b17023SJohn Marino context. */ 173*e4b17023SJohn Marino static int processing_debug_stmt = 0; 174*e4b17023SJohn Marino 175*e4b17023SJohn Marino /* Construct new SSA name for old NAME. ID is the inline context. */ 176*e4b17023SJohn Marino 177*e4b17023SJohn Marino static tree 178*e4b17023SJohn Marino remap_ssa_name (tree name, copy_body_data *id) 179*e4b17023SJohn Marino { 180*e4b17023SJohn Marino tree new_tree; 181*e4b17023SJohn Marino tree *n; 182*e4b17023SJohn Marino 183*e4b17023SJohn Marino gcc_assert (TREE_CODE (name) == SSA_NAME); 184*e4b17023SJohn Marino 185*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, name); 186*e4b17023SJohn Marino if (n) 187*e4b17023SJohn Marino return unshare_expr (*n); 188*e4b17023SJohn Marino 189*e4b17023SJohn Marino if (processing_debug_stmt) 190*e4b17023SJohn Marino { 191*e4b17023SJohn Marino if (TREE_CODE (SSA_NAME_VAR (name)) == PARM_DECL 192*e4b17023SJohn Marino && SSA_NAME_IS_DEFAULT_DEF (name) 193*e4b17023SJohn Marino && id->entry_bb == NULL 194*e4b17023SJohn Marino && single_succ_p (ENTRY_BLOCK_PTR)) 195*e4b17023SJohn Marino { 196*e4b17023SJohn Marino tree vexpr = make_node (DEBUG_EXPR_DECL); 197*e4b17023SJohn Marino gimple def_temp; 198*e4b17023SJohn Marino gimple_stmt_iterator gsi; 199*e4b17023SJohn Marino tree val = SSA_NAME_VAR (name); 200*e4b17023SJohn Marino 201*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, val); 202*e4b17023SJohn Marino if (n != NULL) 203*e4b17023SJohn Marino val = *n; 204*e4b17023SJohn Marino if (TREE_CODE (val) != PARM_DECL) 205*e4b17023SJohn Marino { 206*e4b17023SJohn Marino processing_debug_stmt = -1; 207*e4b17023SJohn Marino return name; 208*e4b17023SJohn Marino } 209*e4b17023SJohn Marino def_temp = gimple_build_debug_source_bind (vexpr, val, NULL); 210*e4b17023SJohn Marino DECL_ARTIFICIAL (vexpr) = 1; 211*e4b17023SJohn Marino TREE_TYPE (vexpr) = TREE_TYPE (name); 212*e4b17023SJohn Marino DECL_MODE (vexpr) = DECL_MODE (SSA_NAME_VAR (name)); 213*e4b17023SJohn Marino gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR)); 214*e4b17023SJohn Marino gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT); 215*e4b17023SJohn Marino return vexpr; 216*e4b17023SJohn Marino } 217*e4b17023SJohn Marino 218*e4b17023SJohn Marino processing_debug_stmt = -1; 219*e4b17023SJohn Marino return name; 220*e4b17023SJohn Marino } 221*e4b17023SJohn Marino 222*e4b17023SJohn Marino /* Do not set DEF_STMT yet as statement is not copied yet. We do that 223*e4b17023SJohn Marino in copy_bb. */ 224*e4b17023SJohn Marino new_tree = remap_decl (SSA_NAME_VAR (name), id); 225*e4b17023SJohn Marino 226*e4b17023SJohn Marino /* We might've substituted constant or another SSA_NAME for 227*e4b17023SJohn Marino the variable. 228*e4b17023SJohn Marino 229*e4b17023SJohn Marino Replace the SSA name representing RESULT_DECL by variable during 230*e4b17023SJohn Marino inlining: this saves us from need to introduce PHI node in a case 231*e4b17023SJohn Marino return value is just partly initialized. */ 232*e4b17023SJohn Marino if ((TREE_CODE (new_tree) == VAR_DECL || TREE_CODE (new_tree) == PARM_DECL) 233*e4b17023SJohn Marino && (TREE_CODE (SSA_NAME_VAR (name)) != RESULT_DECL 234*e4b17023SJohn Marino || !id->transform_return_to_modify)) 235*e4b17023SJohn Marino { 236*e4b17023SJohn Marino struct ptr_info_def *pi; 237*e4b17023SJohn Marino new_tree = make_ssa_name (new_tree, NULL); 238*e4b17023SJohn Marino insert_decl_map (id, name, new_tree); 239*e4b17023SJohn Marino SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_tree) 240*e4b17023SJohn Marino = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name); 241*e4b17023SJohn Marino TREE_TYPE (new_tree) = TREE_TYPE (SSA_NAME_VAR (new_tree)); 242*e4b17023SJohn Marino /* At least IPA points-to info can be directly transferred. */ 243*e4b17023SJohn Marino if (id->src_cfun->gimple_df 244*e4b17023SJohn Marino && id->src_cfun->gimple_df->ipa_pta 245*e4b17023SJohn Marino && (pi = SSA_NAME_PTR_INFO (name)) 246*e4b17023SJohn Marino && !pi->pt.anything) 247*e4b17023SJohn Marino { 248*e4b17023SJohn Marino struct ptr_info_def *new_pi = get_ptr_info (new_tree); 249*e4b17023SJohn Marino new_pi->pt = pi->pt; 250*e4b17023SJohn Marino } 251*e4b17023SJohn Marino if (gimple_nop_p (SSA_NAME_DEF_STMT (name))) 252*e4b17023SJohn Marino { 253*e4b17023SJohn Marino /* By inlining function having uninitialized variable, we might 254*e4b17023SJohn Marino extend the lifetime (variable might get reused). This cause 255*e4b17023SJohn Marino ICE in the case we end up extending lifetime of SSA name across 256*e4b17023SJohn Marino abnormal edge, but also increase register pressure. 257*e4b17023SJohn Marino 258*e4b17023SJohn Marino We simply initialize all uninitialized vars by 0 except 259*e4b17023SJohn Marino for case we are inlining to very first BB. We can avoid 260*e4b17023SJohn Marino this for all BBs that are not inside strongly connected 261*e4b17023SJohn Marino regions of the CFG, but this is expensive to test. */ 262*e4b17023SJohn Marino if (id->entry_bb 263*e4b17023SJohn Marino && is_gimple_reg (SSA_NAME_VAR (name)) 264*e4b17023SJohn Marino && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name) 265*e4b17023SJohn Marino && TREE_CODE (SSA_NAME_VAR (name)) != PARM_DECL 266*e4b17023SJohn Marino && (id->entry_bb != EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest 267*e4b17023SJohn Marino || EDGE_COUNT (id->entry_bb->preds) != 1)) 268*e4b17023SJohn Marino { 269*e4b17023SJohn Marino gimple_stmt_iterator gsi = gsi_last_bb (id->entry_bb); 270*e4b17023SJohn Marino gimple init_stmt; 271*e4b17023SJohn Marino tree zero = build_zero_cst (TREE_TYPE (new_tree)); 272*e4b17023SJohn Marino 273*e4b17023SJohn Marino init_stmt = gimple_build_assign (new_tree, zero); 274*e4b17023SJohn Marino gsi_insert_after (&gsi, init_stmt, GSI_NEW_STMT); 275*e4b17023SJohn Marino SSA_NAME_IS_DEFAULT_DEF (new_tree) = 0; 276*e4b17023SJohn Marino } 277*e4b17023SJohn Marino else 278*e4b17023SJohn Marino { 279*e4b17023SJohn Marino SSA_NAME_DEF_STMT (new_tree) = gimple_build_nop (); 280*e4b17023SJohn Marino if (gimple_default_def (id->src_cfun, SSA_NAME_VAR (name)) 281*e4b17023SJohn Marino == name) 282*e4b17023SJohn Marino set_default_def (SSA_NAME_VAR (new_tree), new_tree); 283*e4b17023SJohn Marino } 284*e4b17023SJohn Marino } 285*e4b17023SJohn Marino } 286*e4b17023SJohn Marino else 287*e4b17023SJohn Marino insert_decl_map (id, name, new_tree); 288*e4b17023SJohn Marino return new_tree; 289*e4b17023SJohn Marino } 290*e4b17023SJohn Marino 291*e4b17023SJohn Marino /* Remap DECL during the copying of the BLOCK tree for the function. */ 292*e4b17023SJohn Marino 293*e4b17023SJohn Marino tree 294*e4b17023SJohn Marino remap_decl (tree decl, copy_body_data *id) 295*e4b17023SJohn Marino { 296*e4b17023SJohn Marino tree *n; 297*e4b17023SJohn Marino 298*e4b17023SJohn Marino /* We only remap local variables in the current function. */ 299*e4b17023SJohn Marino 300*e4b17023SJohn Marino /* See if we have remapped this declaration. */ 301*e4b17023SJohn Marino 302*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, decl); 303*e4b17023SJohn Marino 304*e4b17023SJohn Marino if (!n && processing_debug_stmt) 305*e4b17023SJohn Marino { 306*e4b17023SJohn Marino processing_debug_stmt = -1; 307*e4b17023SJohn Marino return decl; 308*e4b17023SJohn Marino } 309*e4b17023SJohn Marino 310*e4b17023SJohn Marino /* If we didn't already have an equivalent for this declaration, 311*e4b17023SJohn Marino create one now. */ 312*e4b17023SJohn Marino if (!n) 313*e4b17023SJohn Marino { 314*e4b17023SJohn Marino /* Make a copy of the variable or label. */ 315*e4b17023SJohn Marino tree t = id->copy_decl (decl, id); 316*e4b17023SJohn Marino 317*e4b17023SJohn Marino /* Remember it, so that if we encounter this local entity again 318*e4b17023SJohn Marino we can reuse this copy. Do this early because remap_type may 319*e4b17023SJohn Marino need this decl for TYPE_STUB_DECL. */ 320*e4b17023SJohn Marino insert_decl_map (id, decl, t); 321*e4b17023SJohn Marino 322*e4b17023SJohn Marino if (!DECL_P (t)) 323*e4b17023SJohn Marino return t; 324*e4b17023SJohn Marino 325*e4b17023SJohn Marino /* Remap types, if necessary. */ 326*e4b17023SJohn Marino TREE_TYPE (t) = remap_type (TREE_TYPE (t), id); 327*e4b17023SJohn Marino if (TREE_CODE (t) == TYPE_DECL) 328*e4b17023SJohn Marino DECL_ORIGINAL_TYPE (t) = remap_type (DECL_ORIGINAL_TYPE (t), id); 329*e4b17023SJohn Marino 330*e4b17023SJohn Marino /* Remap sizes as necessary. */ 331*e4b17023SJohn Marino walk_tree (&DECL_SIZE (t), copy_tree_body_r, id, NULL); 332*e4b17023SJohn Marino walk_tree (&DECL_SIZE_UNIT (t), copy_tree_body_r, id, NULL); 333*e4b17023SJohn Marino 334*e4b17023SJohn Marino /* If fields, do likewise for offset and qualifier. */ 335*e4b17023SJohn Marino if (TREE_CODE (t) == FIELD_DECL) 336*e4b17023SJohn Marino { 337*e4b17023SJohn Marino walk_tree (&DECL_FIELD_OFFSET (t), copy_tree_body_r, id, NULL); 338*e4b17023SJohn Marino if (TREE_CODE (DECL_CONTEXT (t)) == QUAL_UNION_TYPE) 339*e4b17023SJohn Marino walk_tree (&DECL_QUALIFIER (t), copy_tree_body_r, id, NULL); 340*e4b17023SJohn Marino } 341*e4b17023SJohn Marino 342*e4b17023SJohn Marino if ((TREE_CODE (t) == VAR_DECL 343*e4b17023SJohn Marino || TREE_CODE (t) == RESULT_DECL 344*e4b17023SJohn Marino || TREE_CODE (t) == PARM_DECL) 345*e4b17023SJohn Marino && id->src_fn && DECL_STRUCT_FUNCTION (id->src_fn) 346*e4b17023SJohn Marino && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn)) 347*e4b17023SJohn Marino /* We don't want to mark as referenced VAR_DECLs that were 348*e4b17023SJohn Marino not marked as such in the src function. */ 349*e4b17023SJohn Marino && (TREE_CODE (decl) != VAR_DECL 350*e4b17023SJohn Marino || referenced_var_lookup (DECL_STRUCT_FUNCTION (id->src_fn), 351*e4b17023SJohn Marino DECL_UID (decl)))) 352*e4b17023SJohn Marino add_referenced_var (t); 353*e4b17023SJohn Marino return t; 354*e4b17023SJohn Marino } 355*e4b17023SJohn Marino 356*e4b17023SJohn Marino if (id->do_not_unshare) 357*e4b17023SJohn Marino return *n; 358*e4b17023SJohn Marino else 359*e4b17023SJohn Marino return unshare_expr (*n); 360*e4b17023SJohn Marino } 361*e4b17023SJohn Marino 362*e4b17023SJohn Marino static tree 363*e4b17023SJohn Marino remap_type_1 (tree type, copy_body_data *id) 364*e4b17023SJohn Marino { 365*e4b17023SJohn Marino tree new_tree, t; 366*e4b17023SJohn Marino 367*e4b17023SJohn Marino /* We do need a copy. build and register it now. If this is a pointer or 368*e4b17023SJohn Marino reference type, remap the designated type and make a new pointer or 369*e4b17023SJohn Marino reference type. */ 370*e4b17023SJohn Marino if (TREE_CODE (type) == POINTER_TYPE) 371*e4b17023SJohn Marino { 372*e4b17023SJohn Marino new_tree = build_pointer_type_for_mode (remap_type (TREE_TYPE (type), id), 373*e4b17023SJohn Marino TYPE_MODE (type), 374*e4b17023SJohn Marino TYPE_REF_CAN_ALIAS_ALL (type)); 375*e4b17023SJohn Marino if (TYPE_ATTRIBUTES (type) || TYPE_QUALS (type)) 376*e4b17023SJohn Marino new_tree = build_type_attribute_qual_variant (new_tree, 377*e4b17023SJohn Marino TYPE_ATTRIBUTES (type), 378*e4b17023SJohn Marino TYPE_QUALS (type)); 379*e4b17023SJohn Marino insert_decl_map (id, type, new_tree); 380*e4b17023SJohn Marino return new_tree; 381*e4b17023SJohn Marino } 382*e4b17023SJohn Marino else if (TREE_CODE (type) == REFERENCE_TYPE) 383*e4b17023SJohn Marino { 384*e4b17023SJohn Marino new_tree = build_reference_type_for_mode (remap_type (TREE_TYPE (type), id), 385*e4b17023SJohn Marino TYPE_MODE (type), 386*e4b17023SJohn Marino TYPE_REF_CAN_ALIAS_ALL (type)); 387*e4b17023SJohn Marino if (TYPE_ATTRIBUTES (type) || TYPE_QUALS (type)) 388*e4b17023SJohn Marino new_tree = build_type_attribute_qual_variant (new_tree, 389*e4b17023SJohn Marino TYPE_ATTRIBUTES (type), 390*e4b17023SJohn Marino TYPE_QUALS (type)); 391*e4b17023SJohn Marino insert_decl_map (id, type, new_tree); 392*e4b17023SJohn Marino return new_tree; 393*e4b17023SJohn Marino } 394*e4b17023SJohn Marino else 395*e4b17023SJohn Marino new_tree = copy_node (type); 396*e4b17023SJohn Marino 397*e4b17023SJohn Marino insert_decl_map (id, type, new_tree); 398*e4b17023SJohn Marino 399*e4b17023SJohn Marino /* This is a new type, not a copy of an old type. Need to reassociate 400*e4b17023SJohn Marino variants. We can handle everything except the main variant lazily. */ 401*e4b17023SJohn Marino t = TYPE_MAIN_VARIANT (type); 402*e4b17023SJohn Marino if (type != t) 403*e4b17023SJohn Marino { 404*e4b17023SJohn Marino t = remap_type (t, id); 405*e4b17023SJohn Marino TYPE_MAIN_VARIANT (new_tree) = t; 406*e4b17023SJohn Marino TYPE_NEXT_VARIANT (new_tree) = TYPE_NEXT_VARIANT (t); 407*e4b17023SJohn Marino TYPE_NEXT_VARIANT (t) = new_tree; 408*e4b17023SJohn Marino } 409*e4b17023SJohn Marino else 410*e4b17023SJohn Marino { 411*e4b17023SJohn Marino TYPE_MAIN_VARIANT (new_tree) = new_tree; 412*e4b17023SJohn Marino TYPE_NEXT_VARIANT (new_tree) = NULL; 413*e4b17023SJohn Marino } 414*e4b17023SJohn Marino 415*e4b17023SJohn Marino if (TYPE_STUB_DECL (type)) 416*e4b17023SJohn Marino TYPE_STUB_DECL (new_tree) = remap_decl (TYPE_STUB_DECL (type), id); 417*e4b17023SJohn Marino 418*e4b17023SJohn Marino /* Lazily create pointer and reference types. */ 419*e4b17023SJohn Marino TYPE_POINTER_TO (new_tree) = NULL; 420*e4b17023SJohn Marino TYPE_REFERENCE_TO (new_tree) = NULL; 421*e4b17023SJohn Marino 422*e4b17023SJohn Marino switch (TREE_CODE (new_tree)) 423*e4b17023SJohn Marino { 424*e4b17023SJohn Marino case INTEGER_TYPE: 425*e4b17023SJohn Marino case REAL_TYPE: 426*e4b17023SJohn Marino case FIXED_POINT_TYPE: 427*e4b17023SJohn Marino case ENUMERAL_TYPE: 428*e4b17023SJohn Marino case BOOLEAN_TYPE: 429*e4b17023SJohn Marino t = TYPE_MIN_VALUE (new_tree); 430*e4b17023SJohn Marino if (t && TREE_CODE (t) != INTEGER_CST) 431*e4b17023SJohn Marino walk_tree (&TYPE_MIN_VALUE (new_tree), copy_tree_body_r, id, NULL); 432*e4b17023SJohn Marino 433*e4b17023SJohn Marino t = TYPE_MAX_VALUE (new_tree); 434*e4b17023SJohn Marino if (t && TREE_CODE (t) != INTEGER_CST) 435*e4b17023SJohn Marino walk_tree (&TYPE_MAX_VALUE (new_tree), copy_tree_body_r, id, NULL); 436*e4b17023SJohn Marino return new_tree; 437*e4b17023SJohn Marino 438*e4b17023SJohn Marino case FUNCTION_TYPE: 439*e4b17023SJohn Marino TREE_TYPE (new_tree) = remap_type (TREE_TYPE (new_tree), id); 440*e4b17023SJohn Marino walk_tree (&TYPE_ARG_TYPES (new_tree), copy_tree_body_r, id, NULL); 441*e4b17023SJohn Marino return new_tree; 442*e4b17023SJohn Marino 443*e4b17023SJohn Marino case ARRAY_TYPE: 444*e4b17023SJohn Marino TREE_TYPE (new_tree) = remap_type (TREE_TYPE (new_tree), id); 445*e4b17023SJohn Marino TYPE_DOMAIN (new_tree) = remap_type (TYPE_DOMAIN (new_tree), id); 446*e4b17023SJohn Marino break; 447*e4b17023SJohn Marino 448*e4b17023SJohn Marino case RECORD_TYPE: 449*e4b17023SJohn Marino case UNION_TYPE: 450*e4b17023SJohn Marino case QUAL_UNION_TYPE: 451*e4b17023SJohn Marino { 452*e4b17023SJohn Marino tree f, nf = NULL; 453*e4b17023SJohn Marino 454*e4b17023SJohn Marino for (f = TYPE_FIELDS (new_tree); f ; f = DECL_CHAIN (f)) 455*e4b17023SJohn Marino { 456*e4b17023SJohn Marino t = remap_decl (f, id); 457*e4b17023SJohn Marino DECL_CONTEXT (t) = new_tree; 458*e4b17023SJohn Marino DECL_CHAIN (t) = nf; 459*e4b17023SJohn Marino nf = t; 460*e4b17023SJohn Marino } 461*e4b17023SJohn Marino TYPE_FIELDS (new_tree) = nreverse (nf); 462*e4b17023SJohn Marino } 463*e4b17023SJohn Marino break; 464*e4b17023SJohn Marino 465*e4b17023SJohn Marino case OFFSET_TYPE: 466*e4b17023SJohn Marino default: 467*e4b17023SJohn Marino /* Shouldn't have been thought variable sized. */ 468*e4b17023SJohn Marino gcc_unreachable (); 469*e4b17023SJohn Marino } 470*e4b17023SJohn Marino 471*e4b17023SJohn Marino walk_tree (&TYPE_SIZE (new_tree), copy_tree_body_r, id, NULL); 472*e4b17023SJohn Marino walk_tree (&TYPE_SIZE_UNIT (new_tree), copy_tree_body_r, id, NULL); 473*e4b17023SJohn Marino 474*e4b17023SJohn Marino return new_tree; 475*e4b17023SJohn Marino } 476*e4b17023SJohn Marino 477*e4b17023SJohn Marino tree 478*e4b17023SJohn Marino remap_type (tree type, copy_body_data *id) 479*e4b17023SJohn Marino { 480*e4b17023SJohn Marino tree *node; 481*e4b17023SJohn Marino tree tmp; 482*e4b17023SJohn Marino 483*e4b17023SJohn Marino if (type == NULL) 484*e4b17023SJohn Marino return type; 485*e4b17023SJohn Marino 486*e4b17023SJohn Marino /* See if we have remapped this type. */ 487*e4b17023SJohn Marino node = (tree *) pointer_map_contains (id->decl_map, type); 488*e4b17023SJohn Marino if (node) 489*e4b17023SJohn Marino return *node; 490*e4b17023SJohn Marino 491*e4b17023SJohn Marino /* The type only needs remapping if it's variably modified. */ 492*e4b17023SJohn Marino if (! variably_modified_type_p (type, id->src_fn)) 493*e4b17023SJohn Marino { 494*e4b17023SJohn Marino insert_decl_map (id, type, type); 495*e4b17023SJohn Marino return type; 496*e4b17023SJohn Marino } 497*e4b17023SJohn Marino 498*e4b17023SJohn Marino id->remapping_type_depth++; 499*e4b17023SJohn Marino tmp = remap_type_1 (type, id); 500*e4b17023SJohn Marino id->remapping_type_depth--; 501*e4b17023SJohn Marino 502*e4b17023SJohn Marino return tmp; 503*e4b17023SJohn Marino } 504*e4b17023SJohn Marino 505*e4b17023SJohn Marino /* Return previously remapped type of TYPE in ID. Return NULL if TYPE 506*e4b17023SJohn Marino is NULL or TYPE has not been remapped before. */ 507*e4b17023SJohn Marino 508*e4b17023SJohn Marino static tree 509*e4b17023SJohn Marino remapped_type (tree type, copy_body_data *id) 510*e4b17023SJohn Marino { 511*e4b17023SJohn Marino tree *node; 512*e4b17023SJohn Marino 513*e4b17023SJohn Marino if (type == NULL) 514*e4b17023SJohn Marino return type; 515*e4b17023SJohn Marino 516*e4b17023SJohn Marino /* See if we have remapped this type. */ 517*e4b17023SJohn Marino node = (tree *) pointer_map_contains (id->decl_map, type); 518*e4b17023SJohn Marino if (node) 519*e4b17023SJohn Marino return *node; 520*e4b17023SJohn Marino else 521*e4b17023SJohn Marino return NULL; 522*e4b17023SJohn Marino } 523*e4b17023SJohn Marino 524*e4b17023SJohn Marino /* The type only needs remapping if it's variably modified. */ 525*e4b17023SJohn Marino /* Decide if DECL can be put into BLOCK_NONLOCAL_VARs. */ 526*e4b17023SJohn Marino 527*e4b17023SJohn Marino static bool 528*e4b17023SJohn Marino can_be_nonlocal (tree decl, copy_body_data *id) 529*e4b17023SJohn Marino { 530*e4b17023SJohn Marino /* We can not duplicate function decls. */ 531*e4b17023SJohn Marino if (TREE_CODE (decl) == FUNCTION_DECL) 532*e4b17023SJohn Marino return true; 533*e4b17023SJohn Marino 534*e4b17023SJohn Marino /* Local static vars must be non-local or we get multiple declaration 535*e4b17023SJohn Marino problems. */ 536*e4b17023SJohn Marino if (TREE_CODE (decl) == VAR_DECL 537*e4b17023SJohn Marino && !auto_var_in_fn_p (decl, id->src_fn)) 538*e4b17023SJohn Marino return true; 539*e4b17023SJohn Marino 540*e4b17023SJohn Marino /* At the moment dwarf2out can handle only these types of nodes. We 541*e4b17023SJohn Marino can support more later. */ 542*e4b17023SJohn Marino if (TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != PARM_DECL) 543*e4b17023SJohn Marino return false; 544*e4b17023SJohn Marino 545*e4b17023SJohn Marino /* We must use global type. We call remapped_type instead of 546*e4b17023SJohn Marino remap_type since we don't want to remap this type here if it 547*e4b17023SJohn Marino hasn't been remapped before. */ 548*e4b17023SJohn Marino if (TREE_TYPE (decl) != remapped_type (TREE_TYPE (decl), id)) 549*e4b17023SJohn Marino return false; 550*e4b17023SJohn Marino 551*e4b17023SJohn Marino /* Wihtout SSA we can't tell if variable is used. */ 552*e4b17023SJohn Marino if (!gimple_in_ssa_p (cfun)) 553*e4b17023SJohn Marino return false; 554*e4b17023SJohn Marino 555*e4b17023SJohn Marino /* Live variables must be copied so we can attach DECL_RTL. */ 556*e4b17023SJohn Marino if (var_ann (decl)) 557*e4b17023SJohn Marino return false; 558*e4b17023SJohn Marino 559*e4b17023SJohn Marino return true; 560*e4b17023SJohn Marino } 561*e4b17023SJohn Marino 562*e4b17023SJohn Marino static tree 563*e4b17023SJohn Marino remap_decls (tree decls, VEC(tree,gc) **nonlocalized_list, copy_body_data *id) 564*e4b17023SJohn Marino { 565*e4b17023SJohn Marino tree old_var; 566*e4b17023SJohn Marino tree new_decls = NULL_TREE; 567*e4b17023SJohn Marino 568*e4b17023SJohn Marino /* Remap its variables. */ 569*e4b17023SJohn Marino for (old_var = decls; old_var; old_var = DECL_CHAIN (old_var)) 570*e4b17023SJohn Marino { 571*e4b17023SJohn Marino tree new_var; 572*e4b17023SJohn Marino 573*e4b17023SJohn Marino if (can_be_nonlocal (old_var, id)) 574*e4b17023SJohn Marino { 575*e4b17023SJohn Marino if (TREE_CODE (old_var) == VAR_DECL 576*e4b17023SJohn Marino && ! DECL_EXTERNAL (old_var) 577*e4b17023SJohn Marino && (var_ann (old_var) || !gimple_in_ssa_p (cfun))) 578*e4b17023SJohn Marino add_local_decl (cfun, old_var); 579*e4b17023SJohn Marino if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE) 580*e4b17023SJohn Marino && !DECL_IGNORED_P (old_var) 581*e4b17023SJohn Marino && nonlocalized_list) 582*e4b17023SJohn Marino VEC_safe_push (tree, gc, *nonlocalized_list, old_var); 583*e4b17023SJohn Marino continue; 584*e4b17023SJohn Marino } 585*e4b17023SJohn Marino 586*e4b17023SJohn Marino /* Remap the variable. */ 587*e4b17023SJohn Marino new_var = remap_decl (old_var, id); 588*e4b17023SJohn Marino 589*e4b17023SJohn Marino /* If we didn't remap this variable, we can't mess with its 590*e4b17023SJohn Marino TREE_CHAIN. If we remapped this variable to the return slot, it's 591*e4b17023SJohn Marino already declared somewhere else, so don't declare it here. */ 592*e4b17023SJohn Marino 593*e4b17023SJohn Marino if (new_var == id->retvar) 594*e4b17023SJohn Marino ; 595*e4b17023SJohn Marino else if (!new_var) 596*e4b17023SJohn Marino { 597*e4b17023SJohn Marino if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE) 598*e4b17023SJohn Marino && !DECL_IGNORED_P (old_var) 599*e4b17023SJohn Marino && nonlocalized_list) 600*e4b17023SJohn Marino VEC_safe_push (tree, gc, *nonlocalized_list, old_var); 601*e4b17023SJohn Marino } 602*e4b17023SJohn Marino else 603*e4b17023SJohn Marino { 604*e4b17023SJohn Marino gcc_assert (DECL_P (new_var)); 605*e4b17023SJohn Marino DECL_CHAIN (new_var) = new_decls; 606*e4b17023SJohn Marino new_decls = new_var; 607*e4b17023SJohn Marino 608*e4b17023SJohn Marino /* Also copy value-expressions. */ 609*e4b17023SJohn Marino if (TREE_CODE (new_var) == VAR_DECL 610*e4b17023SJohn Marino && DECL_HAS_VALUE_EXPR_P (new_var)) 611*e4b17023SJohn Marino { 612*e4b17023SJohn Marino tree tem = DECL_VALUE_EXPR (new_var); 613*e4b17023SJohn Marino bool old_regimplify = id->regimplify; 614*e4b17023SJohn Marino id->remapping_type_depth++; 615*e4b17023SJohn Marino walk_tree (&tem, copy_tree_body_r, id, NULL); 616*e4b17023SJohn Marino id->remapping_type_depth--; 617*e4b17023SJohn Marino id->regimplify = old_regimplify; 618*e4b17023SJohn Marino SET_DECL_VALUE_EXPR (new_var, tem); 619*e4b17023SJohn Marino } 620*e4b17023SJohn Marino } 621*e4b17023SJohn Marino } 622*e4b17023SJohn Marino 623*e4b17023SJohn Marino return nreverse (new_decls); 624*e4b17023SJohn Marino } 625*e4b17023SJohn Marino 626*e4b17023SJohn Marino /* Copy the BLOCK to contain remapped versions of the variables 627*e4b17023SJohn Marino therein. And hook the new block into the block-tree. */ 628*e4b17023SJohn Marino 629*e4b17023SJohn Marino static void 630*e4b17023SJohn Marino remap_block (tree *block, copy_body_data *id) 631*e4b17023SJohn Marino { 632*e4b17023SJohn Marino tree old_block; 633*e4b17023SJohn Marino tree new_block; 634*e4b17023SJohn Marino 635*e4b17023SJohn Marino /* Make the new block. */ 636*e4b17023SJohn Marino old_block = *block; 637*e4b17023SJohn Marino new_block = make_node (BLOCK); 638*e4b17023SJohn Marino TREE_USED (new_block) = TREE_USED (old_block); 639*e4b17023SJohn Marino BLOCK_ABSTRACT_ORIGIN (new_block) = old_block; 640*e4b17023SJohn Marino BLOCK_SOURCE_LOCATION (new_block) = BLOCK_SOURCE_LOCATION (old_block); 641*e4b17023SJohn Marino BLOCK_NONLOCALIZED_VARS (new_block) 642*e4b17023SJohn Marino = VEC_copy (tree, gc, BLOCK_NONLOCALIZED_VARS (old_block)); 643*e4b17023SJohn Marino *block = new_block; 644*e4b17023SJohn Marino 645*e4b17023SJohn Marino /* Remap its variables. */ 646*e4b17023SJohn Marino BLOCK_VARS (new_block) = remap_decls (BLOCK_VARS (old_block), 647*e4b17023SJohn Marino &BLOCK_NONLOCALIZED_VARS (new_block), 648*e4b17023SJohn Marino id); 649*e4b17023SJohn Marino 650*e4b17023SJohn Marino if (id->transform_lang_insert_block) 651*e4b17023SJohn Marino id->transform_lang_insert_block (new_block); 652*e4b17023SJohn Marino 653*e4b17023SJohn Marino /* Remember the remapped block. */ 654*e4b17023SJohn Marino insert_decl_map (id, old_block, new_block); 655*e4b17023SJohn Marino } 656*e4b17023SJohn Marino 657*e4b17023SJohn Marino /* Copy the whole block tree and root it in id->block. */ 658*e4b17023SJohn Marino static tree 659*e4b17023SJohn Marino remap_blocks (tree block, copy_body_data *id) 660*e4b17023SJohn Marino { 661*e4b17023SJohn Marino tree t; 662*e4b17023SJohn Marino tree new_tree = block; 663*e4b17023SJohn Marino 664*e4b17023SJohn Marino if (!block) 665*e4b17023SJohn Marino return NULL; 666*e4b17023SJohn Marino 667*e4b17023SJohn Marino remap_block (&new_tree, id); 668*e4b17023SJohn Marino gcc_assert (new_tree != block); 669*e4b17023SJohn Marino for (t = BLOCK_SUBBLOCKS (block); t ; t = BLOCK_CHAIN (t)) 670*e4b17023SJohn Marino prepend_lexical_block (new_tree, remap_blocks (t, id)); 671*e4b17023SJohn Marino /* Blocks are in arbitrary order, but make things slightly prettier and do 672*e4b17023SJohn Marino not swap order when producing a copy. */ 673*e4b17023SJohn Marino BLOCK_SUBBLOCKS (new_tree) = blocks_nreverse (BLOCK_SUBBLOCKS (new_tree)); 674*e4b17023SJohn Marino return new_tree; 675*e4b17023SJohn Marino } 676*e4b17023SJohn Marino 677*e4b17023SJohn Marino static void 678*e4b17023SJohn Marino copy_statement_list (tree *tp) 679*e4b17023SJohn Marino { 680*e4b17023SJohn Marino tree_stmt_iterator oi, ni; 681*e4b17023SJohn Marino tree new_tree; 682*e4b17023SJohn Marino 683*e4b17023SJohn Marino new_tree = alloc_stmt_list (); 684*e4b17023SJohn Marino ni = tsi_start (new_tree); 685*e4b17023SJohn Marino oi = tsi_start (*tp); 686*e4b17023SJohn Marino TREE_TYPE (new_tree) = TREE_TYPE (*tp); 687*e4b17023SJohn Marino *tp = new_tree; 688*e4b17023SJohn Marino 689*e4b17023SJohn Marino for (; !tsi_end_p (oi); tsi_next (&oi)) 690*e4b17023SJohn Marino { 691*e4b17023SJohn Marino tree stmt = tsi_stmt (oi); 692*e4b17023SJohn Marino if (TREE_CODE (stmt) == STATEMENT_LIST) 693*e4b17023SJohn Marino /* This copy is not redundant; tsi_link_after will smash this 694*e4b17023SJohn Marino STATEMENT_LIST into the end of the one we're building, and we 695*e4b17023SJohn Marino don't want to do that with the original. */ 696*e4b17023SJohn Marino copy_statement_list (&stmt); 697*e4b17023SJohn Marino tsi_link_after (&ni, stmt, TSI_CONTINUE_LINKING); 698*e4b17023SJohn Marino } 699*e4b17023SJohn Marino } 700*e4b17023SJohn Marino 701*e4b17023SJohn Marino static void 702*e4b17023SJohn Marino copy_bind_expr (tree *tp, int *walk_subtrees, copy_body_data *id) 703*e4b17023SJohn Marino { 704*e4b17023SJohn Marino tree block = BIND_EXPR_BLOCK (*tp); 705*e4b17023SJohn Marino /* Copy (and replace) the statement. */ 706*e4b17023SJohn Marino copy_tree_r (tp, walk_subtrees, NULL); 707*e4b17023SJohn Marino if (block) 708*e4b17023SJohn Marino { 709*e4b17023SJohn Marino remap_block (&block, id); 710*e4b17023SJohn Marino BIND_EXPR_BLOCK (*tp) = block; 711*e4b17023SJohn Marino } 712*e4b17023SJohn Marino 713*e4b17023SJohn Marino if (BIND_EXPR_VARS (*tp)) 714*e4b17023SJohn Marino /* This will remap a lot of the same decls again, but this should be 715*e4b17023SJohn Marino harmless. */ 716*e4b17023SJohn Marino BIND_EXPR_VARS (*tp) = remap_decls (BIND_EXPR_VARS (*tp), NULL, id); 717*e4b17023SJohn Marino } 718*e4b17023SJohn Marino 719*e4b17023SJohn Marino 720*e4b17023SJohn Marino /* Create a new gimple_seq by remapping all the statements in BODY 721*e4b17023SJohn Marino using the inlining information in ID. */ 722*e4b17023SJohn Marino 723*e4b17023SJohn Marino static gimple_seq 724*e4b17023SJohn Marino remap_gimple_seq (gimple_seq body, copy_body_data *id) 725*e4b17023SJohn Marino { 726*e4b17023SJohn Marino gimple_stmt_iterator si; 727*e4b17023SJohn Marino gimple_seq new_body = NULL; 728*e4b17023SJohn Marino 729*e4b17023SJohn Marino for (si = gsi_start (body); !gsi_end_p (si); gsi_next (&si)) 730*e4b17023SJohn Marino { 731*e4b17023SJohn Marino gimple new_stmt = remap_gimple_stmt (gsi_stmt (si), id); 732*e4b17023SJohn Marino gimple_seq_add_stmt (&new_body, new_stmt); 733*e4b17023SJohn Marino } 734*e4b17023SJohn Marino 735*e4b17023SJohn Marino return new_body; 736*e4b17023SJohn Marino } 737*e4b17023SJohn Marino 738*e4b17023SJohn Marino 739*e4b17023SJohn Marino /* Copy a GIMPLE_BIND statement STMT, remapping all the symbols in its 740*e4b17023SJohn Marino block using the mapping information in ID. */ 741*e4b17023SJohn Marino 742*e4b17023SJohn Marino static gimple 743*e4b17023SJohn Marino copy_gimple_bind (gimple stmt, copy_body_data *id) 744*e4b17023SJohn Marino { 745*e4b17023SJohn Marino gimple new_bind; 746*e4b17023SJohn Marino tree new_block, new_vars; 747*e4b17023SJohn Marino gimple_seq body, new_body; 748*e4b17023SJohn Marino 749*e4b17023SJohn Marino /* Copy the statement. Note that we purposely don't use copy_stmt 750*e4b17023SJohn Marino here because we need to remap statements as we copy. */ 751*e4b17023SJohn Marino body = gimple_bind_body (stmt); 752*e4b17023SJohn Marino new_body = remap_gimple_seq (body, id); 753*e4b17023SJohn Marino 754*e4b17023SJohn Marino new_block = gimple_bind_block (stmt); 755*e4b17023SJohn Marino if (new_block) 756*e4b17023SJohn Marino remap_block (&new_block, id); 757*e4b17023SJohn Marino 758*e4b17023SJohn Marino /* This will remap a lot of the same decls again, but this should be 759*e4b17023SJohn Marino harmless. */ 760*e4b17023SJohn Marino new_vars = gimple_bind_vars (stmt); 761*e4b17023SJohn Marino if (new_vars) 762*e4b17023SJohn Marino new_vars = remap_decls (new_vars, NULL, id); 763*e4b17023SJohn Marino 764*e4b17023SJohn Marino new_bind = gimple_build_bind (new_vars, new_body, new_block); 765*e4b17023SJohn Marino 766*e4b17023SJohn Marino return new_bind; 767*e4b17023SJohn Marino } 768*e4b17023SJohn Marino 769*e4b17023SJohn Marino 770*e4b17023SJohn Marino /* Remap the GIMPLE operand pointed to by *TP. DATA is really a 771*e4b17023SJohn Marino 'struct walk_stmt_info *'. DATA->INFO is a 'copy_body_data *'. 772*e4b17023SJohn Marino WALK_SUBTREES is used to indicate walk_gimple_op whether to keep 773*e4b17023SJohn Marino recursing into the children nodes of *TP. */ 774*e4b17023SJohn Marino 775*e4b17023SJohn Marino static tree 776*e4b17023SJohn Marino remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data) 777*e4b17023SJohn Marino { 778*e4b17023SJohn Marino struct walk_stmt_info *wi_p = (struct walk_stmt_info *) data; 779*e4b17023SJohn Marino copy_body_data *id = (copy_body_data *) wi_p->info; 780*e4b17023SJohn Marino tree fn = id->src_fn; 781*e4b17023SJohn Marino 782*e4b17023SJohn Marino if (TREE_CODE (*tp) == SSA_NAME) 783*e4b17023SJohn Marino { 784*e4b17023SJohn Marino *tp = remap_ssa_name (*tp, id); 785*e4b17023SJohn Marino *walk_subtrees = 0; 786*e4b17023SJohn Marino return NULL; 787*e4b17023SJohn Marino } 788*e4b17023SJohn Marino else if (auto_var_in_fn_p (*tp, fn)) 789*e4b17023SJohn Marino { 790*e4b17023SJohn Marino /* Local variables and labels need to be replaced by equivalent 791*e4b17023SJohn Marino variables. We don't want to copy static variables; there's 792*e4b17023SJohn Marino only one of those, no matter how many times we inline the 793*e4b17023SJohn Marino containing function. Similarly for globals from an outer 794*e4b17023SJohn Marino function. */ 795*e4b17023SJohn Marino tree new_decl; 796*e4b17023SJohn Marino 797*e4b17023SJohn Marino /* Remap the declaration. */ 798*e4b17023SJohn Marino new_decl = remap_decl (*tp, id); 799*e4b17023SJohn Marino gcc_assert (new_decl); 800*e4b17023SJohn Marino /* Replace this variable with the copy. */ 801*e4b17023SJohn Marino STRIP_TYPE_NOPS (new_decl); 802*e4b17023SJohn Marino /* ??? The C++ frontend uses void * pointer zero to initialize 803*e4b17023SJohn Marino any other type. This confuses the middle-end type verification. 804*e4b17023SJohn Marino As cloned bodies do not go through gimplification again the fixup 805*e4b17023SJohn Marino there doesn't trigger. */ 806*e4b17023SJohn Marino if (TREE_CODE (new_decl) == INTEGER_CST 807*e4b17023SJohn Marino && !useless_type_conversion_p (TREE_TYPE (*tp), TREE_TYPE (new_decl))) 808*e4b17023SJohn Marino new_decl = fold_convert (TREE_TYPE (*tp), new_decl); 809*e4b17023SJohn Marino *tp = new_decl; 810*e4b17023SJohn Marino *walk_subtrees = 0; 811*e4b17023SJohn Marino } 812*e4b17023SJohn Marino else if (TREE_CODE (*tp) == STATEMENT_LIST) 813*e4b17023SJohn Marino gcc_unreachable (); 814*e4b17023SJohn Marino else if (TREE_CODE (*tp) == SAVE_EXPR) 815*e4b17023SJohn Marino gcc_unreachable (); 816*e4b17023SJohn Marino else if (TREE_CODE (*tp) == LABEL_DECL 817*e4b17023SJohn Marino && (!DECL_CONTEXT (*tp) 818*e4b17023SJohn Marino || decl_function_context (*tp) == id->src_fn)) 819*e4b17023SJohn Marino /* These may need to be remapped for EH handling. */ 820*e4b17023SJohn Marino *tp = remap_decl (*tp, id); 821*e4b17023SJohn Marino else if (TREE_CODE (*tp) == FIELD_DECL) 822*e4b17023SJohn Marino { 823*e4b17023SJohn Marino /* If the enclosing record type is variably_modified_type_p, the field 824*e4b17023SJohn Marino has already been remapped. Otherwise, it need not be. */ 825*e4b17023SJohn Marino tree *n = (tree *) pointer_map_contains (id->decl_map, *tp); 826*e4b17023SJohn Marino if (n) 827*e4b17023SJohn Marino *tp = *n; 828*e4b17023SJohn Marino *walk_subtrees = 0; 829*e4b17023SJohn Marino } 830*e4b17023SJohn Marino else if (TYPE_P (*tp)) 831*e4b17023SJohn Marino /* Types may need remapping as well. */ 832*e4b17023SJohn Marino *tp = remap_type (*tp, id); 833*e4b17023SJohn Marino else if (CONSTANT_CLASS_P (*tp)) 834*e4b17023SJohn Marino { 835*e4b17023SJohn Marino /* If this is a constant, we have to copy the node iff the type 836*e4b17023SJohn Marino will be remapped. copy_tree_r will not copy a constant. */ 837*e4b17023SJohn Marino tree new_type = remap_type (TREE_TYPE (*tp), id); 838*e4b17023SJohn Marino 839*e4b17023SJohn Marino if (new_type == TREE_TYPE (*tp)) 840*e4b17023SJohn Marino *walk_subtrees = 0; 841*e4b17023SJohn Marino 842*e4b17023SJohn Marino else if (TREE_CODE (*tp) == INTEGER_CST) 843*e4b17023SJohn Marino *tp = build_int_cst_wide (new_type, TREE_INT_CST_LOW (*tp), 844*e4b17023SJohn Marino TREE_INT_CST_HIGH (*tp)); 845*e4b17023SJohn Marino else 846*e4b17023SJohn Marino { 847*e4b17023SJohn Marino *tp = copy_node (*tp); 848*e4b17023SJohn Marino TREE_TYPE (*tp) = new_type; 849*e4b17023SJohn Marino } 850*e4b17023SJohn Marino } 851*e4b17023SJohn Marino else 852*e4b17023SJohn Marino { 853*e4b17023SJohn Marino /* Otherwise, just copy the node. Note that copy_tree_r already 854*e4b17023SJohn Marino knows not to copy VAR_DECLs, etc., so this is safe. */ 855*e4b17023SJohn Marino 856*e4b17023SJohn Marino /* We should never have TREE_BLOCK set on non-statements. */ 857*e4b17023SJohn Marino if (EXPR_P (*tp)) 858*e4b17023SJohn Marino gcc_assert (!TREE_BLOCK (*tp)); 859*e4b17023SJohn Marino 860*e4b17023SJohn Marino if (TREE_CODE (*tp) == MEM_REF) 861*e4b17023SJohn Marino { 862*e4b17023SJohn Marino tree ptr = TREE_OPERAND (*tp, 0); 863*e4b17023SJohn Marino tree type = remap_type (TREE_TYPE (*tp), id); 864*e4b17023SJohn Marino tree old = *tp; 865*e4b17023SJohn Marino 866*e4b17023SJohn Marino /* We need to re-canonicalize MEM_REFs from inline substitutions 867*e4b17023SJohn Marino that can happen when a pointer argument is an ADDR_EXPR. 868*e4b17023SJohn Marino Recurse here manually to allow that. */ 869*e4b17023SJohn Marino walk_tree (&ptr, remap_gimple_op_r, data, NULL); 870*e4b17023SJohn Marino *tp = fold_build2 (MEM_REF, type, 871*e4b17023SJohn Marino ptr, TREE_OPERAND (*tp, 1)); 872*e4b17023SJohn Marino TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old); 873*e4b17023SJohn Marino TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); 874*e4b17023SJohn Marino TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); 875*e4b17023SJohn Marino TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); 876*e4b17023SJohn Marino *walk_subtrees = 0; 877*e4b17023SJohn Marino return NULL; 878*e4b17023SJohn Marino } 879*e4b17023SJohn Marino 880*e4b17023SJohn Marino /* Here is the "usual case". Copy this tree node, and then 881*e4b17023SJohn Marino tweak some special cases. */ 882*e4b17023SJohn Marino copy_tree_r (tp, walk_subtrees, NULL); 883*e4b17023SJohn Marino 884*e4b17023SJohn Marino if (TREE_CODE (*tp) != OMP_CLAUSE) 885*e4b17023SJohn Marino TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id); 886*e4b17023SJohn Marino 887*e4b17023SJohn Marino /* Global variables we haven't seen yet need to go into referenced 888*e4b17023SJohn Marino vars. If not referenced from types only. */ 889*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun) 890*e4b17023SJohn Marino && TREE_CODE (*tp) == VAR_DECL 891*e4b17023SJohn Marino && id->remapping_type_depth == 0 892*e4b17023SJohn Marino && !processing_debug_stmt) 893*e4b17023SJohn Marino add_referenced_var (*tp); 894*e4b17023SJohn Marino 895*e4b17023SJohn Marino if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3)) 896*e4b17023SJohn Marino { 897*e4b17023SJohn Marino /* The copied TARGET_EXPR has never been expanded, even if the 898*e4b17023SJohn Marino original node was expanded already. */ 899*e4b17023SJohn Marino TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3); 900*e4b17023SJohn Marino TREE_OPERAND (*tp, 3) = NULL_TREE; 901*e4b17023SJohn Marino } 902*e4b17023SJohn Marino else if (TREE_CODE (*tp) == ADDR_EXPR) 903*e4b17023SJohn Marino { 904*e4b17023SJohn Marino /* Variable substitution need not be simple. In particular, 905*e4b17023SJohn Marino the MEM_REF substitution above. Make sure that 906*e4b17023SJohn Marino TREE_CONSTANT and friends are up-to-date. But make sure 907*e4b17023SJohn Marino to not improperly set TREE_BLOCK on some sub-expressions. */ 908*e4b17023SJohn Marino int invariant = is_gimple_min_invariant (*tp); 909*e4b17023SJohn Marino tree block = id->block; 910*e4b17023SJohn Marino id->block = NULL_TREE; 911*e4b17023SJohn Marino walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL); 912*e4b17023SJohn Marino id->block = block; 913*e4b17023SJohn Marino recompute_tree_invariant_for_addr_expr (*tp); 914*e4b17023SJohn Marino 915*e4b17023SJohn Marino /* If this used to be invariant, but is not any longer, 916*e4b17023SJohn Marino then regimplification is probably needed. */ 917*e4b17023SJohn Marino if (invariant && !is_gimple_min_invariant (*tp)) 918*e4b17023SJohn Marino id->regimplify = true; 919*e4b17023SJohn Marino 920*e4b17023SJohn Marino *walk_subtrees = 0; 921*e4b17023SJohn Marino } 922*e4b17023SJohn Marino } 923*e4b17023SJohn Marino 924*e4b17023SJohn Marino /* Keep iterating. */ 925*e4b17023SJohn Marino return NULL_TREE; 926*e4b17023SJohn Marino } 927*e4b17023SJohn Marino 928*e4b17023SJohn Marino 929*e4b17023SJohn Marino /* Called from copy_body_id via walk_tree. DATA is really a 930*e4b17023SJohn Marino `copy_body_data *'. */ 931*e4b17023SJohn Marino 932*e4b17023SJohn Marino tree 933*e4b17023SJohn Marino copy_tree_body_r (tree *tp, int *walk_subtrees, void *data) 934*e4b17023SJohn Marino { 935*e4b17023SJohn Marino copy_body_data *id = (copy_body_data *) data; 936*e4b17023SJohn Marino tree fn = id->src_fn; 937*e4b17023SJohn Marino tree new_block; 938*e4b17023SJohn Marino 939*e4b17023SJohn Marino /* Begin by recognizing trees that we'll completely rewrite for the 940*e4b17023SJohn Marino inlining context. Our output for these trees is completely 941*e4b17023SJohn Marino different from out input (e.g. RETURN_EXPR is deleted, and morphs 942*e4b17023SJohn Marino into an edge). Further down, we'll handle trees that get 943*e4b17023SJohn Marino duplicated and/or tweaked. */ 944*e4b17023SJohn Marino 945*e4b17023SJohn Marino /* When requested, RETURN_EXPRs should be transformed to just the 946*e4b17023SJohn Marino contained MODIFY_EXPR. The branch semantics of the return will 947*e4b17023SJohn Marino be handled elsewhere by manipulating the CFG rather than a statement. */ 948*e4b17023SJohn Marino if (TREE_CODE (*tp) == RETURN_EXPR && id->transform_return_to_modify) 949*e4b17023SJohn Marino { 950*e4b17023SJohn Marino tree assignment = TREE_OPERAND (*tp, 0); 951*e4b17023SJohn Marino 952*e4b17023SJohn Marino /* If we're returning something, just turn that into an 953*e4b17023SJohn Marino assignment into the equivalent of the original RESULT_DECL. 954*e4b17023SJohn Marino If the "assignment" is just the result decl, the result 955*e4b17023SJohn Marino decl has already been set (e.g. a recent "foo (&result_decl, 956*e4b17023SJohn Marino ...)"); just toss the entire RETURN_EXPR. */ 957*e4b17023SJohn Marino if (assignment && TREE_CODE (assignment) == MODIFY_EXPR) 958*e4b17023SJohn Marino { 959*e4b17023SJohn Marino /* Replace the RETURN_EXPR with (a copy of) the 960*e4b17023SJohn Marino MODIFY_EXPR hanging underneath. */ 961*e4b17023SJohn Marino *tp = copy_node (assignment); 962*e4b17023SJohn Marino } 963*e4b17023SJohn Marino else /* Else the RETURN_EXPR returns no value. */ 964*e4b17023SJohn Marino { 965*e4b17023SJohn Marino *tp = NULL; 966*e4b17023SJohn Marino return (tree) (void *)1; 967*e4b17023SJohn Marino } 968*e4b17023SJohn Marino } 969*e4b17023SJohn Marino else if (TREE_CODE (*tp) == SSA_NAME) 970*e4b17023SJohn Marino { 971*e4b17023SJohn Marino *tp = remap_ssa_name (*tp, id); 972*e4b17023SJohn Marino *walk_subtrees = 0; 973*e4b17023SJohn Marino return NULL; 974*e4b17023SJohn Marino } 975*e4b17023SJohn Marino 976*e4b17023SJohn Marino /* Local variables and labels need to be replaced by equivalent 977*e4b17023SJohn Marino variables. We don't want to copy static variables; there's only 978*e4b17023SJohn Marino one of those, no matter how many times we inline the containing 979*e4b17023SJohn Marino function. Similarly for globals from an outer function. */ 980*e4b17023SJohn Marino else if (auto_var_in_fn_p (*tp, fn)) 981*e4b17023SJohn Marino { 982*e4b17023SJohn Marino tree new_decl; 983*e4b17023SJohn Marino 984*e4b17023SJohn Marino /* Remap the declaration. */ 985*e4b17023SJohn Marino new_decl = remap_decl (*tp, id); 986*e4b17023SJohn Marino gcc_assert (new_decl); 987*e4b17023SJohn Marino /* Replace this variable with the copy. */ 988*e4b17023SJohn Marino STRIP_TYPE_NOPS (new_decl); 989*e4b17023SJohn Marino *tp = new_decl; 990*e4b17023SJohn Marino *walk_subtrees = 0; 991*e4b17023SJohn Marino } 992*e4b17023SJohn Marino else if (TREE_CODE (*tp) == STATEMENT_LIST) 993*e4b17023SJohn Marino copy_statement_list (tp); 994*e4b17023SJohn Marino else if (TREE_CODE (*tp) == SAVE_EXPR 995*e4b17023SJohn Marino || TREE_CODE (*tp) == TARGET_EXPR) 996*e4b17023SJohn Marino remap_save_expr (tp, id->decl_map, walk_subtrees); 997*e4b17023SJohn Marino else if (TREE_CODE (*tp) == LABEL_DECL 998*e4b17023SJohn Marino && (! DECL_CONTEXT (*tp) 999*e4b17023SJohn Marino || decl_function_context (*tp) == id->src_fn)) 1000*e4b17023SJohn Marino /* These may need to be remapped for EH handling. */ 1001*e4b17023SJohn Marino *tp = remap_decl (*tp, id); 1002*e4b17023SJohn Marino else if (TREE_CODE (*tp) == BIND_EXPR) 1003*e4b17023SJohn Marino copy_bind_expr (tp, walk_subtrees, id); 1004*e4b17023SJohn Marino /* Types may need remapping as well. */ 1005*e4b17023SJohn Marino else if (TYPE_P (*tp)) 1006*e4b17023SJohn Marino *tp = remap_type (*tp, id); 1007*e4b17023SJohn Marino 1008*e4b17023SJohn Marino /* If this is a constant, we have to copy the node iff the type will be 1009*e4b17023SJohn Marino remapped. copy_tree_r will not copy a constant. */ 1010*e4b17023SJohn Marino else if (CONSTANT_CLASS_P (*tp)) 1011*e4b17023SJohn Marino { 1012*e4b17023SJohn Marino tree new_type = remap_type (TREE_TYPE (*tp), id); 1013*e4b17023SJohn Marino 1014*e4b17023SJohn Marino if (new_type == TREE_TYPE (*tp)) 1015*e4b17023SJohn Marino *walk_subtrees = 0; 1016*e4b17023SJohn Marino 1017*e4b17023SJohn Marino else if (TREE_CODE (*tp) == INTEGER_CST) 1018*e4b17023SJohn Marino *tp = build_int_cst_wide (new_type, TREE_INT_CST_LOW (*tp), 1019*e4b17023SJohn Marino TREE_INT_CST_HIGH (*tp)); 1020*e4b17023SJohn Marino else 1021*e4b17023SJohn Marino { 1022*e4b17023SJohn Marino *tp = copy_node (*tp); 1023*e4b17023SJohn Marino TREE_TYPE (*tp) = new_type; 1024*e4b17023SJohn Marino } 1025*e4b17023SJohn Marino } 1026*e4b17023SJohn Marino 1027*e4b17023SJohn Marino /* Otherwise, just copy the node. Note that copy_tree_r already 1028*e4b17023SJohn Marino knows not to copy VAR_DECLs, etc., so this is safe. */ 1029*e4b17023SJohn Marino else 1030*e4b17023SJohn Marino { 1031*e4b17023SJohn Marino /* Here we handle trees that are not completely rewritten. 1032*e4b17023SJohn Marino First we detect some inlining-induced bogosities for 1033*e4b17023SJohn Marino discarding. */ 1034*e4b17023SJohn Marino if (TREE_CODE (*tp) == MODIFY_EXPR 1035*e4b17023SJohn Marino && TREE_OPERAND (*tp, 0) == TREE_OPERAND (*tp, 1) 1036*e4b17023SJohn Marino && (auto_var_in_fn_p (TREE_OPERAND (*tp, 0), fn))) 1037*e4b17023SJohn Marino { 1038*e4b17023SJohn Marino /* Some assignments VAR = VAR; don't generate any rtl code 1039*e4b17023SJohn Marino and thus don't count as variable modification. Avoid 1040*e4b17023SJohn Marino keeping bogosities like 0 = 0. */ 1041*e4b17023SJohn Marino tree decl = TREE_OPERAND (*tp, 0), value; 1042*e4b17023SJohn Marino tree *n; 1043*e4b17023SJohn Marino 1044*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, decl); 1045*e4b17023SJohn Marino if (n) 1046*e4b17023SJohn Marino { 1047*e4b17023SJohn Marino value = *n; 1048*e4b17023SJohn Marino STRIP_TYPE_NOPS (value); 1049*e4b17023SJohn Marino if (TREE_CONSTANT (value) || TREE_READONLY (value)) 1050*e4b17023SJohn Marino { 1051*e4b17023SJohn Marino *tp = build_empty_stmt (EXPR_LOCATION (*tp)); 1052*e4b17023SJohn Marino return copy_tree_body_r (tp, walk_subtrees, data); 1053*e4b17023SJohn Marino } 1054*e4b17023SJohn Marino } 1055*e4b17023SJohn Marino } 1056*e4b17023SJohn Marino else if (TREE_CODE (*tp) == INDIRECT_REF) 1057*e4b17023SJohn Marino { 1058*e4b17023SJohn Marino /* Get rid of *& from inline substitutions that can happen when a 1059*e4b17023SJohn Marino pointer argument is an ADDR_EXPR. */ 1060*e4b17023SJohn Marino tree decl = TREE_OPERAND (*tp, 0); 1061*e4b17023SJohn Marino tree *n; 1062*e4b17023SJohn Marino 1063*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, decl); 1064*e4b17023SJohn Marino if (n) 1065*e4b17023SJohn Marino { 1066*e4b17023SJohn Marino tree new_tree; 1067*e4b17023SJohn Marino tree old; 1068*e4b17023SJohn Marino /* If we happen to get an ADDR_EXPR in n->value, strip 1069*e4b17023SJohn Marino it manually here as we'll eventually get ADDR_EXPRs 1070*e4b17023SJohn Marino which lie about their types pointed to. In this case 1071*e4b17023SJohn Marino build_fold_indirect_ref wouldn't strip the INDIRECT_REF, 1072*e4b17023SJohn Marino but we absolutely rely on that. As fold_indirect_ref 1073*e4b17023SJohn Marino does other useful transformations, try that first, though. */ 1074*e4b17023SJohn Marino tree type = TREE_TYPE (TREE_TYPE (*n)); 1075*e4b17023SJohn Marino if (id->do_not_unshare) 1076*e4b17023SJohn Marino new_tree = *n; 1077*e4b17023SJohn Marino else 1078*e4b17023SJohn Marino new_tree = unshare_expr (*n); 1079*e4b17023SJohn Marino old = *tp; 1080*e4b17023SJohn Marino *tp = gimple_fold_indirect_ref (new_tree); 1081*e4b17023SJohn Marino if (! *tp) 1082*e4b17023SJohn Marino { 1083*e4b17023SJohn Marino if (TREE_CODE (new_tree) == ADDR_EXPR) 1084*e4b17023SJohn Marino { 1085*e4b17023SJohn Marino *tp = fold_indirect_ref_1 (EXPR_LOCATION (new_tree), 1086*e4b17023SJohn Marino type, new_tree); 1087*e4b17023SJohn Marino /* ??? We should either assert here or build 1088*e4b17023SJohn Marino a VIEW_CONVERT_EXPR instead of blindly leaking 1089*e4b17023SJohn Marino incompatible types to our IL. */ 1090*e4b17023SJohn Marino if (! *tp) 1091*e4b17023SJohn Marino *tp = TREE_OPERAND (new_tree, 0); 1092*e4b17023SJohn Marino } 1093*e4b17023SJohn Marino else 1094*e4b17023SJohn Marino { 1095*e4b17023SJohn Marino *tp = build1 (INDIRECT_REF, type, new_tree); 1096*e4b17023SJohn Marino TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); 1097*e4b17023SJohn Marino TREE_SIDE_EFFECTS (*tp) = TREE_SIDE_EFFECTS (old); 1098*e4b17023SJohn Marino TREE_READONLY (*tp) = TREE_READONLY (old); 1099*e4b17023SJohn Marino TREE_THIS_NOTRAP (*tp) = TREE_THIS_NOTRAP (old); 1100*e4b17023SJohn Marino } 1101*e4b17023SJohn Marino } 1102*e4b17023SJohn Marino *walk_subtrees = 0; 1103*e4b17023SJohn Marino return NULL; 1104*e4b17023SJohn Marino } 1105*e4b17023SJohn Marino } 1106*e4b17023SJohn Marino else if (TREE_CODE (*tp) == MEM_REF) 1107*e4b17023SJohn Marino { 1108*e4b17023SJohn Marino /* We need to re-canonicalize MEM_REFs from inline substitutions 1109*e4b17023SJohn Marino that can happen when a pointer argument is an ADDR_EXPR. */ 1110*e4b17023SJohn Marino tree decl = TREE_OPERAND (*tp, 0); 1111*e4b17023SJohn Marino tree *n; 1112*e4b17023SJohn Marino 1113*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, decl); 1114*e4b17023SJohn Marino if (n) 1115*e4b17023SJohn Marino { 1116*e4b17023SJohn Marino tree old = *tp; 1117*e4b17023SJohn Marino *tp = fold_build2 (MEM_REF, TREE_TYPE (*tp), 1118*e4b17023SJohn Marino unshare_expr (*n), TREE_OPERAND (*tp, 1)); 1119*e4b17023SJohn Marino TREE_THIS_VOLATILE (*tp) = TREE_THIS_VOLATILE (old); 1120*e4b17023SJohn Marino TREE_NO_WARNING (*tp) = TREE_NO_WARNING (old); 1121*e4b17023SJohn Marino *walk_subtrees = 0; 1122*e4b17023SJohn Marino return NULL; 1123*e4b17023SJohn Marino } 1124*e4b17023SJohn Marino } 1125*e4b17023SJohn Marino 1126*e4b17023SJohn Marino /* Here is the "usual case". Copy this tree node, and then 1127*e4b17023SJohn Marino tweak some special cases. */ 1128*e4b17023SJohn Marino copy_tree_r (tp, walk_subtrees, NULL); 1129*e4b17023SJohn Marino 1130*e4b17023SJohn Marino /* Global variables we haven't seen yet needs to go into referenced 1131*e4b17023SJohn Marino vars. If not referenced from types or debug stmts only. */ 1132*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun) 1133*e4b17023SJohn Marino && TREE_CODE (*tp) == VAR_DECL 1134*e4b17023SJohn Marino && id->remapping_type_depth == 0 1135*e4b17023SJohn Marino && !processing_debug_stmt) 1136*e4b17023SJohn Marino add_referenced_var (*tp); 1137*e4b17023SJohn Marino 1138*e4b17023SJohn Marino /* If EXPR has block defined, map it to newly constructed block. 1139*e4b17023SJohn Marino When inlining we want EXPRs without block appear in the block 1140*e4b17023SJohn Marino of function call if we are not remapping a type. */ 1141*e4b17023SJohn Marino if (EXPR_P (*tp)) 1142*e4b17023SJohn Marino { 1143*e4b17023SJohn Marino new_block = id->remapping_type_depth == 0 ? id->block : NULL; 1144*e4b17023SJohn Marino if (TREE_BLOCK (*tp)) 1145*e4b17023SJohn Marino { 1146*e4b17023SJohn Marino tree *n; 1147*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, 1148*e4b17023SJohn Marino TREE_BLOCK (*tp)); 1149*e4b17023SJohn Marino gcc_assert (n || id->remapping_type_depth != 0); 1150*e4b17023SJohn Marino if (n) 1151*e4b17023SJohn Marino new_block = *n; 1152*e4b17023SJohn Marino } 1153*e4b17023SJohn Marino TREE_BLOCK (*tp) = new_block; 1154*e4b17023SJohn Marino } 1155*e4b17023SJohn Marino 1156*e4b17023SJohn Marino if (TREE_CODE (*tp) != OMP_CLAUSE) 1157*e4b17023SJohn Marino TREE_TYPE (*tp) = remap_type (TREE_TYPE (*tp), id); 1158*e4b17023SJohn Marino 1159*e4b17023SJohn Marino /* The copied TARGET_EXPR has never been expanded, even if the 1160*e4b17023SJohn Marino original node was expanded already. */ 1161*e4b17023SJohn Marino if (TREE_CODE (*tp) == TARGET_EXPR && TREE_OPERAND (*tp, 3)) 1162*e4b17023SJohn Marino { 1163*e4b17023SJohn Marino TREE_OPERAND (*tp, 1) = TREE_OPERAND (*tp, 3); 1164*e4b17023SJohn Marino TREE_OPERAND (*tp, 3) = NULL_TREE; 1165*e4b17023SJohn Marino } 1166*e4b17023SJohn Marino 1167*e4b17023SJohn Marino /* Variable substitution need not be simple. In particular, the 1168*e4b17023SJohn Marino INDIRECT_REF substitution above. Make sure that TREE_CONSTANT 1169*e4b17023SJohn Marino and friends are up-to-date. */ 1170*e4b17023SJohn Marino else if (TREE_CODE (*tp) == ADDR_EXPR) 1171*e4b17023SJohn Marino { 1172*e4b17023SJohn Marino int invariant = is_gimple_min_invariant (*tp); 1173*e4b17023SJohn Marino walk_tree (&TREE_OPERAND (*tp, 0), copy_tree_body_r, id, NULL); 1174*e4b17023SJohn Marino 1175*e4b17023SJohn Marino /* Handle the case where we substituted an INDIRECT_REF 1176*e4b17023SJohn Marino into the operand of the ADDR_EXPR. */ 1177*e4b17023SJohn Marino if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF) 1178*e4b17023SJohn Marino *tp = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0); 1179*e4b17023SJohn Marino else 1180*e4b17023SJohn Marino recompute_tree_invariant_for_addr_expr (*tp); 1181*e4b17023SJohn Marino 1182*e4b17023SJohn Marino /* If this used to be invariant, but is not any longer, 1183*e4b17023SJohn Marino then regimplification is probably needed. */ 1184*e4b17023SJohn Marino if (invariant && !is_gimple_min_invariant (*tp)) 1185*e4b17023SJohn Marino id->regimplify = true; 1186*e4b17023SJohn Marino 1187*e4b17023SJohn Marino *walk_subtrees = 0; 1188*e4b17023SJohn Marino } 1189*e4b17023SJohn Marino } 1190*e4b17023SJohn Marino 1191*e4b17023SJohn Marino /* Keep iterating. */ 1192*e4b17023SJohn Marino return NULL_TREE; 1193*e4b17023SJohn Marino } 1194*e4b17023SJohn Marino 1195*e4b17023SJohn Marino /* Helper for remap_gimple_stmt. Given an EH region number for the 1196*e4b17023SJohn Marino source function, map that to the duplicate EH region number in 1197*e4b17023SJohn Marino the destination function. */ 1198*e4b17023SJohn Marino 1199*e4b17023SJohn Marino static int 1200*e4b17023SJohn Marino remap_eh_region_nr (int old_nr, copy_body_data *id) 1201*e4b17023SJohn Marino { 1202*e4b17023SJohn Marino eh_region old_r, new_r; 1203*e4b17023SJohn Marino void **slot; 1204*e4b17023SJohn Marino 1205*e4b17023SJohn Marino old_r = get_eh_region_from_number_fn (id->src_cfun, old_nr); 1206*e4b17023SJohn Marino slot = pointer_map_contains (id->eh_map, old_r); 1207*e4b17023SJohn Marino new_r = (eh_region) *slot; 1208*e4b17023SJohn Marino 1209*e4b17023SJohn Marino return new_r->index; 1210*e4b17023SJohn Marino } 1211*e4b17023SJohn Marino 1212*e4b17023SJohn Marino /* Similar, but operate on INTEGER_CSTs. */ 1213*e4b17023SJohn Marino 1214*e4b17023SJohn Marino static tree 1215*e4b17023SJohn Marino remap_eh_region_tree_nr (tree old_t_nr, copy_body_data *id) 1216*e4b17023SJohn Marino { 1217*e4b17023SJohn Marino int old_nr, new_nr; 1218*e4b17023SJohn Marino 1219*e4b17023SJohn Marino old_nr = tree_low_cst (old_t_nr, 0); 1220*e4b17023SJohn Marino new_nr = remap_eh_region_nr (old_nr, id); 1221*e4b17023SJohn Marino 1222*e4b17023SJohn Marino return build_int_cst (integer_type_node, new_nr); 1223*e4b17023SJohn Marino } 1224*e4b17023SJohn Marino 1225*e4b17023SJohn Marino /* Helper for copy_bb. Remap statement STMT using the inlining 1226*e4b17023SJohn Marino information in ID. Return the new statement copy. */ 1227*e4b17023SJohn Marino 1228*e4b17023SJohn Marino static gimple 1229*e4b17023SJohn Marino remap_gimple_stmt (gimple stmt, copy_body_data *id) 1230*e4b17023SJohn Marino { 1231*e4b17023SJohn Marino gimple copy = NULL; 1232*e4b17023SJohn Marino struct walk_stmt_info wi; 1233*e4b17023SJohn Marino tree new_block; 1234*e4b17023SJohn Marino bool skip_first = false; 1235*e4b17023SJohn Marino 1236*e4b17023SJohn Marino /* Begin by recognizing trees that we'll completely rewrite for the 1237*e4b17023SJohn Marino inlining context. Our output for these trees is completely 1238*e4b17023SJohn Marino different from out input (e.g. RETURN_EXPR is deleted, and morphs 1239*e4b17023SJohn Marino into an edge). Further down, we'll handle trees that get 1240*e4b17023SJohn Marino duplicated and/or tweaked. */ 1241*e4b17023SJohn Marino 1242*e4b17023SJohn Marino /* When requested, GIMPLE_RETURNs should be transformed to just the 1243*e4b17023SJohn Marino contained GIMPLE_ASSIGN. The branch semantics of the return will 1244*e4b17023SJohn Marino be handled elsewhere by manipulating the CFG rather than the 1245*e4b17023SJohn Marino statement. */ 1246*e4b17023SJohn Marino if (gimple_code (stmt) == GIMPLE_RETURN && id->transform_return_to_modify) 1247*e4b17023SJohn Marino { 1248*e4b17023SJohn Marino tree retval = gimple_return_retval (stmt); 1249*e4b17023SJohn Marino 1250*e4b17023SJohn Marino /* If we're returning something, just turn that into an 1251*e4b17023SJohn Marino assignment into the equivalent of the original RESULT_DECL. 1252*e4b17023SJohn Marino If RETVAL is just the result decl, the result decl has 1253*e4b17023SJohn Marino already been set (e.g. a recent "foo (&result_decl, ...)"); 1254*e4b17023SJohn Marino just toss the entire GIMPLE_RETURN. */ 1255*e4b17023SJohn Marino if (retval 1256*e4b17023SJohn Marino && (TREE_CODE (retval) != RESULT_DECL 1257*e4b17023SJohn Marino && (TREE_CODE (retval) != SSA_NAME 1258*e4b17023SJohn Marino || TREE_CODE (SSA_NAME_VAR (retval)) != RESULT_DECL))) 1259*e4b17023SJohn Marino { 1260*e4b17023SJohn Marino copy = gimple_build_assign (id->retvar, retval); 1261*e4b17023SJohn Marino /* id->retvar is already substituted. Skip it on later remapping. */ 1262*e4b17023SJohn Marino skip_first = true; 1263*e4b17023SJohn Marino } 1264*e4b17023SJohn Marino else 1265*e4b17023SJohn Marino return gimple_build_nop (); 1266*e4b17023SJohn Marino } 1267*e4b17023SJohn Marino else if (gimple_has_substatements (stmt)) 1268*e4b17023SJohn Marino { 1269*e4b17023SJohn Marino gimple_seq s1, s2; 1270*e4b17023SJohn Marino 1271*e4b17023SJohn Marino /* When cloning bodies from the C++ front end, we will be handed bodies 1272*e4b17023SJohn Marino in High GIMPLE form. Handle here all the High GIMPLE statements that 1273*e4b17023SJohn Marino have embedded statements. */ 1274*e4b17023SJohn Marino switch (gimple_code (stmt)) 1275*e4b17023SJohn Marino { 1276*e4b17023SJohn Marino case GIMPLE_BIND: 1277*e4b17023SJohn Marino copy = copy_gimple_bind (stmt, id); 1278*e4b17023SJohn Marino break; 1279*e4b17023SJohn Marino 1280*e4b17023SJohn Marino case GIMPLE_CATCH: 1281*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_catch_handler (stmt), id); 1282*e4b17023SJohn Marino copy = gimple_build_catch (gimple_catch_types (stmt), s1); 1283*e4b17023SJohn Marino break; 1284*e4b17023SJohn Marino 1285*e4b17023SJohn Marino case GIMPLE_EH_FILTER: 1286*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_eh_filter_failure (stmt), id); 1287*e4b17023SJohn Marino copy = gimple_build_eh_filter (gimple_eh_filter_types (stmt), s1); 1288*e4b17023SJohn Marino break; 1289*e4b17023SJohn Marino 1290*e4b17023SJohn Marino case GIMPLE_TRY: 1291*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_try_eval (stmt), id); 1292*e4b17023SJohn Marino s2 = remap_gimple_seq (gimple_try_cleanup (stmt), id); 1293*e4b17023SJohn Marino copy = gimple_build_try (s1, s2, gimple_try_kind (stmt)); 1294*e4b17023SJohn Marino break; 1295*e4b17023SJohn Marino 1296*e4b17023SJohn Marino case GIMPLE_WITH_CLEANUP_EXPR: 1297*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_wce_cleanup (stmt), id); 1298*e4b17023SJohn Marino copy = gimple_build_wce (s1); 1299*e4b17023SJohn Marino break; 1300*e4b17023SJohn Marino 1301*e4b17023SJohn Marino case GIMPLE_OMP_PARALLEL: 1302*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1303*e4b17023SJohn Marino copy = gimple_build_omp_parallel 1304*e4b17023SJohn Marino (s1, 1305*e4b17023SJohn Marino gimple_omp_parallel_clauses (stmt), 1306*e4b17023SJohn Marino gimple_omp_parallel_child_fn (stmt), 1307*e4b17023SJohn Marino gimple_omp_parallel_data_arg (stmt)); 1308*e4b17023SJohn Marino break; 1309*e4b17023SJohn Marino 1310*e4b17023SJohn Marino case GIMPLE_OMP_TASK: 1311*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1312*e4b17023SJohn Marino copy = gimple_build_omp_task 1313*e4b17023SJohn Marino (s1, 1314*e4b17023SJohn Marino gimple_omp_task_clauses (stmt), 1315*e4b17023SJohn Marino gimple_omp_task_child_fn (stmt), 1316*e4b17023SJohn Marino gimple_omp_task_data_arg (stmt), 1317*e4b17023SJohn Marino gimple_omp_task_copy_fn (stmt), 1318*e4b17023SJohn Marino gimple_omp_task_arg_size (stmt), 1319*e4b17023SJohn Marino gimple_omp_task_arg_align (stmt)); 1320*e4b17023SJohn Marino break; 1321*e4b17023SJohn Marino 1322*e4b17023SJohn Marino case GIMPLE_OMP_FOR: 1323*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1324*e4b17023SJohn Marino s2 = remap_gimple_seq (gimple_omp_for_pre_body (stmt), id); 1325*e4b17023SJohn Marino copy = gimple_build_omp_for (s1, gimple_omp_for_clauses (stmt), 1326*e4b17023SJohn Marino gimple_omp_for_collapse (stmt), s2); 1327*e4b17023SJohn Marino { 1328*e4b17023SJohn Marino size_t i; 1329*e4b17023SJohn Marino for (i = 0; i < gimple_omp_for_collapse (stmt); i++) 1330*e4b17023SJohn Marino { 1331*e4b17023SJohn Marino gimple_omp_for_set_index (copy, i, 1332*e4b17023SJohn Marino gimple_omp_for_index (stmt, i)); 1333*e4b17023SJohn Marino gimple_omp_for_set_initial (copy, i, 1334*e4b17023SJohn Marino gimple_omp_for_initial (stmt, i)); 1335*e4b17023SJohn Marino gimple_omp_for_set_final (copy, i, 1336*e4b17023SJohn Marino gimple_omp_for_final (stmt, i)); 1337*e4b17023SJohn Marino gimple_omp_for_set_incr (copy, i, 1338*e4b17023SJohn Marino gimple_omp_for_incr (stmt, i)); 1339*e4b17023SJohn Marino gimple_omp_for_set_cond (copy, i, 1340*e4b17023SJohn Marino gimple_omp_for_cond (stmt, i)); 1341*e4b17023SJohn Marino } 1342*e4b17023SJohn Marino } 1343*e4b17023SJohn Marino break; 1344*e4b17023SJohn Marino 1345*e4b17023SJohn Marino case GIMPLE_OMP_MASTER: 1346*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1347*e4b17023SJohn Marino copy = gimple_build_omp_master (s1); 1348*e4b17023SJohn Marino break; 1349*e4b17023SJohn Marino 1350*e4b17023SJohn Marino case GIMPLE_OMP_ORDERED: 1351*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1352*e4b17023SJohn Marino copy = gimple_build_omp_ordered (s1); 1353*e4b17023SJohn Marino break; 1354*e4b17023SJohn Marino 1355*e4b17023SJohn Marino case GIMPLE_OMP_SECTION: 1356*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1357*e4b17023SJohn Marino copy = gimple_build_omp_section (s1); 1358*e4b17023SJohn Marino break; 1359*e4b17023SJohn Marino 1360*e4b17023SJohn Marino case GIMPLE_OMP_SECTIONS: 1361*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1362*e4b17023SJohn Marino copy = gimple_build_omp_sections 1363*e4b17023SJohn Marino (s1, gimple_omp_sections_clauses (stmt)); 1364*e4b17023SJohn Marino break; 1365*e4b17023SJohn Marino 1366*e4b17023SJohn Marino case GIMPLE_OMP_SINGLE: 1367*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1368*e4b17023SJohn Marino copy = gimple_build_omp_single 1369*e4b17023SJohn Marino (s1, gimple_omp_single_clauses (stmt)); 1370*e4b17023SJohn Marino break; 1371*e4b17023SJohn Marino 1372*e4b17023SJohn Marino case GIMPLE_OMP_CRITICAL: 1373*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_omp_body (stmt), id); 1374*e4b17023SJohn Marino copy 1375*e4b17023SJohn Marino = gimple_build_omp_critical (s1, gimple_omp_critical_name (stmt)); 1376*e4b17023SJohn Marino break; 1377*e4b17023SJohn Marino 1378*e4b17023SJohn Marino case GIMPLE_TRANSACTION: 1379*e4b17023SJohn Marino s1 = remap_gimple_seq (gimple_transaction_body (stmt), id); 1380*e4b17023SJohn Marino copy = gimple_build_transaction (s1, gimple_transaction_label (stmt)); 1381*e4b17023SJohn Marino gimple_transaction_set_subcode (copy, gimple_transaction_subcode (stmt)); 1382*e4b17023SJohn Marino break; 1383*e4b17023SJohn Marino 1384*e4b17023SJohn Marino default: 1385*e4b17023SJohn Marino gcc_unreachable (); 1386*e4b17023SJohn Marino } 1387*e4b17023SJohn Marino } 1388*e4b17023SJohn Marino else 1389*e4b17023SJohn Marino { 1390*e4b17023SJohn Marino if (gimple_assign_copy_p (stmt) 1391*e4b17023SJohn Marino && gimple_assign_lhs (stmt) == gimple_assign_rhs1 (stmt) 1392*e4b17023SJohn Marino && auto_var_in_fn_p (gimple_assign_lhs (stmt), id->src_fn)) 1393*e4b17023SJohn Marino { 1394*e4b17023SJohn Marino /* Here we handle statements that are not completely rewritten. 1395*e4b17023SJohn Marino First we detect some inlining-induced bogosities for 1396*e4b17023SJohn Marino discarding. */ 1397*e4b17023SJohn Marino 1398*e4b17023SJohn Marino /* Some assignments VAR = VAR; don't generate any rtl code 1399*e4b17023SJohn Marino and thus don't count as variable modification. Avoid 1400*e4b17023SJohn Marino keeping bogosities like 0 = 0. */ 1401*e4b17023SJohn Marino tree decl = gimple_assign_lhs (stmt), value; 1402*e4b17023SJohn Marino tree *n; 1403*e4b17023SJohn Marino 1404*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, decl); 1405*e4b17023SJohn Marino if (n) 1406*e4b17023SJohn Marino { 1407*e4b17023SJohn Marino value = *n; 1408*e4b17023SJohn Marino STRIP_TYPE_NOPS (value); 1409*e4b17023SJohn Marino if (TREE_CONSTANT (value) || TREE_READONLY (value)) 1410*e4b17023SJohn Marino return gimple_build_nop (); 1411*e4b17023SJohn Marino } 1412*e4b17023SJohn Marino } 1413*e4b17023SJohn Marino 1414*e4b17023SJohn Marino if (gimple_debug_bind_p (stmt)) 1415*e4b17023SJohn Marino { 1416*e4b17023SJohn Marino copy = gimple_build_debug_bind (gimple_debug_bind_get_var (stmt), 1417*e4b17023SJohn Marino gimple_debug_bind_get_value (stmt), 1418*e4b17023SJohn Marino stmt); 1419*e4b17023SJohn Marino VEC_safe_push (gimple, heap, id->debug_stmts, copy); 1420*e4b17023SJohn Marino return copy; 1421*e4b17023SJohn Marino } 1422*e4b17023SJohn Marino if (gimple_debug_source_bind_p (stmt)) 1423*e4b17023SJohn Marino { 1424*e4b17023SJohn Marino copy = gimple_build_debug_source_bind 1425*e4b17023SJohn Marino (gimple_debug_source_bind_get_var (stmt), 1426*e4b17023SJohn Marino gimple_debug_source_bind_get_value (stmt), stmt); 1427*e4b17023SJohn Marino VEC_safe_push (gimple, heap, id->debug_stmts, copy); 1428*e4b17023SJohn Marino return copy; 1429*e4b17023SJohn Marino } 1430*e4b17023SJohn Marino 1431*e4b17023SJohn Marino /* Create a new deep copy of the statement. */ 1432*e4b17023SJohn Marino copy = gimple_copy (stmt); 1433*e4b17023SJohn Marino 1434*e4b17023SJohn Marino /* Remap the region numbers for __builtin_eh_{pointer,filter}, 1435*e4b17023SJohn Marino RESX and EH_DISPATCH. */ 1436*e4b17023SJohn Marino if (id->eh_map) 1437*e4b17023SJohn Marino switch (gimple_code (copy)) 1438*e4b17023SJohn Marino { 1439*e4b17023SJohn Marino case GIMPLE_CALL: 1440*e4b17023SJohn Marino { 1441*e4b17023SJohn Marino tree r, fndecl = gimple_call_fndecl (copy); 1442*e4b17023SJohn Marino if (fndecl && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL) 1443*e4b17023SJohn Marino switch (DECL_FUNCTION_CODE (fndecl)) 1444*e4b17023SJohn Marino { 1445*e4b17023SJohn Marino case BUILT_IN_EH_COPY_VALUES: 1446*e4b17023SJohn Marino r = gimple_call_arg (copy, 1); 1447*e4b17023SJohn Marino r = remap_eh_region_tree_nr (r, id); 1448*e4b17023SJohn Marino gimple_call_set_arg (copy, 1, r); 1449*e4b17023SJohn Marino /* FALLTHRU */ 1450*e4b17023SJohn Marino 1451*e4b17023SJohn Marino case BUILT_IN_EH_POINTER: 1452*e4b17023SJohn Marino case BUILT_IN_EH_FILTER: 1453*e4b17023SJohn Marino r = gimple_call_arg (copy, 0); 1454*e4b17023SJohn Marino r = remap_eh_region_tree_nr (r, id); 1455*e4b17023SJohn Marino gimple_call_set_arg (copy, 0, r); 1456*e4b17023SJohn Marino break; 1457*e4b17023SJohn Marino 1458*e4b17023SJohn Marino default: 1459*e4b17023SJohn Marino break; 1460*e4b17023SJohn Marino } 1461*e4b17023SJohn Marino 1462*e4b17023SJohn Marino /* Reset alias info if we didn't apply measures to 1463*e4b17023SJohn Marino keep it valid over inlining by setting DECL_PT_UID. */ 1464*e4b17023SJohn Marino if (!id->src_cfun->gimple_df 1465*e4b17023SJohn Marino || !id->src_cfun->gimple_df->ipa_pta) 1466*e4b17023SJohn Marino gimple_call_reset_alias_info (copy); 1467*e4b17023SJohn Marino } 1468*e4b17023SJohn Marino break; 1469*e4b17023SJohn Marino 1470*e4b17023SJohn Marino case GIMPLE_RESX: 1471*e4b17023SJohn Marino { 1472*e4b17023SJohn Marino int r = gimple_resx_region (copy); 1473*e4b17023SJohn Marino r = remap_eh_region_nr (r, id); 1474*e4b17023SJohn Marino gimple_resx_set_region (copy, r); 1475*e4b17023SJohn Marino } 1476*e4b17023SJohn Marino break; 1477*e4b17023SJohn Marino 1478*e4b17023SJohn Marino case GIMPLE_EH_DISPATCH: 1479*e4b17023SJohn Marino { 1480*e4b17023SJohn Marino int r = gimple_eh_dispatch_region (copy); 1481*e4b17023SJohn Marino r = remap_eh_region_nr (r, id); 1482*e4b17023SJohn Marino gimple_eh_dispatch_set_region (copy, r); 1483*e4b17023SJohn Marino } 1484*e4b17023SJohn Marino break; 1485*e4b17023SJohn Marino 1486*e4b17023SJohn Marino default: 1487*e4b17023SJohn Marino break; 1488*e4b17023SJohn Marino } 1489*e4b17023SJohn Marino } 1490*e4b17023SJohn Marino 1491*e4b17023SJohn Marino /* If STMT has a block defined, map it to the newly constructed 1492*e4b17023SJohn Marino block. When inlining we want statements without a block to 1493*e4b17023SJohn Marino appear in the block of the function call. */ 1494*e4b17023SJohn Marino new_block = id->block; 1495*e4b17023SJohn Marino if (gimple_block (copy)) 1496*e4b17023SJohn Marino { 1497*e4b17023SJohn Marino tree *n; 1498*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, gimple_block (copy)); 1499*e4b17023SJohn Marino gcc_assert (n); 1500*e4b17023SJohn Marino new_block = *n; 1501*e4b17023SJohn Marino } 1502*e4b17023SJohn Marino 1503*e4b17023SJohn Marino gimple_set_block (copy, new_block); 1504*e4b17023SJohn Marino 1505*e4b17023SJohn Marino if (gimple_debug_bind_p (copy) || gimple_debug_source_bind_p (copy)) 1506*e4b17023SJohn Marino return copy; 1507*e4b17023SJohn Marino 1508*e4b17023SJohn Marino /* Remap all the operands in COPY. */ 1509*e4b17023SJohn Marino memset (&wi, 0, sizeof (wi)); 1510*e4b17023SJohn Marino wi.info = id; 1511*e4b17023SJohn Marino if (skip_first) 1512*e4b17023SJohn Marino walk_tree (gimple_op_ptr (copy, 1), remap_gimple_op_r, &wi, NULL); 1513*e4b17023SJohn Marino else 1514*e4b17023SJohn Marino walk_gimple_op (copy, remap_gimple_op_r, &wi); 1515*e4b17023SJohn Marino 1516*e4b17023SJohn Marino /* Clear the copied virtual operands. We are not remapping them here 1517*e4b17023SJohn Marino but are going to recreate them from scratch. */ 1518*e4b17023SJohn Marino if (gimple_has_mem_ops (copy)) 1519*e4b17023SJohn Marino { 1520*e4b17023SJohn Marino gimple_set_vdef (copy, NULL_TREE); 1521*e4b17023SJohn Marino gimple_set_vuse (copy, NULL_TREE); 1522*e4b17023SJohn Marino } 1523*e4b17023SJohn Marino 1524*e4b17023SJohn Marino return copy; 1525*e4b17023SJohn Marino } 1526*e4b17023SJohn Marino 1527*e4b17023SJohn Marino 1528*e4b17023SJohn Marino /* Copy basic block, scale profile accordingly. Edges will be taken care of 1529*e4b17023SJohn Marino later */ 1530*e4b17023SJohn Marino 1531*e4b17023SJohn Marino static basic_block 1532*e4b17023SJohn Marino copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, 1533*e4b17023SJohn Marino gcov_type count_scale) 1534*e4b17023SJohn Marino { 1535*e4b17023SJohn Marino gimple_stmt_iterator gsi, copy_gsi, seq_gsi; 1536*e4b17023SJohn Marino basic_block copy_basic_block; 1537*e4b17023SJohn Marino tree decl; 1538*e4b17023SJohn Marino gcov_type freq; 1539*e4b17023SJohn Marino basic_block prev; 1540*e4b17023SJohn Marino 1541*e4b17023SJohn Marino /* Search for previous copied basic block. */ 1542*e4b17023SJohn Marino prev = bb->prev_bb; 1543*e4b17023SJohn Marino while (!prev->aux) 1544*e4b17023SJohn Marino prev = prev->prev_bb; 1545*e4b17023SJohn Marino 1546*e4b17023SJohn Marino /* create_basic_block() will append every new block to 1547*e4b17023SJohn Marino basic_block_info automatically. */ 1548*e4b17023SJohn Marino copy_basic_block = create_basic_block (NULL, (void *) 0, 1549*e4b17023SJohn Marino (basic_block) prev->aux); 1550*e4b17023SJohn Marino copy_basic_block->count = bb->count * count_scale / REG_BR_PROB_BASE; 1551*e4b17023SJohn Marino 1552*e4b17023SJohn Marino /* We are going to rebuild frequencies from scratch. These values 1553*e4b17023SJohn Marino have just small importance to drive canonicalize_loop_headers. */ 1554*e4b17023SJohn Marino freq = ((gcov_type)bb->frequency * frequency_scale / REG_BR_PROB_BASE); 1555*e4b17023SJohn Marino 1556*e4b17023SJohn Marino /* We recompute frequencies after inlining, so this is quite safe. */ 1557*e4b17023SJohn Marino if (freq > BB_FREQ_MAX) 1558*e4b17023SJohn Marino freq = BB_FREQ_MAX; 1559*e4b17023SJohn Marino copy_basic_block->frequency = freq; 1560*e4b17023SJohn Marino 1561*e4b17023SJohn Marino copy_gsi = gsi_start_bb (copy_basic_block); 1562*e4b17023SJohn Marino 1563*e4b17023SJohn Marino for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 1564*e4b17023SJohn Marino { 1565*e4b17023SJohn Marino gimple stmt = gsi_stmt (gsi); 1566*e4b17023SJohn Marino gimple orig_stmt = stmt; 1567*e4b17023SJohn Marino 1568*e4b17023SJohn Marino id->regimplify = false; 1569*e4b17023SJohn Marino stmt = remap_gimple_stmt (stmt, id); 1570*e4b17023SJohn Marino if (gimple_nop_p (stmt)) 1571*e4b17023SJohn Marino continue; 1572*e4b17023SJohn Marino 1573*e4b17023SJohn Marino gimple_duplicate_stmt_histograms (cfun, stmt, id->src_cfun, orig_stmt); 1574*e4b17023SJohn Marino seq_gsi = copy_gsi; 1575*e4b17023SJohn Marino 1576*e4b17023SJohn Marino /* With return slot optimization we can end up with 1577*e4b17023SJohn Marino non-gimple (foo *)&this->m, fix that here. */ 1578*e4b17023SJohn Marino if (is_gimple_assign (stmt) 1579*e4b17023SJohn Marino && gimple_assign_rhs_code (stmt) == NOP_EXPR 1580*e4b17023SJohn Marino && !is_gimple_val (gimple_assign_rhs1 (stmt))) 1581*e4b17023SJohn Marino { 1582*e4b17023SJohn Marino tree new_rhs; 1583*e4b17023SJohn Marino new_rhs = force_gimple_operand_gsi (&seq_gsi, 1584*e4b17023SJohn Marino gimple_assign_rhs1 (stmt), 1585*e4b17023SJohn Marino true, NULL, false, 1586*e4b17023SJohn Marino GSI_CONTINUE_LINKING); 1587*e4b17023SJohn Marino gimple_assign_set_rhs1 (stmt, new_rhs); 1588*e4b17023SJohn Marino id->regimplify = false; 1589*e4b17023SJohn Marino } 1590*e4b17023SJohn Marino 1591*e4b17023SJohn Marino gsi_insert_after (&seq_gsi, stmt, GSI_NEW_STMT); 1592*e4b17023SJohn Marino 1593*e4b17023SJohn Marino if (id->regimplify) 1594*e4b17023SJohn Marino gimple_regimplify_operands (stmt, &seq_gsi); 1595*e4b17023SJohn Marino 1596*e4b17023SJohn Marino /* If copy_basic_block has been empty at the start of this iteration, 1597*e4b17023SJohn Marino call gsi_start_bb again to get at the newly added statements. */ 1598*e4b17023SJohn Marino if (gsi_end_p (copy_gsi)) 1599*e4b17023SJohn Marino copy_gsi = gsi_start_bb (copy_basic_block); 1600*e4b17023SJohn Marino else 1601*e4b17023SJohn Marino gsi_next (©_gsi); 1602*e4b17023SJohn Marino 1603*e4b17023SJohn Marino /* Process the new statement. The call to gimple_regimplify_operands 1604*e4b17023SJohn Marino possibly turned the statement into multiple statements, we 1605*e4b17023SJohn Marino need to process all of them. */ 1606*e4b17023SJohn Marino do 1607*e4b17023SJohn Marino { 1608*e4b17023SJohn Marino tree fn; 1609*e4b17023SJohn Marino 1610*e4b17023SJohn Marino stmt = gsi_stmt (copy_gsi); 1611*e4b17023SJohn Marino if (is_gimple_call (stmt) 1612*e4b17023SJohn Marino && gimple_call_va_arg_pack_p (stmt) 1613*e4b17023SJohn Marino && id->gimple_call) 1614*e4b17023SJohn Marino { 1615*e4b17023SJohn Marino /* __builtin_va_arg_pack () should be replaced by 1616*e4b17023SJohn Marino all arguments corresponding to ... in the caller. */ 1617*e4b17023SJohn Marino tree p; 1618*e4b17023SJohn Marino gimple new_call; 1619*e4b17023SJohn Marino VEC(tree, heap) *argarray; 1620*e4b17023SJohn Marino size_t nargs = gimple_call_num_args (id->gimple_call); 1621*e4b17023SJohn Marino size_t n; 1622*e4b17023SJohn Marino 1623*e4b17023SJohn Marino for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p)) 1624*e4b17023SJohn Marino nargs--; 1625*e4b17023SJohn Marino 1626*e4b17023SJohn Marino /* Create the new array of arguments. */ 1627*e4b17023SJohn Marino n = nargs + gimple_call_num_args (stmt); 1628*e4b17023SJohn Marino argarray = VEC_alloc (tree, heap, n); 1629*e4b17023SJohn Marino VEC_safe_grow (tree, heap, argarray, n); 1630*e4b17023SJohn Marino 1631*e4b17023SJohn Marino /* Copy all the arguments before '...' */ 1632*e4b17023SJohn Marino memcpy (VEC_address (tree, argarray), 1633*e4b17023SJohn Marino gimple_call_arg_ptr (stmt, 0), 1634*e4b17023SJohn Marino gimple_call_num_args (stmt) * sizeof (tree)); 1635*e4b17023SJohn Marino 1636*e4b17023SJohn Marino /* Append the arguments passed in '...' */ 1637*e4b17023SJohn Marino memcpy (VEC_address(tree, argarray) + gimple_call_num_args (stmt), 1638*e4b17023SJohn Marino gimple_call_arg_ptr (id->gimple_call, 0) 1639*e4b17023SJohn Marino + (gimple_call_num_args (id->gimple_call) - nargs), 1640*e4b17023SJohn Marino nargs * sizeof (tree)); 1641*e4b17023SJohn Marino 1642*e4b17023SJohn Marino new_call = gimple_build_call_vec (gimple_call_fn (stmt), 1643*e4b17023SJohn Marino argarray); 1644*e4b17023SJohn Marino 1645*e4b17023SJohn Marino VEC_free (tree, heap, argarray); 1646*e4b17023SJohn Marino 1647*e4b17023SJohn Marino /* Copy all GIMPLE_CALL flags, location and block, except 1648*e4b17023SJohn Marino GF_CALL_VA_ARG_PACK. */ 1649*e4b17023SJohn Marino gimple_call_copy_flags (new_call, stmt); 1650*e4b17023SJohn Marino gimple_call_set_va_arg_pack (new_call, false); 1651*e4b17023SJohn Marino gimple_set_location (new_call, gimple_location (stmt)); 1652*e4b17023SJohn Marino gimple_set_block (new_call, gimple_block (stmt)); 1653*e4b17023SJohn Marino gimple_call_set_lhs (new_call, gimple_call_lhs (stmt)); 1654*e4b17023SJohn Marino 1655*e4b17023SJohn Marino gsi_replace (©_gsi, new_call, false); 1656*e4b17023SJohn Marino stmt = new_call; 1657*e4b17023SJohn Marino } 1658*e4b17023SJohn Marino else if (is_gimple_call (stmt) 1659*e4b17023SJohn Marino && id->gimple_call 1660*e4b17023SJohn Marino && (decl = gimple_call_fndecl (stmt)) 1661*e4b17023SJohn Marino && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL 1662*e4b17023SJohn Marino && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN) 1663*e4b17023SJohn Marino { 1664*e4b17023SJohn Marino /* __builtin_va_arg_pack_len () should be replaced by 1665*e4b17023SJohn Marino the number of anonymous arguments. */ 1666*e4b17023SJohn Marino size_t nargs = gimple_call_num_args (id->gimple_call); 1667*e4b17023SJohn Marino tree count, p; 1668*e4b17023SJohn Marino gimple new_stmt; 1669*e4b17023SJohn Marino 1670*e4b17023SJohn Marino for (p = DECL_ARGUMENTS (id->src_fn); p; p = DECL_CHAIN (p)) 1671*e4b17023SJohn Marino nargs--; 1672*e4b17023SJohn Marino 1673*e4b17023SJohn Marino count = build_int_cst (integer_type_node, nargs); 1674*e4b17023SJohn Marino new_stmt = gimple_build_assign (gimple_call_lhs (stmt), count); 1675*e4b17023SJohn Marino gsi_replace (©_gsi, new_stmt, false); 1676*e4b17023SJohn Marino stmt = new_stmt; 1677*e4b17023SJohn Marino } 1678*e4b17023SJohn Marino 1679*e4b17023SJohn Marino /* Statements produced by inlining can be unfolded, especially 1680*e4b17023SJohn Marino when we constant propagated some operands. We can't fold 1681*e4b17023SJohn Marino them right now for two reasons: 1682*e4b17023SJohn Marino 1) folding require SSA_NAME_DEF_STMTs to be correct 1683*e4b17023SJohn Marino 2) we can't change function calls to builtins. 1684*e4b17023SJohn Marino So we just mark statement for later folding. We mark 1685*e4b17023SJohn Marino all new statements, instead just statements that has changed 1686*e4b17023SJohn Marino by some nontrivial substitution so even statements made 1687*e4b17023SJohn Marino foldable indirectly are updated. If this turns out to be 1688*e4b17023SJohn Marino expensive, copy_body can be told to watch for nontrivial 1689*e4b17023SJohn Marino changes. */ 1690*e4b17023SJohn Marino if (id->statements_to_fold) 1691*e4b17023SJohn Marino pointer_set_insert (id->statements_to_fold, stmt); 1692*e4b17023SJohn Marino 1693*e4b17023SJohn Marino /* We're duplicating a CALL_EXPR. Find any corresponding 1694*e4b17023SJohn Marino callgraph edges and update or duplicate them. */ 1695*e4b17023SJohn Marino if (is_gimple_call (stmt)) 1696*e4b17023SJohn Marino { 1697*e4b17023SJohn Marino struct cgraph_edge *edge; 1698*e4b17023SJohn Marino int flags; 1699*e4b17023SJohn Marino 1700*e4b17023SJohn Marino switch (id->transform_call_graph_edges) 1701*e4b17023SJohn Marino { 1702*e4b17023SJohn Marino case CB_CGE_DUPLICATE: 1703*e4b17023SJohn Marino edge = cgraph_edge (id->src_node, orig_stmt); 1704*e4b17023SJohn Marino if (edge) 1705*e4b17023SJohn Marino { 1706*e4b17023SJohn Marino int edge_freq = edge->frequency; 1707*e4b17023SJohn Marino edge = cgraph_clone_edge (edge, id->dst_node, stmt, 1708*e4b17023SJohn Marino gimple_uid (stmt), 1709*e4b17023SJohn Marino REG_BR_PROB_BASE, CGRAPH_FREQ_BASE, 1710*e4b17023SJohn Marino true); 1711*e4b17023SJohn Marino /* We could also just rescale the frequency, but 1712*e4b17023SJohn Marino doing so would introduce roundoff errors and make 1713*e4b17023SJohn Marino verifier unhappy. */ 1714*e4b17023SJohn Marino edge->frequency 1715*e4b17023SJohn Marino = compute_call_stmt_bb_frequency (id->dst_node->decl, 1716*e4b17023SJohn Marino copy_basic_block); 1717*e4b17023SJohn Marino if (dump_file 1718*e4b17023SJohn Marino && profile_status_for_function (cfun) != PROFILE_ABSENT 1719*e4b17023SJohn Marino && (edge_freq > edge->frequency + 10 1720*e4b17023SJohn Marino || edge_freq < edge->frequency - 10)) 1721*e4b17023SJohn Marino { 1722*e4b17023SJohn Marino fprintf (dump_file, "Edge frequency estimated by " 1723*e4b17023SJohn Marino "cgraph %i diverge from inliner's estimate %i\n", 1724*e4b17023SJohn Marino edge_freq, 1725*e4b17023SJohn Marino edge->frequency); 1726*e4b17023SJohn Marino fprintf (dump_file, 1727*e4b17023SJohn Marino "Orig bb: %i, orig bb freq %i, new bb freq %i\n", 1728*e4b17023SJohn Marino bb->index, 1729*e4b17023SJohn Marino bb->frequency, 1730*e4b17023SJohn Marino copy_basic_block->frequency); 1731*e4b17023SJohn Marino } 1732*e4b17023SJohn Marino stmt = cgraph_redirect_edge_call_stmt_to_callee (edge); 1733*e4b17023SJohn Marino } 1734*e4b17023SJohn Marino break; 1735*e4b17023SJohn Marino 1736*e4b17023SJohn Marino case CB_CGE_MOVE_CLONES: 1737*e4b17023SJohn Marino cgraph_set_call_stmt_including_clones (id->dst_node, 1738*e4b17023SJohn Marino orig_stmt, stmt); 1739*e4b17023SJohn Marino edge = cgraph_edge (id->dst_node, stmt); 1740*e4b17023SJohn Marino break; 1741*e4b17023SJohn Marino 1742*e4b17023SJohn Marino case CB_CGE_MOVE: 1743*e4b17023SJohn Marino edge = cgraph_edge (id->dst_node, orig_stmt); 1744*e4b17023SJohn Marino if (edge) 1745*e4b17023SJohn Marino cgraph_set_call_stmt (edge, stmt); 1746*e4b17023SJohn Marino break; 1747*e4b17023SJohn Marino 1748*e4b17023SJohn Marino default: 1749*e4b17023SJohn Marino gcc_unreachable (); 1750*e4b17023SJohn Marino } 1751*e4b17023SJohn Marino 1752*e4b17023SJohn Marino /* Constant propagation on argument done during inlining 1753*e4b17023SJohn Marino may create new direct call. Produce an edge for it. */ 1754*e4b17023SJohn Marino if ((!edge 1755*e4b17023SJohn Marino || (edge->indirect_inlining_edge 1756*e4b17023SJohn Marino && id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)) 1757*e4b17023SJohn Marino && id->dst_node->analyzed 1758*e4b17023SJohn Marino && (fn = gimple_call_fndecl (stmt)) != NULL) 1759*e4b17023SJohn Marino { 1760*e4b17023SJohn Marino struct cgraph_node *dest = cgraph_get_node (fn); 1761*e4b17023SJohn Marino 1762*e4b17023SJohn Marino /* We have missing edge in the callgraph. This can happen 1763*e4b17023SJohn Marino when previous inlining turned an indirect call into a 1764*e4b17023SJohn Marino direct call by constant propagating arguments or we are 1765*e4b17023SJohn Marino producing dead clone (for further cloning). In all 1766*e4b17023SJohn Marino other cases we hit a bug (incorrect node sharing is the 1767*e4b17023SJohn Marino most common reason for missing edges). */ 1768*e4b17023SJohn Marino gcc_assert (dest->needed || !dest->analyzed 1769*e4b17023SJohn Marino || dest->address_taken 1770*e4b17023SJohn Marino || !id->src_node->analyzed 1771*e4b17023SJohn Marino || !id->dst_node->analyzed); 1772*e4b17023SJohn Marino if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES) 1773*e4b17023SJohn Marino cgraph_create_edge_including_clones 1774*e4b17023SJohn Marino (id->dst_node, dest, orig_stmt, stmt, bb->count, 1775*e4b17023SJohn Marino compute_call_stmt_bb_frequency (id->dst_node->decl, 1776*e4b17023SJohn Marino copy_basic_block), 1777*e4b17023SJohn Marino CIF_ORIGINALLY_INDIRECT_CALL); 1778*e4b17023SJohn Marino else 1779*e4b17023SJohn Marino cgraph_create_edge (id->dst_node, dest, stmt, 1780*e4b17023SJohn Marino bb->count, 1781*e4b17023SJohn Marino compute_call_stmt_bb_frequency 1782*e4b17023SJohn Marino (id->dst_node->decl, copy_basic_block))->inline_failed 1783*e4b17023SJohn Marino = CIF_ORIGINALLY_INDIRECT_CALL; 1784*e4b17023SJohn Marino if (dump_file) 1785*e4b17023SJohn Marino { 1786*e4b17023SJohn Marino fprintf (dump_file, "Created new direct edge to %s\n", 1787*e4b17023SJohn Marino cgraph_node_name (dest)); 1788*e4b17023SJohn Marino } 1789*e4b17023SJohn Marino } 1790*e4b17023SJohn Marino 1791*e4b17023SJohn Marino flags = gimple_call_flags (stmt); 1792*e4b17023SJohn Marino if (flags & ECF_MAY_BE_ALLOCA) 1793*e4b17023SJohn Marino cfun->calls_alloca = true; 1794*e4b17023SJohn Marino if (flags & ECF_RETURNS_TWICE) 1795*e4b17023SJohn Marino cfun->calls_setjmp = true; 1796*e4b17023SJohn Marino } 1797*e4b17023SJohn Marino 1798*e4b17023SJohn Marino maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt, 1799*e4b17023SJohn Marino id->eh_map, id->eh_lp_nr); 1800*e4b17023SJohn Marino 1801*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun) && !is_gimple_debug (stmt)) 1802*e4b17023SJohn Marino { 1803*e4b17023SJohn Marino ssa_op_iter i; 1804*e4b17023SJohn Marino tree def; 1805*e4b17023SJohn Marino 1806*e4b17023SJohn Marino find_new_referenced_vars (gsi_stmt (copy_gsi)); 1807*e4b17023SJohn Marino FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF) 1808*e4b17023SJohn Marino if (TREE_CODE (def) == SSA_NAME) 1809*e4b17023SJohn Marino SSA_NAME_DEF_STMT (def) = stmt; 1810*e4b17023SJohn Marino } 1811*e4b17023SJohn Marino 1812*e4b17023SJohn Marino gsi_next (©_gsi); 1813*e4b17023SJohn Marino } 1814*e4b17023SJohn Marino while (!gsi_end_p (copy_gsi)); 1815*e4b17023SJohn Marino 1816*e4b17023SJohn Marino copy_gsi = gsi_last_bb (copy_basic_block); 1817*e4b17023SJohn Marino } 1818*e4b17023SJohn Marino 1819*e4b17023SJohn Marino return copy_basic_block; 1820*e4b17023SJohn Marino } 1821*e4b17023SJohn Marino 1822*e4b17023SJohn Marino /* Inserting Single Entry Multiple Exit region in SSA form into code in SSA 1823*e4b17023SJohn Marino form is quite easy, since dominator relationship for old basic blocks does 1824*e4b17023SJohn Marino not change. 1825*e4b17023SJohn Marino 1826*e4b17023SJohn Marino There is however exception where inlining might change dominator relation 1827*e4b17023SJohn Marino across EH edges from basic block within inlined functions destinating 1828*e4b17023SJohn Marino to landing pads in function we inline into. 1829*e4b17023SJohn Marino 1830*e4b17023SJohn Marino The function fills in PHI_RESULTs of such PHI nodes if they refer 1831*e4b17023SJohn Marino to gimple regs. Otherwise, the function mark PHI_RESULT of such 1832*e4b17023SJohn Marino PHI nodes for renaming. For non-gimple regs, renaming is safe: the 1833*e4b17023SJohn Marino EH edges are abnormal and SSA_NAME_OCCURS_IN_ABNORMAL_PHI must be 1834*e4b17023SJohn Marino set, and this means that there will be no overlapping live ranges 1835*e4b17023SJohn Marino for the underlying symbol. 1836*e4b17023SJohn Marino 1837*e4b17023SJohn Marino This might change in future if we allow redirecting of EH edges and 1838*e4b17023SJohn Marino we might want to change way build CFG pre-inlining to include 1839*e4b17023SJohn Marino all the possible edges then. */ 1840*e4b17023SJohn Marino static void 1841*e4b17023SJohn Marino update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb, 1842*e4b17023SJohn Marino bool can_throw, bool nonlocal_goto) 1843*e4b17023SJohn Marino { 1844*e4b17023SJohn Marino edge e; 1845*e4b17023SJohn Marino edge_iterator ei; 1846*e4b17023SJohn Marino 1847*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs) 1848*e4b17023SJohn Marino if (!e->dest->aux 1849*e4b17023SJohn Marino || ((basic_block)e->dest->aux)->index == ENTRY_BLOCK) 1850*e4b17023SJohn Marino { 1851*e4b17023SJohn Marino gimple phi; 1852*e4b17023SJohn Marino gimple_stmt_iterator si; 1853*e4b17023SJohn Marino 1854*e4b17023SJohn Marino if (!nonlocal_goto) 1855*e4b17023SJohn Marino gcc_assert (e->flags & EDGE_EH); 1856*e4b17023SJohn Marino 1857*e4b17023SJohn Marino if (!can_throw) 1858*e4b17023SJohn Marino gcc_assert (!(e->flags & EDGE_EH)); 1859*e4b17023SJohn Marino 1860*e4b17023SJohn Marino for (si = gsi_start_phis (e->dest); !gsi_end_p (si); gsi_next (&si)) 1861*e4b17023SJohn Marino { 1862*e4b17023SJohn Marino edge re; 1863*e4b17023SJohn Marino 1864*e4b17023SJohn Marino phi = gsi_stmt (si); 1865*e4b17023SJohn Marino 1866*e4b17023SJohn Marino /* There shouldn't be any PHI nodes in the ENTRY_BLOCK. */ 1867*e4b17023SJohn Marino gcc_assert (!e->dest->aux); 1868*e4b17023SJohn Marino 1869*e4b17023SJohn Marino gcc_assert ((e->flags & EDGE_EH) 1870*e4b17023SJohn Marino || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi))); 1871*e4b17023SJohn Marino 1872*e4b17023SJohn Marino if (!is_gimple_reg (PHI_RESULT (phi))) 1873*e4b17023SJohn Marino { 1874*e4b17023SJohn Marino mark_sym_for_renaming (SSA_NAME_VAR (PHI_RESULT (phi))); 1875*e4b17023SJohn Marino continue; 1876*e4b17023SJohn Marino } 1877*e4b17023SJohn Marino 1878*e4b17023SJohn Marino re = find_edge (ret_bb, e->dest); 1879*e4b17023SJohn Marino gcc_assert (re); 1880*e4b17023SJohn Marino gcc_assert ((re->flags & (EDGE_EH | EDGE_ABNORMAL)) 1881*e4b17023SJohn Marino == (e->flags & (EDGE_EH | EDGE_ABNORMAL))); 1882*e4b17023SJohn Marino 1883*e4b17023SJohn Marino SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), 1884*e4b17023SJohn Marino USE_FROM_PTR (PHI_ARG_DEF_PTR_FROM_EDGE (phi, re))); 1885*e4b17023SJohn Marino } 1886*e4b17023SJohn Marino } 1887*e4b17023SJohn Marino } 1888*e4b17023SJohn Marino 1889*e4b17023SJohn Marino 1890*e4b17023SJohn Marino /* Copy edges from BB into its copy constructed earlier, scale profile 1891*e4b17023SJohn Marino accordingly. Edges will be taken care of later. Assume aux 1892*e4b17023SJohn Marino pointers to point to the copies of each BB. Return true if any 1893*e4b17023SJohn Marino debug stmts are left after a statement that must end the basic block. */ 1894*e4b17023SJohn Marino 1895*e4b17023SJohn Marino static bool 1896*e4b17023SJohn Marino copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb) 1897*e4b17023SJohn Marino { 1898*e4b17023SJohn Marino basic_block new_bb = (basic_block) bb->aux; 1899*e4b17023SJohn Marino edge_iterator ei; 1900*e4b17023SJohn Marino edge old_edge; 1901*e4b17023SJohn Marino gimple_stmt_iterator si; 1902*e4b17023SJohn Marino int flags; 1903*e4b17023SJohn Marino bool need_debug_cleanup = false; 1904*e4b17023SJohn Marino 1905*e4b17023SJohn Marino /* Use the indices from the original blocks to create edges for the 1906*e4b17023SJohn Marino new ones. */ 1907*e4b17023SJohn Marino FOR_EACH_EDGE (old_edge, ei, bb->succs) 1908*e4b17023SJohn Marino if (!(old_edge->flags & EDGE_EH)) 1909*e4b17023SJohn Marino { 1910*e4b17023SJohn Marino edge new_edge; 1911*e4b17023SJohn Marino 1912*e4b17023SJohn Marino flags = old_edge->flags; 1913*e4b17023SJohn Marino 1914*e4b17023SJohn Marino /* Return edges do get a FALLTHRU flag when the get inlined. */ 1915*e4b17023SJohn Marino if (old_edge->dest->index == EXIT_BLOCK && !old_edge->flags 1916*e4b17023SJohn Marino && old_edge->dest->aux != EXIT_BLOCK_PTR) 1917*e4b17023SJohn Marino flags |= EDGE_FALLTHRU; 1918*e4b17023SJohn Marino new_edge = make_edge (new_bb, (basic_block) old_edge->dest->aux, flags); 1919*e4b17023SJohn Marino new_edge->count = old_edge->count * count_scale / REG_BR_PROB_BASE; 1920*e4b17023SJohn Marino new_edge->probability = old_edge->probability; 1921*e4b17023SJohn Marino } 1922*e4b17023SJohn Marino 1923*e4b17023SJohn Marino if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK) 1924*e4b17023SJohn Marino return false; 1925*e4b17023SJohn Marino 1926*e4b17023SJohn Marino for (si = gsi_start_bb (new_bb); !gsi_end_p (si);) 1927*e4b17023SJohn Marino { 1928*e4b17023SJohn Marino gimple copy_stmt; 1929*e4b17023SJohn Marino bool can_throw, nonlocal_goto; 1930*e4b17023SJohn Marino 1931*e4b17023SJohn Marino copy_stmt = gsi_stmt (si); 1932*e4b17023SJohn Marino if (!is_gimple_debug (copy_stmt)) 1933*e4b17023SJohn Marino { 1934*e4b17023SJohn Marino update_stmt (copy_stmt); 1935*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun)) 1936*e4b17023SJohn Marino mark_symbols_for_renaming (copy_stmt); 1937*e4b17023SJohn Marino } 1938*e4b17023SJohn Marino 1939*e4b17023SJohn Marino /* Do this before the possible split_block. */ 1940*e4b17023SJohn Marino gsi_next (&si); 1941*e4b17023SJohn Marino 1942*e4b17023SJohn Marino /* If this tree could throw an exception, there are two 1943*e4b17023SJohn Marino cases where we need to add abnormal edge(s): the 1944*e4b17023SJohn Marino tree wasn't in a region and there is a "current 1945*e4b17023SJohn Marino region" in the caller; or the original tree had 1946*e4b17023SJohn Marino EH edges. In both cases split the block after the tree, 1947*e4b17023SJohn Marino and add abnormal edge(s) as needed; we need both 1948*e4b17023SJohn Marino those from the callee and the caller. 1949*e4b17023SJohn Marino We check whether the copy can throw, because the const 1950*e4b17023SJohn Marino propagation can change an INDIRECT_REF which throws 1951*e4b17023SJohn Marino into a COMPONENT_REF which doesn't. If the copy 1952*e4b17023SJohn Marino can throw, the original could also throw. */ 1953*e4b17023SJohn Marino can_throw = stmt_can_throw_internal (copy_stmt); 1954*e4b17023SJohn Marino nonlocal_goto = stmt_can_make_abnormal_goto (copy_stmt); 1955*e4b17023SJohn Marino 1956*e4b17023SJohn Marino if (can_throw || nonlocal_goto) 1957*e4b17023SJohn Marino { 1958*e4b17023SJohn Marino if (!gsi_end_p (si)) 1959*e4b17023SJohn Marino { 1960*e4b17023SJohn Marino while (!gsi_end_p (si) && is_gimple_debug (gsi_stmt (si))) 1961*e4b17023SJohn Marino gsi_next (&si); 1962*e4b17023SJohn Marino if (gsi_end_p (si)) 1963*e4b17023SJohn Marino need_debug_cleanup = true; 1964*e4b17023SJohn Marino } 1965*e4b17023SJohn Marino if (!gsi_end_p (si)) 1966*e4b17023SJohn Marino /* Note that bb's predecessor edges aren't necessarily 1967*e4b17023SJohn Marino right at this point; split_block doesn't care. */ 1968*e4b17023SJohn Marino { 1969*e4b17023SJohn Marino edge e = split_block (new_bb, copy_stmt); 1970*e4b17023SJohn Marino 1971*e4b17023SJohn Marino new_bb = e->dest; 1972*e4b17023SJohn Marino new_bb->aux = e->src->aux; 1973*e4b17023SJohn Marino si = gsi_start_bb (new_bb); 1974*e4b17023SJohn Marino } 1975*e4b17023SJohn Marino } 1976*e4b17023SJohn Marino 1977*e4b17023SJohn Marino if (gimple_code (copy_stmt) == GIMPLE_EH_DISPATCH) 1978*e4b17023SJohn Marino make_eh_dispatch_edges (copy_stmt); 1979*e4b17023SJohn Marino else if (can_throw) 1980*e4b17023SJohn Marino make_eh_edges (copy_stmt); 1981*e4b17023SJohn Marino 1982*e4b17023SJohn Marino if (nonlocal_goto) 1983*e4b17023SJohn Marino make_abnormal_goto_edges (gimple_bb (copy_stmt), true); 1984*e4b17023SJohn Marino 1985*e4b17023SJohn Marino if ((can_throw || nonlocal_goto) 1986*e4b17023SJohn Marino && gimple_in_ssa_p (cfun)) 1987*e4b17023SJohn Marino update_ssa_across_abnormal_edges (gimple_bb (copy_stmt), ret_bb, 1988*e4b17023SJohn Marino can_throw, nonlocal_goto); 1989*e4b17023SJohn Marino } 1990*e4b17023SJohn Marino return need_debug_cleanup; 1991*e4b17023SJohn Marino } 1992*e4b17023SJohn Marino 1993*e4b17023SJohn Marino /* Copy the PHIs. All blocks and edges are copied, some blocks 1994*e4b17023SJohn Marino was possibly split and new outgoing EH edges inserted. 1995*e4b17023SJohn Marino BB points to the block of original function and AUX pointers links 1996*e4b17023SJohn Marino the original and newly copied blocks. */ 1997*e4b17023SJohn Marino 1998*e4b17023SJohn Marino static void 1999*e4b17023SJohn Marino copy_phis_for_bb (basic_block bb, copy_body_data *id) 2000*e4b17023SJohn Marino { 2001*e4b17023SJohn Marino basic_block const new_bb = (basic_block) bb->aux; 2002*e4b17023SJohn Marino edge_iterator ei; 2003*e4b17023SJohn Marino gimple phi; 2004*e4b17023SJohn Marino gimple_stmt_iterator si; 2005*e4b17023SJohn Marino edge new_edge; 2006*e4b17023SJohn Marino bool inserted = false; 2007*e4b17023SJohn Marino 2008*e4b17023SJohn Marino for (si = gsi_start (phi_nodes (bb)); !gsi_end_p (si); gsi_next (&si)) 2009*e4b17023SJohn Marino { 2010*e4b17023SJohn Marino tree res, new_res; 2011*e4b17023SJohn Marino gimple new_phi; 2012*e4b17023SJohn Marino 2013*e4b17023SJohn Marino phi = gsi_stmt (si); 2014*e4b17023SJohn Marino res = PHI_RESULT (phi); 2015*e4b17023SJohn Marino new_res = res; 2016*e4b17023SJohn Marino if (is_gimple_reg (res)) 2017*e4b17023SJohn Marino { 2018*e4b17023SJohn Marino walk_tree (&new_res, copy_tree_body_r, id, NULL); 2019*e4b17023SJohn Marino SSA_NAME_DEF_STMT (new_res) 2020*e4b17023SJohn Marino = new_phi = create_phi_node (new_res, new_bb); 2021*e4b17023SJohn Marino FOR_EACH_EDGE (new_edge, ei, new_bb->preds) 2022*e4b17023SJohn Marino { 2023*e4b17023SJohn Marino edge old_edge = find_edge ((basic_block) new_edge->src->aux, bb); 2024*e4b17023SJohn Marino tree arg; 2025*e4b17023SJohn Marino tree new_arg; 2026*e4b17023SJohn Marino tree block = id->block; 2027*e4b17023SJohn Marino edge_iterator ei2; 2028*e4b17023SJohn Marino 2029*e4b17023SJohn Marino /* When doing partial cloning, we allow PHIs on the entry block 2030*e4b17023SJohn Marino as long as all the arguments are the same. Find any input 2031*e4b17023SJohn Marino edge to see argument to copy. */ 2032*e4b17023SJohn Marino if (!old_edge) 2033*e4b17023SJohn Marino FOR_EACH_EDGE (old_edge, ei2, bb->preds) 2034*e4b17023SJohn Marino if (!old_edge->src->aux) 2035*e4b17023SJohn Marino break; 2036*e4b17023SJohn Marino 2037*e4b17023SJohn Marino arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge); 2038*e4b17023SJohn Marino new_arg = arg; 2039*e4b17023SJohn Marino id->block = NULL_TREE; 2040*e4b17023SJohn Marino walk_tree (&new_arg, copy_tree_body_r, id, NULL); 2041*e4b17023SJohn Marino id->block = block; 2042*e4b17023SJohn Marino gcc_assert (new_arg); 2043*e4b17023SJohn Marino /* With return slot optimization we can end up with 2044*e4b17023SJohn Marino non-gimple (foo *)&this->m, fix that here. */ 2045*e4b17023SJohn Marino if (TREE_CODE (new_arg) != SSA_NAME 2046*e4b17023SJohn Marino && TREE_CODE (new_arg) != FUNCTION_DECL 2047*e4b17023SJohn Marino && !is_gimple_val (new_arg)) 2048*e4b17023SJohn Marino { 2049*e4b17023SJohn Marino gimple_seq stmts = NULL; 2050*e4b17023SJohn Marino new_arg = force_gimple_operand (new_arg, &stmts, true, NULL); 2051*e4b17023SJohn Marino gsi_insert_seq_on_edge (new_edge, stmts); 2052*e4b17023SJohn Marino inserted = true; 2053*e4b17023SJohn Marino } 2054*e4b17023SJohn Marino add_phi_arg (new_phi, new_arg, new_edge, 2055*e4b17023SJohn Marino gimple_phi_arg_location_from_edge (phi, old_edge)); 2056*e4b17023SJohn Marino } 2057*e4b17023SJohn Marino } 2058*e4b17023SJohn Marino } 2059*e4b17023SJohn Marino 2060*e4b17023SJohn Marino /* Commit the delayed edge insertions. */ 2061*e4b17023SJohn Marino if (inserted) 2062*e4b17023SJohn Marino FOR_EACH_EDGE (new_edge, ei, new_bb->preds) 2063*e4b17023SJohn Marino gsi_commit_one_edge_insert (new_edge, NULL); 2064*e4b17023SJohn Marino } 2065*e4b17023SJohn Marino 2066*e4b17023SJohn Marino 2067*e4b17023SJohn Marino /* Wrapper for remap_decl so it can be used as a callback. */ 2068*e4b17023SJohn Marino 2069*e4b17023SJohn Marino static tree 2070*e4b17023SJohn Marino remap_decl_1 (tree decl, void *data) 2071*e4b17023SJohn Marino { 2072*e4b17023SJohn Marino return remap_decl (decl, (copy_body_data *) data); 2073*e4b17023SJohn Marino } 2074*e4b17023SJohn Marino 2075*e4b17023SJohn Marino /* Build struct function and associated datastructures for the new clone 2076*e4b17023SJohn Marino NEW_FNDECL to be build. CALLEE_FNDECL is the original */ 2077*e4b17023SJohn Marino 2078*e4b17023SJohn Marino static void 2079*e4b17023SJohn Marino initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) 2080*e4b17023SJohn Marino { 2081*e4b17023SJohn Marino struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl); 2082*e4b17023SJohn Marino gcov_type count_scale; 2083*e4b17023SJohn Marino 2084*e4b17023SJohn Marino if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count) 2085*e4b17023SJohn Marino count_scale = (REG_BR_PROB_BASE * count 2086*e4b17023SJohn Marino / ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count); 2087*e4b17023SJohn Marino else 2088*e4b17023SJohn Marino count_scale = REG_BR_PROB_BASE; 2089*e4b17023SJohn Marino 2090*e4b17023SJohn Marino /* Register specific tree functions. */ 2091*e4b17023SJohn Marino gimple_register_cfg_hooks (); 2092*e4b17023SJohn Marino 2093*e4b17023SJohn Marino /* Get clean struct function. */ 2094*e4b17023SJohn Marino push_struct_function (new_fndecl); 2095*e4b17023SJohn Marino 2096*e4b17023SJohn Marino /* We will rebuild these, so just sanity check that they are empty. */ 2097*e4b17023SJohn Marino gcc_assert (VALUE_HISTOGRAMS (cfun) == NULL); 2098*e4b17023SJohn Marino gcc_assert (cfun->local_decls == NULL); 2099*e4b17023SJohn Marino gcc_assert (cfun->cfg == NULL); 2100*e4b17023SJohn Marino gcc_assert (cfun->decl == new_fndecl); 2101*e4b17023SJohn Marino 2102*e4b17023SJohn Marino /* Copy items we preserve during cloning. */ 2103*e4b17023SJohn Marino cfun->static_chain_decl = src_cfun->static_chain_decl; 2104*e4b17023SJohn Marino cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area; 2105*e4b17023SJohn Marino cfun->function_end_locus = src_cfun->function_end_locus; 2106*e4b17023SJohn Marino cfun->curr_properties = src_cfun->curr_properties; 2107*e4b17023SJohn Marino cfun->last_verified = src_cfun->last_verified; 2108*e4b17023SJohn Marino cfun->va_list_gpr_size = src_cfun->va_list_gpr_size; 2109*e4b17023SJohn Marino cfun->va_list_fpr_size = src_cfun->va_list_fpr_size; 2110*e4b17023SJohn Marino cfun->has_nonlocal_label = src_cfun->has_nonlocal_label; 2111*e4b17023SJohn Marino cfun->stdarg = src_cfun->stdarg; 2112*e4b17023SJohn Marino cfun->after_inlining = src_cfun->after_inlining; 2113*e4b17023SJohn Marino cfun->can_throw_non_call_exceptions 2114*e4b17023SJohn Marino = src_cfun->can_throw_non_call_exceptions; 2115*e4b17023SJohn Marino cfun->returns_struct = src_cfun->returns_struct; 2116*e4b17023SJohn Marino cfun->returns_pcc_struct = src_cfun->returns_pcc_struct; 2117*e4b17023SJohn Marino cfun->after_tree_profile = src_cfun->after_tree_profile; 2118*e4b17023SJohn Marino 2119*e4b17023SJohn Marino init_empty_tree_cfg (); 2120*e4b17023SJohn Marino 2121*e4b17023SJohn Marino profile_status_for_function (cfun) = profile_status_for_function (src_cfun); 2122*e4b17023SJohn Marino ENTRY_BLOCK_PTR->count = 2123*e4b17023SJohn Marino (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count * count_scale / 2124*e4b17023SJohn Marino REG_BR_PROB_BASE); 2125*e4b17023SJohn Marino ENTRY_BLOCK_PTR->frequency 2126*e4b17023SJohn Marino = ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->frequency; 2127*e4b17023SJohn Marino EXIT_BLOCK_PTR->count = 2128*e4b17023SJohn Marino (EXIT_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count * count_scale / 2129*e4b17023SJohn Marino REG_BR_PROB_BASE); 2130*e4b17023SJohn Marino EXIT_BLOCK_PTR->frequency = 2131*e4b17023SJohn Marino EXIT_BLOCK_PTR_FOR_FUNCTION (src_cfun)->frequency; 2132*e4b17023SJohn Marino if (src_cfun->eh) 2133*e4b17023SJohn Marino init_eh_for_function (); 2134*e4b17023SJohn Marino 2135*e4b17023SJohn Marino if (src_cfun->gimple_df) 2136*e4b17023SJohn Marino { 2137*e4b17023SJohn Marino init_tree_ssa (cfun); 2138*e4b17023SJohn Marino cfun->gimple_df->in_ssa_p = true; 2139*e4b17023SJohn Marino init_ssa_operands (); 2140*e4b17023SJohn Marino } 2141*e4b17023SJohn Marino pop_cfun (); 2142*e4b17023SJohn Marino } 2143*e4b17023SJohn Marino 2144*e4b17023SJohn Marino /* Helper function for copy_cfg_body. Move debug stmts from the end 2145*e4b17023SJohn Marino of NEW_BB to the beginning of successor basic blocks when needed. If the 2146*e4b17023SJohn Marino successor has multiple predecessors, reset them, otherwise keep 2147*e4b17023SJohn Marino their value. */ 2148*e4b17023SJohn Marino 2149*e4b17023SJohn Marino static void 2150*e4b17023SJohn Marino maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb) 2151*e4b17023SJohn Marino { 2152*e4b17023SJohn Marino edge e; 2153*e4b17023SJohn Marino edge_iterator ei; 2154*e4b17023SJohn Marino gimple_stmt_iterator si = gsi_last_nondebug_bb (new_bb); 2155*e4b17023SJohn Marino 2156*e4b17023SJohn Marino if (gsi_end_p (si) 2157*e4b17023SJohn Marino || gsi_one_before_end_p (si) 2158*e4b17023SJohn Marino || !(stmt_can_throw_internal (gsi_stmt (si)) 2159*e4b17023SJohn Marino || stmt_can_make_abnormal_goto (gsi_stmt (si)))) 2160*e4b17023SJohn Marino return; 2161*e4b17023SJohn Marino 2162*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, new_bb->succs) 2163*e4b17023SJohn Marino { 2164*e4b17023SJohn Marino gimple_stmt_iterator ssi = gsi_last_bb (new_bb); 2165*e4b17023SJohn Marino gimple_stmt_iterator dsi = gsi_after_labels (e->dest); 2166*e4b17023SJohn Marino while (is_gimple_debug (gsi_stmt (ssi))) 2167*e4b17023SJohn Marino { 2168*e4b17023SJohn Marino gimple stmt = gsi_stmt (ssi), new_stmt; 2169*e4b17023SJohn Marino tree var; 2170*e4b17023SJohn Marino tree value; 2171*e4b17023SJohn Marino 2172*e4b17023SJohn Marino /* For the last edge move the debug stmts instead of copying 2173*e4b17023SJohn Marino them. */ 2174*e4b17023SJohn Marino if (ei_one_before_end_p (ei)) 2175*e4b17023SJohn Marino { 2176*e4b17023SJohn Marino si = ssi; 2177*e4b17023SJohn Marino gsi_prev (&ssi); 2178*e4b17023SJohn Marino if (!single_pred_p (e->dest) && gimple_debug_bind_p (stmt)) 2179*e4b17023SJohn Marino gimple_debug_bind_reset_value (stmt); 2180*e4b17023SJohn Marino gsi_remove (&si, false); 2181*e4b17023SJohn Marino gsi_insert_before (&dsi, stmt, GSI_SAME_STMT); 2182*e4b17023SJohn Marino continue; 2183*e4b17023SJohn Marino } 2184*e4b17023SJohn Marino 2185*e4b17023SJohn Marino if (gimple_debug_bind_p (stmt)) 2186*e4b17023SJohn Marino { 2187*e4b17023SJohn Marino var = gimple_debug_bind_get_var (stmt); 2188*e4b17023SJohn Marino if (single_pred_p (e->dest)) 2189*e4b17023SJohn Marino { 2190*e4b17023SJohn Marino value = gimple_debug_bind_get_value (stmt); 2191*e4b17023SJohn Marino value = unshare_expr (value); 2192*e4b17023SJohn Marino } 2193*e4b17023SJohn Marino else 2194*e4b17023SJohn Marino value = NULL_TREE; 2195*e4b17023SJohn Marino new_stmt = gimple_build_debug_bind (var, value, stmt); 2196*e4b17023SJohn Marino } 2197*e4b17023SJohn Marino else if (gimple_debug_source_bind_p (stmt)) 2198*e4b17023SJohn Marino { 2199*e4b17023SJohn Marino var = gimple_debug_source_bind_get_var (stmt); 2200*e4b17023SJohn Marino value = gimple_debug_source_bind_get_value (stmt); 2201*e4b17023SJohn Marino new_stmt = gimple_build_debug_source_bind (var, value, stmt); 2202*e4b17023SJohn Marino } 2203*e4b17023SJohn Marino else 2204*e4b17023SJohn Marino gcc_unreachable (); 2205*e4b17023SJohn Marino gsi_insert_before (&dsi, new_stmt, GSI_SAME_STMT); 2206*e4b17023SJohn Marino VEC_safe_push (gimple, heap, id->debug_stmts, new_stmt); 2207*e4b17023SJohn Marino gsi_prev (&ssi); 2208*e4b17023SJohn Marino } 2209*e4b17023SJohn Marino } 2210*e4b17023SJohn Marino } 2211*e4b17023SJohn Marino 2212*e4b17023SJohn Marino /* Make a copy of the body of FN so that it can be inserted inline in 2213*e4b17023SJohn Marino another function. Walks FN via CFG, returns new fndecl. */ 2214*e4b17023SJohn Marino 2215*e4b17023SJohn Marino static tree 2216*e4b17023SJohn Marino copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, 2217*e4b17023SJohn Marino basic_block entry_block_map, basic_block exit_block_map, 2218*e4b17023SJohn Marino bitmap blocks_to_copy, basic_block new_entry) 2219*e4b17023SJohn Marino { 2220*e4b17023SJohn Marino tree callee_fndecl = id->src_fn; 2221*e4b17023SJohn Marino /* Original cfun for the callee, doesn't change. */ 2222*e4b17023SJohn Marino struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl); 2223*e4b17023SJohn Marino struct function *cfun_to_copy; 2224*e4b17023SJohn Marino basic_block bb; 2225*e4b17023SJohn Marino tree new_fndecl = NULL; 2226*e4b17023SJohn Marino bool need_debug_cleanup = false; 2227*e4b17023SJohn Marino gcov_type count_scale; 2228*e4b17023SJohn Marino int last; 2229*e4b17023SJohn Marino int incoming_frequency = 0; 2230*e4b17023SJohn Marino gcov_type incoming_count = 0; 2231*e4b17023SJohn Marino 2232*e4b17023SJohn Marino if (ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count) 2233*e4b17023SJohn Marino count_scale = (REG_BR_PROB_BASE * count 2234*e4b17023SJohn Marino / ENTRY_BLOCK_PTR_FOR_FUNCTION (src_cfun)->count); 2235*e4b17023SJohn Marino else 2236*e4b17023SJohn Marino count_scale = REG_BR_PROB_BASE; 2237*e4b17023SJohn Marino 2238*e4b17023SJohn Marino /* Register specific tree functions. */ 2239*e4b17023SJohn Marino gimple_register_cfg_hooks (); 2240*e4b17023SJohn Marino 2241*e4b17023SJohn Marino /* If we are inlining just region of the function, make sure to connect new entry 2242*e4b17023SJohn Marino to ENTRY_BLOCK_PTR. Since new entry can be part of loop, we must compute 2243*e4b17023SJohn Marino frequency and probability of ENTRY_BLOCK_PTR based on the frequencies and 2244*e4b17023SJohn Marino probabilities of edges incoming from nonduplicated region. */ 2245*e4b17023SJohn Marino if (new_entry) 2246*e4b17023SJohn Marino { 2247*e4b17023SJohn Marino edge e; 2248*e4b17023SJohn Marino edge_iterator ei; 2249*e4b17023SJohn Marino 2250*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, new_entry->preds) 2251*e4b17023SJohn Marino if (!e->src->aux) 2252*e4b17023SJohn Marino { 2253*e4b17023SJohn Marino incoming_frequency += EDGE_FREQUENCY (e); 2254*e4b17023SJohn Marino incoming_count += e->count; 2255*e4b17023SJohn Marino } 2256*e4b17023SJohn Marino incoming_count = incoming_count * count_scale / REG_BR_PROB_BASE; 2257*e4b17023SJohn Marino incoming_frequency 2258*e4b17023SJohn Marino = incoming_frequency * frequency_scale / REG_BR_PROB_BASE; 2259*e4b17023SJohn Marino ENTRY_BLOCK_PTR->count = incoming_count; 2260*e4b17023SJohn Marino ENTRY_BLOCK_PTR->frequency = incoming_frequency; 2261*e4b17023SJohn Marino } 2262*e4b17023SJohn Marino 2263*e4b17023SJohn Marino /* Must have a CFG here at this point. */ 2264*e4b17023SJohn Marino gcc_assert (ENTRY_BLOCK_PTR_FOR_FUNCTION 2265*e4b17023SJohn Marino (DECL_STRUCT_FUNCTION (callee_fndecl))); 2266*e4b17023SJohn Marino 2267*e4b17023SJohn Marino cfun_to_copy = id->src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl); 2268*e4b17023SJohn Marino 2269*e4b17023SJohn Marino ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy)->aux = entry_block_map; 2270*e4b17023SJohn Marino EXIT_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy)->aux = exit_block_map; 2271*e4b17023SJohn Marino entry_block_map->aux = ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy); 2272*e4b17023SJohn Marino exit_block_map->aux = EXIT_BLOCK_PTR_FOR_FUNCTION (cfun_to_copy); 2273*e4b17023SJohn Marino 2274*e4b17023SJohn Marino /* Duplicate any exception-handling regions. */ 2275*e4b17023SJohn Marino if (cfun->eh) 2276*e4b17023SJohn Marino id->eh_map = duplicate_eh_regions (cfun_to_copy, NULL, id->eh_lp_nr, 2277*e4b17023SJohn Marino remap_decl_1, id); 2278*e4b17023SJohn Marino 2279*e4b17023SJohn Marino /* Use aux pointers to map the original blocks to copy. */ 2280*e4b17023SJohn Marino FOR_EACH_BB_FN (bb, cfun_to_copy) 2281*e4b17023SJohn Marino if (!blocks_to_copy || bitmap_bit_p (blocks_to_copy, bb->index)) 2282*e4b17023SJohn Marino { 2283*e4b17023SJohn Marino basic_block new_bb = copy_bb (id, bb, frequency_scale, count_scale); 2284*e4b17023SJohn Marino bb->aux = new_bb; 2285*e4b17023SJohn Marino new_bb->aux = bb; 2286*e4b17023SJohn Marino } 2287*e4b17023SJohn Marino 2288*e4b17023SJohn Marino last = last_basic_block; 2289*e4b17023SJohn Marino 2290*e4b17023SJohn Marino /* Now that we've duplicated the blocks, duplicate their edges. */ 2291*e4b17023SJohn Marino FOR_ALL_BB_FN (bb, cfun_to_copy) 2292*e4b17023SJohn Marino if (!blocks_to_copy 2293*e4b17023SJohn Marino || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) 2294*e4b17023SJohn Marino need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map); 2295*e4b17023SJohn Marino 2296*e4b17023SJohn Marino if (new_entry) 2297*e4b17023SJohn Marino { 2298*e4b17023SJohn Marino edge e = make_edge (entry_block_map, (basic_block)new_entry->aux, EDGE_FALLTHRU); 2299*e4b17023SJohn Marino e->probability = REG_BR_PROB_BASE; 2300*e4b17023SJohn Marino e->count = incoming_count; 2301*e4b17023SJohn Marino } 2302*e4b17023SJohn Marino 2303*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun)) 2304*e4b17023SJohn Marino FOR_ALL_BB_FN (bb, cfun_to_copy) 2305*e4b17023SJohn Marino if (!blocks_to_copy 2306*e4b17023SJohn Marino || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) 2307*e4b17023SJohn Marino copy_phis_for_bb (bb, id); 2308*e4b17023SJohn Marino 2309*e4b17023SJohn Marino FOR_ALL_BB_FN (bb, cfun_to_copy) 2310*e4b17023SJohn Marino if (bb->aux) 2311*e4b17023SJohn Marino { 2312*e4b17023SJohn Marino if (need_debug_cleanup 2313*e4b17023SJohn Marino && bb->index != ENTRY_BLOCK 2314*e4b17023SJohn Marino && bb->index != EXIT_BLOCK) 2315*e4b17023SJohn Marino maybe_move_debug_stmts_to_successors (id, (basic_block) bb->aux); 2316*e4b17023SJohn Marino ((basic_block)bb->aux)->aux = NULL; 2317*e4b17023SJohn Marino bb->aux = NULL; 2318*e4b17023SJohn Marino } 2319*e4b17023SJohn Marino 2320*e4b17023SJohn Marino /* Zero out AUX fields of newly created block during EH edge 2321*e4b17023SJohn Marino insertion. */ 2322*e4b17023SJohn Marino for (; last < last_basic_block; last++) 2323*e4b17023SJohn Marino { 2324*e4b17023SJohn Marino if (need_debug_cleanup) 2325*e4b17023SJohn Marino maybe_move_debug_stmts_to_successors (id, BASIC_BLOCK (last)); 2326*e4b17023SJohn Marino BASIC_BLOCK (last)->aux = NULL; 2327*e4b17023SJohn Marino } 2328*e4b17023SJohn Marino entry_block_map->aux = NULL; 2329*e4b17023SJohn Marino exit_block_map->aux = NULL; 2330*e4b17023SJohn Marino 2331*e4b17023SJohn Marino if (id->eh_map) 2332*e4b17023SJohn Marino { 2333*e4b17023SJohn Marino pointer_map_destroy (id->eh_map); 2334*e4b17023SJohn Marino id->eh_map = NULL; 2335*e4b17023SJohn Marino } 2336*e4b17023SJohn Marino 2337*e4b17023SJohn Marino return new_fndecl; 2338*e4b17023SJohn Marino } 2339*e4b17023SJohn Marino 2340*e4b17023SJohn Marino /* Copy the debug STMT using ID. We deal with these statements in a 2341*e4b17023SJohn Marino special way: if any variable in their VALUE expression wasn't 2342*e4b17023SJohn Marino remapped yet, we won't remap it, because that would get decl uids 2343*e4b17023SJohn Marino out of sync, causing codegen differences between -g and -g0. If 2344*e4b17023SJohn Marino this arises, we drop the VALUE expression altogether. */ 2345*e4b17023SJohn Marino 2346*e4b17023SJohn Marino static void 2347*e4b17023SJohn Marino copy_debug_stmt (gimple stmt, copy_body_data *id) 2348*e4b17023SJohn Marino { 2349*e4b17023SJohn Marino tree t, *n; 2350*e4b17023SJohn Marino struct walk_stmt_info wi; 2351*e4b17023SJohn Marino 2352*e4b17023SJohn Marino t = id->block; 2353*e4b17023SJohn Marino if (gimple_block (stmt)) 2354*e4b17023SJohn Marino { 2355*e4b17023SJohn Marino n = (tree *) pointer_map_contains (id->decl_map, gimple_block (stmt)); 2356*e4b17023SJohn Marino if (n) 2357*e4b17023SJohn Marino t = *n; 2358*e4b17023SJohn Marino } 2359*e4b17023SJohn Marino gimple_set_block (stmt, t); 2360*e4b17023SJohn Marino 2361*e4b17023SJohn Marino /* Remap all the operands in COPY. */ 2362*e4b17023SJohn Marino memset (&wi, 0, sizeof (wi)); 2363*e4b17023SJohn Marino wi.info = id; 2364*e4b17023SJohn Marino 2365*e4b17023SJohn Marino processing_debug_stmt = 1; 2366*e4b17023SJohn Marino 2367*e4b17023SJohn Marino if (gimple_debug_source_bind_p (stmt)) 2368*e4b17023SJohn Marino t = gimple_debug_source_bind_get_var (stmt); 2369*e4b17023SJohn Marino else 2370*e4b17023SJohn Marino t = gimple_debug_bind_get_var (stmt); 2371*e4b17023SJohn Marino 2372*e4b17023SJohn Marino if (TREE_CODE (t) == PARM_DECL && id->debug_map 2373*e4b17023SJohn Marino && (n = (tree *) pointer_map_contains (id->debug_map, t))) 2374*e4b17023SJohn Marino { 2375*e4b17023SJohn Marino gcc_assert (TREE_CODE (*n) == VAR_DECL); 2376*e4b17023SJohn Marino t = *n; 2377*e4b17023SJohn Marino } 2378*e4b17023SJohn Marino else if (TREE_CODE (t) == VAR_DECL 2379*e4b17023SJohn Marino && !TREE_STATIC (t) 2380*e4b17023SJohn Marino && gimple_in_ssa_p (cfun) 2381*e4b17023SJohn Marino && !pointer_map_contains (id->decl_map, t) 2382*e4b17023SJohn Marino && !var_ann (t)) 2383*e4b17023SJohn Marino /* T is a non-localized variable. */; 2384*e4b17023SJohn Marino else 2385*e4b17023SJohn Marino walk_tree (&t, remap_gimple_op_r, &wi, NULL); 2386*e4b17023SJohn Marino 2387*e4b17023SJohn Marino if (gimple_debug_bind_p (stmt)) 2388*e4b17023SJohn Marino { 2389*e4b17023SJohn Marino gimple_debug_bind_set_var (stmt, t); 2390*e4b17023SJohn Marino 2391*e4b17023SJohn Marino if (gimple_debug_bind_has_value_p (stmt)) 2392*e4b17023SJohn Marino walk_tree (gimple_debug_bind_get_value_ptr (stmt), 2393*e4b17023SJohn Marino remap_gimple_op_r, &wi, NULL); 2394*e4b17023SJohn Marino 2395*e4b17023SJohn Marino /* Punt if any decl couldn't be remapped. */ 2396*e4b17023SJohn Marino if (processing_debug_stmt < 0) 2397*e4b17023SJohn Marino gimple_debug_bind_reset_value (stmt); 2398*e4b17023SJohn Marino } 2399*e4b17023SJohn Marino else if (gimple_debug_source_bind_p (stmt)) 2400*e4b17023SJohn Marino { 2401*e4b17023SJohn Marino gimple_debug_source_bind_set_var (stmt, t); 2402*e4b17023SJohn Marino walk_tree (gimple_debug_source_bind_get_value_ptr (stmt), 2403*e4b17023SJohn Marino remap_gimple_op_r, &wi, NULL); 2404*e4b17023SJohn Marino } 2405*e4b17023SJohn Marino 2406*e4b17023SJohn Marino processing_debug_stmt = 0; 2407*e4b17023SJohn Marino 2408*e4b17023SJohn Marino update_stmt (stmt); 2409*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun)) 2410*e4b17023SJohn Marino mark_symbols_for_renaming (stmt); 2411*e4b17023SJohn Marino } 2412*e4b17023SJohn Marino 2413*e4b17023SJohn Marino /* Process deferred debug stmts. In order to give values better odds 2414*e4b17023SJohn Marino of being successfully remapped, we delay the processing of debug 2415*e4b17023SJohn Marino stmts until all other stmts that might require remapping are 2416*e4b17023SJohn Marino processed. */ 2417*e4b17023SJohn Marino 2418*e4b17023SJohn Marino static void 2419*e4b17023SJohn Marino copy_debug_stmts (copy_body_data *id) 2420*e4b17023SJohn Marino { 2421*e4b17023SJohn Marino size_t i; 2422*e4b17023SJohn Marino gimple stmt; 2423*e4b17023SJohn Marino 2424*e4b17023SJohn Marino if (!id->debug_stmts) 2425*e4b17023SJohn Marino return; 2426*e4b17023SJohn Marino 2427*e4b17023SJohn Marino FOR_EACH_VEC_ELT (gimple, id->debug_stmts, i, stmt) 2428*e4b17023SJohn Marino copy_debug_stmt (stmt, id); 2429*e4b17023SJohn Marino 2430*e4b17023SJohn Marino VEC_free (gimple, heap, id->debug_stmts); 2431*e4b17023SJohn Marino } 2432*e4b17023SJohn Marino 2433*e4b17023SJohn Marino /* Make a copy of the body of SRC_FN so that it can be inserted inline in 2434*e4b17023SJohn Marino another function. */ 2435*e4b17023SJohn Marino 2436*e4b17023SJohn Marino static tree 2437*e4b17023SJohn Marino copy_tree_body (copy_body_data *id) 2438*e4b17023SJohn Marino { 2439*e4b17023SJohn Marino tree fndecl = id->src_fn; 2440*e4b17023SJohn Marino tree body = DECL_SAVED_TREE (fndecl); 2441*e4b17023SJohn Marino 2442*e4b17023SJohn Marino walk_tree (&body, copy_tree_body_r, id, NULL); 2443*e4b17023SJohn Marino 2444*e4b17023SJohn Marino return body; 2445*e4b17023SJohn Marino } 2446*e4b17023SJohn Marino 2447*e4b17023SJohn Marino /* Make a copy of the body of FN so that it can be inserted inline in 2448*e4b17023SJohn Marino another function. */ 2449*e4b17023SJohn Marino 2450*e4b17023SJohn Marino static tree 2451*e4b17023SJohn Marino copy_body (copy_body_data *id, gcov_type count, int frequency_scale, 2452*e4b17023SJohn Marino basic_block entry_block_map, basic_block exit_block_map, 2453*e4b17023SJohn Marino bitmap blocks_to_copy, basic_block new_entry) 2454*e4b17023SJohn Marino { 2455*e4b17023SJohn Marino tree fndecl = id->src_fn; 2456*e4b17023SJohn Marino tree body; 2457*e4b17023SJohn Marino 2458*e4b17023SJohn Marino /* If this body has a CFG, walk CFG and copy. */ 2459*e4b17023SJohn Marino gcc_assert (ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (fndecl))); 2460*e4b17023SJohn Marino body = copy_cfg_body (id, count, frequency_scale, entry_block_map, exit_block_map, 2461*e4b17023SJohn Marino blocks_to_copy, new_entry); 2462*e4b17023SJohn Marino copy_debug_stmts (id); 2463*e4b17023SJohn Marino 2464*e4b17023SJohn Marino return body; 2465*e4b17023SJohn Marino } 2466*e4b17023SJohn Marino 2467*e4b17023SJohn Marino /* Return true if VALUE is an ADDR_EXPR of an automatic variable 2468*e4b17023SJohn Marino defined in function FN, or of a data member thereof. */ 2469*e4b17023SJohn Marino 2470*e4b17023SJohn Marino static bool 2471*e4b17023SJohn Marino self_inlining_addr_expr (tree value, tree fn) 2472*e4b17023SJohn Marino { 2473*e4b17023SJohn Marino tree var; 2474*e4b17023SJohn Marino 2475*e4b17023SJohn Marino if (TREE_CODE (value) != ADDR_EXPR) 2476*e4b17023SJohn Marino return false; 2477*e4b17023SJohn Marino 2478*e4b17023SJohn Marino var = get_base_address (TREE_OPERAND (value, 0)); 2479*e4b17023SJohn Marino 2480*e4b17023SJohn Marino return var && auto_var_in_fn_p (var, fn); 2481*e4b17023SJohn Marino } 2482*e4b17023SJohn Marino 2483*e4b17023SJohn Marino /* Append to BB a debug annotation that binds VAR to VALUE, inheriting 2484*e4b17023SJohn Marino lexical block and line number information from base_stmt, if given, 2485*e4b17023SJohn Marino or from the last stmt of the block otherwise. */ 2486*e4b17023SJohn Marino 2487*e4b17023SJohn Marino static gimple 2488*e4b17023SJohn Marino insert_init_debug_bind (copy_body_data *id, 2489*e4b17023SJohn Marino basic_block bb, tree var, tree value, 2490*e4b17023SJohn Marino gimple base_stmt) 2491*e4b17023SJohn Marino { 2492*e4b17023SJohn Marino gimple note; 2493*e4b17023SJohn Marino gimple_stmt_iterator gsi; 2494*e4b17023SJohn Marino tree tracked_var; 2495*e4b17023SJohn Marino 2496*e4b17023SJohn Marino if (!gimple_in_ssa_p (id->src_cfun)) 2497*e4b17023SJohn Marino return NULL; 2498*e4b17023SJohn Marino 2499*e4b17023SJohn Marino if (!MAY_HAVE_DEBUG_STMTS) 2500*e4b17023SJohn Marino return NULL; 2501*e4b17023SJohn Marino 2502*e4b17023SJohn Marino tracked_var = target_for_debug_bind (var); 2503*e4b17023SJohn Marino if (!tracked_var) 2504*e4b17023SJohn Marino return NULL; 2505*e4b17023SJohn Marino 2506*e4b17023SJohn Marino if (bb) 2507*e4b17023SJohn Marino { 2508*e4b17023SJohn Marino gsi = gsi_last_bb (bb); 2509*e4b17023SJohn Marino if (!base_stmt && !gsi_end_p (gsi)) 2510*e4b17023SJohn Marino base_stmt = gsi_stmt (gsi); 2511*e4b17023SJohn Marino } 2512*e4b17023SJohn Marino 2513*e4b17023SJohn Marino note = gimple_build_debug_bind (tracked_var, value, base_stmt); 2514*e4b17023SJohn Marino 2515*e4b17023SJohn Marino if (bb) 2516*e4b17023SJohn Marino { 2517*e4b17023SJohn Marino if (!gsi_end_p (gsi)) 2518*e4b17023SJohn Marino gsi_insert_after (&gsi, note, GSI_SAME_STMT); 2519*e4b17023SJohn Marino else 2520*e4b17023SJohn Marino gsi_insert_before (&gsi, note, GSI_SAME_STMT); 2521*e4b17023SJohn Marino } 2522*e4b17023SJohn Marino 2523*e4b17023SJohn Marino return note; 2524*e4b17023SJohn Marino } 2525*e4b17023SJohn Marino 2526*e4b17023SJohn Marino static void 2527*e4b17023SJohn Marino insert_init_stmt (copy_body_data *id, basic_block bb, gimple init_stmt) 2528*e4b17023SJohn Marino { 2529*e4b17023SJohn Marino /* If VAR represents a zero-sized variable, it's possible that the 2530*e4b17023SJohn Marino assignment statement may result in no gimple statements. */ 2531*e4b17023SJohn Marino if (init_stmt) 2532*e4b17023SJohn Marino { 2533*e4b17023SJohn Marino gimple_stmt_iterator si = gsi_last_bb (bb); 2534*e4b17023SJohn Marino 2535*e4b17023SJohn Marino /* We can end up with init statements that store to a non-register 2536*e4b17023SJohn Marino from a rhs with a conversion. Handle that here by forcing the 2537*e4b17023SJohn Marino rhs into a temporary. gimple_regimplify_operands is not 2538*e4b17023SJohn Marino prepared to do this for us. */ 2539*e4b17023SJohn Marino if (!is_gimple_debug (init_stmt) 2540*e4b17023SJohn Marino && !is_gimple_reg (gimple_assign_lhs (init_stmt)) 2541*e4b17023SJohn Marino && is_gimple_reg_type (TREE_TYPE (gimple_assign_lhs (init_stmt))) 2542*e4b17023SJohn Marino && gimple_assign_rhs_class (init_stmt) == GIMPLE_UNARY_RHS) 2543*e4b17023SJohn Marino { 2544*e4b17023SJohn Marino tree rhs = build1 (gimple_assign_rhs_code (init_stmt), 2545*e4b17023SJohn Marino gimple_expr_type (init_stmt), 2546*e4b17023SJohn Marino gimple_assign_rhs1 (init_stmt)); 2547*e4b17023SJohn Marino rhs = force_gimple_operand_gsi (&si, rhs, true, NULL_TREE, false, 2548*e4b17023SJohn Marino GSI_NEW_STMT); 2549*e4b17023SJohn Marino gimple_assign_set_rhs_code (init_stmt, TREE_CODE (rhs)); 2550*e4b17023SJohn Marino gimple_assign_set_rhs1 (init_stmt, rhs); 2551*e4b17023SJohn Marino } 2552*e4b17023SJohn Marino gsi_insert_after (&si, init_stmt, GSI_NEW_STMT); 2553*e4b17023SJohn Marino gimple_regimplify_operands (init_stmt, &si); 2554*e4b17023SJohn Marino mark_symbols_for_renaming (init_stmt); 2555*e4b17023SJohn Marino 2556*e4b17023SJohn Marino if (!is_gimple_debug (init_stmt) && MAY_HAVE_DEBUG_STMTS) 2557*e4b17023SJohn Marino { 2558*e4b17023SJohn Marino tree var, def = gimple_assign_lhs (init_stmt); 2559*e4b17023SJohn Marino 2560*e4b17023SJohn Marino if (TREE_CODE (def) == SSA_NAME) 2561*e4b17023SJohn Marino var = SSA_NAME_VAR (def); 2562*e4b17023SJohn Marino else 2563*e4b17023SJohn Marino var = def; 2564*e4b17023SJohn Marino 2565*e4b17023SJohn Marino insert_init_debug_bind (id, bb, var, def, init_stmt); 2566*e4b17023SJohn Marino } 2567*e4b17023SJohn Marino } 2568*e4b17023SJohn Marino } 2569*e4b17023SJohn Marino 2570*e4b17023SJohn Marino /* Initialize parameter P with VALUE. If needed, produce init statement 2571*e4b17023SJohn Marino at the end of BB. When BB is NULL, we return init statement to be 2572*e4b17023SJohn Marino output later. */ 2573*e4b17023SJohn Marino static gimple 2574*e4b17023SJohn Marino setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn, 2575*e4b17023SJohn Marino basic_block bb, tree *vars) 2576*e4b17023SJohn Marino { 2577*e4b17023SJohn Marino gimple init_stmt = NULL; 2578*e4b17023SJohn Marino tree var; 2579*e4b17023SJohn Marino tree rhs = value; 2580*e4b17023SJohn Marino tree def = (gimple_in_ssa_p (cfun) 2581*e4b17023SJohn Marino ? gimple_default_def (id->src_cfun, p) : NULL); 2582*e4b17023SJohn Marino 2583*e4b17023SJohn Marino if (value 2584*e4b17023SJohn Marino && value != error_mark_node 2585*e4b17023SJohn Marino && !useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value))) 2586*e4b17023SJohn Marino { 2587*e4b17023SJohn Marino /* If we can match up types by promotion/demotion do so. */ 2588*e4b17023SJohn Marino if (fold_convertible_p (TREE_TYPE (p), value)) 2589*e4b17023SJohn Marino rhs = fold_convert (TREE_TYPE (p), value); 2590*e4b17023SJohn Marino else 2591*e4b17023SJohn Marino { 2592*e4b17023SJohn Marino /* ??? For valid programs we should not end up here. 2593*e4b17023SJohn Marino Still if we end up with truly mismatched types here, fall back 2594*e4b17023SJohn Marino to using a VIEW_CONVERT_EXPR or a literal zero to not leak invalid 2595*e4b17023SJohn Marino GIMPLE to the following passes. */ 2596*e4b17023SJohn Marino if (!is_gimple_reg_type (TREE_TYPE (value)) 2597*e4b17023SJohn Marino || TYPE_SIZE (TREE_TYPE (p)) == TYPE_SIZE (TREE_TYPE (value))) 2598*e4b17023SJohn Marino rhs = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (p), value); 2599*e4b17023SJohn Marino else 2600*e4b17023SJohn Marino rhs = build_zero_cst (TREE_TYPE (p)); 2601*e4b17023SJohn Marino } 2602*e4b17023SJohn Marino } 2603*e4b17023SJohn Marino 2604*e4b17023SJohn Marino /* Make an equivalent VAR_DECL. Note that we must NOT remap the type 2605*e4b17023SJohn Marino here since the type of this decl must be visible to the calling 2606*e4b17023SJohn Marino function. */ 2607*e4b17023SJohn Marino var = copy_decl_to_var (p, id); 2608*e4b17023SJohn Marino 2609*e4b17023SJohn Marino /* We're actually using the newly-created var. */ 2610*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun) && TREE_CODE (var) == VAR_DECL) 2611*e4b17023SJohn Marino add_referenced_var (var); 2612*e4b17023SJohn Marino 2613*e4b17023SJohn Marino /* Declare this new variable. */ 2614*e4b17023SJohn Marino DECL_CHAIN (var) = *vars; 2615*e4b17023SJohn Marino *vars = var; 2616*e4b17023SJohn Marino 2617*e4b17023SJohn Marino /* Make gimplifier happy about this variable. */ 2618*e4b17023SJohn Marino DECL_SEEN_IN_BIND_EXPR_P (var) = 1; 2619*e4b17023SJohn Marino 2620*e4b17023SJohn Marino /* We are eventually using the value - make sure all variables 2621*e4b17023SJohn Marino referenced therein are properly recorded. */ 2622*e4b17023SJohn Marino if (value 2623*e4b17023SJohn Marino && gimple_in_ssa_p (cfun) 2624*e4b17023SJohn Marino && TREE_CODE (value) == ADDR_EXPR) 2625*e4b17023SJohn Marino { 2626*e4b17023SJohn Marino tree base = get_base_address (TREE_OPERAND (value, 0)); 2627*e4b17023SJohn Marino if (base && TREE_CODE (base) == VAR_DECL) 2628*e4b17023SJohn Marino add_referenced_var (base); 2629*e4b17023SJohn Marino } 2630*e4b17023SJohn Marino 2631*e4b17023SJohn Marino /* If the parameter is never assigned to, has no SSA_NAMEs created, 2632*e4b17023SJohn Marino we would not need to create a new variable here at all, if it 2633*e4b17023SJohn Marino weren't for debug info. Still, we can just use the argument 2634*e4b17023SJohn Marino value. */ 2635*e4b17023SJohn Marino if (TREE_READONLY (p) 2636*e4b17023SJohn Marino && !TREE_ADDRESSABLE (p) 2637*e4b17023SJohn Marino && value && !TREE_SIDE_EFFECTS (value) 2638*e4b17023SJohn Marino && !def) 2639*e4b17023SJohn Marino { 2640*e4b17023SJohn Marino /* We may produce non-gimple trees by adding NOPs or introduce 2641*e4b17023SJohn Marino invalid sharing when operand is not really constant. 2642*e4b17023SJohn Marino It is not big deal to prohibit constant propagation here as 2643*e4b17023SJohn Marino we will constant propagate in DOM1 pass anyway. */ 2644*e4b17023SJohn Marino if (is_gimple_min_invariant (value) 2645*e4b17023SJohn Marino && useless_type_conversion_p (TREE_TYPE (p), 2646*e4b17023SJohn Marino TREE_TYPE (value)) 2647*e4b17023SJohn Marino /* We have to be very careful about ADDR_EXPR. Make sure 2648*e4b17023SJohn Marino the base variable isn't a local variable of the inlined 2649*e4b17023SJohn Marino function, e.g., when doing recursive inlining, direct or 2650*e4b17023SJohn Marino mutually-recursive or whatever, which is why we don't 2651*e4b17023SJohn Marino just test whether fn == current_function_decl. */ 2652*e4b17023SJohn Marino && ! self_inlining_addr_expr (value, fn)) 2653*e4b17023SJohn Marino { 2654*e4b17023SJohn Marino insert_decl_map (id, p, value); 2655*e4b17023SJohn Marino insert_debug_decl_map (id, p, var); 2656*e4b17023SJohn Marino return insert_init_debug_bind (id, bb, var, value, NULL); 2657*e4b17023SJohn Marino } 2658*e4b17023SJohn Marino } 2659*e4b17023SJohn Marino 2660*e4b17023SJohn Marino /* Register the VAR_DECL as the equivalent for the PARM_DECL; 2661*e4b17023SJohn Marino that way, when the PARM_DECL is encountered, it will be 2662*e4b17023SJohn Marino automatically replaced by the VAR_DECL. */ 2663*e4b17023SJohn Marino insert_decl_map (id, p, var); 2664*e4b17023SJohn Marino 2665*e4b17023SJohn Marino /* Even if P was TREE_READONLY, the new VAR should not be. 2666*e4b17023SJohn Marino In the original code, we would have constructed a 2667*e4b17023SJohn Marino temporary, and then the function body would have never 2668*e4b17023SJohn Marino changed the value of P. However, now, we will be 2669*e4b17023SJohn Marino constructing VAR directly. The constructor body may 2670*e4b17023SJohn Marino change its value multiple times as it is being 2671*e4b17023SJohn Marino constructed. Therefore, it must not be TREE_READONLY; 2672*e4b17023SJohn Marino the back-end assumes that TREE_READONLY variable is 2673*e4b17023SJohn Marino assigned to only once. */ 2674*e4b17023SJohn Marino if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (p))) 2675*e4b17023SJohn Marino TREE_READONLY (var) = 0; 2676*e4b17023SJohn Marino 2677*e4b17023SJohn Marino /* If there is no setup required and we are in SSA, take the easy route 2678*e4b17023SJohn Marino replacing all SSA names representing the function parameter by the 2679*e4b17023SJohn Marino SSA name passed to function. 2680*e4b17023SJohn Marino 2681*e4b17023SJohn Marino We need to construct map for the variable anyway as it might be used 2682*e4b17023SJohn Marino in different SSA names when parameter is set in function. 2683*e4b17023SJohn Marino 2684*e4b17023SJohn Marino Do replacement at -O0 for const arguments replaced by constant. 2685*e4b17023SJohn Marino This is important for builtin_constant_p and other construct requiring 2686*e4b17023SJohn Marino constant argument to be visible in inlined function body. */ 2687*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun) && rhs && def && is_gimple_reg (p) 2688*e4b17023SJohn Marino && (optimize 2689*e4b17023SJohn Marino || (TREE_READONLY (p) 2690*e4b17023SJohn Marino && is_gimple_min_invariant (rhs))) 2691*e4b17023SJohn Marino && (TREE_CODE (rhs) == SSA_NAME 2692*e4b17023SJohn Marino || is_gimple_min_invariant (rhs)) 2693*e4b17023SJohn Marino && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)) 2694*e4b17023SJohn Marino { 2695*e4b17023SJohn Marino insert_decl_map (id, def, rhs); 2696*e4b17023SJohn Marino return insert_init_debug_bind (id, bb, var, rhs, NULL); 2697*e4b17023SJohn Marino } 2698*e4b17023SJohn Marino 2699*e4b17023SJohn Marino /* If the value of argument is never used, don't care about initializing 2700*e4b17023SJohn Marino it. */ 2701*e4b17023SJohn Marino if (optimize && gimple_in_ssa_p (cfun) && !def && is_gimple_reg (p)) 2702*e4b17023SJohn Marino { 2703*e4b17023SJohn Marino gcc_assert (!value || !TREE_SIDE_EFFECTS (value)); 2704*e4b17023SJohn Marino return insert_init_debug_bind (id, bb, var, rhs, NULL); 2705*e4b17023SJohn Marino } 2706*e4b17023SJohn Marino 2707*e4b17023SJohn Marino /* Initialize this VAR_DECL from the equivalent argument. Convert 2708*e4b17023SJohn Marino the argument to the proper type in case it was promoted. */ 2709*e4b17023SJohn Marino if (value) 2710*e4b17023SJohn Marino { 2711*e4b17023SJohn Marino if (rhs == error_mark_node) 2712*e4b17023SJohn Marino { 2713*e4b17023SJohn Marino insert_decl_map (id, p, var); 2714*e4b17023SJohn Marino return insert_init_debug_bind (id, bb, var, rhs, NULL); 2715*e4b17023SJohn Marino } 2716*e4b17023SJohn Marino 2717*e4b17023SJohn Marino STRIP_USELESS_TYPE_CONVERSION (rhs); 2718*e4b17023SJohn Marino 2719*e4b17023SJohn Marino /* We want to use MODIFY_EXPR, not INIT_EXPR here so that we 2720*e4b17023SJohn Marino keep our trees in gimple form. */ 2721*e4b17023SJohn Marino if (def && gimple_in_ssa_p (cfun) && is_gimple_reg (p)) 2722*e4b17023SJohn Marino { 2723*e4b17023SJohn Marino def = remap_ssa_name (def, id); 2724*e4b17023SJohn Marino init_stmt = gimple_build_assign (def, rhs); 2725*e4b17023SJohn Marino SSA_NAME_IS_DEFAULT_DEF (def) = 0; 2726*e4b17023SJohn Marino set_default_def (var, NULL); 2727*e4b17023SJohn Marino } 2728*e4b17023SJohn Marino else 2729*e4b17023SJohn Marino init_stmt = gimple_build_assign (var, rhs); 2730*e4b17023SJohn Marino 2731*e4b17023SJohn Marino if (bb && init_stmt) 2732*e4b17023SJohn Marino insert_init_stmt (id, bb, init_stmt); 2733*e4b17023SJohn Marino } 2734*e4b17023SJohn Marino return init_stmt; 2735*e4b17023SJohn Marino } 2736*e4b17023SJohn Marino 2737*e4b17023SJohn Marino /* Generate code to initialize the parameters of the function at the 2738*e4b17023SJohn Marino top of the stack in ID from the GIMPLE_CALL STMT. */ 2739*e4b17023SJohn Marino 2740*e4b17023SJohn Marino static void 2741*e4b17023SJohn Marino initialize_inlined_parameters (copy_body_data *id, gimple stmt, 2742*e4b17023SJohn Marino tree fn, basic_block bb) 2743*e4b17023SJohn Marino { 2744*e4b17023SJohn Marino tree parms; 2745*e4b17023SJohn Marino size_t i; 2746*e4b17023SJohn Marino tree p; 2747*e4b17023SJohn Marino tree vars = NULL_TREE; 2748*e4b17023SJohn Marino tree static_chain = gimple_call_chain (stmt); 2749*e4b17023SJohn Marino 2750*e4b17023SJohn Marino /* Figure out what the parameters are. */ 2751*e4b17023SJohn Marino parms = DECL_ARGUMENTS (fn); 2752*e4b17023SJohn Marino 2753*e4b17023SJohn Marino /* Loop through the parameter declarations, replacing each with an 2754*e4b17023SJohn Marino equivalent VAR_DECL, appropriately initialized. */ 2755*e4b17023SJohn Marino for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++) 2756*e4b17023SJohn Marino { 2757*e4b17023SJohn Marino tree val; 2758*e4b17023SJohn Marino val = i < gimple_call_num_args (stmt) ? gimple_call_arg (stmt, i) : NULL; 2759*e4b17023SJohn Marino setup_one_parameter (id, p, val, fn, bb, &vars); 2760*e4b17023SJohn Marino } 2761*e4b17023SJohn Marino /* After remapping parameters remap their types. This has to be done 2762*e4b17023SJohn Marino in a second loop over all parameters to appropriately remap 2763*e4b17023SJohn Marino variable sized arrays when the size is specified in a 2764*e4b17023SJohn Marino parameter following the array. */ 2765*e4b17023SJohn Marino for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++) 2766*e4b17023SJohn Marino { 2767*e4b17023SJohn Marino tree *varp = (tree *) pointer_map_contains (id->decl_map, p); 2768*e4b17023SJohn Marino if (varp 2769*e4b17023SJohn Marino && TREE_CODE (*varp) == VAR_DECL) 2770*e4b17023SJohn Marino { 2771*e4b17023SJohn Marino tree def = (gimple_in_ssa_p (cfun) && is_gimple_reg (p) 2772*e4b17023SJohn Marino ? gimple_default_def (id->src_cfun, p) : NULL); 2773*e4b17023SJohn Marino tree var = *varp; 2774*e4b17023SJohn Marino TREE_TYPE (var) = remap_type (TREE_TYPE (var), id); 2775*e4b17023SJohn Marino /* Also remap the default definition if it was remapped 2776*e4b17023SJohn Marino to the default definition of the parameter replacement 2777*e4b17023SJohn Marino by the parameter setup. */ 2778*e4b17023SJohn Marino if (def) 2779*e4b17023SJohn Marino { 2780*e4b17023SJohn Marino tree *defp = (tree *) pointer_map_contains (id->decl_map, def); 2781*e4b17023SJohn Marino if (defp 2782*e4b17023SJohn Marino && TREE_CODE (*defp) == SSA_NAME 2783*e4b17023SJohn Marino && SSA_NAME_VAR (*defp) == var) 2784*e4b17023SJohn Marino TREE_TYPE (*defp) = TREE_TYPE (var); 2785*e4b17023SJohn Marino } 2786*e4b17023SJohn Marino } 2787*e4b17023SJohn Marino } 2788*e4b17023SJohn Marino 2789*e4b17023SJohn Marino /* Initialize the static chain. */ 2790*e4b17023SJohn Marino p = DECL_STRUCT_FUNCTION (fn)->static_chain_decl; 2791*e4b17023SJohn Marino gcc_assert (fn != current_function_decl); 2792*e4b17023SJohn Marino if (p) 2793*e4b17023SJohn Marino { 2794*e4b17023SJohn Marino /* No static chain? Seems like a bug in tree-nested.c. */ 2795*e4b17023SJohn Marino gcc_assert (static_chain); 2796*e4b17023SJohn Marino 2797*e4b17023SJohn Marino setup_one_parameter (id, p, static_chain, fn, bb, &vars); 2798*e4b17023SJohn Marino } 2799*e4b17023SJohn Marino 2800*e4b17023SJohn Marino declare_inline_vars (id->block, vars); 2801*e4b17023SJohn Marino } 2802*e4b17023SJohn Marino 2803*e4b17023SJohn Marino 2804*e4b17023SJohn Marino /* Declare a return variable to replace the RESULT_DECL for the 2805*e4b17023SJohn Marino function we are calling. An appropriate DECL_STMT is returned. 2806*e4b17023SJohn Marino The USE_STMT is filled to contain a use of the declaration to 2807*e4b17023SJohn Marino indicate the return value of the function. 2808*e4b17023SJohn Marino 2809*e4b17023SJohn Marino RETURN_SLOT, if non-null is place where to store the result. It 2810*e4b17023SJohn Marino is set only for CALL_EXPR_RETURN_SLOT_OPT. MODIFY_DEST, if non-null, 2811*e4b17023SJohn Marino was the LHS of the MODIFY_EXPR to which this call is the RHS. 2812*e4b17023SJohn Marino 2813*e4b17023SJohn Marino The return value is a (possibly null) value that holds the result 2814*e4b17023SJohn Marino as seen by the caller. */ 2815*e4b17023SJohn Marino 2816*e4b17023SJohn Marino static tree 2817*e4b17023SJohn Marino declare_return_variable (copy_body_data *id, tree return_slot, tree modify_dest, 2818*e4b17023SJohn Marino basic_block entry_bb) 2819*e4b17023SJohn Marino { 2820*e4b17023SJohn Marino tree callee = id->src_fn; 2821*e4b17023SJohn Marino tree result = DECL_RESULT (callee); 2822*e4b17023SJohn Marino tree callee_type = TREE_TYPE (result); 2823*e4b17023SJohn Marino tree caller_type; 2824*e4b17023SJohn Marino tree var, use; 2825*e4b17023SJohn Marino 2826*e4b17023SJohn Marino /* Handle type-mismatches in the function declaration return type 2827*e4b17023SJohn Marino vs. the call expression. */ 2828*e4b17023SJohn Marino if (modify_dest) 2829*e4b17023SJohn Marino caller_type = TREE_TYPE (modify_dest); 2830*e4b17023SJohn Marino else 2831*e4b17023SJohn Marino caller_type = TREE_TYPE (TREE_TYPE (callee)); 2832*e4b17023SJohn Marino 2833*e4b17023SJohn Marino /* We don't need to do anything for functions that don't return anything. */ 2834*e4b17023SJohn Marino if (VOID_TYPE_P (callee_type)) 2835*e4b17023SJohn Marino return NULL_TREE; 2836*e4b17023SJohn Marino 2837*e4b17023SJohn Marino /* If there was a return slot, then the return value is the 2838*e4b17023SJohn Marino dereferenced address of that object. */ 2839*e4b17023SJohn Marino if (return_slot) 2840*e4b17023SJohn Marino { 2841*e4b17023SJohn Marino /* The front end shouldn't have used both return_slot and 2842*e4b17023SJohn Marino a modify expression. */ 2843*e4b17023SJohn Marino gcc_assert (!modify_dest); 2844*e4b17023SJohn Marino if (DECL_BY_REFERENCE (result)) 2845*e4b17023SJohn Marino { 2846*e4b17023SJohn Marino tree return_slot_addr = build_fold_addr_expr (return_slot); 2847*e4b17023SJohn Marino STRIP_USELESS_TYPE_CONVERSION (return_slot_addr); 2848*e4b17023SJohn Marino 2849*e4b17023SJohn Marino /* We are going to construct *&return_slot and we can't do that 2850*e4b17023SJohn Marino for variables believed to be not addressable. 2851*e4b17023SJohn Marino 2852*e4b17023SJohn Marino FIXME: This check possibly can match, because values returned 2853*e4b17023SJohn Marino via return slot optimization are not believed to have address 2854*e4b17023SJohn Marino taken by alias analysis. */ 2855*e4b17023SJohn Marino gcc_assert (TREE_CODE (return_slot) != SSA_NAME); 2856*e4b17023SJohn Marino var = return_slot_addr; 2857*e4b17023SJohn Marino } 2858*e4b17023SJohn Marino else 2859*e4b17023SJohn Marino { 2860*e4b17023SJohn Marino var = return_slot; 2861*e4b17023SJohn Marino gcc_assert (TREE_CODE (var) != SSA_NAME); 2862*e4b17023SJohn Marino TREE_ADDRESSABLE (var) |= TREE_ADDRESSABLE (result); 2863*e4b17023SJohn Marino } 2864*e4b17023SJohn Marino if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE 2865*e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE) 2866*e4b17023SJohn Marino && !DECL_GIMPLE_REG_P (result) 2867*e4b17023SJohn Marino && DECL_P (var)) 2868*e4b17023SJohn Marino DECL_GIMPLE_REG_P (var) = 0; 2869*e4b17023SJohn Marino use = NULL; 2870*e4b17023SJohn Marino goto done; 2871*e4b17023SJohn Marino } 2872*e4b17023SJohn Marino 2873*e4b17023SJohn Marino /* All types requiring non-trivial constructors should have been handled. */ 2874*e4b17023SJohn Marino gcc_assert (!TREE_ADDRESSABLE (callee_type)); 2875*e4b17023SJohn Marino 2876*e4b17023SJohn Marino /* Attempt to avoid creating a new temporary variable. */ 2877*e4b17023SJohn Marino if (modify_dest 2878*e4b17023SJohn Marino && TREE_CODE (modify_dest) != SSA_NAME) 2879*e4b17023SJohn Marino { 2880*e4b17023SJohn Marino bool use_it = false; 2881*e4b17023SJohn Marino 2882*e4b17023SJohn Marino /* We can't use MODIFY_DEST if there's type promotion involved. */ 2883*e4b17023SJohn Marino if (!useless_type_conversion_p (callee_type, caller_type)) 2884*e4b17023SJohn Marino use_it = false; 2885*e4b17023SJohn Marino 2886*e4b17023SJohn Marino /* ??? If we're assigning to a variable sized type, then we must 2887*e4b17023SJohn Marino reuse the destination variable, because we've no good way to 2888*e4b17023SJohn Marino create variable sized temporaries at this point. */ 2889*e4b17023SJohn Marino else if (TREE_CODE (TYPE_SIZE_UNIT (caller_type)) != INTEGER_CST) 2890*e4b17023SJohn Marino use_it = true; 2891*e4b17023SJohn Marino 2892*e4b17023SJohn Marino /* If the callee cannot possibly modify MODIFY_DEST, then we can 2893*e4b17023SJohn Marino reuse it as the result of the call directly. Don't do this if 2894*e4b17023SJohn Marino it would promote MODIFY_DEST to addressable. */ 2895*e4b17023SJohn Marino else if (TREE_ADDRESSABLE (result)) 2896*e4b17023SJohn Marino use_it = false; 2897*e4b17023SJohn Marino else 2898*e4b17023SJohn Marino { 2899*e4b17023SJohn Marino tree base_m = get_base_address (modify_dest); 2900*e4b17023SJohn Marino 2901*e4b17023SJohn Marino /* If the base isn't a decl, then it's a pointer, and we don't 2902*e4b17023SJohn Marino know where that's going to go. */ 2903*e4b17023SJohn Marino if (!DECL_P (base_m)) 2904*e4b17023SJohn Marino use_it = false; 2905*e4b17023SJohn Marino else if (is_global_var (base_m)) 2906*e4b17023SJohn Marino use_it = false; 2907*e4b17023SJohn Marino else if ((TREE_CODE (TREE_TYPE (result)) == COMPLEX_TYPE 2908*e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (result)) == VECTOR_TYPE) 2909*e4b17023SJohn Marino && !DECL_GIMPLE_REG_P (result) 2910*e4b17023SJohn Marino && DECL_GIMPLE_REG_P (base_m)) 2911*e4b17023SJohn Marino use_it = false; 2912*e4b17023SJohn Marino else if (!TREE_ADDRESSABLE (base_m)) 2913*e4b17023SJohn Marino use_it = true; 2914*e4b17023SJohn Marino } 2915*e4b17023SJohn Marino 2916*e4b17023SJohn Marino if (use_it) 2917*e4b17023SJohn Marino { 2918*e4b17023SJohn Marino var = modify_dest; 2919*e4b17023SJohn Marino use = NULL; 2920*e4b17023SJohn Marino goto done; 2921*e4b17023SJohn Marino } 2922*e4b17023SJohn Marino } 2923*e4b17023SJohn Marino 2924*e4b17023SJohn Marino gcc_assert (TREE_CODE (TYPE_SIZE_UNIT (callee_type)) == INTEGER_CST); 2925*e4b17023SJohn Marino 2926*e4b17023SJohn Marino var = copy_result_decl_to_var (result, id); 2927*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun)) 2928*e4b17023SJohn Marino add_referenced_var (var); 2929*e4b17023SJohn Marino 2930*e4b17023SJohn Marino DECL_SEEN_IN_BIND_EXPR_P (var) = 1; 2931*e4b17023SJohn Marino 2932*e4b17023SJohn Marino /* Do not have the rest of GCC warn about this variable as it should 2933*e4b17023SJohn Marino not be visible to the user. */ 2934*e4b17023SJohn Marino TREE_NO_WARNING (var) = 1; 2935*e4b17023SJohn Marino 2936*e4b17023SJohn Marino declare_inline_vars (id->block, var); 2937*e4b17023SJohn Marino 2938*e4b17023SJohn Marino /* Build the use expr. If the return type of the function was 2939*e4b17023SJohn Marino promoted, convert it back to the expected type. */ 2940*e4b17023SJohn Marino use = var; 2941*e4b17023SJohn Marino if (!useless_type_conversion_p (caller_type, TREE_TYPE (var))) 2942*e4b17023SJohn Marino { 2943*e4b17023SJohn Marino /* If we can match up types by promotion/demotion do so. */ 2944*e4b17023SJohn Marino if (fold_convertible_p (caller_type, var)) 2945*e4b17023SJohn Marino use = fold_convert (caller_type, var); 2946*e4b17023SJohn Marino else 2947*e4b17023SJohn Marino { 2948*e4b17023SJohn Marino /* ??? For valid programs we should not end up here. 2949*e4b17023SJohn Marino Still if we end up with truly mismatched types here, fall back 2950*e4b17023SJohn Marino to using a MEM_REF to not leak invalid GIMPLE to the following 2951*e4b17023SJohn Marino passes. */ 2952*e4b17023SJohn Marino /* Prevent var from being written into SSA form. */ 2953*e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE 2954*e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE) 2955*e4b17023SJohn Marino DECL_GIMPLE_REG_P (var) = false; 2956*e4b17023SJohn Marino else if (is_gimple_reg_type (TREE_TYPE (var))) 2957*e4b17023SJohn Marino TREE_ADDRESSABLE (var) = true; 2958*e4b17023SJohn Marino use = fold_build2 (MEM_REF, caller_type, 2959*e4b17023SJohn Marino build_fold_addr_expr (var), 2960*e4b17023SJohn Marino build_int_cst (ptr_type_node, 0)); 2961*e4b17023SJohn Marino } 2962*e4b17023SJohn Marino } 2963*e4b17023SJohn Marino 2964*e4b17023SJohn Marino STRIP_USELESS_TYPE_CONVERSION (use); 2965*e4b17023SJohn Marino 2966*e4b17023SJohn Marino if (DECL_BY_REFERENCE (result)) 2967*e4b17023SJohn Marino { 2968*e4b17023SJohn Marino TREE_ADDRESSABLE (var) = 1; 2969*e4b17023SJohn Marino var = build_fold_addr_expr (var); 2970*e4b17023SJohn Marino } 2971*e4b17023SJohn Marino 2972*e4b17023SJohn Marino done: 2973*e4b17023SJohn Marino /* Register the VAR_DECL as the equivalent for the RESULT_DECL; that 2974*e4b17023SJohn Marino way, when the RESULT_DECL is encountered, it will be 2975*e4b17023SJohn Marino automatically replaced by the VAR_DECL. 2976*e4b17023SJohn Marino 2977*e4b17023SJohn Marino When returning by reference, ensure that RESULT_DECL remaps to 2978*e4b17023SJohn Marino gimple_val. */ 2979*e4b17023SJohn Marino if (DECL_BY_REFERENCE (result) 2980*e4b17023SJohn Marino && !is_gimple_val (var)) 2981*e4b17023SJohn Marino { 2982*e4b17023SJohn Marino tree temp = create_tmp_var (TREE_TYPE (result), "retvalptr"); 2983*e4b17023SJohn Marino if (gimple_in_ssa_p (id->src_cfun)) 2984*e4b17023SJohn Marino add_referenced_var (temp); 2985*e4b17023SJohn Marino insert_decl_map (id, result, temp); 2986*e4b17023SJohn Marino /* When RESULT_DECL is in SSA form, we need to use it's default_def 2987*e4b17023SJohn Marino SSA_NAME. */ 2988*e4b17023SJohn Marino if (gimple_in_ssa_p (id->src_cfun) && gimple_default_def (id->src_cfun, result)) 2989*e4b17023SJohn Marino temp = remap_ssa_name (gimple_default_def (id->src_cfun, result), id); 2990*e4b17023SJohn Marino insert_init_stmt (id, entry_bb, gimple_build_assign (temp, var)); 2991*e4b17023SJohn Marino } 2992*e4b17023SJohn Marino else 2993*e4b17023SJohn Marino insert_decl_map (id, result, var); 2994*e4b17023SJohn Marino 2995*e4b17023SJohn Marino /* Remember this so we can ignore it in remap_decls. */ 2996*e4b17023SJohn Marino id->retvar = var; 2997*e4b17023SJohn Marino 2998*e4b17023SJohn Marino return use; 2999*e4b17023SJohn Marino } 3000*e4b17023SJohn Marino 3001*e4b17023SJohn Marino /* Callback through walk_tree. Determine if a DECL_INITIAL makes reference 3002*e4b17023SJohn Marino to a local label. */ 3003*e4b17023SJohn Marino 3004*e4b17023SJohn Marino static tree 3005*e4b17023SJohn Marino has_label_address_in_static_1 (tree *nodep, int *walk_subtrees, void *fnp) 3006*e4b17023SJohn Marino { 3007*e4b17023SJohn Marino tree node = *nodep; 3008*e4b17023SJohn Marino tree fn = (tree) fnp; 3009*e4b17023SJohn Marino 3010*e4b17023SJohn Marino if (TREE_CODE (node) == LABEL_DECL && DECL_CONTEXT (node) == fn) 3011*e4b17023SJohn Marino return node; 3012*e4b17023SJohn Marino 3013*e4b17023SJohn Marino if (TYPE_P (node)) 3014*e4b17023SJohn Marino *walk_subtrees = 0; 3015*e4b17023SJohn Marino 3016*e4b17023SJohn Marino return NULL_TREE; 3017*e4b17023SJohn Marino } 3018*e4b17023SJohn Marino 3019*e4b17023SJohn Marino /* Determine if the function can be copied. If so return NULL. If 3020*e4b17023SJohn Marino not return a string describng the reason for failure. */ 3021*e4b17023SJohn Marino 3022*e4b17023SJohn Marino static const char * 3023*e4b17023SJohn Marino copy_forbidden (struct function *fun, tree fndecl) 3024*e4b17023SJohn Marino { 3025*e4b17023SJohn Marino const char *reason = fun->cannot_be_copied_reason; 3026*e4b17023SJohn Marino tree decl; 3027*e4b17023SJohn Marino unsigned ix; 3028*e4b17023SJohn Marino 3029*e4b17023SJohn Marino /* Only examine the function once. */ 3030*e4b17023SJohn Marino if (fun->cannot_be_copied_set) 3031*e4b17023SJohn Marino return reason; 3032*e4b17023SJohn Marino 3033*e4b17023SJohn Marino /* We cannot copy a function that receives a non-local goto 3034*e4b17023SJohn Marino because we cannot remap the destination label used in the 3035*e4b17023SJohn Marino function that is performing the non-local goto. */ 3036*e4b17023SJohn Marino /* ??? Actually, this should be possible, if we work at it. 3037*e4b17023SJohn Marino No doubt there's just a handful of places that simply 3038*e4b17023SJohn Marino assume it doesn't happen and don't substitute properly. */ 3039*e4b17023SJohn Marino if (fun->has_nonlocal_label) 3040*e4b17023SJohn Marino { 3041*e4b17023SJohn Marino reason = G_("function %q+F can never be copied " 3042*e4b17023SJohn Marino "because it receives a non-local goto"); 3043*e4b17023SJohn Marino goto fail; 3044*e4b17023SJohn Marino } 3045*e4b17023SJohn Marino 3046*e4b17023SJohn Marino FOR_EACH_LOCAL_DECL (fun, ix, decl) 3047*e4b17023SJohn Marino if (TREE_CODE (decl) == VAR_DECL 3048*e4b17023SJohn Marino && TREE_STATIC (decl) 3049*e4b17023SJohn Marino && !DECL_EXTERNAL (decl) 3050*e4b17023SJohn Marino && DECL_INITIAL (decl) 3051*e4b17023SJohn Marino && walk_tree_without_duplicates (&DECL_INITIAL (decl), 3052*e4b17023SJohn Marino has_label_address_in_static_1, 3053*e4b17023SJohn Marino fndecl)) 3054*e4b17023SJohn Marino { 3055*e4b17023SJohn Marino reason = G_("function %q+F can never be copied because it saves " 3056*e4b17023SJohn Marino "address of local label in a static variable"); 3057*e4b17023SJohn Marino goto fail; 3058*e4b17023SJohn Marino } 3059*e4b17023SJohn Marino 3060*e4b17023SJohn Marino fail: 3061*e4b17023SJohn Marino fun->cannot_be_copied_reason = reason; 3062*e4b17023SJohn Marino fun->cannot_be_copied_set = true; 3063*e4b17023SJohn Marino return reason; 3064*e4b17023SJohn Marino } 3065*e4b17023SJohn Marino 3066*e4b17023SJohn Marino 3067*e4b17023SJohn Marino static const char *inline_forbidden_reason; 3068*e4b17023SJohn Marino 3069*e4b17023SJohn Marino /* A callback for walk_gimple_seq to handle statements. Returns non-null 3070*e4b17023SJohn Marino iff a function can not be inlined. Also sets the reason why. */ 3071*e4b17023SJohn Marino 3072*e4b17023SJohn Marino static tree 3073*e4b17023SJohn Marino inline_forbidden_p_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, 3074*e4b17023SJohn Marino struct walk_stmt_info *wip) 3075*e4b17023SJohn Marino { 3076*e4b17023SJohn Marino tree fn = (tree) wip->info; 3077*e4b17023SJohn Marino tree t; 3078*e4b17023SJohn Marino gimple stmt = gsi_stmt (*gsi); 3079*e4b17023SJohn Marino 3080*e4b17023SJohn Marino switch (gimple_code (stmt)) 3081*e4b17023SJohn Marino { 3082*e4b17023SJohn Marino case GIMPLE_CALL: 3083*e4b17023SJohn Marino /* Refuse to inline alloca call unless user explicitly forced so as 3084*e4b17023SJohn Marino this may change program's memory overhead drastically when the 3085*e4b17023SJohn Marino function using alloca is called in loop. In GCC present in 3086*e4b17023SJohn Marino SPEC2000 inlining into schedule_block cause it to require 2GB of 3087*e4b17023SJohn Marino RAM instead of 256MB. Don't do so for alloca calls emitted for 3088*e4b17023SJohn Marino VLA objects as those can't cause unbounded growth (they're always 3089*e4b17023SJohn Marino wrapped inside stack_save/stack_restore regions. */ 3090*e4b17023SJohn Marino if (gimple_alloca_call_p (stmt) 3091*e4b17023SJohn Marino && !gimple_call_alloca_for_var_p (stmt) 3092*e4b17023SJohn Marino && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))) 3093*e4b17023SJohn Marino { 3094*e4b17023SJohn Marino inline_forbidden_reason 3095*e4b17023SJohn Marino = G_("function %q+F can never be inlined because it uses " 3096*e4b17023SJohn Marino "alloca (override using the always_inline attribute)"); 3097*e4b17023SJohn Marino *handled_ops_p = true; 3098*e4b17023SJohn Marino return fn; 3099*e4b17023SJohn Marino } 3100*e4b17023SJohn Marino 3101*e4b17023SJohn Marino t = gimple_call_fndecl (stmt); 3102*e4b17023SJohn Marino if (t == NULL_TREE) 3103*e4b17023SJohn Marino break; 3104*e4b17023SJohn Marino 3105*e4b17023SJohn Marino /* We cannot inline functions that call setjmp. */ 3106*e4b17023SJohn Marino if (setjmp_call_p (t)) 3107*e4b17023SJohn Marino { 3108*e4b17023SJohn Marino inline_forbidden_reason 3109*e4b17023SJohn Marino = G_("function %q+F can never be inlined because it uses setjmp"); 3110*e4b17023SJohn Marino *handled_ops_p = true; 3111*e4b17023SJohn Marino return t; 3112*e4b17023SJohn Marino } 3113*e4b17023SJohn Marino 3114*e4b17023SJohn Marino if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL) 3115*e4b17023SJohn Marino switch (DECL_FUNCTION_CODE (t)) 3116*e4b17023SJohn Marino { 3117*e4b17023SJohn Marino /* We cannot inline functions that take a variable number of 3118*e4b17023SJohn Marino arguments. */ 3119*e4b17023SJohn Marino case BUILT_IN_VA_START: 3120*e4b17023SJohn Marino case BUILT_IN_NEXT_ARG: 3121*e4b17023SJohn Marino case BUILT_IN_VA_END: 3122*e4b17023SJohn Marino inline_forbidden_reason 3123*e4b17023SJohn Marino = G_("function %q+F can never be inlined because it " 3124*e4b17023SJohn Marino "uses variable argument lists"); 3125*e4b17023SJohn Marino *handled_ops_p = true; 3126*e4b17023SJohn Marino return t; 3127*e4b17023SJohn Marino 3128*e4b17023SJohn Marino case BUILT_IN_LONGJMP: 3129*e4b17023SJohn Marino /* We can't inline functions that call __builtin_longjmp at 3130*e4b17023SJohn Marino all. The non-local goto machinery really requires the 3131*e4b17023SJohn Marino destination be in a different function. If we allow the 3132*e4b17023SJohn Marino function calling __builtin_longjmp to be inlined into the 3133*e4b17023SJohn Marino function calling __builtin_setjmp, Things will Go Awry. */ 3134*e4b17023SJohn Marino inline_forbidden_reason 3135*e4b17023SJohn Marino = G_("function %q+F can never be inlined because " 3136*e4b17023SJohn Marino "it uses setjmp-longjmp exception handling"); 3137*e4b17023SJohn Marino *handled_ops_p = true; 3138*e4b17023SJohn Marino return t; 3139*e4b17023SJohn Marino 3140*e4b17023SJohn Marino case BUILT_IN_NONLOCAL_GOTO: 3141*e4b17023SJohn Marino /* Similarly. */ 3142*e4b17023SJohn Marino inline_forbidden_reason 3143*e4b17023SJohn Marino = G_("function %q+F can never be inlined because " 3144*e4b17023SJohn Marino "it uses non-local goto"); 3145*e4b17023SJohn Marino *handled_ops_p = true; 3146*e4b17023SJohn Marino return t; 3147*e4b17023SJohn Marino 3148*e4b17023SJohn Marino case BUILT_IN_RETURN: 3149*e4b17023SJohn Marino case BUILT_IN_APPLY_ARGS: 3150*e4b17023SJohn Marino /* If a __builtin_apply_args caller would be inlined, 3151*e4b17023SJohn Marino it would be saving arguments of the function it has 3152*e4b17023SJohn Marino been inlined into. Similarly __builtin_return would 3153*e4b17023SJohn Marino return from the function the inline has been inlined into. */ 3154*e4b17023SJohn Marino inline_forbidden_reason 3155*e4b17023SJohn Marino = G_("function %q+F can never be inlined because " 3156*e4b17023SJohn Marino "it uses __builtin_return or __builtin_apply_args"); 3157*e4b17023SJohn Marino *handled_ops_p = true; 3158*e4b17023SJohn Marino return t; 3159*e4b17023SJohn Marino 3160*e4b17023SJohn Marino default: 3161*e4b17023SJohn Marino break; 3162*e4b17023SJohn Marino } 3163*e4b17023SJohn Marino break; 3164*e4b17023SJohn Marino 3165*e4b17023SJohn Marino case GIMPLE_GOTO: 3166*e4b17023SJohn Marino t = gimple_goto_dest (stmt); 3167*e4b17023SJohn Marino 3168*e4b17023SJohn Marino /* We will not inline a function which uses computed goto. The 3169*e4b17023SJohn Marino addresses of its local labels, which may be tucked into 3170*e4b17023SJohn Marino global storage, are of course not constant across 3171*e4b17023SJohn Marino instantiations, which causes unexpected behavior. */ 3172*e4b17023SJohn Marino if (TREE_CODE (t) != LABEL_DECL) 3173*e4b17023SJohn Marino { 3174*e4b17023SJohn Marino inline_forbidden_reason 3175*e4b17023SJohn Marino = G_("function %q+F can never be inlined " 3176*e4b17023SJohn Marino "because it contains a computed goto"); 3177*e4b17023SJohn Marino *handled_ops_p = true; 3178*e4b17023SJohn Marino return t; 3179*e4b17023SJohn Marino } 3180*e4b17023SJohn Marino break; 3181*e4b17023SJohn Marino 3182*e4b17023SJohn Marino default: 3183*e4b17023SJohn Marino break; 3184*e4b17023SJohn Marino } 3185*e4b17023SJohn Marino 3186*e4b17023SJohn Marino *handled_ops_p = false; 3187*e4b17023SJohn Marino return NULL_TREE; 3188*e4b17023SJohn Marino } 3189*e4b17023SJohn Marino 3190*e4b17023SJohn Marino /* Return true if FNDECL is a function that cannot be inlined into 3191*e4b17023SJohn Marino another one. */ 3192*e4b17023SJohn Marino 3193*e4b17023SJohn Marino static bool 3194*e4b17023SJohn Marino inline_forbidden_p (tree fndecl) 3195*e4b17023SJohn Marino { 3196*e4b17023SJohn Marino struct function *fun = DECL_STRUCT_FUNCTION (fndecl); 3197*e4b17023SJohn Marino struct walk_stmt_info wi; 3198*e4b17023SJohn Marino struct pointer_set_t *visited_nodes; 3199*e4b17023SJohn Marino basic_block bb; 3200*e4b17023SJohn Marino bool forbidden_p = false; 3201*e4b17023SJohn Marino 3202*e4b17023SJohn Marino /* First check for shared reasons not to copy the code. */ 3203*e4b17023SJohn Marino inline_forbidden_reason = copy_forbidden (fun, fndecl); 3204*e4b17023SJohn Marino if (inline_forbidden_reason != NULL) 3205*e4b17023SJohn Marino return true; 3206*e4b17023SJohn Marino 3207*e4b17023SJohn Marino /* Next, walk the statements of the function looking for 3208*e4b17023SJohn Marino constraucts we can't handle, or are non-optimal for inlining. */ 3209*e4b17023SJohn Marino visited_nodes = pointer_set_create (); 3210*e4b17023SJohn Marino memset (&wi, 0, sizeof (wi)); 3211*e4b17023SJohn Marino wi.info = (void *) fndecl; 3212*e4b17023SJohn Marino wi.pset = visited_nodes; 3213*e4b17023SJohn Marino 3214*e4b17023SJohn Marino FOR_EACH_BB_FN (bb, fun) 3215*e4b17023SJohn Marino { 3216*e4b17023SJohn Marino gimple ret; 3217*e4b17023SJohn Marino gimple_seq seq = bb_seq (bb); 3218*e4b17023SJohn Marino ret = walk_gimple_seq (seq, inline_forbidden_p_stmt, NULL, &wi); 3219*e4b17023SJohn Marino forbidden_p = (ret != NULL); 3220*e4b17023SJohn Marino if (forbidden_p) 3221*e4b17023SJohn Marino break; 3222*e4b17023SJohn Marino } 3223*e4b17023SJohn Marino 3224*e4b17023SJohn Marino pointer_set_destroy (visited_nodes); 3225*e4b17023SJohn Marino return forbidden_p; 3226*e4b17023SJohn Marino } 3227*e4b17023SJohn Marino 3228*e4b17023SJohn Marino /* Returns nonzero if FN is a function that does not have any 3229*e4b17023SJohn Marino fundamental inline blocking properties. */ 3230*e4b17023SJohn Marino 3231*e4b17023SJohn Marino bool 3232*e4b17023SJohn Marino tree_inlinable_function_p (tree fn) 3233*e4b17023SJohn Marino { 3234*e4b17023SJohn Marino bool inlinable = true; 3235*e4b17023SJohn Marino bool do_warning; 3236*e4b17023SJohn Marino tree always_inline; 3237*e4b17023SJohn Marino 3238*e4b17023SJohn Marino /* If we've already decided this function shouldn't be inlined, 3239*e4b17023SJohn Marino there's no need to check again. */ 3240*e4b17023SJohn Marino if (DECL_UNINLINABLE (fn)) 3241*e4b17023SJohn Marino return false; 3242*e4b17023SJohn Marino 3243*e4b17023SJohn Marino /* We only warn for functions declared `inline' by the user. */ 3244*e4b17023SJohn Marino do_warning = (warn_inline 3245*e4b17023SJohn Marino && DECL_DECLARED_INLINE_P (fn) 3246*e4b17023SJohn Marino && !DECL_NO_INLINE_WARNING_P (fn) 3247*e4b17023SJohn Marino && !DECL_IN_SYSTEM_HEADER (fn)); 3248*e4b17023SJohn Marino 3249*e4b17023SJohn Marino always_inline = lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)); 3250*e4b17023SJohn Marino 3251*e4b17023SJohn Marino if (flag_no_inline 3252*e4b17023SJohn Marino && always_inline == NULL) 3253*e4b17023SJohn Marino { 3254*e4b17023SJohn Marino if (do_warning) 3255*e4b17023SJohn Marino warning (OPT_Winline, "function %q+F can never be inlined because it " 3256*e4b17023SJohn Marino "is suppressed using -fno-inline", fn); 3257*e4b17023SJohn Marino inlinable = false; 3258*e4b17023SJohn Marino } 3259*e4b17023SJohn Marino 3260*e4b17023SJohn Marino else if (!function_attribute_inlinable_p (fn)) 3261*e4b17023SJohn Marino { 3262*e4b17023SJohn Marino if (do_warning) 3263*e4b17023SJohn Marino warning (OPT_Winline, "function %q+F can never be inlined because it " 3264*e4b17023SJohn Marino "uses attributes conflicting with inlining", fn); 3265*e4b17023SJohn Marino inlinable = false; 3266*e4b17023SJohn Marino } 3267*e4b17023SJohn Marino 3268*e4b17023SJohn Marino else if (inline_forbidden_p (fn)) 3269*e4b17023SJohn Marino { 3270*e4b17023SJohn Marino /* See if we should warn about uninlinable functions. Previously, 3271*e4b17023SJohn Marino some of these warnings would be issued while trying to expand 3272*e4b17023SJohn Marino the function inline, but that would cause multiple warnings 3273*e4b17023SJohn Marino about functions that would for example call alloca. But since 3274*e4b17023SJohn Marino this a property of the function, just one warning is enough. 3275*e4b17023SJohn Marino As a bonus we can now give more details about the reason why a 3276*e4b17023SJohn Marino function is not inlinable. */ 3277*e4b17023SJohn Marino if (always_inline) 3278*e4b17023SJohn Marino error (inline_forbidden_reason, fn); 3279*e4b17023SJohn Marino else if (do_warning) 3280*e4b17023SJohn Marino warning (OPT_Winline, inline_forbidden_reason, fn); 3281*e4b17023SJohn Marino 3282*e4b17023SJohn Marino inlinable = false; 3283*e4b17023SJohn Marino } 3284*e4b17023SJohn Marino 3285*e4b17023SJohn Marino /* Squirrel away the result so that we don't have to check again. */ 3286*e4b17023SJohn Marino DECL_UNINLINABLE (fn) = !inlinable; 3287*e4b17023SJohn Marino 3288*e4b17023SJohn Marino return inlinable; 3289*e4b17023SJohn Marino } 3290*e4b17023SJohn Marino 3291*e4b17023SJohn Marino /* Estimate the cost of a memory move. Use machine dependent 3292*e4b17023SJohn Marino word size and take possible memcpy call into account. */ 3293*e4b17023SJohn Marino 3294*e4b17023SJohn Marino int 3295*e4b17023SJohn Marino estimate_move_cost (tree type) 3296*e4b17023SJohn Marino { 3297*e4b17023SJohn Marino HOST_WIDE_INT size; 3298*e4b17023SJohn Marino 3299*e4b17023SJohn Marino gcc_assert (!VOID_TYPE_P (type)); 3300*e4b17023SJohn Marino 3301*e4b17023SJohn Marino if (TREE_CODE (type) == VECTOR_TYPE) 3302*e4b17023SJohn Marino { 3303*e4b17023SJohn Marino enum machine_mode inner = TYPE_MODE (TREE_TYPE (type)); 3304*e4b17023SJohn Marino enum machine_mode simd 3305*e4b17023SJohn Marino = targetm.vectorize.preferred_simd_mode (inner); 3306*e4b17023SJohn Marino int simd_mode_size = GET_MODE_SIZE (simd); 3307*e4b17023SJohn Marino return ((GET_MODE_SIZE (TYPE_MODE (type)) + simd_mode_size - 1) 3308*e4b17023SJohn Marino / simd_mode_size); 3309*e4b17023SJohn Marino } 3310*e4b17023SJohn Marino 3311*e4b17023SJohn Marino size = int_size_in_bytes (type); 3312*e4b17023SJohn Marino 3313*e4b17023SJohn Marino if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO (!optimize_size)) 3314*e4b17023SJohn Marino /* Cost of a memcpy call, 3 arguments and the call. */ 3315*e4b17023SJohn Marino return 4; 3316*e4b17023SJohn Marino else 3317*e4b17023SJohn Marino return ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES); 3318*e4b17023SJohn Marino } 3319*e4b17023SJohn Marino 3320*e4b17023SJohn Marino /* Returns cost of operation CODE, according to WEIGHTS */ 3321*e4b17023SJohn Marino 3322*e4b17023SJohn Marino static int 3323*e4b17023SJohn Marino estimate_operator_cost (enum tree_code code, eni_weights *weights, 3324*e4b17023SJohn Marino tree op1 ATTRIBUTE_UNUSED, tree op2) 3325*e4b17023SJohn Marino { 3326*e4b17023SJohn Marino switch (code) 3327*e4b17023SJohn Marino { 3328*e4b17023SJohn Marino /* These are "free" conversions, or their presumed cost 3329*e4b17023SJohn Marino is folded into other operations. */ 3330*e4b17023SJohn Marino case RANGE_EXPR: 3331*e4b17023SJohn Marino CASE_CONVERT: 3332*e4b17023SJohn Marino case COMPLEX_EXPR: 3333*e4b17023SJohn Marino case PAREN_EXPR: 3334*e4b17023SJohn Marino case VIEW_CONVERT_EXPR: 3335*e4b17023SJohn Marino return 0; 3336*e4b17023SJohn Marino 3337*e4b17023SJohn Marino /* Assign cost of 1 to usual operations. 3338*e4b17023SJohn Marino ??? We may consider mapping RTL costs to this. */ 3339*e4b17023SJohn Marino case COND_EXPR: 3340*e4b17023SJohn Marino case VEC_COND_EXPR: 3341*e4b17023SJohn Marino case VEC_PERM_EXPR: 3342*e4b17023SJohn Marino 3343*e4b17023SJohn Marino case PLUS_EXPR: 3344*e4b17023SJohn Marino case POINTER_PLUS_EXPR: 3345*e4b17023SJohn Marino case MINUS_EXPR: 3346*e4b17023SJohn Marino case MULT_EXPR: 3347*e4b17023SJohn Marino case FMA_EXPR: 3348*e4b17023SJohn Marino 3349*e4b17023SJohn Marino case ADDR_SPACE_CONVERT_EXPR: 3350*e4b17023SJohn Marino case FIXED_CONVERT_EXPR: 3351*e4b17023SJohn Marino case FIX_TRUNC_EXPR: 3352*e4b17023SJohn Marino 3353*e4b17023SJohn Marino case NEGATE_EXPR: 3354*e4b17023SJohn Marino case FLOAT_EXPR: 3355*e4b17023SJohn Marino case MIN_EXPR: 3356*e4b17023SJohn Marino case MAX_EXPR: 3357*e4b17023SJohn Marino case ABS_EXPR: 3358*e4b17023SJohn Marino 3359*e4b17023SJohn Marino case LSHIFT_EXPR: 3360*e4b17023SJohn Marino case RSHIFT_EXPR: 3361*e4b17023SJohn Marino case LROTATE_EXPR: 3362*e4b17023SJohn Marino case RROTATE_EXPR: 3363*e4b17023SJohn Marino case VEC_LSHIFT_EXPR: 3364*e4b17023SJohn Marino case VEC_RSHIFT_EXPR: 3365*e4b17023SJohn Marino 3366*e4b17023SJohn Marino case BIT_IOR_EXPR: 3367*e4b17023SJohn Marino case BIT_XOR_EXPR: 3368*e4b17023SJohn Marino case BIT_AND_EXPR: 3369*e4b17023SJohn Marino case BIT_NOT_EXPR: 3370*e4b17023SJohn Marino 3371*e4b17023SJohn Marino case TRUTH_ANDIF_EXPR: 3372*e4b17023SJohn Marino case TRUTH_ORIF_EXPR: 3373*e4b17023SJohn Marino case TRUTH_AND_EXPR: 3374*e4b17023SJohn Marino case TRUTH_OR_EXPR: 3375*e4b17023SJohn Marino case TRUTH_XOR_EXPR: 3376*e4b17023SJohn Marino case TRUTH_NOT_EXPR: 3377*e4b17023SJohn Marino 3378*e4b17023SJohn Marino case LT_EXPR: 3379*e4b17023SJohn Marino case LE_EXPR: 3380*e4b17023SJohn Marino case GT_EXPR: 3381*e4b17023SJohn Marino case GE_EXPR: 3382*e4b17023SJohn Marino case EQ_EXPR: 3383*e4b17023SJohn Marino case NE_EXPR: 3384*e4b17023SJohn Marino case ORDERED_EXPR: 3385*e4b17023SJohn Marino case UNORDERED_EXPR: 3386*e4b17023SJohn Marino 3387*e4b17023SJohn Marino case UNLT_EXPR: 3388*e4b17023SJohn Marino case UNLE_EXPR: 3389*e4b17023SJohn Marino case UNGT_EXPR: 3390*e4b17023SJohn Marino case UNGE_EXPR: 3391*e4b17023SJohn Marino case UNEQ_EXPR: 3392*e4b17023SJohn Marino case LTGT_EXPR: 3393*e4b17023SJohn Marino 3394*e4b17023SJohn Marino case CONJ_EXPR: 3395*e4b17023SJohn Marino 3396*e4b17023SJohn Marino case PREDECREMENT_EXPR: 3397*e4b17023SJohn Marino case PREINCREMENT_EXPR: 3398*e4b17023SJohn Marino case POSTDECREMENT_EXPR: 3399*e4b17023SJohn Marino case POSTINCREMENT_EXPR: 3400*e4b17023SJohn Marino 3401*e4b17023SJohn Marino case REALIGN_LOAD_EXPR: 3402*e4b17023SJohn Marino 3403*e4b17023SJohn Marino case REDUC_MAX_EXPR: 3404*e4b17023SJohn Marino case REDUC_MIN_EXPR: 3405*e4b17023SJohn Marino case REDUC_PLUS_EXPR: 3406*e4b17023SJohn Marino case WIDEN_SUM_EXPR: 3407*e4b17023SJohn Marino case WIDEN_MULT_EXPR: 3408*e4b17023SJohn Marino case DOT_PROD_EXPR: 3409*e4b17023SJohn Marino case WIDEN_MULT_PLUS_EXPR: 3410*e4b17023SJohn Marino case WIDEN_MULT_MINUS_EXPR: 3411*e4b17023SJohn Marino case WIDEN_LSHIFT_EXPR: 3412*e4b17023SJohn Marino 3413*e4b17023SJohn Marino case VEC_WIDEN_MULT_HI_EXPR: 3414*e4b17023SJohn Marino case VEC_WIDEN_MULT_LO_EXPR: 3415*e4b17023SJohn Marino case VEC_UNPACK_HI_EXPR: 3416*e4b17023SJohn Marino case VEC_UNPACK_LO_EXPR: 3417*e4b17023SJohn Marino case VEC_UNPACK_FLOAT_HI_EXPR: 3418*e4b17023SJohn Marino case VEC_UNPACK_FLOAT_LO_EXPR: 3419*e4b17023SJohn Marino case VEC_PACK_TRUNC_EXPR: 3420*e4b17023SJohn Marino case VEC_PACK_SAT_EXPR: 3421*e4b17023SJohn Marino case VEC_PACK_FIX_TRUNC_EXPR: 3422*e4b17023SJohn Marino case VEC_WIDEN_LSHIFT_HI_EXPR: 3423*e4b17023SJohn Marino case VEC_WIDEN_LSHIFT_LO_EXPR: 3424*e4b17023SJohn Marino 3425*e4b17023SJohn Marino return 1; 3426*e4b17023SJohn Marino 3427*e4b17023SJohn Marino /* Few special cases of expensive operations. This is useful 3428*e4b17023SJohn Marino to avoid inlining on functions having too many of these. */ 3429*e4b17023SJohn Marino case TRUNC_DIV_EXPR: 3430*e4b17023SJohn Marino case CEIL_DIV_EXPR: 3431*e4b17023SJohn Marino case FLOOR_DIV_EXPR: 3432*e4b17023SJohn Marino case ROUND_DIV_EXPR: 3433*e4b17023SJohn Marino case EXACT_DIV_EXPR: 3434*e4b17023SJohn Marino case TRUNC_MOD_EXPR: 3435*e4b17023SJohn Marino case CEIL_MOD_EXPR: 3436*e4b17023SJohn Marino case FLOOR_MOD_EXPR: 3437*e4b17023SJohn Marino case ROUND_MOD_EXPR: 3438*e4b17023SJohn Marino case RDIV_EXPR: 3439*e4b17023SJohn Marino if (TREE_CODE (op2) != INTEGER_CST) 3440*e4b17023SJohn Marino return weights->div_mod_cost; 3441*e4b17023SJohn Marino return 1; 3442*e4b17023SJohn Marino 3443*e4b17023SJohn Marino default: 3444*e4b17023SJohn Marino /* We expect a copy assignment with no operator. */ 3445*e4b17023SJohn Marino gcc_assert (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS); 3446*e4b17023SJohn Marino return 0; 3447*e4b17023SJohn Marino } 3448*e4b17023SJohn Marino } 3449*e4b17023SJohn Marino 3450*e4b17023SJohn Marino 3451*e4b17023SJohn Marino /* Estimate number of instructions that will be created by expanding 3452*e4b17023SJohn Marino the statements in the statement sequence STMTS. 3453*e4b17023SJohn Marino WEIGHTS contains weights attributed to various constructs. */ 3454*e4b17023SJohn Marino 3455*e4b17023SJohn Marino static 3456*e4b17023SJohn Marino int estimate_num_insns_seq (gimple_seq stmts, eni_weights *weights) 3457*e4b17023SJohn Marino { 3458*e4b17023SJohn Marino int cost; 3459*e4b17023SJohn Marino gimple_stmt_iterator gsi; 3460*e4b17023SJohn Marino 3461*e4b17023SJohn Marino cost = 0; 3462*e4b17023SJohn Marino for (gsi = gsi_start (stmts); !gsi_end_p (gsi); gsi_next (&gsi)) 3463*e4b17023SJohn Marino cost += estimate_num_insns (gsi_stmt (gsi), weights); 3464*e4b17023SJohn Marino 3465*e4b17023SJohn Marino return cost; 3466*e4b17023SJohn Marino } 3467*e4b17023SJohn Marino 3468*e4b17023SJohn Marino 3469*e4b17023SJohn Marino /* Estimate number of instructions that will be created by expanding STMT. 3470*e4b17023SJohn Marino WEIGHTS contains weights attributed to various constructs. */ 3471*e4b17023SJohn Marino 3472*e4b17023SJohn Marino int 3473*e4b17023SJohn Marino estimate_num_insns (gimple stmt, eni_weights *weights) 3474*e4b17023SJohn Marino { 3475*e4b17023SJohn Marino unsigned cost, i; 3476*e4b17023SJohn Marino enum gimple_code code = gimple_code (stmt); 3477*e4b17023SJohn Marino tree lhs; 3478*e4b17023SJohn Marino tree rhs; 3479*e4b17023SJohn Marino 3480*e4b17023SJohn Marino switch (code) 3481*e4b17023SJohn Marino { 3482*e4b17023SJohn Marino case GIMPLE_ASSIGN: 3483*e4b17023SJohn Marino /* Try to estimate the cost of assignments. We have three cases to 3484*e4b17023SJohn Marino deal with: 3485*e4b17023SJohn Marino 1) Simple assignments to registers; 3486*e4b17023SJohn Marino 2) Stores to things that must live in memory. This includes 3487*e4b17023SJohn Marino "normal" stores to scalars, but also assignments of large 3488*e4b17023SJohn Marino structures, or constructors of big arrays; 3489*e4b17023SJohn Marino 3490*e4b17023SJohn Marino Let us look at the first two cases, assuming we have "a = b + C": 3491*e4b17023SJohn Marino <GIMPLE_ASSIGN <var_decl "a"> 3492*e4b17023SJohn Marino <plus_expr <var_decl "b"> <constant C>> 3493*e4b17023SJohn Marino If "a" is a GIMPLE register, the assignment to it is free on almost 3494*e4b17023SJohn Marino any target, because "a" usually ends up in a real register. Hence 3495*e4b17023SJohn Marino the only cost of this expression comes from the PLUS_EXPR, and we 3496*e4b17023SJohn Marino can ignore the GIMPLE_ASSIGN. 3497*e4b17023SJohn Marino If "a" is not a GIMPLE register, the assignment to "a" will most 3498*e4b17023SJohn Marino likely be a real store, so the cost of the GIMPLE_ASSIGN is the cost 3499*e4b17023SJohn Marino of moving something into "a", which we compute using the function 3500*e4b17023SJohn Marino estimate_move_cost. */ 3501*e4b17023SJohn Marino if (gimple_clobber_p (stmt)) 3502*e4b17023SJohn Marino return 0; /* ={v} {CLOBBER} stmt expands to nothing. */ 3503*e4b17023SJohn Marino 3504*e4b17023SJohn Marino lhs = gimple_assign_lhs (stmt); 3505*e4b17023SJohn Marino rhs = gimple_assign_rhs1 (stmt); 3506*e4b17023SJohn Marino 3507*e4b17023SJohn Marino if (is_gimple_reg (lhs)) 3508*e4b17023SJohn Marino cost = 0; 3509*e4b17023SJohn Marino else 3510*e4b17023SJohn Marino cost = estimate_move_cost (TREE_TYPE (lhs)); 3511*e4b17023SJohn Marino 3512*e4b17023SJohn Marino if (!is_gimple_reg (rhs) && !is_gimple_min_invariant (rhs)) 3513*e4b17023SJohn Marino cost += estimate_move_cost (TREE_TYPE (rhs)); 3514*e4b17023SJohn Marino 3515*e4b17023SJohn Marino cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights, 3516*e4b17023SJohn Marino gimple_assign_rhs1 (stmt), 3517*e4b17023SJohn Marino get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) 3518*e4b17023SJohn Marino == GIMPLE_BINARY_RHS 3519*e4b17023SJohn Marino ? gimple_assign_rhs2 (stmt) : NULL); 3520*e4b17023SJohn Marino break; 3521*e4b17023SJohn Marino 3522*e4b17023SJohn Marino case GIMPLE_COND: 3523*e4b17023SJohn Marino cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights, 3524*e4b17023SJohn Marino gimple_op (stmt, 0), 3525*e4b17023SJohn Marino gimple_op (stmt, 1)); 3526*e4b17023SJohn Marino break; 3527*e4b17023SJohn Marino 3528*e4b17023SJohn Marino case GIMPLE_SWITCH: 3529*e4b17023SJohn Marino /* Take into account cost of the switch + guess 2 conditional jumps for 3530*e4b17023SJohn Marino each case label. 3531*e4b17023SJohn Marino 3532*e4b17023SJohn Marino TODO: once the switch expansion logic is sufficiently separated, we can 3533*e4b17023SJohn Marino do better job on estimating cost of the switch. */ 3534*e4b17023SJohn Marino if (weights->time_based) 3535*e4b17023SJohn Marino cost = floor_log2 (gimple_switch_num_labels (stmt)) * 2; 3536*e4b17023SJohn Marino else 3537*e4b17023SJohn Marino cost = gimple_switch_num_labels (stmt) * 2; 3538*e4b17023SJohn Marino break; 3539*e4b17023SJohn Marino 3540*e4b17023SJohn Marino case GIMPLE_CALL: 3541*e4b17023SJohn Marino { 3542*e4b17023SJohn Marino tree decl = gimple_call_fndecl (stmt); 3543*e4b17023SJohn Marino struct cgraph_node *node = NULL; 3544*e4b17023SJohn Marino 3545*e4b17023SJohn Marino /* Do not special case builtins where we see the body. 3546*e4b17023SJohn Marino This just confuse inliner. */ 3547*e4b17023SJohn Marino if (!decl || !(node = cgraph_get_node (decl)) || node->analyzed) 3548*e4b17023SJohn Marino ; 3549*e4b17023SJohn Marino /* For buitins that are likely expanded to nothing or 3550*e4b17023SJohn Marino inlined do not account operand costs. */ 3551*e4b17023SJohn Marino else if (is_simple_builtin (decl)) 3552*e4b17023SJohn Marino return 0; 3553*e4b17023SJohn Marino else if (is_inexpensive_builtin (decl)) 3554*e4b17023SJohn Marino return weights->target_builtin_call_cost; 3555*e4b17023SJohn Marino else if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL) 3556*e4b17023SJohn Marino { 3557*e4b17023SJohn Marino /* We canonicalize x * x to pow (x, 2.0) with -ffast-math, so 3558*e4b17023SJohn Marino specialize the cheap expansion we do here. 3559*e4b17023SJohn Marino ??? This asks for a more general solution. */ 3560*e4b17023SJohn Marino switch (DECL_FUNCTION_CODE (decl)) 3561*e4b17023SJohn Marino { 3562*e4b17023SJohn Marino case BUILT_IN_POW: 3563*e4b17023SJohn Marino case BUILT_IN_POWF: 3564*e4b17023SJohn Marino case BUILT_IN_POWL: 3565*e4b17023SJohn Marino if (TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST 3566*e4b17023SJohn Marino && REAL_VALUES_EQUAL 3567*e4b17023SJohn Marino (TREE_REAL_CST (gimple_call_arg (stmt, 1)), dconst2)) 3568*e4b17023SJohn Marino return estimate_operator_cost (MULT_EXPR, weights, 3569*e4b17023SJohn Marino gimple_call_arg (stmt, 0), 3570*e4b17023SJohn Marino gimple_call_arg (stmt, 0)); 3571*e4b17023SJohn Marino break; 3572*e4b17023SJohn Marino 3573*e4b17023SJohn Marino default: 3574*e4b17023SJohn Marino break; 3575*e4b17023SJohn Marino } 3576*e4b17023SJohn Marino } 3577*e4b17023SJohn Marino 3578*e4b17023SJohn Marino cost = node ? weights->call_cost : weights->indirect_call_cost; 3579*e4b17023SJohn Marino if (gimple_call_lhs (stmt)) 3580*e4b17023SJohn Marino cost += estimate_move_cost (TREE_TYPE (gimple_call_lhs (stmt))); 3581*e4b17023SJohn Marino for (i = 0; i < gimple_call_num_args (stmt); i++) 3582*e4b17023SJohn Marino { 3583*e4b17023SJohn Marino tree arg = gimple_call_arg (stmt, i); 3584*e4b17023SJohn Marino cost += estimate_move_cost (TREE_TYPE (arg)); 3585*e4b17023SJohn Marino } 3586*e4b17023SJohn Marino break; 3587*e4b17023SJohn Marino } 3588*e4b17023SJohn Marino 3589*e4b17023SJohn Marino case GIMPLE_RETURN: 3590*e4b17023SJohn Marino return weights->return_cost; 3591*e4b17023SJohn Marino 3592*e4b17023SJohn Marino case GIMPLE_GOTO: 3593*e4b17023SJohn Marino case GIMPLE_LABEL: 3594*e4b17023SJohn Marino case GIMPLE_NOP: 3595*e4b17023SJohn Marino case GIMPLE_PHI: 3596*e4b17023SJohn Marino case GIMPLE_PREDICT: 3597*e4b17023SJohn Marino case GIMPLE_DEBUG: 3598*e4b17023SJohn Marino return 0; 3599*e4b17023SJohn Marino 3600*e4b17023SJohn Marino case GIMPLE_ASM: 3601*e4b17023SJohn Marino return asm_str_count (gimple_asm_string (stmt)); 3602*e4b17023SJohn Marino 3603*e4b17023SJohn Marino case GIMPLE_RESX: 3604*e4b17023SJohn Marino /* This is either going to be an external function call with one 3605*e4b17023SJohn Marino argument, or two register copy statements plus a goto. */ 3606*e4b17023SJohn Marino return 2; 3607*e4b17023SJohn Marino 3608*e4b17023SJohn Marino case GIMPLE_EH_DISPATCH: 3609*e4b17023SJohn Marino /* ??? This is going to turn into a switch statement. Ideally 3610*e4b17023SJohn Marino we'd have a look at the eh region and estimate the number of 3611*e4b17023SJohn Marino edges involved. */ 3612*e4b17023SJohn Marino return 10; 3613*e4b17023SJohn Marino 3614*e4b17023SJohn Marino case GIMPLE_BIND: 3615*e4b17023SJohn Marino return estimate_num_insns_seq (gimple_bind_body (stmt), weights); 3616*e4b17023SJohn Marino 3617*e4b17023SJohn Marino case GIMPLE_EH_FILTER: 3618*e4b17023SJohn Marino return estimate_num_insns_seq (gimple_eh_filter_failure (stmt), weights); 3619*e4b17023SJohn Marino 3620*e4b17023SJohn Marino case GIMPLE_CATCH: 3621*e4b17023SJohn Marino return estimate_num_insns_seq (gimple_catch_handler (stmt), weights); 3622*e4b17023SJohn Marino 3623*e4b17023SJohn Marino case GIMPLE_TRY: 3624*e4b17023SJohn Marino return (estimate_num_insns_seq (gimple_try_eval (stmt), weights) 3625*e4b17023SJohn Marino + estimate_num_insns_seq (gimple_try_cleanup (stmt), weights)); 3626*e4b17023SJohn Marino 3627*e4b17023SJohn Marino /* OpenMP directives are generally very expensive. */ 3628*e4b17023SJohn Marino 3629*e4b17023SJohn Marino case GIMPLE_OMP_RETURN: 3630*e4b17023SJohn Marino case GIMPLE_OMP_SECTIONS_SWITCH: 3631*e4b17023SJohn Marino case GIMPLE_OMP_ATOMIC_STORE: 3632*e4b17023SJohn Marino case GIMPLE_OMP_CONTINUE: 3633*e4b17023SJohn Marino /* ...except these, which are cheap. */ 3634*e4b17023SJohn Marino return 0; 3635*e4b17023SJohn Marino 3636*e4b17023SJohn Marino case GIMPLE_OMP_ATOMIC_LOAD: 3637*e4b17023SJohn Marino return weights->omp_cost; 3638*e4b17023SJohn Marino 3639*e4b17023SJohn Marino case GIMPLE_OMP_FOR: 3640*e4b17023SJohn Marino return (weights->omp_cost 3641*e4b17023SJohn Marino + estimate_num_insns_seq (gimple_omp_body (stmt), weights) 3642*e4b17023SJohn Marino + estimate_num_insns_seq (gimple_omp_for_pre_body (stmt), weights)); 3643*e4b17023SJohn Marino 3644*e4b17023SJohn Marino case GIMPLE_OMP_PARALLEL: 3645*e4b17023SJohn Marino case GIMPLE_OMP_TASK: 3646*e4b17023SJohn Marino case GIMPLE_OMP_CRITICAL: 3647*e4b17023SJohn Marino case GIMPLE_OMP_MASTER: 3648*e4b17023SJohn Marino case GIMPLE_OMP_ORDERED: 3649*e4b17023SJohn Marino case GIMPLE_OMP_SECTION: 3650*e4b17023SJohn Marino case GIMPLE_OMP_SECTIONS: 3651*e4b17023SJohn Marino case GIMPLE_OMP_SINGLE: 3652*e4b17023SJohn Marino return (weights->omp_cost 3653*e4b17023SJohn Marino + estimate_num_insns_seq (gimple_omp_body (stmt), weights)); 3654*e4b17023SJohn Marino 3655*e4b17023SJohn Marino case GIMPLE_TRANSACTION: 3656*e4b17023SJohn Marino return (weights->tm_cost 3657*e4b17023SJohn Marino + estimate_num_insns_seq (gimple_transaction_body (stmt), 3658*e4b17023SJohn Marino weights)); 3659*e4b17023SJohn Marino 3660*e4b17023SJohn Marino default: 3661*e4b17023SJohn Marino gcc_unreachable (); 3662*e4b17023SJohn Marino } 3663*e4b17023SJohn Marino 3664*e4b17023SJohn Marino return cost; 3665*e4b17023SJohn Marino } 3666*e4b17023SJohn Marino 3667*e4b17023SJohn Marino /* Estimate number of instructions that will be created by expanding 3668*e4b17023SJohn Marino function FNDECL. WEIGHTS contains weights attributed to various 3669*e4b17023SJohn Marino constructs. */ 3670*e4b17023SJohn Marino 3671*e4b17023SJohn Marino int 3672*e4b17023SJohn Marino estimate_num_insns_fn (tree fndecl, eni_weights *weights) 3673*e4b17023SJohn Marino { 3674*e4b17023SJohn Marino struct function *my_function = DECL_STRUCT_FUNCTION (fndecl); 3675*e4b17023SJohn Marino gimple_stmt_iterator bsi; 3676*e4b17023SJohn Marino basic_block bb; 3677*e4b17023SJohn Marino int n = 0; 3678*e4b17023SJohn Marino 3679*e4b17023SJohn Marino gcc_assert (my_function && my_function->cfg); 3680*e4b17023SJohn Marino FOR_EACH_BB_FN (bb, my_function) 3681*e4b17023SJohn Marino { 3682*e4b17023SJohn Marino for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) 3683*e4b17023SJohn Marino n += estimate_num_insns (gsi_stmt (bsi), weights); 3684*e4b17023SJohn Marino } 3685*e4b17023SJohn Marino 3686*e4b17023SJohn Marino return n; 3687*e4b17023SJohn Marino } 3688*e4b17023SJohn Marino 3689*e4b17023SJohn Marino 3690*e4b17023SJohn Marino /* Initializes weights used by estimate_num_insns. */ 3691*e4b17023SJohn Marino 3692*e4b17023SJohn Marino void 3693*e4b17023SJohn Marino init_inline_once (void) 3694*e4b17023SJohn Marino { 3695*e4b17023SJohn Marino eni_size_weights.call_cost = 1; 3696*e4b17023SJohn Marino eni_size_weights.indirect_call_cost = 3; 3697*e4b17023SJohn Marino eni_size_weights.target_builtin_call_cost = 1; 3698*e4b17023SJohn Marino eni_size_weights.div_mod_cost = 1; 3699*e4b17023SJohn Marino eni_size_weights.omp_cost = 40; 3700*e4b17023SJohn Marino eni_size_weights.tm_cost = 10; 3701*e4b17023SJohn Marino eni_size_weights.time_based = false; 3702*e4b17023SJohn Marino eni_size_weights.return_cost = 1; 3703*e4b17023SJohn Marino 3704*e4b17023SJohn Marino /* Estimating time for call is difficult, since we have no idea what the 3705*e4b17023SJohn Marino called function does. In the current uses of eni_time_weights, 3706*e4b17023SJohn Marino underestimating the cost does less harm than overestimating it, so 3707*e4b17023SJohn Marino we choose a rather small value here. */ 3708*e4b17023SJohn Marino eni_time_weights.call_cost = 10; 3709*e4b17023SJohn Marino eni_time_weights.indirect_call_cost = 15; 3710*e4b17023SJohn Marino eni_time_weights.target_builtin_call_cost = 1; 3711*e4b17023SJohn Marino eni_time_weights.div_mod_cost = 10; 3712*e4b17023SJohn Marino eni_time_weights.omp_cost = 40; 3713*e4b17023SJohn Marino eni_time_weights.tm_cost = 40; 3714*e4b17023SJohn Marino eni_time_weights.time_based = true; 3715*e4b17023SJohn Marino eni_time_weights.return_cost = 2; 3716*e4b17023SJohn Marino } 3717*e4b17023SJohn Marino 3718*e4b17023SJohn Marino /* Estimate the number of instructions in a gimple_seq. */ 3719*e4b17023SJohn Marino 3720*e4b17023SJohn Marino int 3721*e4b17023SJohn Marino count_insns_seq (gimple_seq seq, eni_weights *weights) 3722*e4b17023SJohn Marino { 3723*e4b17023SJohn Marino gimple_stmt_iterator gsi; 3724*e4b17023SJohn Marino int n = 0; 3725*e4b17023SJohn Marino for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi)) 3726*e4b17023SJohn Marino n += estimate_num_insns (gsi_stmt (gsi), weights); 3727*e4b17023SJohn Marino 3728*e4b17023SJohn Marino return n; 3729*e4b17023SJohn Marino } 3730*e4b17023SJohn Marino 3731*e4b17023SJohn Marino 3732*e4b17023SJohn Marino /* Install new lexical TREE_BLOCK underneath 'current_block'. */ 3733*e4b17023SJohn Marino 3734*e4b17023SJohn Marino static void 3735*e4b17023SJohn Marino prepend_lexical_block (tree current_block, tree new_block) 3736*e4b17023SJohn Marino { 3737*e4b17023SJohn Marino BLOCK_CHAIN (new_block) = BLOCK_SUBBLOCKS (current_block); 3738*e4b17023SJohn Marino BLOCK_SUBBLOCKS (current_block) = new_block; 3739*e4b17023SJohn Marino BLOCK_SUPERCONTEXT (new_block) = current_block; 3740*e4b17023SJohn Marino } 3741*e4b17023SJohn Marino 3742*e4b17023SJohn Marino /* Add local variables from CALLEE to CALLER. */ 3743*e4b17023SJohn Marino 3744*e4b17023SJohn Marino static inline void 3745*e4b17023SJohn Marino add_local_variables (struct function *callee, struct function *caller, 3746*e4b17023SJohn Marino copy_body_data *id, bool check_var_ann) 3747*e4b17023SJohn Marino { 3748*e4b17023SJohn Marino tree var; 3749*e4b17023SJohn Marino unsigned ix; 3750*e4b17023SJohn Marino 3751*e4b17023SJohn Marino FOR_EACH_LOCAL_DECL (callee, ix, var) 3752*e4b17023SJohn Marino if (TREE_STATIC (var) && !TREE_ASM_WRITTEN (var)) 3753*e4b17023SJohn Marino { 3754*e4b17023SJohn Marino if (!check_var_ann 3755*e4b17023SJohn Marino || (var_ann (var) && add_referenced_var (var))) 3756*e4b17023SJohn Marino add_local_decl (caller, var); 3757*e4b17023SJohn Marino } 3758*e4b17023SJohn Marino else if (!can_be_nonlocal (var, id)) 3759*e4b17023SJohn Marino { 3760*e4b17023SJohn Marino tree new_var = remap_decl (var, id); 3761*e4b17023SJohn Marino 3762*e4b17023SJohn Marino /* Remap debug-expressions. */ 3763*e4b17023SJohn Marino if (TREE_CODE (new_var) == VAR_DECL 3764*e4b17023SJohn Marino && DECL_DEBUG_EXPR_IS_FROM (new_var) 3765*e4b17023SJohn Marino && new_var != var) 3766*e4b17023SJohn Marino { 3767*e4b17023SJohn Marino tree tem = DECL_DEBUG_EXPR (var); 3768*e4b17023SJohn Marino bool old_regimplify = id->regimplify; 3769*e4b17023SJohn Marino id->remapping_type_depth++; 3770*e4b17023SJohn Marino walk_tree (&tem, copy_tree_body_r, id, NULL); 3771*e4b17023SJohn Marino id->remapping_type_depth--; 3772*e4b17023SJohn Marino id->regimplify = old_regimplify; 3773*e4b17023SJohn Marino SET_DECL_DEBUG_EXPR (new_var, tem); 3774*e4b17023SJohn Marino } 3775*e4b17023SJohn Marino add_local_decl (caller, new_var); 3776*e4b17023SJohn Marino } 3777*e4b17023SJohn Marino } 3778*e4b17023SJohn Marino 3779*e4b17023SJohn Marino /* If STMT is a GIMPLE_CALL, replace it with its inline expansion. */ 3780*e4b17023SJohn Marino 3781*e4b17023SJohn Marino static bool 3782*e4b17023SJohn Marino expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id) 3783*e4b17023SJohn Marino { 3784*e4b17023SJohn Marino tree use_retvar; 3785*e4b17023SJohn Marino tree fn; 3786*e4b17023SJohn Marino struct pointer_map_t *st, *dst; 3787*e4b17023SJohn Marino tree return_slot; 3788*e4b17023SJohn Marino tree modify_dest; 3789*e4b17023SJohn Marino location_t saved_location; 3790*e4b17023SJohn Marino struct cgraph_edge *cg_edge; 3791*e4b17023SJohn Marino cgraph_inline_failed_t reason; 3792*e4b17023SJohn Marino basic_block return_block; 3793*e4b17023SJohn Marino edge e; 3794*e4b17023SJohn Marino gimple_stmt_iterator gsi, stmt_gsi; 3795*e4b17023SJohn Marino bool successfully_inlined = FALSE; 3796*e4b17023SJohn Marino bool purge_dead_abnormal_edges; 3797*e4b17023SJohn Marino 3798*e4b17023SJohn Marino /* Set input_location here so we get the right instantiation context 3799*e4b17023SJohn Marino if we call instantiate_decl from inlinable_function_p. */ 3800*e4b17023SJohn Marino saved_location = input_location; 3801*e4b17023SJohn Marino if (gimple_has_location (stmt)) 3802*e4b17023SJohn Marino input_location = gimple_location (stmt); 3803*e4b17023SJohn Marino 3804*e4b17023SJohn Marino /* From here on, we're only interested in CALL_EXPRs. */ 3805*e4b17023SJohn Marino if (gimple_code (stmt) != GIMPLE_CALL) 3806*e4b17023SJohn Marino goto egress; 3807*e4b17023SJohn Marino 3808*e4b17023SJohn Marino cg_edge = cgraph_edge (id->dst_node, stmt); 3809*e4b17023SJohn Marino gcc_checking_assert (cg_edge); 3810*e4b17023SJohn Marino /* First, see if we can figure out what function is being called. 3811*e4b17023SJohn Marino If we cannot, then there is no hope of inlining the function. */ 3812*e4b17023SJohn Marino if (cg_edge->indirect_unknown_callee) 3813*e4b17023SJohn Marino goto egress; 3814*e4b17023SJohn Marino fn = cg_edge->callee->decl; 3815*e4b17023SJohn Marino gcc_checking_assert (fn); 3816*e4b17023SJohn Marino 3817*e4b17023SJohn Marino /* If FN is a declaration of a function in a nested scope that was 3818*e4b17023SJohn Marino globally declared inline, we don't set its DECL_INITIAL. 3819*e4b17023SJohn Marino However, we can't blindly follow DECL_ABSTRACT_ORIGIN because the 3820*e4b17023SJohn Marino C++ front-end uses it for cdtors to refer to their internal 3821*e4b17023SJohn Marino declarations, that are not real functions. Fortunately those 3822*e4b17023SJohn Marino don't have trees to be saved, so we can tell by checking their 3823*e4b17023SJohn Marino gimple_body. */ 3824*e4b17023SJohn Marino if (!DECL_INITIAL (fn) 3825*e4b17023SJohn Marino && DECL_ABSTRACT_ORIGIN (fn) 3826*e4b17023SJohn Marino && gimple_has_body_p (DECL_ABSTRACT_ORIGIN (fn))) 3827*e4b17023SJohn Marino fn = DECL_ABSTRACT_ORIGIN (fn); 3828*e4b17023SJohn Marino 3829*e4b17023SJohn Marino /* Don't try to inline functions that are not well-suited to inlining. */ 3830*e4b17023SJohn Marino if (!cgraph_inline_p (cg_edge, &reason)) 3831*e4b17023SJohn Marino { 3832*e4b17023SJohn Marino /* If this call was originally indirect, we do not want to emit any 3833*e4b17023SJohn Marino inlining related warnings or sorry messages because there are no 3834*e4b17023SJohn Marino guarantees regarding those. */ 3835*e4b17023SJohn Marino if (cg_edge->indirect_inlining_edge) 3836*e4b17023SJohn Marino goto egress; 3837*e4b17023SJohn Marino 3838*e4b17023SJohn Marino if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) 3839*e4b17023SJohn Marino /* Avoid warnings during early inline pass. */ 3840*e4b17023SJohn Marino && cgraph_global_info_ready 3841*e4b17023SJohn Marino /* PR 20090218-1_0.c. Body can be provided by another module. */ 3842*e4b17023SJohn Marino && (reason != CIF_BODY_NOT_AVAILABLE || !flag_generate_lto)) 3843*e4b17023SJohn Marino { 3844*e4b17023SJohn Marino error ("inlining failed in call to always_inline %q+F: %s", fn, 3845*e4b17023SJohn Marino cgraph_inline_failed_string (reason)); 3846*e4b17023SJohn Marino error ("called from here"); 3847*e4b17023SJohn Marino } 3848*e4b17023SJohn Marino else if (warn_inline 3849*e4b17023SJohn Marino && DECL_DECLARED_INLINE_P (fn) 3850*e4b17023SJohn Marino && !DECL_NO_INLINE_WARNING_P (fn) 3851*e4b17023SJohn Marino && !DECL_IN_SYSTEM_HEADER (fn) 3852*e4b17023SJohn Marino && reason != CIF_UNSPECIFIED 3853*e4b17023SJohn Marino && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fn)) 3854*e4b17023SJohn Marino /* Do not warn about not inlined recursive calls. */ 3855*e4b17023SJohn Marino && !cgraph_edge_recursive_p (cg_edge) 3856*e4b17023SJohn Marino /* Avoid warnings during early inline pass. */ 3857*e4b17023SJohn Marino && cgraph_global_info_ready) 3858*e4b17023SJohn Marino { 3859*e4b17023SJohn Marino warning (OPT_Winline, "inlining failed in call to %q+F: %s", 3860*e4b17023SJohn Marino fn, _(cgraph_inline_failed_string (reason))); 3861*e4b17023SJohn Marino warning (OPT_Winline, "called from here"); 3862*e4b17023SJohn Marino } 3863*e4b17023SJohn Marino goto egress; 3864*e4b17023SJohn Marino } 3865*e4b17023SJohn Marino fn = cg_edge->callee->decl; 3866*e4b17023SJohn Marino 3867*e4b17023SJohn Marino #ifdef ENABLE_CHECKING 3868*e4b17023SJohn Marino if (cg_edge->callee->decl != id->dst_node->decl) 3869*e4b17023SJohn Marino verify_cgraph_node (cg_edge->callee); 3870*e4b17023SJohn Marino #endif 3871*e4b17023SJohn Marino 3872*e4b17023SJohn Marino /* We will be inlining this callee. */ 3873*e4b17023SJohn Marino id->eh_lp_nr = lookup_stmt_eh_lp (stmt); 3874*e4b17023SJohn Marino 3875*e4b17023SJohn Marino /* Update the callers EH personality. */ 3876*e4b17023SJohn Marino if (DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl)) 3877*e4b17023SJohn Marino DECL_FUNCTION_PERSONALITY (cg_edge->caller->decl) 3878*e4b17023SJohn Marino = DECL_FUNCTION_PERSONALITY (cg_edge->callee->decl); 3879*e4b17023SJohn Marino 3880*e4b17023SJohn Marino /* Split the block holding the GIMPLE_CALL. */ 3881*e4b17023SJohn Marino e = split_block (bb, stmt); 3882*e4b17023SJohn Marino bb = e->src; 3883*e4b17023SJohn Marino return_block = e->dest; 3884*e4b17023SJohn Marino remove_edge (e); 3885*e4b17023SJohn Marino 3886*e4b17023SJohn Marino /* split_block splits after the statement; work around this by 3887*e4b17023SJohn Marino moving the call into the second block manually. Not pretty, 3888*e4b17023SJohn Marino but seems easier than doing the CFG manipulation by hand 3889*e4b17023SJohn Marino when the GIMPLE_CALL is in the last statement of BB. */ 3890*e4b17023SJohn Marino stmt_gsi = gsi_last_bb (bb); 3891*e4b17023SJohn Marino gsi_remove (&stmt_gsi, false); 3892*e4b17023SJohn Marino 3893*e4b17023SJohn Marino /* If the GIMPLE_CALL was in the last statement of BB, it may have 3894*e4b17023SJohn Marino been the source of abnormal edges. In this case, schedule 3895*e4b17023SJohn Marino the removal of dead abnormal edges. */ 3896*e4b17023SJohn Marino gsi = gsi_start_bb (return_block); 3897*e4b17023SJohn Marino if (gsi_end_p (gsi)) 3898*e4b17023SJohn Marino { 3899*e4b17023SJohn Marino gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); 3900*e4b17023SJohn Marino purge_dead_abnormal_edges = true; 3901*e4b17023SJohn Marino } 3902*e4b17023SJohn Marino else 3903*e4b17023SJohn Marino { 3904*e4b17023SJohn Marino gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); 3905*e4b17023SJohn Marino purge_dead_abnormal_edges = false; 3906*e4b17023SJohn Marino } 3907*e4b17023SJohn Marino 3908*e4b17023SJohn Marino stmt_gsi = gsi_start_bb (return_block); 3909*e4b17023SJohn Marino 3910*e4b17023SJohn Marino /* Build a block containing code to initialize the arguments, the 3911*e4b17023SJohn Marino actual inline expansion of the body, and a label for the return 3912*e4b17023SJohn Marino statements within the function to jump to. The type of the 3913*e4b17023SJohn Marino statement expression is the return type of the function call. */ 3914*e4b17023SJohn Marino id->block = make_node (BLOCK); 3915*e4b17023SJohn Marino BLOCK_ABSTRACT_ORIGIN (id->block) = fn; 3916*e4b17023SJohn Marino BLOCK_SOURCE_LOCATION (id->block) = input_location; 3917*e4b17023SJohn Marino prepend_lexical_block (gimple_block (stmt), id->block); 3918*e4b17023SJohn Marino 3919*e4b17023SJohn Marino /* Local declarations will be replaced by their equivalents in this 3920*e4b17023SJohn Marino map. */ 3921*e4b17023SJohn Marino st = id->decl_map; 3922*e4b17023SJohn Marino id->decl_map = pointer_map_create (); 3923*e4b17023SJohn Marino dst = id->debug_map; 3924*e4b17023SJohn Marino id->debug_map = NULL; 3925*e4b17023SJohn Marino 3926*e4b17023SJohn Marino /* Record the function we are about to inline. */ 3927*e4b17023SJohn Marino id->src_fn = fn; 3928*e4b17023SJohn Marino id->src_node = cg_edge->callee; 3929*e4b17023SJohn Marino id->src_cfun = DECL_STRUCT_FUNCTION (fn); 3930*e4b17023SJohn Marino id->gimple_call = stmt; 3931*e4b17023SJohn Marino 3932*e4b17023SJohn Marino gcc_assert (!id->src_cfun->after_inlining); 3933*e4b17023SJohn Marino 3934*e4b17023SJohn Marino id->entry_bb = bb; 3935*e4b17023SJohn Marino if (lookup_attribute ("cold", DECL_ATTRIBUTES (fn))) 3936*e4b17023SJohn Marino { 3937*e4b17023SJohn Marino gimple_stmt_iterator si = gsi_last_bb (bb); 3938*e4b17023SJohn Marino gsi_insert_after (&si, gimple_build_predict (PRED_COLD_FUNCTION, 3939*e4b17023SJohn Marino NOT_TAKEN), 3940*e4b17023SJohn Marino GSI_NEW_STMT); 3941*e4b17023SJohn Marino } 3942*e4b17023SJohn Marino initialize_inlined_parameters (id, stmt, fn, bb); 3943*e4b17023SJohn Marino 3944*e4b17023SJohn Marino if (DECL_INITIAL (fn)) 3945*e4b17023SJohn Marino prepend_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id)); 3946*e4b17023SJohn Marino 3947*e4b17023SJohn Marino /* Return statements in the function body will be replaced by jumps 3948*e4b17023SJohn Marino to the RET_LABEL. */ 3949*e4b17023SJohn Marino gcc_assert (DECL_INITIAL (fn)); 3950*e4b17023SJohn Marino gcc_assert (TREE_CODE (DECL_INITIAL (fn)) == BLOCK); 3951*e4b17023SJohn Marino 3952*e4b17023SJohn Marino /* Find the LHS to which the result of this call is assigned. */ 3953*e4b17023SJohn Marino return_slot = NULL; 3954*e4b17023SJohn Marino if (gimple_call_lhs (stmt)) 3955*e4b17023SJohn Marino { 3956*e4b17023SJohn Marino modify_dest = gimple_call_lhs (stmt); 3957*e4b17023SJohn Marino 3958*e4b17023SJohn Marino /* The function which we are inlining might not return a value, 3959*e4b17023SJohn Marino in which case we should issue a warning that the function 3960*e4b17023SJohn Marino does not return a value. In that case the optimizers will 3961*e4b17023SJohn Marino see that the variable to which the value is assigned was not 3962*e4b17023SJohn Marino initialized. We do not want to issue a warning about that 3963*e4b17023SJohn Marino uninitialized variable. */ 3964*e4b17023SJohn Marino if (DECL_P (modify_dest)) 3965*e4b17023SJohn Marino TREE_NO_WARNING (modify_dest) = 1; 3966*e4b17023SJohn Marino 3967*e4b17023SJohn Marino if (gimple_call_return_slot_opt_p (stmt)) 3968*e4b17023SJohn Marino { 3969*e4b17023SJohn Marino return_slot = modify_dest; 3970*e4b17023SJohn Marino modify_dest = NULL; 3971*e4b17023SJohn Marino } 3972*e4b17023SJohn Marino } 3973*e4b17023SJohn Marino else 3974*e4b17023SJohn Marino modify_dest = NULL; 3975*e4b17023SJohn Marino 3976*e4b17023SJohn Marino /* If we are inlining a call to the C++ operator new, we don't want 3977*e4b17023SJohn Marino to use type based alias analysis on the return value. Otherwise 3978*e4b17023SJohn Marino we may get confused if the compiler sees that the inlined new 3979*e4b17023SJohn Marino function returns a pointer which was just deleted. See bug 3980*e4b17023SJohn Marino 33407. */ 3981*e4b17023SJohn Marino if (DECL_IS_OPERATOR_NEW (fn)) 3982*e4b17023SJohn Marino { 3983*e4b17023SJohn Marino return_slot = NULL; 3984*e4b17023SJohn Marino modify_dest = NULL; 3985*e4b17023SJohn Marino } 3986*e4b17023SJohn Marino 3987*e4b17023SJohn Marino /* Declare the return variable for the function. */ 3988*e4b17023SJohn Marino use_retvar = declare_return_variable (id, return_slot, modify_dest, bb); 3989*e4b17023SJohn Marino 3990*e4b17023SJohn Marino /* Add local vars in this inlined callee to caller. */ 3991*e4b17023SJohn Marino add_local_variables (id->src_cfun, cfun, id, true); 3992*e4b17023SJohn Marino 3993*e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS)) 3994*e4b17023SJohn Marino { 3995*e4b17023SJohn Marino fprintf (dump_file, "Inlining "); 3996*e4b17023SJohn Marino print_generic_expr (dump_file, id->src_fn, 0); 3997*e4b17023SJohn Marino fprintf (dump_file, " to "); 3998*e4b17023SJohn Marino print_generic_expr (dump_file, id->dst_fn, 0); 3999*e4b17023SJohn Marino fprintf (dump_file, " with frequency %i\n", cg_edge->frequency); 4000*e4b17023SJohn Marino } 4001*e4b17023SJohn Marino 4002*e4b17023SJohn Marino /* This is it. Duplicate the callee body. Assume callee is 4003*e4b17023SJohn Marino pre-gimplified. Note that we must not alter the caller 4004*e4b17023SJohn Marino function in any way before this point, as this CALL_EXPR may be 4005*e4b17023SJohn Marino a self-referential call; if we're calling ourselves, we need to 4006*e4b17023SJohn Marino duplicate our body before altering anything. */ 4007*e4b17023SJohn Marino copy_body (id, bb->count, 4008*e4b17023SJohn Marino cg_edge->frequency * REG_BR_PROB_BASE / CGRAPH_FREQ_BASE, 4009*e4b17023SJohn Marino bb, return_block, NULL, NULL); 4010*e4b17023SJohn Marino 4011*e4b17023SJohn Marino /* Reset the escaped solution. */ 4012*e4b17023SJohn Marino if (cfun->gimple_df) 4013*e4b17023SJohn Marino pt_solution_reset (&cfun->gimple_df->escaped); 4014*e4b17023SJohn Marino 4015*e4b17023SJohn Marino /* Clean up. */ 4016*e4b17023SJohn Marino if (id->debug_map) 4017*e4b17023SJohn Marino { 4018*e4b17023SJohn Marino pointer_map_destroy (id->debug_map); 4019*e4b17023SJohn Marino id->debug_map = dst; 4020*e4b17023SJohn Marino } 4021*e4b17023SJohn Marino pointer_map_destroy (id->decl_map); 4022*e4b17023SJohn Marino id->decl_map = st; 4023*e4b17023SJohn Marino 4024*e4b17023SJohn Marino /* Unlink the calls virtual operands before replacing it. */ 4025*e4b17023SJohn Marino unlink_stmt_vdef (stmt); 4026*e4b17023SJohn Marino 4027*e4b17023SJohn Marino /* If the inlined function returns a result that we care about, 4028*e4b17023SJohn Marino substitute the GIMPLE_CALL with an assignment of the return 4029*e4b17023SJohn Marino variable to the LHS of the call. That is, if STMT was 4030*e4b17023SJohn Marino 'a = foo (...)', substitute the call with 'a = USE_RETVAR'. */ 4031*e4b17023SJohn Marino if (use_retvar && gimple_call_lhs (stmt)) 4032*e4b17023SJohn Marino { 4033*e4b17023SJohn Marino gimple old_stmt = stmt; 4034*e4b17023SJohn Marino stmt = gimple_build_assign (gimple_call_lhs (stmt), use_retvar); 4035*e4b17023SJohn Marino gsi_replace (&stmt_gsi, stmt, false); 4036*e4b17023SJohn Marino if (gimple_in_ssa_p (cfun)) 4037*e4b17023SJohn Marino mark_symbols_for_renaming (stmt); 4038*e4b17023SJohn Marino maybe_clean_or_replace_eh_stmt (old_stmt, stmt); 4039*e4b17023SJohn Marino } 4040*e4b17023SJohn Marino else 4041*e4b17023SJohn Marino { 4042*e4b17023SJohn Marino /* Handle the case of inlining a function with no return 4043*e4b17023SJohn Marino statement, which causes the return value to become undefined. */ 4044*e4b17023SJohn Marino if (gimple_call_lhs (stmt) 4045*e4b17023SJohn Marino && TREE_CODE (gimple_call_lhs (stmt)) == SSA_NAME) 4046*e4b17023SJohn Marino { 4047*e4b17023SJohn Marino tree name = gimple_call_lhs (stmt); 4048*e4b17023SJohn Marino tree var = SSA_NAME_VAR (name); 4049*e4b17023SJohn Marino tree def = gimple_default_def (cfun, var); 4050*e4b17023SJohn Marino 4051*e4b17023SJohn Marino if (def) 4052*e4b17023SJohn Marino { 4053*e4b17023SJohn Marino /* If the variable is used undefined, make this name 4054*e4b17023SJohn Marino undefined via a move. */ 4055*e4b17023SJohn Marino stmt = gimple_build_assign (gimple_call_lhs (stmt), def); 4056*e4b17023SJohn Marino gsi_replace (&stmt_gsi, stmt, true); 4057*e4b17023SJohn Marino } 4058*e4b17023SJohn Marino else 4059*e4b17023SJohn Marino { 4060*e4b17023SJohn Marino /* Otherwise make this variable undefined. */ 4061*e4b17023SJohn Marino gsi_remove (&stmt_gsi, true); 4062*e4b17023SJohn Marino set_default_def (var, name); 4063*e4b17023SJohn Marino SSA_NAME_DEF_STMT (name) = gimple_build_nop (); 4064*e4b17023SJohn Marino } 4065*e4b17023SJohn Marino } 4066*e4b17023SJohn Marino else 4067*e4b17023SJohn Marino gsi_remove (&stmt_gsi, true); 4068*e4b17023SJohn Marino } 4069*e4b17023SJohn Marino 4070*e4b17023SJohn Marino if (purge_dead_abnormal_edges) 4071*e4b17023SJohn Marino { 4072*e4b17023SJohn Marino gimple_purge_dead_eh_edges (return_block); 4073*e4b17023SJohn Marino gimple_purge_dead_abnormal_call_edges (return_block); 4074*e4b17023SJohn Marino } 4075*e4b17023SJohn Marino 4076*e4b17023SJohn Marino /* If the value of the new expression is ignored, that's OK. We 4077*e4b17023SJohn Marino don't warn about this for CALL_EXPRs, so we shouldn't warn about 4078*e4b17023SJohn Marino the equivalent inlined version either. */ 4079*e4b17023SJohn Marino if (is_gimple_assign (stmt)) 4080*e4b17023SJohn Marino { 4081*e4b17023SJohn Marino gcc_assert (gimple_assign_single_p (stmt) 4082*e4b17023SJohn Marino || CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))); 4083*e4b17023SJohn Marino TREE_USED (gimple_assign_rhs1 (stmt)) = 1; 4084*e4b17023SJohn Marino } 4085*e4b17023SJohn Marino 4086*e4b17023SJohn Marino /* Output the inlining info for this abstract function, since it has been 4087*e4b17023SJohn Marino inlined. If we don't do this now, we can lose the information about the 4088*e4b17023SJohn Marino variables in the function when the blocks get blown away as soon as we 4089*e4b17023SJohn Marino remove the cgraph node. */ 4090*e4b17023SJohn Marino (*debug_hooks->outlining_inline_function) (cg_edge->callee->decl); 4091*e4b17023SJohn Marino 4092*e4b17023SJohn Marino /* Update callgraph if needed. */ 4093*e4b17023SJohn Marino cgraph_remove_node (cg_edge->callee); 4094*e4b17023SJohn Marino 4095*e4b17023SJohn Marino id->block = NULL_TREE; 4096*e4b17023SJohn Marino successfully_inlined = TRUE; 4097*e4b17023SJohn Marino 4098*e4b17023SJohn Marino egress: 4099*e4b17023SJohn Marino input_location = saved_location; 4100*e4b17023SJohn Marino return successfully_inlined; 4101*e4b17023SJohn Marino } 4102*e4b17023SJohn Marino 4103*e4b17023SJohn Marino /* Expand call statements reachable from STMT_P. 4104*e4b17023SJohn Marino We can only have CALL_EXPRs as the "toplevel" tree code or nested 4105*e4b17023SJohn Marino in a MODIFY_EXPR. */ 4106*e4b17023SJohn Marino 4107*e4b17023SJohn Marino static bool 4108*e4b17023SJohn Marino gimple_expand_calls_inline (basic_block bb, copy_body_data *id) 4109*e4b17023SJohn Marino { 4110*e4b17023SJohn Marino gimple_stmt_iterator gsi; 4111*e4b17023SJohn Marino 4112*e4b17023SJohn Marino for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) 4113*e4b17023SJohn Marino { 4114*e4b17023SJohn Marino gimple stmt = gsi_stmt (gsi); 4115*e4b17023SJohn Marino 4116*e4b17023SJohn Marino if (is_gimple_call (stmt) 4117*e4b17023SJohn Marino && expand_call_inline (bb, stmt, id)) 4118*e4b17023SJohn Marino return true; 4119*e4b17023SJohn Marino } 4120*e4b17023SJohn Marino 4121*e4b17023SJohn Marino return false; 4122*e4b17023SJohn Marino } 4123*e4b17023SJohn Marino 4124*e4b17023SJohn Marino 4125*e4b17023SJohn Marino /* Walk all basic blocks created after FIRST and try to fold every statement 4126*e4b17023SJohn Marino in the STATEMENTS pointer set. */ 4127*e4b17023SJohn Marino 4128*e4b17023SJohn Marino static void 4129*e4b17023SJohn Marino fold_marked_statements (int first, struct pointer_set_t *statements) 4130*e4b17023SJohn Marino { 4131*e4b17023SJohn Marino for (; first < n_basic_blocks; first++) 4132*e4b17023SJohn Marino if (BASIC_BLOCK (first)) 4133*e4b17023SJohn Marino { 4134*e4b17023SJohn Marino gimple_stmt_iterator gsi; 4135*e4b17023SJohn Marino 4136*e4b17023SJohn Marino for (gsi = gsi_start_bb (BASIC_BLOCK (first)); 4137*e4b17023SJohn Marino !gsi_end_p (gsi); 4138*e4b17023SJohn Marino gsi_next (&gsi)) 4139*e4b17023SJohn Marino if (pointer_set_contains (statements, gsi_stmt (gsi))) 4140*e4b17023SJohn Marino { 4141*e4b17023SJohn Marino gimple old_stmt = gsi_stmt (gsi); 4142*e4b17023SJohn Marino tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl (old_stmt) : 0; 4143*e4b17023SJohn Marino 4144*e4b17023SJohn Marino if (old_decl && DECL_BUILT_IN (old_decl)) 4145*e4b17023SJohn Marino { 4146*e4b17023SJohn Marino /* Folding builtins can create multiple instructions, 4147*e4b17023SJohn Marino we need to look at all of them. */ 4148*e4b17023SJohn Marino gimple_stmt_iterator i2 = gsi; 4149*e4b17023SJohn Marino gsi_prev (&i2); 4150*e4b17023SJohn Marino if (fold_stmt (&gsi)) 4151*e4b17023SJohn Marino { 4152*e4b17023SJohn Marino gimple new_stmt; 4153*e4b17023SJohn Marino /* If a builtin at the end of a bb folded into nothing, 4154*e4b17023SJohn Marino the following loop won't work. */ 4155*e4b17023SJohn Marino if (gsi_end_p (gsi)) 4156*e4b17023SJohn Marino { 4157*e4b17023SJohn Marino cgraph_update_edges_for_call_stmt (old_stmt, 4158*e4b17023SJohn Marino old_decl, NULL); 4159*e4b17023SJohn Marino break; 4160*e4b17023SJohn Marino } 4161*e4b17023SJohn Marino if (gsi_end_p (i2)) 4162*e4b17023SJohn Marino i2 = gsi_start_bb (BASIC_BLOCK (first)); 4163*e4b17023SJohn Marino else 4164*e4b17023SJohn Marino gsi_next (&i2); 4165*e4b17023SJohn Marino while (1) 4166*e4b17023SJohn Marino { 4167*e4b17023SJohn Marino new_stmt = gsi_stmt (i2); 4168*e4b17023SJohn Marino update_stmt (new_stmt); 4169*e4b17023SJohn Marino cgraph_update_edges_for_call_stmt (old_stmt, old_decl, 4170*e4b17023SJohn Marino new_stmt); 4171*e4b17023SJohn Marino 4172*e4b17023SJohn Marino if (new_stmt == gsi_stmt (gsi)) 4173*e4b17023SJohn Marino { 4174*e4b17023SJohn Marino /* It is okay to check only for the very last 4175*e4b17023SJohn Marino of these statements. If it is a throwing 4176*e4b17023SJohn Marino statement nothing will change. If it isn't 4177*e4b17023SJohn Marino this can remove EH edges. If that weren't 4178*e4b17023SJohn Marino correct then because some intermediate stmts 4179*e4b17023SJohn Marino throw, but not the last one. That would mean 4180*e4b17023SJohn Marino we'd have to split the block, which we can't 4181*e4b17023SJohn Marino here and we'd loose anyway. And as builtins 4182*e4b17023SJohn Marino probably never throw, this all 4183*e4b17023SJohn Marino is mood anyway. */ 4184*e4b17023SJohn Marino if (maybe_clean_or_replace_eh_stmt (old_stmt, 4185*e4b17023SJohn Marino new_stmt)) 4186*e4b17023SJohn Marino gimple_purge_dead_eh_edges (BASIC_BLOCK (first)); 4187*e4b17023SJohn Marino break; 4188*e4b17023SJohn Marino } 4189*e4b17023SJohn Marino gsi_next (&i2); 4190*e4b17023SJohn Marino } 4191*e4b17023SJohn Marino } 4192*e4b17023SJohn Marino } 4193*e4b17023SJohn Marino else if (fold_stmt (&gsi)) 4194*e4b17023SJohn Marino { 4195*e4b17023SJohn Marino /* Re-read the statement from GSI as fold_stmt() may 4196*e4b17023SJohn Marino have changed it. */ 4197*e4b17023SJohn Marino gimple new_stmt = gsi_stmt (gsi); 4198*e4b17023SJohn Marino update_stmt (new_stmt); 4199*e4b17023SJohn Marino 4200*e4b17023SJohn Marino if (is_gimple_call (old_stmt) 4201*e4b17023SJohn Marino || is_gimple_call (new_stmt)) 4202*e4b17023SJohn Marino cgraph_update_edges_for_call_stmt (old_stmt, old_decl, 4203*e4b17023SJohn Marino new_stmt); 4204*e4b17023SJohn Marino 4205*e4b17023SJohn Marino if (maybe_clean_or_replace_eh_stmt (old_stmt, new_stmt)) 4206*e4b17023SJohn Marino gimple_purge_dead_eh_edges (BASIC_BLOCK (first)); 4207*e4b17023SJohn Marino } 4208*e4b17023SJohn Marino } 4209*e4b17023SJohn Marino } 4210*e4b17023SJohn Marino } 4211*e4b17023SJohn Marino 4212*e4b17023SJohn Marino /* Return true if BB has at least one abnormal outgoing edge. */ 4213*e4b17023SJohn Marino 4214*e4b17023SJohn Marino static inline bool 4215*e4b17023SJohn Marino has_abnormal_outgoing_edge_p (basic_block bb) 4216*e4b17023SJohn Marino { 4217*e4b17023SJohn Marino edge e; 4218*e4b17023SJohn Marino edge_iterator ei; 4219*e4b17023SJohn Marino 4220*e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs) 4221*e4b17023SJohn Marino if (e->flags & EDGE_ABNORMAL) 4222*e4b17023SJohn Marino return true; 4223*e4b17023SJohn Marino 4224*e4b17023SJohn Marino return false; 4225*e4b17023SJohn Marino } 4226*e4b17023SJohn Marino 4227*e4b17023SJohn Marino /* Expand calls to inline functions in the body of FN. */ 4228*e4b17023SJohn Marino 4229*e4b17023SJohn Marino unsigned int 4230*e4b17023SJohn Marino optimize_inline_calls (tree fn) 4231*e4b17023SJohn Marino { 4232*e4b17023SJohn Marino copy_body_data id; 4233*e4b17023SJohn Marino basic_block bb; 4234*e4b17023SJohn Marino int last = n_basic_blocks; 4235*e4b17023SJohn Marino struct gimplify_ctx gctx; 4236*e4b17023SJohn Marino bool inlined_p = false; 4237*e4b17023SJohn Marino 4238*e4b17023SJohn Marino /* Clear out ID. */ 4239*e4b17023SJohn Marino memset (&id, 0, sizeof (id)); 4240*e4b17023SJohn Marino 4241*e4b17023SJohn Marino id.src_node = id.dst_node = cgraph_get_node (fn); 4242*e4b17023SJohn Marino gcc_assert (id.dst_node->analyzed); 4243*e4b17023SJohn Marino id.dst_fn = fn; 4244*e4b17023SJohn Marino /* Or any functions that aren't finished yet. */ 4245*e4b17023SJohn Marino if (current_function_decl) 4246*e4b17023SJohn Marino id.dst_fn = current_function_decl; 4247*e4b17023SJohn Marino 4248*e4b17023SJohn Marino id.copy_decl = copy_decl_maybe_to_var; 4249*e4b17023SJohn Marino id.transform_call_graph_edges = CB_CGE_DUPLICATE; 4250*e4b17023SJohn Marino id.transform_new_cfg = false; 4251*e4b17023SJohn Marino id.transform_return_to_modify = true; 4252*e4b17023SJohn Marino id.transform_lang_insert_block = NULL; 4253*e4b17023SJohn Marino id.statements_to_fold = pointer_set_create (); 4254*e4b17023SJohn Marino 4255*e4b17023SJohn Marino push_gimplify_context (&gctx); 4256*e4b17023SJohn Marino 4257*e4b17023SJohn Marino /* We make no attempts to keep dominance info up-to-date. */ 4258*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS); 4259*e4b17023SJohn Marino free_dominance_info (CDI_POST_DOMINATORS); 4260*e4b17023SJohn Marino 4261*e4b17023SJohn Marino /* Register specific gimple functions. */ 4262*e4b17023SJohn Marino gimple_register_cfg_hooks (); 4263*e4b17023SJohn Marino 4264*e4b17023SJohn Marino /* Reach the trees by walking over the CFG, and note the 4265*e4b17023SJohn Marino enclosing basic-blocks in the call edges. */ 4266*e4b17023SJohn Marino /* We walk the blocks going forward, because inlined function bodies 4267*e4b17023SJohn Marino will split id->current_basic_block, and the new blocks will 4268*e4b17023SJohn Marino follow it; we'll trudge through them, processing their CALL_EXPRs 4269*e4b17023SJohn Marino along the way. */ 4270*e4b17023SJohn Marino FOR_EACH_BB (bb) 4271*e4b17023SJohn Marino inlined_p |= gimple_expand_calls_inline (bb, &id); 4272*e4b17023SJohn Marino 4273*e4b17023SJohn Marino pop_gimplify_context (NULL); 4274*e4b17023SJohn Marino 4275*e4b17023SJohn Marino #ifdef ENABLE_CHECKING 4276*e4b17023SJohn Marino { 4277*e4b17023SJohn Marino struct cgraph_edge *e; 4278*e4b17023SJohn Marino 4279*e4b17023SJohn Marino verify_cgraph_node (id.dst_node); 4280*e4b17023SJohn Marino 4281*e4b17023SJohn Marino /* Double check that we inlined everything we are supposed to inline. */ 4282*e4b17023SJohn Marino for (e = id.dst_node->callees; e; e = e->next_callee) 4283*e4b17023SJohn Marino gcc_assert (e->inline_failed); 4284*e4b17023SJohn Marino } 4285*e4b17023SJohn Marino #endif 4286*e4b17023SJohn Marino 4287*e4b17023SJohn Marino /* Fold queued statements. */ 4288*e4b17023SJohn Marino fold_marked_statements (last, id.statements_to_fold); 4289*e4b17023SJohn Marino pointer_set_destroy (id.statements_to_fold); 4290*e4b17023SJohn Marino 4291*e4b17023SJohn Marino gcc_assert (!id.debug_stmts); 4292*e4b17023SJohn Marino 4293*e4b17023SJohn Marino /* If we didn't inline into the function there is nothing to do. */ 4294*e4b17023SJohn Marino if (!inlined_p) 4295*e4b17023SJohn Marino return 0; 4296*e4b17023SJohn Marino 4297*e4b17023SJohn Marino /* Renumber the lexical scoping (non-code) blocks consecutively. */ 4298*e4b17023SJohn Marino number_blocks (fn); 4299*e4b17023SJohn Marino 4300*e4b17023SJohn Marino delete_unreachable_blocks_update_callgraph (&id); 4301*e4b17023SJohn Marino #ifdef ENABLE_CHECKING 4302*e4b17023SJohn Marino verify_cgraph_node (id.dst_node); 4303*e4b17023SJohn Marino #endif 4304*e4b17023SJohn Marino 4305*e4b17023SJohn Marino /* It would be nice to check SSA/CFG/statement consistency here, but it is 4306*e4b17023SJohn Marino not possible yet - the IPA passes might make various functions to not 4307*e4b17023SJohn Marino throw and they don't care to proactively update local EH info. This is 4308*e4b17023SJohn Marino done later in fixup_cfg pass that also execute the verification. */ 4309*e4b17023SJohn Marino return (TODO_update_ssa 4310*e4b17023SJohn Marino | TODO_cleanup_cfg 4311*e4b17023SJohn Marino | (gimple_in_ssa_p (cfun) ? TODO_remove_unused_locals : 0) 4312*e4b17023SJohn Marino | (gimple_in_ssa_p (cfun) ? TODO_update_address_taken : 0) 4313*e4b17023SJohn Marino | (profile_status != PROFILE_ABSENT ? TODO_rebuild_frequencies : 0)); 4314*e4b17023SJohn Marino } 4315*e4b17023SJohn Marino 4316*e4b17023SJohn Marino /* Passed to walk_tree. Copies the node pointed to, if appropriate. */ 4317*e4b17023SJohn Marino 4318*e4b17023SJohn Marino tree 4319*e4b17023SJohn Marino copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) 4320*e4b17023SJohn Marino { 4321*e4b17023SJohn Marino enum tree_code code = TREE_CODE (*tp); 4322*e4b17023SJohn Marino enum tree_code_class cl = TREE_CODE_CLASS (code); 4323*e4b17023SJohn Marino 4324*e4b17023SJohn Marino /* We make copies of most nodes. */ 4325*e4b17023SJohn Marino if (IS_EXPR_CODE_CLASS (cl) 4326*e4b17023SJohn Marino || code == TREE_LIST 4327*e4b17023SJohn Marino || code == TREE_VEC 4328*e4b17023SJohn Marino || code == TYPE_DECL 4329*e4b17023SJohn Marino || code == OMP_CLAUSE) 4330*e4b17023SJohn Marino { 4331*e4b17023SJohn Marino /* Because the chain gets clobbered when we make a copy, we save it 4332*e4b17023SJohn Marino here. */ 4333*e4b17023SJohn Marino tree chain = NULL_TREE, new_tree; 4334*e4b17023SJohn Marino 4335*e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (code, TS_COMMON)) 4336*e4b17023SJohn Marino chain = TREE_CHAIN (*tp); 4337*e4b17023SJohn Marino 4338*e4b17023SJohn Marino /* Copy the node. */ 4339*e4b17023SJohn Marino new_tree = copy_node (*tp); 4340*e4b17023SJohn Marino 4341*e4b17023SJohn Marino /* Propagate mudflap marked-ness. */ 4342*e4b17023SJohn Marino if (flag_mudflap && mf_marked_p (*tp)) 4343*e4b17023SJohn Marino mf_mark (new_tree); 4344*e4b17023SJohn Marino 4345*e4b17023SJohn Marino *tp = new_tree; 4346*e4b17023SJohn Marino 4347*e4b17023SJohn Marino /* Now, restore the chain, if appropriate. That will cause 4348*e4b17023SJohn Marino walk_tree to walk into the chain as well. */ 4349*e4b17023SJohn Marino if (code == PARM_DECL 4350*e4b17023SJohn Marino || code == TREE_LIST 4351*e4b17023SJohn Marino || code == OMP_CLAUSE) 4352*e4b17023SJohn Marino TREE_CHAIN (*tp) = chain; 4353*e4b17023SJohn Marino 4354*e4b17023SJohn Marino /* For now, we don't update BLOCKs when we make copies. So, we 4355*e4b17023SJohn Marino have to nullify all BIND_EXPRs. */ 4356*e4b17023SJohn Marino if (TREE_CODE (*tp) == BIND_EXPR) 4357*e4b17023SJohn Marino BIND_EXPR_BLOCK (*tp) = NULL_TREE; 4358*e4b17023SJohn Marino } 4359*e4b17023SJohn Marino else if (code == CONSTRUCTOR) 4360*e4b17023SJohn Marino { 4361*e4b17023SJohn Marino /* CONSTRUCTOR nodes need special handling because 4362*e4b17023SJohn Marino we need to duplicate the vector of elements. */ 4363*e4b17023SJohn Marino tree new_tree; 4364*e4b17023SJohn Marino 4365*e4b17023SJohn Marino new_tree = copy_node (*tp); 4366*e4b17023SJohn Marino 4367*e4b17023SJohn Marino /* Propagate mudflap marked-ness. */ 4368*e4b17023SJohn Marino if (flag_mudflap && mf_marked_p (*tp)) 4369*e4b17023SJohn Marino mf_mark (new_tree); 4370*e4b17023SJohn Marino 4371*e4b17023SJohn Marino CONSTRUCTOR_ELTS (new_tree) = VEC_copy (constructor_elt, gc, 4372*e4b17023SJohn Marino CONSTRUCTOR_ELTS (*tp)); 4373*e4b17023SJohn Marino *tp = new_tree; 4374*e4b17023SJohn Marino } 4375*e4b17023SJohn Marino else if (code == STATEMENT_LIST) 4376*e4b17023SJohn Marino /* We used to just abort on STATEMENT_LIST, but we can run into them 4377*e4b17023SJohn Marino with statement-expressions (c++/40975). */ 4378*e4b17023SJohn Marino copy_statement_list (tp); 4379*e4b17023SJohn Marino else if (TREE_CODE_CLASS (code) == tcc_type) 4380*e4b17023SJohn Marino *walk_subtrees = 0; 4381*e4b17023SJohn Marino else if (TREE_CODE_CLASS (code) == tcc_declaration) 4382*e4b17023SJohn Marino *walk_subtrees = 0; 4383*e4b17023SJohn Marino else if (TREE_CODE_CLASS (code) == tcc_constant) 4384*e4b17023SJohn Marino *walk_subtrees = 0; 4385*e4b17023SJohn Marino return NULL_TREE; 4386*e4b17023SJohn Marino } 4387*e4b17023SJohn Marino 4388*e4b17023SJohn Marino /* The SAVE_EXPR pointed to by TP is being copied. If ST contains 4389*e4b17023SJohn Marino information indicating to what new SAVE_EXPR this one should be mapped, 4390*e4b17023SJohn Marino use that one. Otherwise, create a new node and enter it in ST. FN is 4391*e4b17023SJohn Marino the function into which the copy will be placed. */ 4392*e4b17023SJohn Marino 4393*e4b17023SJohn Marino static void 4394*e4b17023SJohn Marino remap_save_expr (tree *tp, void *st_, int *walk_subtrees) 4395*e4b17023SJohn Marino { 4396*e4b17023SJohn Marino struct pointer_map_t *st = (struct pointer_map_t *) st_; 4397*e4b17023SJohn Marino tree *n; 4398*e4b17023SJohn Marino tree t; 4399*e4b17023SJohn Marino 4400*e4b17023SJohn Marino /* See if we already encountered this SAVE_EXPR. */ 4401*e4b17023SJohn Marino n = (tree *) pointer_map_contains (st, *tp); 4402*e4b17023SJohn Marino 4403*e4b17023SJohn Marino /* If we didn't already remap this SAVE_EXPR, do so now. */ 4404*e4b17023SJohn Marino if (!n) 4405*e4b17023SJohn Marino { 4406*e4b17023SJohn Marino t = copy_node (*tp); 4407*e4b17023SJohn Marino 4408*e4b17023SJohn Marino /* Remember this SAVE_EXPR. */ 4409*e4b17023SJohn Marino *pointer_map_insert (st, *tp) = t; 4410*e4b17023SJohn Marino /* Make sure we don't remap an already-remapped SAVE_EXPR. */ 4411*e4b17023SJohn Marino *pointer_map_insert (st, t) = t; 4412*e4b17023SJohn Marino } 4413*e4b17023SJohn Marino else 4414*e4b17023SJohn Marino { 4415*e4b17023SJohn Marino /* We've already walked into this SAVE_EXPR; don't do it again. */ 4416*e4b17023SJohn Marino *walk_subtrees = 0; 4417*e4b17023SJohn Marino t = *n; 4418*e4b17023SJohn Marino } 4419*e4b17023SJohn Marino 4420*e4b17023SJohn Marino /* Replace this SAVE_EXPR with the copy. */ 4421*e4b17023SJohn Marino *tp = t; 4422*e4b17023SJohn Marino } 4423*e4b17023SJohn Marino 4424*e4b17023SJohn Marino /* Called via walk_tree. If *TP points to a DECL_STMT for a local label, 4425*e4b17023SJohn Marino copies the declaration and enters it in the splay_tree in DATA (which is 4426*e4b17023SJohn Marino really an `copy_body_data *'). */ 4427*e4b17023SJohn Marino 4428*e4b17023SJohn Marino static tree 4429*e4b17023SJohn Marino mark_local_for_remap_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, 4430*e4b17023SJohn Marino void *data) 4431*e4b17023SJohn Marino { 4432*e4b17023SJohn Marino copy_body_data *id = (copy_body_data *) data; 4433*e4b17023SJohn Marino 4434*e4b17023SJohn Marino /* Don't walk into types. */ 4435*e4b17023SJohn Marino if (TYPE_P (*tp)) 4436*e4b17023SJohn Marino *walk_subtrees = 0; 4437*e4b17023SJohn Marino 4438*e4b17023SJohn Marino else if (TREE_CODE (*tp) == LABEL_EXPR) 4439*e4b17023SJohn Marino { 4440*e4b17023SJohn Marino tree decl = TREE_OPERAND (*tp, 0); 4441*e4b17023SJohn Marino 4442*e4b17023SJohn Marino /* Copy the decl and remember the copy. */ 4443*e4b17023SJohn Marino insert_decl_map (id, decl, id->copy_decl (decl, id)); 4444*e4b17023SJohn Marino } 4445*e4b17023SJohn Marino 4446*e4b17023SJohn Marino return NULL_TREE; 4447*e4b17023SJohn Marino } 4448*e4b17023SJohn Marino 4449*e4b17023SJohn Marino /* Perform any modifications to EXPR required when it is unsaved. Does 4450*e4b17023SJohn Marino not recurse into EXPR's subtrees. */ 4451*e4b17023SJohn Marino 4452*e4b17023SJohn Marino static void 4453*e4b17023SJohn Marino unsave_expr_1 (tree expr) 4454*e4b17023SJohn Marino { 4455*e4b17023SJohn Marino switch (TREE_CODE (expr)) 4456*e4b17023SJohn Marino { 4457*e4b17023SJohn Marino case TARGET_EXPR: 4458*e4b17023SJohn Marino /* Don't mess with a TARGET_EXPR that hasn't been expanded. 4459*e4b17023SJohn Marino It's OK for this to happen if it was part of a subtree that 4460*e4b17023SJohn Marino isn't immediately expanded, such as operand 2 of another 4461*e4b17023SJohn Marino TARGET_EXPR. */ 4462*e4b17023SJohn Marino if (TREE_OPERAND (expr, 1)) 4463*e4b17023SJohn Marino break; 4464*e4b17023SJohn Marino 4465*e4b17023SJohn Marino TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 3); 4466*e4b17023SJohn Marino TREE_OPERAND (expr, 3) = NULL_TREE; 4467*e4b17023SJohn Marino break; 4468*e4b17023SJohn Marino 4469*e4b17023SJohn Marino default: 4470*e4b17023SJohn Marino break; 4471*e4b17023SJohn Marino } 4472*e4b17023SJohn Marino } 4473*e4b17023SJohn Marino 4474*e4b17023SJohn Marino /* Called via walk_tree when an expression is unsaved. Using the 4475*e4b17023SJohn Marino splay_tree pointed to by ST (which is really a `splay_tree'), 4476*e4b17023SJohn Marino remaps all local declarations to appropriate replacements. */ 4477*e4b17023SJohn Marino 4478*e4b17023SJohn Marino static tree 4479*e4b17023SJohn Marino unsave_r (tree *tp, int *walk_subtrees, void *data) 4480*e4b17023SJohn Marino { 4481*e4b17023SJohn Marino copy_body_data *id = (copy_body_data *) data; 4482*e4b17023SJohn Marino struct pointer_map_t *st = id->decl_map; 4483*e4b17023SJohn Marino tree *n; 4484*e4b17023SJohn Marino 4485*e4b17023SJohn Marino /* Only a local declaration (variable or label). */ 4486*e4b17023SJohn Marino if ((TREE_CODE (*tp) == VAR_DECL && !TREE_STATIC (*tp)) 4487*e4b17023SJohn Marino || TREE_CODE (*tp) == LABEL_DECL) 4488*e4b17023SJohn Marino { 4489*e4b17023SJohn Marino /* Lookup the declaration. */ 4490*e4b17023SJohn Marino n = (tree *) pointer_map_contains (st, *tp); 4491*e4b17023SJohn Marino 4492*e4b17023SJohn Marino /* If it's there, remap it. */ 4493*e4b17023SJohn Marino if (n) 4494*e4b17023SJohn Marino *tp = *n; 4495*e4b17023SJohn Marino } 4496*e4b17023SJohn Marino 4497*e4b17023SJohn Marino else if (TREE_CODE (*tp) == STATEMENT_LIST) 4498*e4b17023SJohn Marino gcc_unreachable (); 4499*e4b17023SJohn Marino else if (TREE_CODE (*tp) == BIND_EXPR) 4500*e4b17023SJohn Marino copy_bind_expr (tp, walk_subtrees, id); 4501*e4b17023SJohn Marino else if (TREE_CODE (*tp) == SAVE_EXPR 4502*e4b17023SJohn Marino || TREE_CODE (*tp) == TARGET_EXPR) 4503*e4b17023SJohn Marino remap_save_expr (tp, st, walk_subtrees); 4504*e4b17023SJohn Marino else 4505*e4b17023SJohn Marino { 4506*e4b17023SJohn Marino copy_tree_r (tp, walk_subtrees, NULL); 4507*e4b17023SJohn Marino 4508*e4b17023SJohn Marino /* Do whatever unsaving is required. */ 4509*e4b17023SJohn Marino unsave_expr_1 (*tp); 4510*e4b17023SJohn Marino } 4511*e4b17023SJohn Marino 4512*e4b17023SJohn Marino /* Keep iterating. */ 4513*e4b17023SJohn Marino return NULL_TREE; 4514*e4b17023SJohn Marino } 4515*e4b17023SJohn Marino 4516*e4b17023SJohn Marino /* Copies everything in EXPR and replaces variables, labels 4517*e4b17023SJohn Marino and SAVE_EXPRs local to EXPR. */ 4518*e4b17023SJohn Marino 4519*e4b17023SJohn Marino tree 4520*e4b17023SJohn Marino unsave_expr_now (tree expr) 4521*e4b17023SJohn Marino { 4522*e4b17023SJohn Marino copy_body_data id; 4523*e4b17023SJohn Marino 4524*e4b17023SJohn Marino /* There's nothing to do for NULL_TREE. */ 4525*e4b17023SJohn Marino if (expr == 0) 4526*e4b17023SJohn Marino return expr; 4527*e4b17023SJohn Marino 4528*e4b17023SJohn Marino /* Set up ID. */ 4529*e4b17023SJohn Marino memset (&id, 0, sizeof (id)); 4530*e4b17023SJohn Marino id.src_fn = current_function_decl; 4531*e4b17023SJohn Marino id.dst_fn = current_function_decl; 4532*e4b17023SJohn Marino id.decl_map = pointer_map_create (); 4533*e4b17023SJohn Marino id.debug_map = NULL; 4534*e4b17023SJohn Marino 4535*e4b17023SJohn Marino id.copy_decl = copy_decl_no_change; 4536*e4b17023SJohn Marino id.transform_call_graph_edges = CB_CGE_DUPLICATE; 4537*e4b17023SJohn Marino id.transform_new_cfg = false; 4538*e4b17023SJohn Marino id.transform_return_to_modify = false; 4539*e4b17023SJohn Marino id.transform_lang_insert_block = NULL; 4540*e4b17023SJohn Marino 4541*e4b17023SJohn Marino /* Walk the tree once to find local labels. */ 4542*e4b17023SJohn Marino walk_tree_without_duplicates (&expr, mark_local_for_remap_r, &id); 4543*e4b17023SJohn Marino 4544*e4b17023SJohn Marino /* Walk the tree again, copying, remapping, and unsaving. */ 4545*e4b17023SJohn Marino walk_tree (&expr, unsave_r, &id, NULL); 4546*e4b17023SJohn Marino 4547*e4b17023SJohn Marino /* Clean up. */ 4548*e4b17023SJohn Marino pointer_map_destroy (id.decl_map); 4549*e4b17023SJohn Marino if (id.debug_map) 4550*e4b17023SJohn Marino pointer_map_destroy (id.debug_map); 4551*e4b17023SJohn Marino 4552*e4b17023SJohn Marino return expr; 4553*e4b17023SJohn Marino } 4554*e4b17023SJohn Marino 4555*e4b17023SJohn Marino /* Called via walk_gimple_seq. If *GSIP points to a GIMPLE_LABEL for a local 4556*e4b17023SJohn Marino label, copies the declaration and enters it in the splay_tree in DATA (which 4557*e4b17023SJohn Marino is really a 'copy_body_data *'. */ 4558*e4b17023SJohn Marino 4559*e4b17023SJohn Marino static tree 4560*e4b17023SJohn Marino mark_local_labels_stmt (gimple_stmt_iterator *gsip, 4561*e4b17023SJohn Marino bool *handled_ops_p ATTRIBUTE_UNUSED, 4562*e4b17023SJohn Marino struct walk_stmt_info *wi) 4563*e4b17023SJohn Marino { 4564*e4b17023SJohn Marino copy_body_data *id = (copy_body_data *) wi->info; 4565*e4b17023SJohn Marino gimple stmt = gsi_stmt (*gsip); 4566*e4b17023SJohn Marino 4567*e4b17023SJohn Marino if (gimple_code (stmt) == GIMPLE_LABEL) 4568*e4b17023SJohn Marino { 4569*e4b17023SJohn Marino tree decl = gimple_label_label (stmt); 4570*e4b17023SJohn Marino 4571*e4b17023SJohn Marino /* Copy the decl and remember the copy. */ 4572*e4b17023SJohn Marino insert_decl_map (id, decl, id->copy_decl (decl, id)); 4573*e4b17023SJohn Marino } 4574*e4b17023SJohn Marino 4575*e4b17023SJohn Marino return NULL_TREE; 4576*e4b17023SJohn Marino } 4577*e4b17023SJohn Marino 4578*e4b17023SJohn Marino 4579*e4b17023SJohn Marino /* Called via walk_gimple_seq by copy_gimple_seq_and_replace_local. 4580*e4b17023SJohn Marino Using the splay_tree pointed to by ST (which is really a `splay_tree'), 4581*e4b17023SJohn Marino remaps all local declarations to appropriate replacements in gimple 4582*e4b17023SJohn Marino operands. */ 4583*e4b17023SJohn Marino 4584*e4b17023SJohn Marino static tree 4585*e4b17023SJohn Marino replace_locals_op (tree *tp, int *walk_subtrees, void *data) 4586*e4b17023SJohn Marino { 4587*e4b17023SJohn Marino struct walk_stmt_info *wi = (struct walk_stmt_info*) data; 4588*e4b17023SJohn Marino copy_body_data *id = (copy_body_data *) wi->info; 4589*e4b17023SJohn Marino struct pointer_map_t *st = id->decl_map; 4590*e4b17023SJohn Marino tree *n; 4591*e4b17023SJohn Marino tree expr = *tp; 4592*e4b17023SJohn Marino 4593*e4b17023SJohn Marino /* Only a local declaration (variable or label). */ 4594*e4b17023SJohn Marino if ((TREE_CODE (expr) == VAR_DECL 4595*e4b17023SJohn Marino && !TREE_STATIC (expr)) 4596*e4b17023SJohn Marino || TREE_CODE (expr) == LABEL_DECL) 4597*e4b17023SJohn Marino { 4598*e4b17023SJohn Marino /* Lookup the declaration. */ 4599*e4b17023SJohn Marino n = (tree *) pointer_map_contains (st, expr); 4600*e4b17023SJohn Marino 4601*e4b17023SJohn Marino /* If it's there, remap it. */ 4602*e4b17023SJohn Marino if (n) 4603*e4b17023SJohn Marino *tp = *n; 4604*e4b17023SJohn Marino *walk_subtrees = 0; 4605*e4b17023SJohn Marino } 4606*e4b17023SJohn Marino else if (TREE_CODE (expr) == STATEMENT_LIST 4607*e4b17023SJohn Marino || TREE_CODE (expr) == BIND_EXPR 4608*e4b17023SJohn Marino || TREE_CODE (expr) == SAVE_EXPR) 4609*e4b17023SJohn Marino gcc_unreachable (); 4610*e4b17023SJohn Marino else if (TREE_CODE (expr) == TARGET_EXPR) 4611*e4b17023SJohn Marino { 4612*e4b17023SJohn Marino /* Don't mess with a TARGET_EXPR that hasn't been expanded. 4613*e4b17023SJohn Marino It's OK for this to happen if it was part of a subtree that 4614*e4b17023SJohn Marino isn't immediately expanded, such as operand 2 of another 4615*e4b17023SJohn Marino TARGET_EXPR. */ 4616*e4b17023SJohn Marino if (!TREE_OPERAND (expr, 1)) 4617*e4b17023SJohn Marino { 4618*e4b17023SJohn Marino TREE_OPERAND (expr, 1) = TREE_OPERAND (expr, 3); 4619*e4b17023SJohn Marino TREE_OPERAND (expr, 3) = NULL_TREE; 4620*e4b17023SJohn Marino } 4621*e4b17023SJohn Marino } 4622*e4b17023SJohn Marino 4623*e4b17023SJohn Marino /* Keep iterating. */ 4624*e4b17023SJohn Marino return NULL_TREE; 4625*e4b17023SJohn Marino } 4626*e4b17023SJohn Marino 4627*e4b17023SJohn Marino 4628*e4b17023SJohn Marino /* Called via walk_gimple_seq by copy_gimple_seq_and_replace_local. 4629*e4b17023SJohn Marino Using the splay_tree pointed to by ST (which is really a `splay_tree'), 4630*e4b17023SJohn Marino remaps all local declarations to appropriate replacements in gimple 4631*e4b17023SJohn Marino statements. */ 4632*e4b17023SJohn Marino 4633*e4b17023SJohn Marino static tree 4634*e4b17023SJohn Marino replace_locals_stmt (gimple_stmt_iterator *gsip, 4635*e4b17023SJohn Marino bool *handled_ops_p ATTRIBUTE_UNUSED, 4636*e4b17023SJohn Marino struct walk_stmt_info *wi) 4637*e4b17023SJohn Marino { 4638*e4b17023SJohn Marino copy_body_data *id = (copy_body_data *) wi->info; 4639*e4b17023SJohn Marino gimple stmt = gsi_stmt (*gsip); 4640*e4b17023SJohn Marino 4641*e4b17023SJohn Marino if (gimple_code (stmt) == GIMPLE_BIND) 4642*e4b17023SJohn Marino { 4643*e4b17023SJohn Marino tree block = gimple_bind_block (stmt); 4644*e4b17023SJohn Marino 4645*e4b17023SJohn Marino if (block) 4646*e4b17023SJohn Marino { 4647*e4b17023SJohn Marino remap_block (&block, id); 4648*e4b17023SJohn Marino gimple_bind_set_block (stmt, block); 4649*e4b17023SJohn Marino } 4650*e4b17023SJohn Marino 4651*e4b17023SJohn Marino /* This will remap a lot of the same decls again, but this should be 4652*e4b17023SJohn Marino harmless. */ 4653*e4b17023SJohn Marino if (gimple_bind_vars (stmt)) 4654*e4b17023SJohn Marino gimple_bind_set_vars (stmt, remap_decls (gimple_bind_vars (stmt), NULL, id)); 4655*e4b17023SJohn Marino } 4656*e4b17023SJohn Marino 4657*e4b17023SJohn Marino /* Keep iterating. */ 4658*e4b17023SJohn Marino return NULL_TREE; 4659*e4b17023SJohn Marino } 4660*e4b17023SJohn Marino 4661*e4b17023SJohn Marino 4662*e4b17023SJohn Marino /* Copies everything in SEQ and replaces variables and labels local to 4663*e4b17023SJohn Marino current_function_decl. */ 4664*e4b17023SJohn Marino 4665*e4b17023SJohn Marino gimple_seq 4666*e4b17023SJohn Marino copy_gimple_seq_and_replace_locals (gimple_seq seq) 4667*e4b17023SJohn Marino { 4668*e4b17023SJohn Marino copy_body_data id; 4669*e4b17023SJohn Marino struct walk_stmt_info wi; 4670*e4b17023SJohn Marino struct pointer_set_t *visited; 4671*e4b17023SJohn Marino gimple_seq copy; 4672*e4b17023SJohn Marino 4673*e4b17023SJohn Marino /* There's nothing to do for NULL_TREE. */ 4674*e4b17023SJohn Marino if (seq == NULL) 4675*e4b17023SJohn Marino return seq; 4676*e4b17023SJohn Marino 4677*e4b17023SJohn Marino /* Set up ID. */ 4678*e4b17023SJohn Marino memset (&id, 0, sizeof (id)); 4679*e4b17023SJohn Marino id.src_fn = current_function_decl; 4680*e4b17023SJohn Marino id.dst_fn = current_function_decl; 4681*e4b17023SJohn Marino id.decl_map = pointer_map_create (); 4682*e4b17023SJohn Marino id.debug_map = NULL; 4683*e4b17023SJohn Marino 4684*e4b17023SJohn Marino id.copy_decl = copy_decl_no_change; 4685*e4b17023SJohn Marino id.transform_call_graph_edges = CB_CGE_DUPLICATE; 4686*e4b17023SJohn Marino id.transform_new_cfg = false; 4687*e4b17023SJohn Marino id.transform_return_to_modify = false; 4688*e4b17023SJohn Marino id.transform_lang_insert_block = NULL; 4689*e4b17023SJohn Marino 4690*e4b17023SJohn Marino /* Walk the tree once to find local labels. */ 4691*e4b17023SJohn Marino memset (&wi, 0, sizeof (wi)); 4692*e4b17023SJohn Marino visited = pointer_set_create (); 4693*e4b17023SJohn Marino wi.info = &id; 4694*e4b17023SJohn Marino wi.pset = visited; 4695*e4b17023SJohn Marino walk_gimple_seq (seq, mark_local_labels_stmt, NULL, &wi); 4696*e4b17023SJohn Marino pointer_set_destroy (visited); 4697*e4b17023SJohn Marino 4698*e4b17023SJohn Marino copy = gimple_seq_copy (seq); 4699*e4b17023SJohn Marino 4700*e4b17023SJohn Marino /* Walk the copy, remapping decls. */ 4701*e4b17023SJohn Marino memset (&wi, 0, sizeof (wi)); 4702*e4b17023SJohn Marino wi.info = &id; 4703*e4b17023SJohn Marino walk_gimple_seq (copy, replace_locals_stmt, replace_locals_op, &wi); 4704*e4b17023SJohn Marino 4705*e4b17023SJohn Marino /* Clean up. */ 4706*e4b17023SJohn Marino pointer_map_destroy (id.decl_map); 4707*e4b17023SJohn Marino if (id.debug_map) 4708*e4b17023SJohn Marino pointer_map_destroy (id.debug_map); 4709*e4b17023SJohn Marino 4710*e4b17023SJohn Marino return copy; 4711*e4b17023SJohn Marino } 4712*e4b17023SJohn Marino 4713*e4b17023SJohn Marino 4714*e4b17023SJohn Marino /* Allow someone to determine if SEARCH is a child of TOP from gdb. */ 4715*e4b17023SJohn Marino 4716*e4b17023SJohn Marino static tree 4717*e4b17023SJohn Marino debug_find_tree_1 (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data) 4718*e4b17023SJohn Marino { 4719*e4b17023SJohn Marino if (*tp == data) 4720*e4b17023SJohn Marino return (tree) data; 4721*e4b17023SJohn Marino else 4722*e4b17023SJohn Marino return NULL; 4723*e4b17023SJohn Marino } 4724*e4b17023SJohn Marino 4725*e4b17023SJohn Marino DEBUG_FUNCTION bool 4726*e4b17023SJohn Marino debug_find_tree (tree top, tree search) 4727*e4b17023SJohn Marino { 4728*e4b17023SJohn Marino return walk_tree_without_duplicates (&top, debug_find_tree_1, search) != 0; 4729*e4b17023SJohn Marino } 4730*e4b17023SJohn Marino 4731*e4b17023SJohn Marino 4732*e4b17023SJohn Marino /* Declare the variables created by the inliner. Add all the variables in 4733*e4b17023SJohn Marino VARS to BIND_EXPR. */ 4734*e4b17023SJohn Marino 4735*e4b17023SJohn Marino static void 4736*e4b17023SJohn Marino declare_inline_vars (tree block, tree vars) 4737*e4b17023SJohn Marino { 4738*e4b17023SJohn Marino tree t; 4739*e4b17023SJohn Marino for (t = vars; t; t = DECL_CHAIN (t)) 4740*e4b17023SJohn Marino { 4741*e4b17023SJohn Marino DECL_SEEN_IN_BIND_EXPR_P (t) = 1; 4742*e4b17023SJohn Marino gcc_assert (!TREE_STATIC (t) && !TREE_ASM_WRITTEN (t)); 4743*e4b17023SJohn Marino add_local_decl (cfun, t); 4744*e4b17023SJohn Marino } 4745*e4b17023SJohn Marino 4746*e4b17023SJohn Marino if (block) 4747*e4b17023SJohn Marino BLOCK_VARS (block) = chainon (BLOCK_VARS (block), vars); 4748*e4b17023SJohn Marino } 4749*e4b17023SJohn Marino 4750*e4b17023SJohn Marino /* Copy NODE (which must be a DECL). The DECL originally was in the FROM_FN, 4751*e4b17023SJohn Marino but now it will be in the TO_FN. PARM_TO_VAR means enable PARM_DECL to 4752*e4b17023SJohn Marino VAR_DECL translation. */ 4753*e4b17023SJohn Marino 4754*e4b17023SJohn Marino static tree 4755*e4b17023SJohn Marino copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy) 4756*e4b17023SJohn Marino { 4757*e4b17023SJohn Marino /* Don't generate debug information for the copy if we wouldn't have 4758*e4b17023SJohn Marino generated it for the copy either. */ 4759*e4b17023SJohn Marino DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl); 4760*e4b17023SJohn Marino DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl); 4761*e4b17023SJohn Marino 4762*e4b17023SJohn Marino /* Set the DECL_ABSTRACT_ORIGIN so the debugging routines know what 4763*e4b17023SJohn Marino declaration inspired this copy. */ 4764*e4b17023SJohn Marino DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl); 4765*e4b17023SJohn Marino 4766*e4b17023SJohn Marino /* The new variable/label has no RTL, yet. */ 4767*e4b17023SJohn Marino if (CODE_CONTAINS_STRUCT (TREE_CODE (copy), TS_DECL_WRTL) 4768*e4b17023SJohn Marino && !TREE_STATIC (copy) && !DECL_EXTERNAL (copy)) 4769*e4b17023SJohn Marino SET_DECL_RTL (copy, 0); 4770*e4b17023SJohn Marino 4771*e4b17023SJohn Marino /* These args would always appear unused, if not for this. */ 4772*e4b17023SJohn Marino TREE_USED (copy) = 1; 4773*e4b17023SJohn Marino 4774*e4b17023SJohn Marino /* Set the context for the new declaration. */ 4775*e4b17023SJohn Marino if (!DECL_CONTEXT (decl)) 4776*e4b17023SJohn Marino /* Globals stay global. */ 4777*e4b17023SJohn Marino ; 4778*e4b17023SJohn Marino else if (DECL_CONTEXT (decl) != id->src_fn) 4779*e4b17023SJohn Marino /* Things that weren't in the scope of the function we're inlining 4780*e4b17023SJohn Marino from aren't in the scope we're inlining to, either. */ 4781*e4b17023SJohn Marino ; 4782*e4b17023SJohn Marino else if (TREE_STATIC (decl)) 4783*e4b17023SJohn Marino /* Function-scoped static variables should stay in the original 4784*e4b17023SJohn Marino function. */ 4785*e4b17023SJohn Marino ; 4786*e4b17023SJohn Marino else 4787*e4b17023SJohn Marino /* Ordinary automatic local variables are now in the scope of the 4788*e4b17023SJohn Marino new function. */ 4789*e4b17023SJohn Marino DECL_CONTEXT (copy) = id->dst_fn; 4790*e4b17023SJohn Marino 4791*e4b17023SJohn Marino if (TREE_CODE (decl) == VAR_DECL 4792*e4b17023SJohn Marino /* C++ clones functions during parsing, before 4793*e4b17023SJohn Marino referenced_vars. */ 4794*e4b17023SJohn Marino && gimple_referenced_vars (DECL_STRUCT_FUNCTION (id->src_fn)) 4795*e4b17023SJohn Marino && referenced_var_lookup (DECL_STRUCT_FUNCTION (id->src_fn), 4796*e4b17023SJohn Marino DECL_UID (decl))) 4797*e4b17023SJohn Marino add_referenced_var (copy); 4798*e4b17023SJohn Marino 4799*e4b17023SJohn Marino return copy; 4800*e4b17023SJohn Marino } 4801*e4b17023SJohn Marino 4802*e4b17023SJohn Marino static tree 4803*e4b17023SJohn Marino copy_decl_to_var (tree decl, copy_body_data *id) 4804*e4b17023SJohn Marino { 4805*e4b17023SJohn Marino tree copy, type; 4806*e4b17023SJohn Marino 4807*e4b17023SJohn Marino gcc_assert (TREE_CODE (decl) == PARM_DECL 4808*e4b17023SJohn Marino || TREE_CODE (decl) == RESULT_DECL); 4809*e4b17023SJohn Marino 4810*e4b17023SJohn Marino type = TREE_TYPE (decl); 4811*e4b17023SJohn Marino 4812*e4b17023SJohn Marino copy = build_decl (DECL_SOURCE_LOCATION (id->dst_fn), 4813*e4b17023SJohn Marino VAR_DECL, DECL_NAME (decl), type); 4814*e4b17023SJohn Marino if (DECL_PT_UID_SET_P (decl)) 4815*e4b17023SJohn Marino SET_DECL_PT_UID (copy, DECL_PT_UID (decl)); 4816*e4b17023SJohn Marino TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl); 4817*e4b17023SJohn Marino TREE_READONLY (copy) = TREE_READONLY (decl); 4818*e4b17023SJohn Marino TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl); 4819*e4b17023SJohn Marino DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl); 4820*e4b17023SJohn Marino 4821*e4b17023SJohn Marino return copy_decl_for_dup_finish (id, decl, copy); 4822*e4b17023SJohn Marino } 4823*e4b17023SJohn Marino 4824*e4b17023SJohn Marino /* Like copy_decl_to_var, but create a return slot object instead of a 4825*e4b17023SJohn Marino pointer variable for return by invisible reference. */ 4826*e4b17023SJohn Marino 4827*e4b17023SJohn Marino static tree 4828*e4b17023SJohn Marino copy_result_decl_to_var (tree decl, copy_body_data *id) 4829*e4b17023SJohn Marino { 4830*e4b17023SJohn Marino tree copy, type; 4831*e4b17023SJohn Marino 4832*e4b17023SJohn Marino gcc_assert (TREE_CODE (decl) == PARM_DECL 4833*e4b17023SJohn Marino || TREE_CODE (decl) == RESULT_DECL); 4834*e4b17023SJohn Marino 4835*e4b17023SJohn Marino type = TREE_TYPE (decl); 4836*e4b17023SJohn Marino if (DECL_BY_REFERENCE (decl)) 4837*e4b17023SJohn Marino type = TREE_TYPE (type); 4838*e4b17023SJohn Marino 4839*e4b17023SJohn Marino copy = build_decl (DECL_SOURCE_LOCATION (id->dst_fn), 4840*e4b17023SJohn Marino VAR_DECL, DECL_NAME (decl), type); 4841*e4b17023SJohn Marino if (DECL_PT_UID_SET_P (decl)) 4842*e4b17023SJohn Marino SET_DECL_PT_UID (copy, DECL_PT_UID (decl)); 4843*e4b17023SJohn Marino TREE_READONLY (copy) = TREE_READONLY (decl); 4844*e4b17023SJohn Marino TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl); 4845*e4b17023SJohn Marino if (!DECL_BY_REFERENCE (decl)) 4846*e4b17023SJohn Marino { 4847*e4b17023SJohn Marino TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl); 4848*e4b17023SJohn Marino DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl); 4849*e4b17023SJohn Marino } 4850*e4b17023SJohn Marino 4851*e4b17023SJohn Marino return copy_decl_for_dup_finish (id, decl, copy); 4852*e4b17023SJohn Marino } 4853*e4b17023SJohn Marino 4854*e4b17023SJohn Marino tree 4855*e4b17023SJohn Marino copy_decl_no_change (tree decl, copy_body_data *id) 4856*e4b17023SJohn Marino { 4857*e4b17023SJohn Marino tree copy; 4858*e4b17023SJohn Marino 4859*e4b17023SJohn Marino copy = copy_node (decl); 4860*e4b17023SJohn Marino 4861*e4b17023SJohn Marino /* The COPY is not abstract; it will be generated in DST_FN. */ 4862*e4b17023SJohn Marino DECL_ABSTRACT (copy) = 0; 4863*e4b17023SJohn Marino lang_hooks.dup_lang_specific_decl (copy); 4864*e4b17023SJohn Marino 4865*e4b17023SJohn Marino /* TREE_ADDRESSABLE isn't used to indicate that a label's address has 4866*e4b17023SJohn Marino been taken; it's for internal bookkeeping in expand_goto_internal. */ 4867*e4b17023SJohn Marino if (TREE_CODE (copy) == LABEL_DECL) 4868*e4b17023SJohn Marino { 4869*e4b17023SJohn Marino TREE_ADDRESSABLE (copy) = 0; 4870*e4b17023SJohn Marino LABEL_DECL_UID (copy) = -1; 4871*e4b17023SJohn Marino } 4872*e4b17023SJohn Marino 4873*e4b17023SJohn Marino return copy_decl_for_dup_finish (id, decl, copy); 4874*e4b17023SJohn Marino } 4875*e4b17023SJohn Marino 4876*e4b17023SJohn Marino static tree 4877*e4b17023SJohn Marino copy_decl_maybe_to_var (tree decl, copy_body_data *id) 4878*e4b17023SJohn Marino { 4879*e4b17023SJohn Marino if (TREE_CODE (decl) == PARM_DECL || TREE_CODE (decl) == RESULT_DECL) 4880*e4b17023SJohn Marino return copy_decl_to_var (decl, id); 4881*e4b17023SJohn Marino else 4882*e4b17023SJohn Marino return copy_decl_no_change (decl, id); 4883*e4b17023SJohn Marino } 4884*e4b17023SJohn Marino 4885*e4b17023SJohn Marino /* Return a copy of the function's argument tree. */ 4886*e4b17023SJohn Marino static tree 4887*e4b17023SJohn Marino copy_arguments_for_versioning (tree orig_parm, copy_body_data * id, 4888*e4b17023SJohn Marino bitmap args_to_skip, tree *vars) 4889*e4b17023SJohn Marino { 4890*e4b17023SJohn Marino tree arg, *parg; 4891*e4b17023SJohn Marino tree new_parm = NULL; 4892*e4b17023SJohn Marino int i = 0; 4893*e4b17023SJohn Marino 4894*e4b17023SJohn Marino parg = &new_parm; 4895*e4b17023SJohn Marino 4896*e4b17023SJohn Marino for (arg = orig_parm; arg; arg = DECL_CHAIN (arg), i++) 4897*e4b17023SJohn Marino if (!args_to_skip || !bitmap_bit_p (args_to_skip, i)) 4898*e4b17023SJohn Marino { 4899*e4b17023SJohn Marino tree new_tree = remap_decl (arg, id); 4900*e4b17023SJohn Marino if (TREE_CODE (new_tree) != PARM_DECL) 4901*e4b17023SJohn Marino new_tree = id->copy_decl (arg, id); 4902*e4b17023SJohn Marino lang_hooks.dup_lang_specific_decl (new_tree); 4903*e4b17023SJohn Marino *parg = new_tree; 4904*e4b17023SJohn Marino parg = &DECL_CHAIN (new_tree); 4905*e4b17023SJohn Marino } 4906*e4b17023SJohn Marino else if (!pointer_map_contains (id->decl_map, arg)) 4907*e4b17023SJohn Marino { 4908*e4b17023SJohn Marino /* Make an equivalent VAR_DECL. If the argument was used 4909*e4b17023SJohn Marino as temporary variable later in function, the uses will be 4910*e4b17023SJohn Marino replaced by local variable. */ 4911*e4b17023SJohn Marino tree var = copy_decl_to_var (arg, id); 4912*e4b17023SJohn Marino add_referenced_var (var); 4913*e4b17023SJohn Marino insert_decl_map (id, arg, var); 4914*e4b17023SJohn Marino /* Declare this new variable. */ 4915*e4b17023SJohn Marino DECL_CHAIN (var) = *vars; 4916*e4b17023SJohn Marino *vars = var; 4917*e4b17023SJohn Marino } 4918*e4b17023SJohn Marino return new_parm; 4919*e4b17023SJohn Marino } 4920*e4b17023SJohn Marino 4921*e4b17023SJohn Marino /* Return a copy of the function's static chain. */ 4922*e4b17023SJohn Marino static tree 4923*e4b17023SJohn Marino copy_static_chain (tree static_chain, copy_body_data * id) 4924*e4b17023SJohn Marino { 4925*e4b17023SJohn Marino tree *chain_copy, *pvar; 4926*e4b17023SJohn Marino 4927*e4b17023SJohn Marino chain_copy = &static_chain; 4928*e4b17023SJohn Marino for (pvar = chain_copy; *pvar; pvar = &DECL_CHAIN (*pvar)) 4929*e4b17023SJohn Marino { 4930*e4b17023SJohn Marino tree new_tree = remap_decl (*pvar, id); 4931*e4b17023SJohn Marino lang_hooks.dup_lang_specific_decl (new_tree); 4932*e4b17023SJohn Marino DECL_CHAIN (new_tree) = DECL_CHAIN (*pvar); 4933*e4b17023SJohn Marino *pvar = new_tree; 4934*e4b17023SJohn Marino } 4935*e4b17023SJohn Marino return static_chain; 4936*e4b17023SJohn Marino } 4937*e4b17023SJohn Marino 4938*e4b17023SJohn Marino /* Return true if the function is allowed to be versioned. 4939*e4b17023SJohn Marino This is a guard for the versioning functionality. */ 4940*e4b17023SJohn Marino 4941*e4b17023SJohn Marino bool 4942*e4b17023SJohn Marino tree_versionable_function_p (tree fndecl) 4943*e4b17023SJohn Marino { 4944*e4b17023SJohn Marino return (!lookup_attribute ("noclone", DECL_ATTRIBUTES (fndecl)) 4945*e4b17023SJohn Marino && copy_forbidden (DECL_STRUCT_FUNCTION (fndecl), fndecl) == NULL); 4946*e4b17023SJohn Marino } 4947*e4b17023SJohn Marino 4948*e4b17023SJohn Marino /* Delete all unreachable basic blocks and update callgraph. 4949*e4b17023SJohn Marino Doing so is somewhat nontrivial because we need to update all clones and 4950*e4b17023SJohn Marino remove inline function that become unreachable. */ 4951*e4b17023SJohn Marino 4952*e4b17023SJohn Marino static bool 4953*e4b17023SJohn Marino delete_unreachable_blocks_update_callgraph (copy_body_data *id) 4954*e4b17023SJohn Marino { 4955*e4b17023SJohn Marino bool changed = false; 4956*e4b17023SJohn Marino basic_block b, next_bb; 4957*e4b17023SJohn Marino 4958*e4b17023SJohn Marino find_unreachable_blocks (); 4959*e4b17023SJohn Marino 4960*e4b17023SJohn Marino /* Delete all unreachable basic blocks. */ 4961*e4b17023SJohn Marino 4962*e4b17023SJohn Marino for (b = ENTRY_BLOCK_PTR->next_bb; b != EXIT_BLOCK_PTR; b = next_bb) 4963*e4b17023SJohn Marino { 4964*e4b17023SJohn Marino next_bb = b->next_bb; 4965*e4b17023SJohn Marino 4966*e4b17023SJohn Marino if (!(b->flags & BB_REACHABLE)) 4967*e4b17023SJohn Marino { 4968*e4b17023SJohn Marino gimple_stmt_iterator bsi; 4969*e4b17023SJohn Marino 4970*e4b17023SJohn Marino for (bsi = gsi_start_bb (b); !gsi_end_p (bsi); gsi_next (&bsi)) 4971*e4b17023SJohn Marino if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL) 4972*e4b17023SJohn Marino { 4973*e4b17023SJohn Marino struct cgraph_edge *e; 4974*e4b17023SJohn Marino struct cgraph_node *node; 4975*e4b17023SJohn Marino 4976*e4b17023SJohn Marino if ((e = cgraph_edge (id->dst_node, gsi_stmt (bsi))) != NULL) 4977*e4b17023SJohn Marino { 4978*e4b17023SJohn Marino if (!e->inline_failed) 4979*e4b17023SJohn Marino cgraph_remove_node_and_inline_clones (e->callee); 4980*e4b17023SJohn Marino else 4981*e4b17023SJohn Marino cgraph_remove_edge (e); 4982*e4b17023SJohn Marino } 4983*e4b17023SJohn Marino if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES 4984*e4b17023SJohn Marino && id->dst_node->clones) 4985*e4b17023SJohn Marino for (node = id->dst_node->clones; node != id->dst_node;) 4986*e4b17023SJohn Marino { 4987*e4b17023SJohn Marino if ((e = cgraph_edge (node, gsi_stmt (bsi))) != NULL) 4988*e4b17023SJohn Marino { 4989*e4b17023SJohn Marino if (!e->inline_failed) 4990*e4b17023SJohn Marino cgraph_remove_node_and_inline_clones (e->callee); 4991*e4b17023SJohn Marino else 4992*e4b17023SJohn Marino cgraph_remove_edge (e); 4993*e4b17023SJohn Marino } 4994*e4b17023SJohn Marino 4995*e4b17023SJohn Marino if (node->clones) 4996*e4b17023SJohn Marino node = node->clones; 4997*e4b17023SJohn Marino else if (node->next_sibling_clone) 4998*e4b17023SJohn Marino node = node->next_sibling_clone; 4999*e4b17023SJohn Marino else 5000*e4b17023SJohn Marino { 5001*e4b17023SJohn Marino while (node != id->dst_node && !node->next_sibling_clone) 5002*e4b17023SJohn Marino node = node->clone_of; 5003*e4b17023SJohn Marino if (node != id->dst_node) 5004*e4b17023SJohn Marino node = node->next_sibling_clone; 5005*e4b17023SJohn Marino } 5006*e4b17023SJohn Marino } 5007*e4b17023SJohn Marino } 5008*e4b17023SJohn Marino delete_basic_block (b); 5009*e4b17023SJohn Marino changed = true; 5010*e4b17023SJohn Marino } 5011*e4b17023SJohn Marino } 5012*e4b17023SJohn Marino 5013*e4b17023SJohn Marino return changed; 5014*e4b17023SJohn Marino } 5015*e4b17023SJohn Marino 5016*e4b17023SJohn Marino /* Update clone info after duplication. */ 5017*e4b17023SJohn Marino 5018*e4b17023SJohn Marino static void 5019*e4b17023SJohn Marino update_clone_info (copy_body_data * id) 5020*e4b17023SJohn Marino { 5021*e4b17023SJohn Marino struct cgraph_node *node; 5022*e4b17023SJohn Marino if (!id->dst_node->clones) 5023*e4b17023SJohn Marino return; 5024*e4b17023SJohn Marino for (node = id->dst_node->clones; node != id->dst_node;) 5025*e4b17023SJohn Marino { 5026*e4b17023SJohn Marino /* First update replace maps to match the new body. */ 5027*e4b17023SJohn Marino if (node->clone.tree_map) 5028*e4b17023SJohn Marino { 5029*e4b17023SJohn Marino unsigned int i; 5030*e4b17023SJohn Marino for (i = 0; i < VEC_length (ipa_replace_map_p, node->clone.tree_map); i++) 5031*e4b17023SJohn Marino { 5032*e4b17023SJohn Marino struct ipa_replace_map *replace_info; 5033*e4b17023SJohn Marino replace_info = VEC_index (ipa_replace_map_p, node->clone.tree_map, i); 5034*e4b17023SJohn Marino walk_tree (&replace_info->old_tree, copy_tree_body_r, id, NULL); 5035*e4b17023SJohn Marino walk_tree (&replace_info->new_tree, copy_tree_body_r, id, NULL); 5036*e4b17023SJohn Marino } 5037*e4b17023SJohn Marino } 5038*e4b17023SJohn Marino if (node->clones) 5039*e4b17023SJohn Marino node = node->clones; 5040*e4b17023SJohn Marino else if (node->next_sibling_clone) 5041*e4b17023SJohn Marino node = node->next_sibling_clone; 5042*e4b17023SJohn Marino else 5043*e4b17023SJohn Marino { 5044*e4b17023SJohn Marino while (node != id->dst_node && !node->next_sibling_clone) 5045*e4b17023SJohn Marino node = node->clone_of; 5046*e4b17023SJohn Marino if (node != id->dst_node) 5047*e4b17023SJohn Marino node = node->next_sibling_clone; 5048*e4b17023SJohn Marino } 5049*e4b17023SJohn Marino } 5050*e4b17023SJohn Marino } 5051*e4b17023SJohn Marino 5052*e4b17023SJohn Marino /* Create a copy of a function's tree. 5053*e4b17023SJohn Marino OLD_DECL and NEW_DECL are FUNCTION_DECL tree nodes 5054*e4b17023SJohn Marino of the original function and the new copied function 5055*e4b17023SJohn Marino respectively. In case we want to replace a DECL 5056*e4b17023SJohn Marino tree with another tree while duplicating the function's 5057*e4b17023SJohn Marino body, TREE_MAP represents the mapping between these 5058*e4b17023SJohn Marino trees. If UPDATE_CLONES is set, the call_stmt fields 5059*e4b17023SJohn Marino of edges of clones of the function will be updated. 5060*e4b17023SJohn Marino 5061*e4b17023SJohn Marino If non-NULL ARGS_TO_SKIP determine function parameters to remove 5062*e4b17023SJohn Marino from new version. 5063*e4b17023SJohn Marino If SKIP_RETURN is true, the new version will return void. 5064*e4b17023SJohn Marino If non-NULL BLOCK_TO_COPY determine what basic blocks to copy. 5065*e4b17023SJohn Marino If non_NULL NEW_ENTRY determine new entry BB of the clone. 5066*e4b17023SJohn Marino */ 5067*e4b17023SJohn Marino void 5068*e4b17023SJohn Marino tree_function_versioning (tree old_decl, tree new_decl, 5069*e4b17023SJohn Marino VEC(ipa_replace_map_p,gc)* tree_map, 5070*e4b17023SJohn Marino bool update_clones, bitmap args_to_skip, 5071*e4b17023SJohn Marino bool skip_return, bitmap blocks_to_copy, 5072*e4b17023SJohn Marino basic_block new_entry) 5073*e4b17023SJohn Marino { 5074*e4b17023SJohn Marino struct cgraph_node *old_version_node; 5075*e4b17023SJohn Marino struct cgraph_node *new_version_node; 5076*e4b17023SJohn Marino copy_body_data id; 5077*e4b17023SJohn Marino tree p; 5078*e4b17023SJohn Marino unsigned i; 5079*e4b17023SJohn Marino struct ipa_replace_map *replace_info; 5080*e4b17023SJohn Marino basic_block old_entry_block, bb; 5081*e4b17023SJohn Marino VEC (gimple, heap) *init_stmts = VEC_alloc (gimple, heap, 10); 5082*e4b17023SJohn Marino 5083*e4b17023SJohn Marino tree old_current_function_decl = current_function_decl; 5084*e4b17023SJohn Marino tree vars = NULL_TREE; 5085*e4b17023SJohn Marino 5086*e4b17023SJohn Marino gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL 5087*e4b17023SJohn Marino && TREE_CODE (new_decl) == FUNCTION_DECL); 5088*e4b17023SJohn Marino DECL_POSSIBLY_INLINED (old_decl) = 1; 5089*e4b17023SJohn Marino 5090*e4b17023SJohn Marino old_version_node = cgraph_get_node (old_decl); 5091*e4b17023SJohn Marino gcc_checking_assert (old_version_node); 5092*e4b17023SJohn Marino new_version_node = cgraph_get_node (new_decl); 5093*e4b17023SJohn Marino gcc_checking_assert (new_version_node); 5094*e4b17023SJohn Marino 5095*e4b17023SJohn Marino /* Copy over debug args. */ 5096*e4b17023SJohn Marino if (DECL_HAS_DEBUG_ARGS_P (old_decl)) 5097*e4b17023SJohn Marino { 5098*e4b17023SJohn Marino VEC(tree, gc) **new_debug_args, **old_debug_args; 5099*e4b17023SJohn Marino gcc_checking_assert (decl_debug_args_lookup (new_decl) == NULL); 5100*e4b17023SJohn Marino DECL_HAS_DEBUG_ARGS_P (new_decl) = 0; 5101*e4b17023SJohn Marino old_debug_args = decl_debug_args_lookup (old_decl); 5102*e4b17023SJohn Marino if (old_debug_args) 5103*e4b17023SJohn Marino { 5104*e4b17023SJohn Marino new_debug_args = decl_debug_args_insert (new_decl); 5105*e4b17023SJohn Marino *new_debug_args = VEC_copy (tree, gc, *old_debug_args); 5106*e4b17023SJohn Marino } 5107*e4b17023SJohn Marino } 5108*e4b17023SJohn Marino 5109*e4b17023SJohn Marino /* Output the inlining info for this abstract function, since it has been 5110*e4b17023SJohn Marino inlined. If we don't do this now, we can lose the information about the 5111*e4b17023SJohn Marino variables in the function when the blocks get blown away as soon as we 5112*e4b17023SJohn Marino remove the cgraph node. */ 5113*e4b17023SJohn Marino (*debug_hooks->outlining_inline_function) (old_decl); 5114*e4b17023SJohn Marino 5115*e4b17023SJohn Marino DECL_ARTIFICIAL (new_decl) = 1; 5116*e4b17023SJohn Marino DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl); 5117*e4b17023SJohn Marino DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl); 5118*e4b17023SJohn Marino 5119*e4b17023SJohn Marino /* Prepare the data structures for the tree copy. */ 5120*e4b17023SJohn Marino memset (&id, 0, sizeof (id)); 5121*e4b17023SJohn Marino 5122*e4b17023SJohn Marino /* Generate a new name for the new version. */ 5123*e4b17023SJohn Marino id.statements_to_fold = pointer_set_create (); 5124*e4b17023SJohn Marino 5125*e4b17023SJohn Marino id.decl_map = pointer_map_create (); 5126*e4b17023SJohn Marino id.debug_map = NULL; 5127*e4b17023SJohn Marino id.src_fn = old_decl; 5128*e4b17023SJohn Marino id.dst_fn = new_decl; 5129*e4b17023SJohn Marino id.src_node = old_version_node; 5130*e4b17023SJohn Marino id.dst_node = new_version_node; 5131*e4b17023SJohn Marino id.src_cfun = DECL_STRUCT_FUNCTION (old_decl); 5132*e4b17023SJohn Marino if (id.src_node->ipa_transforms_to_apply) 5133*e4b17023SJohn Marino { 5134*e4b17023SJohn Marino VEC(ipa_opt_pass,heap) * old_transforms_to_apply = id.dst_node->ipa_transforms_to_apply; 5135*e4b17023SJohn Marino unsigned int i; 5136*e4b17023SJohn Marino 5137*e4b17023SJohn Marino id.dst_node->ipa_transforms_to_apply = VEC_copy (ipa_opt_pass, heap, 5138*e4b17023SJohn Marino id.src_node->ipa_transforms_to_apply); 5139*e4b17023SJohn Marino for (i = 0; i < VEC_length (ipa_opt_pass, old_transforms_to_apply); i++) 5140*e4b17023SJohn Marino VEC_safe_push (ipa_opt_pass, heap, id.dst_node->ipa_transforms_to_apply, 5141*e4b17023SJohn Marino VEC_index (ipa_opt_pass, 5142*e4b17023SJohn Marino old_transforms_to_apply, 5143*e4b17023SJohn Marino i)); 5144*e4b17023SJohn Marino } 5145*e4b17023SJohn Marino 5146*e4b17023SJohn Marino id.copy_decl = copy_decl_no_change; 5147*e4b17023SJohn Marino id.transform_call_graph_edges 5148*e4b17023SJohn Marino = update_clones ? CB_CGE_MOVE_CLONES : CB_CGE_MOVE; 5149*e4b17023SJohn Marino id.transform_new_cfg = true; 5150*e4b17023SJohn Marino id.transform_return_to_modify = false; 5151*e4b17023SJohn Marino id.transform_lang_insert_block = NULL; 5152*e4b17023SJohn Marino 5153*e4b17023SJohn Marino current_function_decl = new_decl; 5154*e4b17023SJohn Marino old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION 5155*e4b17023SJohn Marino (DECL_STRUCT_FUNCTION (old_decl)); 5156*e4b17023SJohn Marino initialize_cfun (new_decl, old_decl, 5157*e4b17023SJohn Marino old_entry_block->count); 5158*e4b17023SJohn Marino DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta 5159*e4b17023SJohn Marino = id.src_cfun->gimple_df->ipa_pta; 5160*e4b17023SJohn Marino push_cfun (DECL_STRUCT_FUNCTION (new_decl)); 5161*e4b17023SJohn Marino 5162*e4b17023SJohn Marino /* Copy the function's static chain. */ 5163*e4b17023SJohn Marino p = DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl; 5164*e4b17023SJohn Marino if (p) 5165*e4b17023SJohn Marino DECL_STRUCT_FUNCTION (new_decl)->static_chain_decl = 5166*e4b17023SJohn Marino copy_static_chain (DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl, 5167*e4b17023SJohn Marino &id); 5168*e4b17023SJohn Marino 5169*e4b17023SJohn Marino /* If there's a tree_map, prepare for substitution. */ 5170*e4b17023SJohn Marino if (tree_map) 5171*e4b17023SJohn Marino for (i = 0; i < VEC_length (ipa_replace_map_p, tree_map); i++) 5172*e4b17023SJohn Marino { 5173*e4b17023SJohn Marino gimple init; 5174*e4b17023SJohn Marino replace_info = VEC_index (ipa_replace_map_p, tree_map, i); 5175*e4b17023SJohn Marino if (replace_info->replace_p) 5176*e4b17023SJohn Marino { 5177*e4b17023SJohn Marino tree op = replace_info->new_tree; 5178*e4b17023SJohn Marino if (!replace_info->old_tree) 5179*e4b17023SJohn Marino { 5180*e4b17023SJohn Marino int i = replace_info->parm_num; 5181*e4b17023SJohn Marino tree parm; 5182*e4b17023SJohn Marino for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm)) 5183*e4b17023SJohn Marino i --; 5184*e4b17023SJohn Marino replace_info->old_tree = parm; 5185*e4b17023SJohn Marino } 5186*e4b17023SJohn Marino 5187*e4b17023SJohn Marino 5188*e4b17023SJohn Marino STRIP_NOPS (op); 5189*e4b17023SJohn Marino 5190*e4b17023SJohn Marino if (TREE_CODE (op) == VIEW_CONVERT_EXPR) 5191*e4b17023SJohn Marino op = TREE_OPERAND (op, 0); 5192*e4b17023SJohn Marino 5193*e4b17023SJohn Marino if (TREE_CODE (op) == ADDR_EXPR) 5194*e4b17023SJohn Marino { 5195*e4b17023SJohn Marino op = TREE_OPERAND (op, 0); 5196*e4b17023SJohn Marino while (handled_component_p (op)) 5197*e4b17023SJohn Marino op = TREE_OPERAND (op, 0); 5198*e4b17023SJohn Marino if (TREE_CODE (op) == VAR_DECL) 5199*e4b17023SJohn Marino add_referenced_var (op); 5200*e4b17023SJohn Marino } 5201*e4b17023SJohn Marino gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL); 5202*e4b17023SJohn Marino init = setup_one_parameter (&id, replace_info->old_tree, 5203*e4b17023SJohn Marino replace_info->new_tree, id.src_fn, 5204*e4b17023SJohn Marino NULL, 5205*e4b17023SJohn Marino &vars); 5206*e4b17023SJohn Marino if (init) 5207*e4b17023SJohn Marino VEC_safe_push (gimple, heap, init_stmts, init); 5208*e4b17023SJohn Marino } 5209*e4b17023SJohn Marino } 5210*e4b17023SJohn Marino /* Copy the function's arguments. */ 5211*e4b17023SJohn Marino if (DECL_ARGUMENTS (old_decl) != NULL_TREE) 5212*e4b17023SJohn Marino DECL_ARGUMENTS (new_decl) = 5213*e4b17023SJohn Marino copy_arguments_for_versioning (DECL_ARGUMENTS (old_decl), &id, 5214*e4b17023SJohn Marino args_to_skip, &vars); 5215*e4b17023SJohn Marino 5216*e4b17023SJohn Marino DECL_INITIAL (new_decl) = remap_blocks (DECL_INITIAL (id.src_fn), &id); 5217*e4b17023SJohn Marino BLOCK_SUPERCONTEXT (DECL_INITIAL (new_decl)) = new_decl; 5218*e4b17023SJohn Marino 5219*e4b17023SJohn Marino declare_inline_vars (DECL_INITIAL (new_decl), vars); 5220*e4b17023SJohn Marino 5221*e4b17023SJohn Marino if (!VEC_empty (tree, DECL_STRUCT_FUNCTION (old_decl)->local_decls)) 5222*e4b17023SJohn Marino /* Add local vars. */ 5223*e4b17023SJohn Marino add_local_variables (DECL_STRUCT_FUNCTION (old_decl), cfun, &id, false); 5224*e4b17023SJohn Marino 5225*e4b17023SJohn Marino if (DECL_RESULT (old_decl) == NULL_TREE) 5226*e4b17023SJohn Marino ; 5227*e4b17023SJohn Marino else if (skip_return && !VOID_TYPE_P (TREE_TYPE (DECL_RESULT (old_decl)))) 5228*e4b17023SJohn Marino { 5229*e4b17023SJohn Marino DECL_RESULT (new_decl) 5230*e4b17023SJohn Marino = build_decl (DECL_SOURCE_LOCATION (DECL_RESULT (old_decl)), 5231*e4b17023SJohn Marino RESULT_DECL, NULL_TREE, void_type_node); 5232*e4b17023SJohn Marino DECL_CONTEXT (DECL_RESULT (new_decl)) = new_decl; 5233*e4b17023SJohn Marino cfun->returns_struct = 0; 5234*e4b17023SJohn Marino cfun->returns_pcc_struct = 0; 5235*e4b17023SJohn Marino } 5236*e4b17023SJohn Marino else 5237*e4b17023SJohn Marino { 5238*e4b17023SJohn Marino tree old_name; 5239*e4b17023SJohn Marino DECL_RESULT (new_decl) = remap_decl (DECL_RESULT (old_decl), &id); 5240*e4b17023SJohn Marino lang_hooks.dup_lang_specific_decl (DECL_RESULT (new_decl)); 5241*e4b17023SJohn Marino if (gimple_in_ssa_p (id.src_cfun) 5242*e4b17023SJohn Marino && DECL_BY_REFERENCE (DECL_RESULT (old_decl)) 5243*e4b17023SJohn Marino && (old_name 5244*e4b17023SJohn Marino = gimple_default_def (id.src_cfun, DECL_RESULT (old_decl)))) 5245*e4b17023SJohn Marino { 5246*e4b17023SJohn Marino tree new_name = make_ssa_name (DECL_RESULT (new_decl), NULL); 5247*e4b17023SJohn Marino insert_decl_map (&id, old_name, new_name); 5248*e4b17023SJohn Marino SSA_NAME_DEF_STMT (new_name) = gimple_build_nop (); 5249*e4b17023SJohn Marino set_default_def (DECL_RESULT (new_decl), new_name); 5250*e4b17023SJohn Marino } 5251*e4b17023SJohn Marino } 5252*e4b17023SJohn Marino 5253*e4b17023SJohn Marino /* Copy the Function's body. */ 5254*e4b17023SJohn Marino copy_body (&id, old_entry_block->count, REG_BR_PROB_BASE, 5255*e4b17023SJohn Marino ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, blocks_to_copy, new_entry); 5256*e4b17023SJohn Marino 5257*e4b17023SJohn Marino /* Renumber the lexical scoping (non-code) blocks consecutively. */ 5258*e4b17023SJohn Marino number_blocks (new_decl); 5259*e4b17023SJohn Marino 5260*e4b17023SJohn Marino /* We want to create the BB unconditionally, so that the addition of 5261*e4b17023SJohn Marino debug stmts doesn't affect BB count, which may in the end cause 5262*e4b17023SJohn Marino codegen differences. */ 5263*e4b17023SJohn Marino bb = split_edge (single_succ_edge (ENTRY_BLOCK_PTR)); 5264*e4b17023SJohn Marino while (VEC_length (gimple, init_stmts)) 5265*e4b17023SJohn Marino insert_init_stmt (&id, bb, VEC_pop (gimple, init_stmts)); 5266*e4b17023SJohn Marino update_clone_info (&id); 5267*e4b17023SJohn Marino 5268*e4b17023SJohn Marino /* Remap the nonlocal_goto_save_area, if any. */ 5269*e4b17023SJohn Marino if (cfun->nonlocal_goto_save_area) 5270*e4b17023SJohn Marino { 5271*e4b17023SJohn Marino struct walk_stmt_info wi; 5272*e4b17023SJohn Marino 5273*e4b17023SJohn Marino memset (&wi, 0, sizeof (wi)); 5274*e4b17023SJohn Marino wi.info = &id; 5275*e4b17023SJohn Marino walk_tree (&cfun->nonlocal_goto_save_area, remap_gimple_op_r, &wi, NULL); 5276*e4b17023SJohn Marino } 5277*e4b17023SJohn Marino 5278*e4b17023SJohn Marino /* Clean up. */ 5279*e4b17023SJohn Marino pointer_map_destroy (id.decl_map); 5280*e4b17023SJohn Marino if (id.debug_map) 5281*e4b17023SJohn Marino pointer_map_destroy (id.debug_map); 5282*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS); 5283*e4b17023SJohn Marino free_dominance_info (CDI_POST_DOMINATORS); 5284*e4b17023SJohn Marino 5285*e4b17023SJohn Marino fold_marked_statements (0, id.statements_to_fold); 5286*e4b17023SJohn Marino pointer_set_destroy (id.statements_to_fold); 5287*e4b17023SJohn Marino fold_cond_expr_cond (); 5288*e4b17023SJohn Marino delete_unreachable_blocks_update_callgraph (&id); 5289*e4b17023SJohn Marino if (id.dst_node->analyzed) 5290*e4b17023SJohn Marino cgraph_rebuild_references (); 5291*e4b17023SJohn Marino update_ssa (TODO_update_ssa); 5292*e4b17023SJohn Marino 5293*e4b17023SJohn Marino /* After partial cloning we need to rescale frequencies, so they are 5294*e4b17023SJohn Marino within proper range in the cloned function. */ 5295*e4b17023SJohn Marino if (new_entry) 5296*e4b17023SJohn Marino { 5297*e4b17023SJohn Marino struct cgraph_edge *e; 5298*e4b17023SJohn Marino rebuild_frequencies (); 5299*e4b17023SJohn Marino 5300*e4b17023SJohn Marino new_version_node->count = ENTRY_BLOCK_PTR->count; 5301*e4b17023SJohn Marino for (e = new_version_node->callees; e; e = e->next_callee) 5302*e4b17023SJohn Marino { 5303*e4b17023SJohn Marino basic_block bb = gimple_bb (e->call_stmt); 5304*e4b17023SJohn Marino e->frequency = compute_call_stmt_bb_frequency (current_function_decl, 5305*e4b17023SJohn Marino bb); 5306*e4b17023SJohn Marino e->count = bb->count; 5307*e4b17023SJohn Marino } 5308*e4b17023SJohn Marino for (e = new_version_node->indirect_calls; e; e = e->next_callee) 5309*e4b17023SJohn Marino { 5310*e4b17023SJohn Marino basic_block bb = gimple_bb (e->call_stmt); 5311*e4b17023SJohn Marino e->frequency = compute_call_stmt_bb_frequency (current_function_decl, 5312*e4b17023SJohn Marino bb); 5313*e4b17023SJohn Marino e->count = bb->count; 5314*e4b17023SJohn Marino } 5315*e4b17023SJohn Marino } 5316*e4b17023SJohn Marino 5317*e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS); 5318*e4b17023SJohn Marino free_dominance_info (CDI_POST_DOMINATORS); 5319*e4b17023SJohn Marino 5320*e4b17023SJohn Marino gcc_assert (!id.debug_stmts); 5321*e4b17023SJohn Marino VEC_free (gimple, heap, init_stmts); 5322*e4b17023SJohn Marino pop_cfun (); 5323*e4b17023SJohn Marino current_function_decl = old_current_function_decl; 5324*e4b17023SJohn Marino gcc_assert (!current_function_decl 5325*e4b17023SJohn Marino || DECL_STRUCT_FUNCTION (current_function_decl) == cfun); 5326*e4b17023SJohn Marino return; 5327*e4b17023SJohn Marino } 5328*e4b17023SJohn Marino 5329*e4b17023SJohn Marino /* EXP is CALL_EXPR present in a GENERIC expression tree. Try to integrate 5330*e4b17023SJohn Marino the callee and return the inlined body on success. */ 5331*e4b17023SJohn Marino 5332*e4b17023SJohn Marino tree 5333*e4b17023SJohn Marino maybe_inline_call_in_expr (tree exp) 5334*e4b17023SJohn Marino { 5335*e4b17023SJohn Marino tree fn = get_callee_fndecl (exp); 5336*e4b17023SJohn Marino 5337*e4b17023SJohn Marino /* We can only try to inline "const" functions. */ 5338*e4b17023SJohn Marino if (fn && TREE_READONLY (fn) && DECL_SAVED_TREE (fn)) 5339*e4b17023SJohn Marino { 5340*e4b17023SJohn Marino struct pointer_map_t *decl_map = pointer_map_create (); 5341*e4b17023SJohn Marino call_expr_arg_iterator iter; 5342*e4b17023SJohn Marino copy_body_data id; 5343*e4b17023SJohn Marino tree param, arg, t; 5344*e4b17023SJohn Marino 5345*e4b17023SJohn Marino /* Remap the parameters. */ 5346*e4b17023SJohn Marino for (param = DECL_ARGUMENTS (fn), arg = first_call_expr_arg (exp, &iter); 5347*e4b17023SJohn Marino param; 5348*e4b17023SJohn Marino param = DECL_CHAIN (param), arg = next_call_expr_arg (&iter)) 5349*e4b17023SJohn Marino *pointer_map_insert (decl_map, param) = arg; 5350*e4b17023SJohn Marino 5351*e4b17023SJohn Marino memset (&id, 0, sizeof (id)); 5352*e4b17023SJohn Marino id.src_fn = fn; 5353*e4b17023SJohn Marino id.dst_fn = current_function_decl; 5354*e4b17023SJohn Marino id.src_cfun = DECL_STRUCT_FUNCTION (fn); 5355*e4b17023SJohn Marino id.decl_map = decl_map; 5356*e4b17023SJohn Marino 5357*e4b17023SJohn Marino id.copy_decl = copy_decl_no_change; 5358*e4b17023SJohn Marino id.transform_call_graph_edges = CB_CGE_DUPLICATE; 5359*e4b17023SJohn Marino id.transform_new_cfg = false; 5360*e4b17023SJohn Marino id.transform_return_to_modify = true; 5361*e4b17023SJohn Marino id.transform_lang_insert_block = NULL; 5362*e4b17023SJohn Marino 5363*e4b17023SJohn Marino /* Make sure not to unshare trees behind the front-end's back 5364*e4b17023SJohn Marino since front-end specific mechanisms may rely on sharing. */ 5365*e4b17023SJohn Marino id.regimplify = false; 5366*e4b17023SJohn Marino id.do_not_unshare = true; 5367*e4b17023SJohn Marino 5368*e4b17023SJohn Marino /* We're not inside any EH region. */ 5369*e4b17023SJohn Marino id.eh_lp_nr = 0; 5370*e4b17023SJohn Marino 5371*e4b17023SJohn Marino t = copy_tree_body (&id); 5372*e4b17023SJohn Marino pointer_map_destroy (decl_map); 5373*e4b17023SJohn Marino 5374*e4b17023SJohn Marino /* We can only return something suitable for use in a GENERIC 5375*e4b17023SJohn Marino expression tree. */ 5376*e4b17023SJohn Marino if (TREE_CODE (t) == MODIFY_EXPR) 5377*e4b17023SJohn Marino return TREE_OPERAND (t, 1); 5378*e4b17023SJohn Marino } 5379*e4b17023SJohn Marino 5380*e4b17023SJohn Marino return NULL_TREE; 5381*e4b17023SJohn Marino } 5382*e4b17023SJohn Marino 5383*e4b17023SJohn Marino /* Duplicate a type, fields and all. */ 5384*e4b17023SJohn Marino 5385*e4b17023SJohn Marino tree 5386*e4b17023SJohn Marino build_duplicate_type (tree type) 5387*e4b17023SJohn Marino { 5388*e4b17023SJohn Marino struct copy_body_data id; 5389*e4b17023SJohn Marino 5390*e4b17023SJohn Marino memset (&id, 0, sizeof (id)); 5391*e4b17023SJohn Marino id.src_fn = current_function_decl; 5392*e4b17023SJohn Marino id.dst_fn = current_function_decl; 5393*e4b17023SJohn Marino id.src_cfun = cfun; 5394*e4b17023SJohn Marino id.decl_map = pointer_map_create (); 5395*e4b17023SJohn Marino id.debug_map = NULL; 5396*e4b17023SJohn Marino id.copy_decl = copy_decl_no_change; 5397*e4b17023SJohn Marino 5398*e4b17023SJohn Marino type = remap_type_1 (type, &id); 5399*e4b17023SJohn Marino 5400*e4b17023SJohn Marino pointer_map_destroy (id.decl_map); 5401*e4b17023SJohn Marino if (id.debug_map) 5402*e4b17023SJohn Marino pointer_map_destroy (id.debug_map); 5403*e4b17023SJohn Marino 5404*e4b17023SJohn Marino TYPE_CANONICAL (type) = type; 5405*e4b17023SJohn Marino 5406*e4b17023SJohn Marino return type; 5407*e4b17023SJohn Marino } 5408