1 /* Perform optimizations on tree structure. 2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2007, 2008, 2009 3 Free Software Foundation, Inc. 4 Written by Mark Michell (mark@codesourcery.com). 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it 9 under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3, or (at your option) 11 any later version. 12 13 GCC is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22 #include "config.h" 23 #include "system.h" 24 #include "coretypes.h" 25 #include "tm.h" 26 #include "tree.h" 27 #include "cp-tree.h" 28 #include "rtl.h" 29 #include "insn-config.h" 30 #include "input.h" 31 #include "integrate.h" 32 #include "toplev.h" 33 #include "varray.h" 34 #include "params.h" 35 #include "hashtab.h" 36 #include "target.h" 37 #include "debug.h" 38 #include "tree-inline.h" 39 #include "flags.h" 40 #include "langhooks.h" 41 #include "diagnostic.h" 42 #include "tree-dump.h" 43 #include "gimple.h" 44 #include "tree-iterator.h" 45 #include "cgraph.h" 46 47 /* Prototypes. */ 48 49 static void update_cloned_parm (tree, tree, bool); 50 51 /* CLONED_PARM is a copy of CLONE, generated for a cloned constructor 52 or destructor. Update it to ensure that the source-position for 53 the cloned parameter matches that for the original, and that the 54 debugging generation code will be able to find the original PARM. */ 55 56 static void 57 update_cloned_parm (tree parm, tree cloned_parm, bool first) 58 { 59 DECL_ABSTRACT_ORIGIN (cloned_parm) = parm; 60 61 /* We may have taken its address. */ 62 TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm); 63 64 /* The definition might have different constness. */ 65 TREE_READONLY (cloned_parm) = TREE_READONLY (parm); 66 67 TREE_USED (cloned_parm) = !first || TREE_USED (parm); 68 69 /* The name may have changed from the declaration. */ 70 DECL_NAME (cloned_parm) = DECL_NAME (parm); 71 DECL_SOURCE_LOCATION (cloned_parm) = DECL_SOURCE_LOCATION (parm); 72 TREE_TYPE (cloned_parm) = TREE_TYPE (parm); 73 74 DECL_GIMPLE_REG_P (cloned_parm) = DECL_GIMPLE_REG_P (parm); 75 } 76 77 78 /* FN is a function in High GIMPLE form that has a complete body and no 79 CFG. CLONE is a function whose body is to be set to a copy of FN, 80 mapping argument declarations according to the ARG_MAP splay_tree. */ 81 82 static void 83 clone_body (tree clone, tree fn, void *arg_map) 84 { 85 copy_body_data id; 86 tree stmts; 87 88 /* Clone the body, as if we were making an inline call. But, remap 89 the parameters in the callee to the parameters of caller. */ 90 memset (&id, 0, sizeof (id)); 91 id.src_fn = fn; 92 id.dst_fn = clone; 93 id.src_cfun = DECL_STRUCT_FUNCTION (fn); 94 id.decl_map = (struct pointer_map_t *) arg_map; 95 96 id.copy_decl = copy_decl_no_change; 97 id.transform_call_graph_edges = CB_CGE_DUPLICATE; 98 id.transform_new_cfg = true; 99 id.transform_return_to_modify = false; 100 id.transform_lang_insert_block = NULL; 101 102 /* We're not inside any EH region. */ 103 id.eh_lp_nr = 0; 104 105 stmts = DECL_SAVED_TREE (fn); 106 walk_tree (&stmts, copy_tree_body_r, &id, NULL); 107 108 /* Also remap the initializer of any static variables so that they (in 109 particular, any label addresses) correspond to the base variant rather 110 than the abstract one. */ 111 if (DECL_NAME (clone) == base_dtor_identifier 112 || DECL_NAME (clone) == base_ctor_identifier) 113 { 114 tree decls = DECL_STRUCT_FUNCTION (fn)->local_decls; 115 for (; decls; decls = TREE_CHAIN (decls)) 116 { 117 tree decl = TREE_VALUE (decls); 118 walk_tree (&DECL_INITIAL (decl), copy_tree_body_r, &id, NULL); 119 } 120 } 121 122 append_to_statement_list_force (stmts, &DECL_SAVED_TREE (clone)); 123 } 124 125 /* DELETE_DTOR is a delete destructor whose body will be built. 126 COMPLETE_DTOR is the corresponding complete destructor. */ 127 128 static void 129 build_delete_destructor_body (tree delete_dtor, tree complete_dtor) 130 { 131 tree call_dtor, call_delete; 132 tree parm = DECL_ARGUMENTS (delete_dtor); 133 tree virtual_size = cxx_sizeof (current_class_type); 134 135 /* Call the corresponding complete destructor. */ 136 gcc_assert (complete_dtor); 137 call_dtor = build_cxx_call (complete_dtor, 1, &parm); 138 add_stmt (call_dtor); 139 140 add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label)); 141 142 /* Call the delete function. */ 143 call_delete = build_op_delete_call (DELETE_EXPR, current_class_ptr, 144 virtual_size, 145 /*global_p=*/false, 146 /*placement=*/NULL_TREE, 147 /*alloc_fn=*/NULL_TREE); 148 add_stmt (call_delete); 149 150 /* Return the address of the object. */ 151 if (targetm.cxx.cdtor_returns_this ()) 152 { 153 tree val = DECL_ARGUMENTS (delete_dtor); 154 val = build2 (MODIFY_EXPR, TREE_TYPE (val), 155 DECL_RESULT (delete_dtor), val); 156 add_stmt (build_stmt (0, RETURN_EXPR, val)); 157 } 158 } 159 160 /* Return name of comdat group for complete and base ctor (or dtor) 161 that have the same body. If dtor is virtual, deleting dtor goes 162 into this comdat group as well. */ 163 164 static tree 165 cdtor_comdat_group (tree complete, tree base) 166 { 167 tree complete_name = DECL_COMDAT_GROUP (complete); 168 tree base_name = DECL_COMDAT_GROUP (base); 169 char *grp_name; 170 const char *p, *q; 171 bool diff_seen = false; 172 size_t idx; 173 if (complete_name == NULL) 174 complete_name = cxx_comdat_group (complete); 175 if (base_name == NULL) 176 base_name = cxx_comdat_group (base); 177 gcc_assert (IDENTIFIER_LENGTH (complete_name) 178 == IDENTIFIER_LENGTH (base_name)); 179 grp_name = XALLOCAVEC (char, IDENTIFIER_LENGTH (complete_name) + 1); 180 p = IDENTIFIER_POINTER (complete_name); 181 q = IDENTIFIER_POINTER (base_name); 182 for (idx = 0; idx < IDENTIFIER_LENGTH (complete_name); idx++) 183 if (p[idx] == q[idx]) 184 grp_name[idx] = p[idx]; 185 else 186 { 187 gcc_assert (!diff_seen 188 && idx > 0 189 && (p[idx - 1] == 'C' || p[idx - 1] == 'D') 190 && p[idx] == '1' 191 && q[idx] == '2'); 192 grp_name[idx] = '5'; 193 diff_seen = true; 194 } 195 grp_name[idx] = '\0'; 196 gcc_assert (diff_seen); 197 return get_identifier (grp_name); 198 } 199 200 /* FN is a function that has a complete body. Clone the body as 201 necessary. Returns nonzero if there's no longer any need to 202 process the main body. */ 203 204 bool 205 maybe_clone_body (tree fn) 206 { 207 tree comdat_group = NULL_TREE; 208 tree clone; 209 tree fns[3]; 210 bool first = true; 211 bool in_charge_parm_used; 212 int idx; 213 bool need_alias = false; 214 215 /* We only clone constructors and destructors. */ 216 if (!DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (fn) 217 && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (fn)) 218 return 0; 219 220 /* Emit the DWARF1 abstract instance. */ 221 (*debug_hooks->deferred_inline_function) (fn); 222 223 in_charge_parm_used = CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fn)) != NULL; 224 fns[0] = NULL_TREE; 225 fns[1] = NULL_TREE; 226 fns[2] = NULL_TREE; 227 228 /* Look for the complete destructor which may be used to build the 229 delete destructor. */ 230 FOR_EACH_CLONE (clone, fn) 231 if (DECL_NAME (clone) == complete_dtor_identifier 232 || DECL_NAME (clone) == complete_ctor_identifier) 233 fns[1] = clone; 234 else if (DECL_NAME (clone) == base_dtor_identifier 235 || DECL_NAME (clone) == base_ctor_identifier) 236 fns[0] = clone; 237 else if (DECL_NAME (clone) == deleting_dtor_identifier) 238 fns[2] = clone; 239 else 240 gcc_unreachable (); 241 242 /* Remember if we can't have multiple clones for some reason. We need to 243 check this before we remap local static initializers in clone_body. */ 244 if (!tree_versionable_function_p (fn)) 245 need_alias = true; 246 247 /* We know that any clones immediately follow FN in the TYPE_METHODS 248 list. */ 249 push_to_top_level (); 250 for (idx = 0; idx < 3; idx++) 251 { 252 tree parm; 253 tree clone_parm; 254 int parmno; 255 bool alias = false; 256 struct pointer_map_t *decl_map; 257 258 clone = fns[idx]; 259 if (!clone) 260 continue; 261 262 /* Update CLONE's source position information to match FN's. */ 263 DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn); 264 DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn); 265 DECL_COMDAT (clone) = DECL_COMDAT (fn); 266 DECL_WEAK (clone) = DECL_WEAK (fn); 267 268 /* We don't copy the comdat group from fn to clone because the assembler 269 name of fn was corrupted by write_mangled_name by adding *INTERNAL* 270 to it. By doing so, it also corrupted the comdat group. */ 271 if (DECL_ONE_ONLY (fn)) 272 DECL_COMDAT_GROUP (clone) = cxx_comdat_group (clone); 273 DECL_SECTION_NAME (clone) = DECL_SECTION_NAME (fn); 274 DECL_USE_TEMPLATE (clone) = DECL_USE_TEMPLATE (fn); 275 DECL_EXTERNAL (clone) = DECL_EXTERNAL (fn); 276 DECL_INTERFACE_KNOWN (clone) = DECL_INTERFACE_KNOWN (fn); 277 DECL_NOT_REALLY_EXTERN (clone) = DECL_NOT_REALLY_EXTERN (fn); 278 TREE_PUBLIC (clone) = TREE_PUBLIC (fn); 279 DECL_VISIBILITY (clone) = DECL_VISIBILITY (fn); 280 DECL_VISIBILITY_SPECIFIED (clone) = DECL_VISIBILITY_SPECIFIED (fn); 281 DECL_DLLIMPORT_P (clone) = DECL_DLLIMPORT_P (fn); 282 DECL_ATTRIBUTES (clone) = copy_list (DECL_ATTRIBUTES (fn)); 283 DECL_DISREGARD_INLINE_LIMITS (clone) = DECL_DISREGARD_INLINE_LIMITS (fn); 284 285 /* Adjust the parameter names and locations. */ 286 parm = DECL_ARGUMENTS (fn); 287 clone_parm = DECL_ARGUMENTS (clone); 288 /* Update the `this' parameter, which is always first. */ 289 update_cloned_parm (parm, clone_parm, first); 290 parm = TREE_CHAIN (parm); 291 clone_parm = TREE_CHAIN (clone_parm); 292 if (DECL_HAS_IN_CHARGE_PARM_P (fn)) 293 parm = TREE_CHAIN (parm); 294 if (DECL_HAS_VTT_PARM_P (fn)) 295 parm = TREE_CHAIN (parm); 296 if (DECL_HAS_VTT_PARM_P (clone)) 297 clone_parm = TREE_CHAIN (clone_parm); 298 for (; parm; 299 parm = TREE_CHAIN (parm), clone_parm = TREE_CHAIN (clone_parm)) 300 /* Update this parameter. */ 301 update_cloned_parm (parm, clone_parm, first); 302 303 /* Start processing the function. */ 304 start_preparsed_function (clone, NULL_TREE, SF_PRE_PARSED); 305 306 /* Tell cgraph if both ctors or both dtors are known to have 307 the same body. */ 308 if (!in_charge_parm_used 309 && fns[0] 310 && idx == 1 311 && !flag_use_repository 312 && DECL_INTERFACE_KNOWN (fns[0]) 313 && (SUPPORTS_ONE_ONLY || !DECL_WEAK (fns[0])) 314 && (!DECL_ONE_ONLY (fns[0]) 315 || (HAVE_COMDAT_GROUP 316 && DECL_WEAK (fns[0]))) 317 && cgraph_same_body_alias (clone, fns[0])) 318 { 319 alias = true; 320 if (DECL_ONE_ONLY (fns[0])) 321 { 322 /* For comdat base and complete cdtors put them 323 into the same, *[CD]5* comdat group instead of 324 *[CD][12]*. */ 325 comdat_group = cdtor_comdat_group (fns[1], fns[0]); 326 DECL_COMDAT_GROUP (fns[0]) = comdat_group; 327 } 328 } 329 330 /* Build the delete destructor by calling complete destructor 331 and delete function. */ 332 if (idx == 2) 333 build_delete_destructor_body (clone, fns[1]); 334 else if (alias) 335 /* No need to populate body. */ ; 336 else 337 { 338 /* If we can't have multiple copies of FN (say, because there's a 339 static local initialized with the address of a label), we need 340 to use an alias for the complete variant. */ 341 if (idx == 1 && need_alias) 342 { 343 if (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_set) 344 sorry (DECL_STRUCT_FUNCTION (fn)->cannot_be_copied_reason, fn); 345 else 346 sorry ("making multiple clones of %qD", fn); 347 } 348 349 /* Remap the parameters. */ 350 decl_map = pointer_map_create (); 351 for (parmno = 0, 352 parm = DECL_ARGUMENTS (fn), 353 clone_parm = DECL_ARGUMENTS (clone); 354 parm; 355 ++parmno, 356 parm = TREE_CHAIN (parm)) 357 { 358 /* Map the in-charge parameter to an appropriate constant. */ 359 if (DECL_HAS_IN_CHARGE_PARM_P (fn) && parmno == 1) 360 { 361 tree in_charge; 362 in_charge = in_charge_arg_for_name (DECL_NAME (clone)); 363 *pointer_map_insert (decl_map, parm) = in_charge; 364 } 365 else if (DECL_ARTIFICIAL (parm) 366 && DECL_NAME (parm) == vtt_parm_identifier) 367 { 368 /* For a subobject constructor or destructor, the next 369 argument is the VTT parameter. Remap the VTT_PARM 370 from the CLONE to this parameter. */ 371 if (DECL_HAS_VTT_PARM_P (clone)) 372 { 373 DECL_ABSTRACT_ORIGIN (clone_parm) = parm; 374 *pointer_map_insert (decl_map, parm) = clone_parm; 375 clone_parm = TREE_CHAIN (clone_parm); 376 } 377 /* Otherwise, map the VTT parameter to `NULL'. */ 378 else 379 *pointer_map_insert (decl_map, parm) 380 = fold_convert (TREE_TYPE (parm), null_pointer_node); 381 } 382 /* Map other parameters to their equivalents in the cloned 383 function. */ 384 else 385 { 386 *pointer_map_insert (decl_map, parm) = clone_parm; 387 clone_parm = TREE_CHAIN (clone_parm); 388 } 389 } 390 391 if (targetm.cxx.cdtor_returns_this ()) 392 { 393 parm = DECL_RESULT (fn); 394 clone_parm = DECL_RESULT (clone); 395 *pointer_map_insert (decl_map, parm) = clone_parm; 396 } 397 398 /* Clone the body. */ 399 clone_body (clone, fn, decl_map); 400 401 /* Clean up. */ 402 pointer_map_destroy (decl_map); 403 } 404 405 /* The clone can throw iff the original function can throw. */ 406 cp_function_chain->can_throw = !TREE_NOTHROW (fn); 407 408 /* Now, expand this function into RTL, if appropriate. */ 409 finish_function (0); 410 BLOCK_ABSTRACT_ORIGIN (DECL_INITIAL (clone)) = DECL_INITIAL (fn); 411 if (alias) 412 { 413 if (expand_or_defer_fn_1 (clone)) 414 emit_associated_thunks (clone); 415 } 416 else 417 expand_or_defer_fn (clone); 418 first = false; 419 } 420 pop_from_top_level (); 421 422 if (comdat_group) 423 { 424 DECL_COMDAT_GROUP (fns[1]) = comdat_group; 425 if (fns[2]) 426 { 427 struct cgraph_node *base_dtor_node, *deleting_dtor_node; 428 /* If *[CD][12]* dtors go into the *[CD]5* comdat group and dtor is 429 virtual, it goes into the same comdat group as well. */ 430 DECL_COMDAT_GROUP (fns[2]) = comdat_group; 431 base_dtor_node = cgraph_node (fns[0]); 432 deleting_dtor_node = cgraph_node (fns[2]); 433 gcc_assert (base_dtor_node->same_comdat_group == NULL); 434 gcc_assert (deleting_dtor_node->same_comdat_group == NULL); 435 base_dtor_node->same_comdat_group = deleting_dtor_node; 436 deleting_dtor_node->same_comdat_group = base_dtor_node; 437 } 438 } 439 440 /* We don't need to process the original function any further. */ 441 return 1; 442 } 443