diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f610bed0291..9a9a9ce184e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,87 @@ +2012-08-10 Richard Guenther + + * tree.h (SSA_NAME_VAR): Return NULL_TREE if an IDENTIFIER_NODE + is recorded as var. + (SSA_NAME_IDENTIFIER): Return the IDENTIFIER_NODE of the SSA_NAME + or its SSA_NAME_VAR. + (SET_SSA_NAME_VAR_OR_IDENTIFIER): New setter. + * tree-ssanames.c (make_ssa_name_fn): Handle creating anonymous + SSA names by passing a type instead of a variable decl. + (release_ssa_name): Use SET_SSA_NAME_VAR_OR_IDENTIFIER. + (copy_ssa_name_fn): Handle anonymous SSA names. + (replace_ssa_name_symbol): Use SET_SSA_NAME_VAR_OR_IDENTIFIER. + * tree-flow-inline.h (make_temp_ssa_name): New inline function. + * tree-pretty-print.c (dump_generic_node): Use SSA_NAME_IDENTIFIER, + dump SSA names without a name as . + * cfgexpand.c (expand_used_vars): Assing anonymous SSA names we are + going to expand a decl. + (gimple_expand_cfg): Assign all SSA names of a partition the + decl we created for its leader. + * tree-ssa.c (target_for_debug_bind): Handle SSA_NAMEs. + (verify_ssa_name): Handle anonymous SSA names. + (verify_def): Likewise. + * tree-predcom.c (eliminate_temp_copies): Likewise. + * tree-ssa-copyrename.c (copy_rename_partition_coalesce): Likewise. + * tree-ssa-live.c (var_map_base_init): Compute conflicts for + anonymous SSA names with the same type. + (mark_all_vars_used_1): Handle anonymous SSA names. + (verify_live_on_entry): Likewise. + * tree-ssa-coalesce.c (abnormal_corrupt): Remove. + (create_outofssa_var_map): Adjust with respect to conflicts we + compute for anonymous SSA names. Do not restrict abnormal + coalescing. + (coalesce_partitions): Do not restrict abnormal coalescing. + Assert we only ever coalesce variables we computed conflicts for. + * tree-ssa-ter.c (process_replaceable): Do not restrict TER + of anonymous names. + * expr.c (expand_expr_real_1): Handle anonymous SSA names + expanded from IVOPTs by creating a raw REG here. + * tree-cfg.c (replace_ssa_name): Handle anonymous SSA names. + (dump_function_to_file): Dump anonymous SSA names alongside + with their types in the variable list. + (verify_gimple_return): Guard use of SSA_NAME_VAR. + * tree-into-ssa.c (mark_for_renaming): Handle a NULL symbol. + (rewrite_into_ssa): Make SSA names anonymous. + * tree-ssa-structalias.c (alias_get_name): Rewrite. + * tree-ssa-uninit.c (ssa_undefined_value_p): Handle anonymous + SSA names. + (warn_uninitialized_phi): Likewise. + * tree-ssa-loop-ivopts.c (prepare_decl_rtl): Defer expanding + anonymous SSA names to the expander. + (determine_iv_cost): Anonymous SSA names are artificial. + * tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): + Handle anonymous SSA names. + * lto-streamer-out.c (output_ssa_names): Stream SSA_NAME_VAR + or if NULL, the type of the SSA name. + * tree-inline.c (remap_ssa_name): Handle anonymous SSA names, + remap names as anonymous where appropriate. + (insert_init_stmt): Pass SSA names down to insert_init_debug_bind. + * tree-ssa-uncprop.c (uncprop_into_successor_phis): Adjust + according to what we create conflicts for in out-of-SSA + coalescing. + * tree-parloops.c (separate_decls_in_region_name): Handle + anonymous SSA names. + (add_field_for_name): Likewise. + * tree.c (get_name): Handle SSA names. + * tree-ssa-loop-im.c (gen_lsm_tmp_name): Defer to get_name for + SSA_NAMEs. + * tree-vect-loop-manip.c (adjust_debug_stmts): Use + virtual_operand_p. + * tree-sra.c (create_access_replacement): Give up generating + a DECL_DEBUG_EXPR for SSA names in the memory reference. + (replace_removed_params_ssa_names): Guard use of SSA_NAME_VAR. + * tree-complex.c (get_component_ssa_name): Handle anonymous + SSA names. + (set_component_ssa_name): Likewise. + * tree-ssa-sccvn.c (visit_reference_op_load): Likewise. + * tree-object-size.c (collect_object_sizes_for): Handle + uninitialized SSA names properly. + * ipa-inline-analysis.c (eliminated_by_inlining_prob): Guard use of + SSA_NAME_VAR. + * ipa-split.c (test_nonssa_use): Likewise. + (consider_split): Likewise. + (mark_nonssa_use): Likewise. + 2012-08-09 Jan Hubicka PR middle-end/54146 diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 7181930e488..c460b358612 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,7 @@ +2012-08-10 Richard Guenther + + * c-pretty-print.c (pp_c_expression): Handle anonymous SSA names. + 2012-08-07 Steven Bosscher * c-pretty-print.c (pp_c_function_definition): Use pp_newline_and_flush diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c index e040a3744b5..edeccce7a12 100644 --- a/gcc/c-family/c-pretty-print.c +++ b/gcc/c-family/c-pretty-print.c @@ -2141,7 +2141,8 @@ pp_c_expression (c_pretty_printer *pp, tree e) break; case SSA_NAME: - if (!DECL_ARTIFICIAL (SSA_NAME_VAR (e))) + if (SSA_NAME_VAR (e) + && !DECL_ARTIFICIAL (SSA_NAME_VAR (e))) pp_c_expression (pp, SSA_NAME_VAR (e)); else pp_c_ws_string (pp, M_("")); diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 9bf6af64224..c6cd4e29089 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1453,6 +1453,7 @@ expand_used_vars (void) { tree var, outer_block = DECL_INITIAL (current_function_decl); VEC(tree,heap) *maybe_local_decls = NULL; + struct pointer_map_t *ssa_name_decls; unsigned i; unsigned len; @@ -1465,11 +1466,23 @@ expand_used_vars (void) init_vars_expansion (); + ssa_name_decls = pointer_map_create (); for (i = 0; i < SA.map->num_partitions; i++) { tree var = partition_to_var (SA.map, i); gcc_assert (is_gimple_reg (var)); + + /* Assign decls to each SSA name partition, share decls for partitions + we could have coalesced (those with the same type). */ + if (SSA_NAME_VAR (var) == NULL_TREE) + { + void **slot = pointer_map_insert (ssa_name_decls, TREE_TYPE (var)); + if (!*slot) + *slot = (void *) create_tmp_reg (TREE_TYPE (var), NULL); + replace_ssa_name_symbol (var, (tree) *slot); + } + if (TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL) expand_one_var (var, true, true); else @@ -1486,6 +1499,7 @@ expand_used_vars (void) } } } + pointer_map_destroy (ssa_name_decls); /* At this point all variables on the local_decls with TREE_USED set are not associated with any block scope. Lay them out. */ @@ -4450,7 +4464,6 @@ gimple_expand_cfg (void) rtx r; if (!name - || !POINTER_TYPE_P (TREE_TYPE (name)) /* We might have generated new SSA names in update_alias_info_with_stack_vars. They will have a NULL defining statements, and won't be part of the partitioning, @@ -4460,6 +4473,18 @@ gimple_expand_cfg (void) part = var_to_partition (SA.map, name); if (part == NO_PARTITION) continue; + + /* Adjust all partition members to get the underlying decl of + the representative which we might have created in expand_one_var. */ + if (SSA_NAME_VAR (name) == NULL_TREE) + { + tree leader = partition_to_var (SA.map, part); + gcc_assert (SSA_NAME_VAR (leader) != NULL_TREE); + replace_ssa_name_symbol (name, SSA_NAME_VAR (leader)); + } + if (!POINTER_TYPE_P (TREE_TYPE (name))) + continue; + r = SA.partition_to_pseudo[part]; if (REG_P (r)) mark_reg_pointer (r, get_pointer_alignment (name)); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index db335c85bfb..b967735d2b5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,7 @@ +2012-08-10 Richard Guenther + + * error.c (dump_expr): Handle anonymous SSA names. + 2012-08-07 Steven Bosscher * error.c (print_instantiation_context): Pretty-print a newline before diff --git a/gcc/cp/error.c b/gcc/cp/error.c index 17646e2c5a1..40f96d33f9b 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -1803,7 +1803,8 @@ dump_expr (tree t, int flags) break; case SSA_NAME: - if (!DECL_ARTIFICIAL (SSA_NAME_VAR (t))) + if (SSA_NAME_VAR (t) + && !DECL_ARTIFICIAL (SSA_NAME_VAR (t))) dump_expr (SSA_NAME_VAR (t), flags); else pp_cxx_ws_string (cxx_pp, M_("")); diff --git a/gcc/expr.c b/gcc/expr.c index f7c4419fcee..69e043dd4d9 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -9159,8 +9159,13 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode, base variable. This unnecessarily allocates a pseudo, see how we can reuse it, if partition base vars have it set already. */ if (!currently_expanding_to_rtl) - return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier, - NULL); + { + tree var = SSA_NAME_VAR (exp); + if (var && DECL_RTL_SET_P (var)) + return DECL_RTL (var); + return gen_raw_REG (TYPE_MODE (TREE_TYPE (exp)), + LAST_VIRTUAL_REGISTER + 1); + } g = get_gimple_for_ssa_name (exp); /* For EXPAND_INITIALIZER try harder to get something simpler. */ diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index a444e916f9c..41d556a3afc 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -1394,9 +1394,9 @@ eliminated_by_inlining_prob (gimple stmt) || (TREE_CODE(inner_lhs) == MEM_REF && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0)) || (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME - && TREE_CODE (SSA_NAME_VAR - (TREE_OPERAND (inner_lhs, 0))) - == RESULT_DECL)))) + && SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0)) + && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND + (inner_lhs, 0))) == RESULT_DECL)))) lhs_free = true; if (lhs_free && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs))) diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 85d28f88221..2b5bc22b60f 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -157,6 +157,7 @@ test_nonssa_use (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data) to pretend that the value pointed to is actual result decl. */ if ((TREE_CODE (t) == MEM_REF || INDIRECT_REF_P (t)) && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME + && SSA_NAME_VAR (TREE_OPERAND (t, 0)) && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (t, 0))) == RESULT_DECL && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) return @@ -525,6 +526,7 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, /* Special case is value returned by reference we record as if it was non-ssa set to result_decl. */ else if (TREE_CODE (retval) == SSA_NAME + && SSA_NAME_VAR (retval) && TREE_CODE (SSA_NAME_VAR (retval)) == RESULT_DECL && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) current->split_part_set_retval @@ -698,6 +700,7 @@ mark_nonssa_use (gimple stmt ATTRIBUTE_UNUSED, tree t, void *data) to pretend that the value pointed to is actual result decl. */ if ((TREE_CODE (t) == MEM_REF || INDIRECT_REF_P (t)) && TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME + && SSA_NAME_VAR (TREE_OPERAND (t, 0)) && TREE_CODE (SSA_NAME_VAR (TREE_OPERAND (t, 0))) == RESULT_DECL && DECL_BY_REFERENCE (DECL_RESULT (current_function_decl))) return diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index cfcd3d0a570..a0eac254c8f 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -619,7 +619,11 @@ output_ssa_names (struct output_block *ob, struct function *fn) streamer_write_uhwi (ob, i); streamer_write_char_stream (ob->main_stream, SSA_NAME_IS_DEFAULT_DEF (ptr)); - stream_write_tree (ob, SSA_NAME_VAR (ptr), true); + if (SSA_NAME_VAR (ptr)) + stream_write_tree (ob, SSA_NAME_VAR (ptr), true); + else + /* ??? This drops SSA_NAME_IDENTIFIER on the floor. */ + stream_write_tree (ob, TREE_TYPE (ptr), true); } streamer_write_zero (ob); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c5f63245cb4..be6b56a721b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,25 @@ +2012-08-10 Richard Guenther + + * g++.dg/plugin/selfassign.c: Adjust. + * gcc.dg/plugin/selfassign.c: Likewise. + * gcc.dg/strlenopt-11.c: Likewise. + * gcc.dg/strlenopt-13.c: Likewise. + * gcc.dg/no-strict-overflow-4.c: Likewise. + * gcc.dg/strict-overflow-4.c: Likewise. + * gcc.dg/tree-ssa/alias-11.c: Likewise. + * gcc.dg/tree-ssa/alias-6.c: Likewise. + * gcc.dg/tree-ssa/asm-3.c: Likewise. + * gcc.dg/tree-ssa/pr18908.c: Likewise. + * gcc.dg/tree-ssa/pr19431.c: Likewise. + * gcc.dg/tree-ssa/ssa-pre-21.c: Likewise. + * gcc.dg/tree-ssa/phi-opt-10.c: Likewise. + * gcc.dg/tree-ssa/phi-opt-7.c: Likewise. + * gcc.dg/tree-ssa/slsr-27.c: Likewise. + * gcc.dg/tree-ssa/slsr-28.c: Likewise. + * gcc.dg/tree-ssa/slsr-29.c: Likewise. + * gcc.dg/pr46309.c: Likewise. + * gcc.dg/tree-ssa/loop-5.c: Likewise. + 2012-08-09 Uros Bizjak * gcc.c-torture/compile/20120727-1.c (dg-options): Add -mfpmath=387 diff --git a/gcc/testsuite/g++.dg/plugin/selfassign.c b/gcc/testsuite/g++.dg/plugin/selfassign.c index feb4130e532..2c417744f9e 100644 --- a/gcc/testsuite/g++.dg/plugin/selfassign.c +++ b/gcc/testsuite/g++.dg/plugin/selfassign.c @@ -46,7 +46,7 @@ get_real_ref_rhs (tree expr) e.g. D.1797_14, we need to grab the rhs of its SSA def statement (i.e. foo.x). */ tree vdecl = SSA_NAME_VAR (expr); - if (DECL_ARTIFICIAL (vdecl) + if ((!vdecl || DECL_ARTIFICIAL (vdecl)) && !gimple_nop_p (SSA_NAME_DEF_STMT (expr))) { gimple def_stmt = SSA_NAME_DEF_STMT (expr); @@ -86,6 +86,8 @@ get_real_ref_rhs (tree expr) static tree get_non_ssa_expr (tree expr) { + if (!expr) + return NULL_TREE; switch (TREE_CODE (expr)) { case VAR_DECL: @@ -149,7 +151,7 @@ get_non_ssa_expr (tree expr) case SSA_NAME: { tree vdecl = SSA_NAME_VAR (expr); - if (DECL_ARTIFICIAL (vdecl) + if ((!vdecl || DECL_ARTIFICIAL (vdecl)) && !gimple_nop_p (SSA_NAME_DEF_STMT (expr))) { gimple def_stmt = SSA_NAME_DEF_STMT (expr); @@ -209,7 +211,7 @@ warn_self_assign (gimple stmt) if (TREE_CODE (lhs) == SSA_NAME) { lhs = SSA_NAME_VAR (lhs); - if (DECL_ARTIFICIAL (lhs)) + if (!lhs || DECL_ARTIFICIAL (lhs)) return; } diff --git a/gcc/testsuite/gcc.dg/no-strict-overflow-4.c b/gcc/testsuite/gcc.dg/no-strict-overflow-4.c index 32d35c4cb4b..c3b57bba022 100644 --- a/gcc/testsuite/gcc.dg/no-strict-overflow-4.c +++ b/gcc/testsuite/gcc.dg/no-strict-overflow-4.c @@ -12,8 +12,5 @@ foo (int i) return i + 1 > i; } -/* We expect to see ""; confirm that, so that we know to count - it in the real test. */ -/* { dg-final { scan-tree-dump-times "\]*>" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times ">|<" 3 "optimized" } } */ +/* { dg-final { scan-tree-dump "\[^ \]*_.(\\\(D\\\))? (>|<) \[^ \]*_." "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c index feb4130e532..2c417744f9e 100644 --- a/gcc/testsuite/gcc.dg/plugin/selfassign.c +++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c @@ -46,7 +46,7 @@ get_real_ref_rhs (tree expr) e.g. D.1797_14, we need to grab the rhs of its SSA def statement (i.e. foo.x). */ tree vdecl = SSA_NAME_VAR (expr); - if (DECL_ARTIFICIAL (vdecl) + if ((!vdecl || DECL_ARTIFICIAL (vdecl)) && !gimple_nop_p (SSA_NAME_DEF_STMT (expr))) { gimple def_stmt = SSA_NAME_DEF_STMT (expr); @@ -86,6 +86,8 @@ get_real_ref_rhs (tree expr) static tree get_non_ssa_expr (tree expr) { + if (!expr) + return NULL_TREE; switch (TREE_CODE (expr)) { case VAR_DECL: @@ -149,7 +151,7 @@ get_non_ssa_expr (tree expr) case SSA_NAME: { tree vdecl = SSA_NAME_VAR (expr); - if (DECL_ARTIFICIAL (vdecl) + if ((!vdecl || DECL_ARTIFICIAL (vdecl)) && !gimple_nop_p (SSA_NAME_DEF_STMT (expr))) { gimple def_stmt = SSA_NAME_DEF_STMT (expr); @@ -209,7 +211,7 @@ warn_self_assign (gimple stmt) if (TREE_CODE (lhs) == SSA_NAME) { lhs = SSA_NAME_VAR (lhs); - if (DECL_ARTIFICIAL (lhs)) + if (!lhs || DECL_ARTIFICIAL (lhs)) return; } diff --git a/gcc/testsuite/gcc.dg/pr46309.c b/gcc/testsuite/gcc.dg/pr46309.c index 68a344a1bdc..ee154ccd2f3 100644 --- a/gcc/testsuite/gcc.dg/pr46309.c +++ b/gcc/testsuite/gcc.dg/pr46309.c @@ -65,6 +65,6 @@ f6 (unsigned int a) /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.1, 1. and -.2, 2.\[\n\r\]* into" 1 "reassoc1" } } */ /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.0, 31. and -.64, 95.\[\n\r\]* into" 2 "reassoc1" } } */ /* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.128, 159. and -.192, 223.\[\n\r\]* into" 1 "reassoc1" } } */ -/* { dg-final { scan-tree-dump-times "Optimizing range tests D.\[0-9\]*_\[0-9\]* -.0, 31. and -.128, 159.\[\n\r\]* into" 1 "reassoc2" } } */ +/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 31. and -.128, 159.\[\n\r\]* into" 1 "reassoc2" } } */ /* { dg-final { cleanup-tree-dump "reassoc1" } } */ /* { dg-final { cleanup-tree-dump "reassoc2" } } */ diff --git a/gcc/testsuite/gcc.dg/strict-overflow-4.c b/gcc/testsuite/gcc.dg/strict-overflow-4.c index 1a8c4ed4330..ad2d635e464 100644 --- a/gcc/testsuite/gcc.dg/strict-overflow-4.c +++ b/gcc/testsuite/gcc.dg/strict-overflow-4.c @@ -12,8 +12,5 @@ foo (int i) return i + 1 > i; } -/* We expect to see ""; confirm that, so that we know to count - it in the real test. */ -/* { dg-final { scan-tree-dump-times "\]*>" 1 "optimized" } } */ -/* { dg-final { scan-tree-dump-times ">|<" 2 "optimized" } } */ +/* { dg-final { scan-tree-dump "return 1;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-11.c b/gcc/testsuite/gcc.dg/strlenopt-11.c index 03f8790d0c6..888eeb20cdc 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-11.c +++ b/gcc/testsuite/gcc.dg/strlenopt-11.c @@ -64,7 +64,7 @@ main () /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times " D\.\[0-9_\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times " D\.\[0-9_\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times " D\.\[0-9_\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen" } } */ /* { dg-final { cleanup-tree-dump "strlen" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-13.c b/gcc/testsuite/gcc.dg/strlenopt-13.c index 62effcd64d0..9413cb53e2f 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-13.c +++ b/gcc/testsuite/gcc.dg/strlenopt-13.c @@ -61,8 +61,8 @@ main () /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */ -/* { dg-final { scan-tree-dump-times " D\.\[0-9_\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times " D\.\[0-9_\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times " D\.\[0-9_\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen" } } */ -/* { dg-final { scan-tree-dump-times " D\.\[0-9_\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen" } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" } } */ /* { dg-final { cleanup-tree-dump "strlen" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-11.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-11.c index d4ce34bd8cb..1f8a12d85e2 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/alias-11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-11.c @@ -15,7 +15,7 @@ int bar(void) } /* We need to have both: a load from "a[0]" and a load from "*p.a", - the latter can be an ssa temporary. */ + the latter is an ssa temporary. */ /* { dg-final { scan-tree-dump "= a.0.;" "optimized" } } */ -/* { dg-final { scan-tree-dump "= \\*\[pD\]" "optimized" } } */ +/* { dg-final { scan-tree-dump "= \\*\[^\r\n\]*_.;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-6.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-6.c index bcc011898fa..9a41920e76f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/alias-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-6.c @@ -15,7 +15,7 @@ int bar(void) } /* We need to have both: a load from "a[0]" and a load from "*p.a", - the latter can be an ssa temporary. */ + the latter is an ssa temporary. */ /* { dg-final { scan-tree-dump "= a.0.;" "optimized" } } */ -/* { dg-final { scan-tree-dump "= \\*\[pD\]" "optimized" } } */ +/* { dg-final { scan-tree-dump "= \\*\[^\r\n\]*_.;" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/asm-3.c b/gcc/testsuite/gcc.dg/tree-ssa/asm-3.c index 5ed282e49a1..29b27f4ff56 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/asm-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/asm-3.c @@ -31,6 +31,6 @@ void test(void) /* { dg-final { scan-tree-dump-times "hardreg" 3 "optimized" } } */ /* In particular, hardreg should *not* appear in the call to bar. */ -/* { dg-final { scan-tree-dump-times "bar \[(\]t_.\[)\]" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "bar \[(\]\[^\n\r\]*_.\[)\]" 1 "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-5.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-5.c index a8db74afe14..e9ff9fcfe38 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-5.c @@ -18,7 +18,7 @@ void xxx(void) /* Only iter variable should remain. */ -/* { dg-final { scan-tree-dump-times "int iter" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "int jiter" 0 "optimized" } } */ /* And jter shouldn't be an induction variable anymore (no PHI node). */ /* { dg-final { scan-tree-dump-times "jter_\[0-9\]* = PHI" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c index 52b5942eb3a..62d007d4548 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-10.c @@ -7,5 +7,5 @@ int eqm1_phi (unsigned long a) { return a ? 0 : -1; } int spaceship1 (long a) { return a > 0 ? 1 : a < 0 ? -1 : 0; } int spaceship2 (long a) { return a > 0 ? 1 : a == 0 ? 0 : -1; } -/* { dg-final { scan-tree-dump-times " = -D" 4 "optimized"} } */ +/* { dg-final { scan-tree-dump-times " = -\[^\r\n\]*_.;" 4 "optimized"} } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c index 944acf94921..bd897554e2a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/phi-opt-7.c @@ -18,6 +18,6 @@ int f(int t, int c) /* There should be one ifs as one of them should be changed into a conditional and the other should be there still. */ /* { dg-final { scan-tree-dump-times "if" 1 "optimized" } }*/ -/* { dg-final { scan-tree-dump-times "D.\[0-9\]*_\[0-9\]* = c_\[0-9\]*.D. != 0" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "\[^\r\n\]*_. = c_\[0-9\]*.D. != 0" 1 "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr18908.c b/gcc/testsuite/gcc.dg/tree-ssa/pr18908.c index cfc92fec9c4..3707efe36c3 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr18908.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr18908.c @@ -4,6 +4,6 @@ _Bool f3(_Bool *p) { *p ^= 1; } /* We should be able to canonicalize the above to use bitwise not. */ -/* { dg-final { scan-tree-dump "~D" "forwprop1" } } */ +/* { dg-final { scan-tree-dump "~\[^\n\r\]*_.;" "forwprop1" } } */ /* { dg-final { scan-tree-dump-not "\\\^ 1" "forwprop1" } } */ /* { dg-final { cleanup-tree-dump "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr19431.c b/gcc/testsuite/gcc.dg/tree-ssa/pr19431.c index 1c87acbddda..08972063e0d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr19431.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr19431.c @@ -24,6 +24,5 @@ int f(int k, int i1, int j1) return *f1; } -/* { dg-final { scan-tree-dump "i1_. = PHI \]*>" "optimized" } } */ -/* { dg-final { scan-tree-dump "return i1_.;" "optimized" } } */ +/* { dg-final { scan-tree-dump "\[^\r\n\]*_. = PHI \]*>" "optimized" } } */ /* { dg-final { cleanup-tree-dump "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c index b0defc7a879..eb5734ae543 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c @@ -17,6 +17,6 @@ f (struct x *p, unsigned int n) } /* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" } } */ -/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ D" 1 "dom2" } } */ -/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)D" 3 "dom2" } } */ +/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+;" 1 "dom2" } } */ +/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 3 "dom2" } } */ /* { dg-final { cleanup-tree-dump "dom2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c index fdf1596b802..7e7c7516e6a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c @@ -21,6 +21,6 @@ f (struct x *p, unsigned int n) } /* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" } } */ -/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ D" 1 "dom2" } } */ -/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)D" 9 "dom2" } } */ +/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+" 1 "dom2" } } */ +/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom2" } } */ /* { dg-final { cleanup-tree-dump "dom2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c index 2366a863137..2a8fe0e6d6c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c @@ -23,6 +23,6 @@ f (struct x *p, unsigned int n) } /* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" } } */ -/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ D" 1 "dom2" } } */ -/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)D" 9 "dom2" } } */ +/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+" 1 "dom2" } } */ +/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom2" } } */ /* { dg-final { cleanup-tree-dump "dom2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c index 10efb12b4ab..e4c9772f61f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c @@ -11,5 +11,5 @@ NumSift (long *array, unsigned long k) /* There should be only two loads left. */ -/* { dg-final { scan-tree-dump-times "= \\\*D\[^\n;\]*;" 2 "pre" } } */ +/* { dg-final { scan-tree-dump-times "= \\\*\[^\n;\]*;" 2 "pre" } } */ /* { dg-final { cleanup-tree-dump "pre" } } */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 4f2ddc02ada..daa0b446f5f 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4085,6 +4085,7 @@ verify_gimple_return (gimple stmt) if ((TREE_CODE (op) == RESULT_DECL && DECL_BY_REFERENCE (op)) || (TREE_CODE (op) == SSA_NAME + && SSA_NAME_VAR (op) && TREE_CODE (SSA_NAME_VAR (op)) == RESULT_DECL && DECL_BY_REFERENCE (SSA_NAME_VAR (op)))) op = TREE_TYPE (op); @@ -5945,7 +5946,7 @@ replace_ssa_name (tree name, struct pointer_map_t *vars_map, tree to_context) { void **loc; - tree new_name, decl = SSA_NAME_VAR (name); + tree new_name; gcc_assert (is_gimple_reg (name)); @@ -5953,12 +5954,19 @@ replace_ssa_name (tree name, struct pointer_map_t *vars_map, if (!loc) { - replace_by_duplicate_decl (&decl, vars_map, to_context); - - new_name = make_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context), - decl, SSA_NAME_DEF_STMT (name)); - if (SSA_NAME_IS_DEFAULT_DEF (name)) - set_ssa_default_def (DECL_STRUCT_FUNCTION (to_context), decl, new_name); + tree decl = SSA_NAME_VAR (name); + if (decl) + { + replace_by_duplicate_decl (&decl, vars_map, to_context); + new_name = make_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context), + decl, SSA_NAME_DEF_STMT (name)); + if (SSA_NAME_IS_DEFAULT_DEF (name)) + set_ssa_default_def (DECL_STRUCT_FUNCTION (to_context), + decl, new_name); + } + else + new_name = copy_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context), + name, SSA_NAME_DEF_STMT (name)); loc = pointer_map_insert (vars_map, name); *loc = new_name; @@ -6684,6 +6692,19 @@ dump_function_to_file (tree fn, FILE *file, int flags) any_var = true; } + if (gimple_in_ssa_p (cfun)) + for (ix = 1; ix < num_ssa_names; ++ix) + { + tree name = ssa_name (ix); + if (name && !SSA_NAME_VAR (name)) + { + fprintf (file, " "); + print_generic_expr (file, TREE_TYPE (name), flags); + fprintf (file, " "); + print_generic_expr (file, name, flags); + fprintf (file, ";\n"); + } + } } if (cfun && cfun->decl == fn && cfun->cfg && basic_block_info) diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index a34d04842f2..c6c5227e287 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -488,7 +488,10 @@ get_component_ssa_name (tree ssa_name, bool imag_p) ret = VEC_index (tree, complex_ssa_name_components, ssa_name_index); if (ret == NULL) { - ret = get_component_var (SSA_NAME_VAR (ssa_name), imag_p); + if (SSA_NAME_VAR (ssa_name)) + ret = get_component_var (SSA_NAME_VAR (ssa_name), imag_p); + else + ret = TREE_TYPE (TREE_TYPE (ssa_name)); ret = make_ssa_name (ret, NULL); /* Copy some properties from the original. In particular, whether it @@ -549,7 +552,8 @@ set_component_ssa_name (tree ssa_name, bool imag_p, tree value) { /* Replace an anonymous base value with the variable from cvc_lookup. This should result in better debug info. */ - if (DECL_IGNORED_P (SSA_NAME_VAR (value)) + if (SSA_NAME_VAR (ssa_name) + && (!SSA_NAME_VAR (value) || DECL_IGNORED_P (SSA_NAME_VAR (value))) && !DECL_IGNORED_P (SSA_NAME_VAR (ssa_name))) { comp = get_component_var (SSA_NAME_VAR (ssa_name), imag_p); diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index e40974ea2a5..7bd0db3917a 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -1162,6 +1162,18 @@ duplicate_ssa_name (tree var, gimple stmt) return duplicate_ssa_name_fn (cfun, var, stmt); } +/* Return an anonymous SSA_NAME node for type TYPE defined in statement STMT + in function cfun. Arrange so that it uses NAME in dumps. */ + +static inline tree +make_temp_ssa_name (tree type, gimple stmt, const char *name) +{ + tree ssa_name; + gcc_checking_assert (TYPE_P (type)); + ssa_name = make_ssa_name_fn (cfun, type, stmt); + SET_SSA_NAME_VAR_OR_IDENTIFIER (ssa_name, get_identifier (name)); + return ssa_name; +} /* Returns the base object and a constant BITS_PER_UNIT offset in *POFFSET that denotes the starting address of the memory access EXP. diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6b6b78cab8b..879292b72e1 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -176,7 +176,7 @@ static int processing_debug_stmt = 0; static tree remap_ssa_name (tree name, copy_body_data *id) { - tree new_tree; + tree new_tree, var; tree *n; gcc_assert (TREE_CODE (name) == SSA_NAME); @@ -218,9 +218,38 @@ remap_ssa_name (tree name, copy_body_data *id) return name; } + /* Remap anonymous SSA names or SSA names of anonymous decls. */ + var = SSA_NAME_VAR (name); + if (!var + || (!SSA_NAME_IS_DEFAULT_DEF (name) + && TREE_CODE (var) == VAR_DECL + && !VAR_DECL_IS_VIRTUAL_OPERAND (var) + && DECL_ARTIFICIAL (var) + && DECL_IGNORED_P (var) + && !DECL_NAME (var))) + { + struct ptr_info_def *pi; + new_tree = make_ssa_name (remap_type (TREE_TYPE (name), id), NULL); + if (!var && SSA_NAME_IDENTIFIER (name)) + SET_SSA_NAME_VAR_OR_IDENTIFIER (new_tree, SSA_NAME_IDENTIFIER (name)); + insert_decl_map (id, name, new_tree); + SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_tree) + = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name); + /* At least IPA points-to info can be directly transferred. */ + if (id->src_cfun->gimple_df + && id->src_cfun->gimple_df->ipa_pta + && (pi = SSA_NAME_PTR_INFO (name)) + && !pi->pt.anything) + { + struct ptr_info_def *new_pi = get_ptr_info (new_tree); + new_pi->pt = pi->pt; + } + return new_tree; + } + /* Do not set DEF_STMT yet as statement is not copied yet. We do that in copy_bb. */ - new_tree = remap_decl (SSA_NAME_VAR (name), id); + new_tree = remap_decl (var, id); /* We might've substituted constant or another SSA_NAME for the variable. @@ -229,7 +258,8 @@ remap_ssa_name (tree name, copy_body_data *id) inlining: this saves us from need to introduce PHI node in a case return value is just partly initialized. */ if ((TREE_CODE (new_tree) == VAR_DECL || TREE_CODE (new_tree) == PARM_DECL) - && (TREE_CODE (SSA_NAME_VAR (name)) != RESULT_DECL + && (!SSA_NAME_VAR (name) + || TREE_CODE (SSA_NAME_VAR (name)) != RESULT_DECL || !id->transform_return_to_modify)) { struct ptr_info_def *pi; @@ -259,7 +289,8 @@ remap_ssa_name (tree name, copy_body_data *id) regions of the CFG, but this is expensive to test. */ if (id->entry_bb && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name) - && TREE_CODE (SSA_NAME_VAR (name)) != PARM_DECL + && (!SSA_NAME_VAR (name) + || TREE_CODE (SSA_NAME_VAR (name)) != PARM_DECL) && (id->entry_bb != EDGE_SUCC (ENTRY_BLOCK_PTR, 0)->dest || EDGE_COUNT (id->entry_bb->preds) != 1)) { @@ -1184,6 +1215,7 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id) if (retval && (TREE_CODE (retval) != RESULT_DECL && (TREE_CODE (retval) != SSA_NAME + || ! SSA_NAME_VAR (retval) || TREE_CODE (SSA_NAME_VAR (retval)) != RESULT_DECL))) { copy = gimple_build_assign (id->retvar, retval); @@ -2474,14 +2506,8 @@ insert_init_stmt (copy_body_data *id, basic_block bb, gimple init_stmt) if (!is_gimple_debug (init_stmt) && MAY_HAVE_DEBUG_STMTS) { - tree var, def = gimple_assign_lhs (init_stmt); - - if (TREE_CODE (def) == SSA_NAME) - var = SSA_NAME_VAR (def); - else - var = def; - - insert_init_debug_bind (id, bb, var, def, init_stmt); + tree def = gimple_assign_lhs (init_stmt); + insert_init_debug_bind (id, bb, def, def, init_stmt); } } } diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 3e0c817b23b..815d8a866d8 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -249,7 +249,7 @@ mark_for_renaming (tree sym) static bool marked_for_renaming (tree sym) { - if (!symbols_to_rename_set) + if (!symbols_to_rename_set || sym == NULL_TREE) return false; return bitmap_bit_p (symbols_to_rename_set, DECL_UID (sym)); } @@ -2388,6 +2388,7 @@ rewrite_into_ssa (void) { bitmap_head *dfs; basic_block bb; + unsigned i; /* Initialize operand data structures. */ init_ssa_operands (cfun); @@ -2428,6 +2429,25 @@ rewrite_into_ssa (void) fini_ssa_renamer (); + /* Try to get rid of all gimplifier generated temporaries by making + its SSA names anonymous. This way we can garbage collect them + all after removing unused locals which we do in our TODO. */ + for (i = 1; i < num_ssa_names; ++i) + { + tree decl, name = ssa_name (i); + if (!name + || SSA_NAME_IS_DEFAULT_DEF (name)) + continue; + decl = SSA_NAME_VAR (name); + if (decl + && TREE_CODE (decl) == VAR_DECL + && !VAR_DECL_IS_VIRTUAL_OPERAND (decl) + && DECL_ARTIFICIAL (decl) + && DECL_IGNORED_P (decl) + && !DECL_NAME (decl)) + SET_SSA_NAME_VAR_OR_IDENTIFIER (name, NULL_TREE); + } + return 0; } diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 7e341b0ec72..fcf9316a395 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -973,14 +973,12 @@ collect_object_sizes_for (struct object_size_info *osi, tree var) break; case GIMPLE_NOP: - { - tree decl = SSA_NAME_VAR (var); - - if (TREE_CODE (decl) != PARM_DECL && DECL_INITIAL (decl)) - expr_object_size (osi, var, DECL_INITIAL (decl)); - else - expr_object_size (osi, var, decl); - } + if (SSA_NAME_VAR (var) + && TREE_CODE (SSA_NAME_VAR (var)) == PARM_DECL) + expr_object_size (osi, var, SSA_NAME_VAR (var)); + else + /* Uninitialized SSA names point nowhere. */ + object_sizes[object_size_type][varno] = unknown[object_size_type]; break; case GIMPLE_PHI: diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index 4853e0702b6..e79eef47802 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -795,7 +795,25 @@ separate_decls_in_region_name (tree name, if (slot && *slot) return ((struct name_to_copy_elt *) *slot)->new_name; + if (copy_name_p) + { + copy = duplicate_ssa_name (name, NULL); + nelt = XNEW (struct name_to_copy_elt); + nelt->version = idx; + nelt->new_name = copy; + nelt->field = NULL_TREE; + *slot = nelt; + } + else + { + gcc_assert (!slot); + copy = name; + } + var = SSA_NAME_VAR (name); + if (!var) + return copy; + uid = DECL_UID (var); ielt.uid = uid; dslot = htab_find_slot_with_hash (decl_copies, &ielt, uid, INSERT); @@ -822,21 +840,6 @@ separate_decls_in_region_name (tree name, else var_copy = ((struct int_tree_map *) *dslot)->to; - if (copy_name_p) - { - copy = duplicate_ssa_name (name, NULL); - nelt = XNEW (struct name_to_copy_elt); - nelt->version = idx; - nelt->new_name = copy; - nelt->field = NULL_TREE; - *slot = nelt; - } - else - { - gcc_assert (!slot); - copy = name; - } - replace_ssa_name_symbol (copy, var_copy); return copy; } @@ -966,9 +969,9 @@ add_field_for_name (void **slot, void *data) struct name_to_copy_elt *const elt = (struct name_to_copy_elt *) *slot; tree type = (tree) data; tree name = ssa_name (elt->version); - tree var = SSA_NAME_VAR (name); - tree field = build_decl (DECL_SOURCE_LOCATION (var), - FIELD_DECL, DECL_NAME (var), TREE_TYPE (var)); + tree field = build_decl (UNKNOWN_LOCATION, + FIELD_DECL, SSA_NAME_IDENTIFIER (name), + TREE_TYPE (name)); insert_field_into_struct (type, field); elt->field = field; diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index a0d5d3ea14c..b13300c4d11 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1901,7 +1901,7 @@ eliminate_temp_copies (struct loop *loop, bitmap tmp_vars) phi = gsi_stmt (psi); name = PHI_RESULT (phi); var = SSA_NAME_VAR (name); - if (!bitmap_bit_p (tmp_vars, DECL_UID (var))) + if (!var || !bitmap_bit_p (tmp_vars, DECL_UID (var))) continue; use = PHI_ARG_DEF_FROM_EDGE (phi, e); gcc_assert (TREE_CODE (use) == SSA_NAME); diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index c7bb5206454..8bd483a3a0e 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2043,7 +2043,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags, break; case SSA_NAME: - dump_generic_node (buffer, SSA_NAME_VAR (node), spc, flags, false); + if (SSA_NAME_IDENTIFIER (node)) + dump_generic_node (buffer, SSA_NAME_IDENTIFIER (node), + spc, flags, false); pp_string (buffer, "_"); pp_decimal_int (buffer, SSA_NAME_VERSION (node)); if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node)) diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 820acd08efb..4d210ad896e 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -1885,6 +1885,7 @@ create_access_replacement (struct access *access) { char *pretty_name = make_fancy_name (access->expr); tree debug_expr = unshare_expr (access->expr), d; + bool fail = false; DECL_NAME (repl) = get_identifier (pretty_name); obstack_free (&name_obstack, pretty_name); @@ -1894,29 +1895,34 @@ create_access_replacement (struct access *access) used SSA_NAMEs and thus they could be freed. All debug info generation cares is whether something is constant or variable and that get_ref_base_and_extent works properly on the - expression. */ - for (d = debug_expr; handled_component_p (d); d = TREE_OPERAND (d, 0)) + expression. It cannot handle accesses at a non-constant offset + though, so just give up in those cases. */ + for (d = debug_expr; !fail && handled_component_p (d); + d = TREE_OPERAND (d, 0)) switch (TREE_CODE (d)) { case ARRAY_REF: case ARRAY_RANGE_REF: if (TREE_OPERAND (d, 1) - && TREE_CODE (TREE_OPERAND (d, 1)) == SSA_NAME) - TREE_OPERAND (d, 1) = SSA_NAME_VAR (TREE_OPERAND (d, 1)); + && TREE_CODE (TREE_OPERAND (d, 1)) != INTEGER_CST) + fail = true; if (TREE_OPERAND (d, 3) - && TREE_CODE (TREE_OPERAND (d, 3)) == SSA_NAME) - TREE_OPERAND (d, 3) = SSA_NAME_VAR (TREE_OPERAND (d, 3)); + && TREE_CODE (TREE_OPERAND (d, 3)) != INTEGER_CST) + fail = true; /* FALLTHRU */ case COMPONENT_REF: if (TREE_OPERAND (d, 2) - && TREE_CODE (TREE_OPERAND (d, 2)) == SSA_NAME) - TREE_OPERAND (d, 2) = SSA_NAME_VAR (TREE_OPERAND (d, 2)); + && TREE_CODE (TREE_OPERAND (d, 2)) != INTEGER_CST) + fail = true; break; default: break; } - SET_DECL_DEBUG_EXPR (repl, debug_expr); - DECL_DEBUG_EXPR_IS_FROM (repl) = 1; + if (!fail) + { + SET_DECL_DEBUG_EXPR (repl, debug_expr); + DECL_DEBUG_EXPR_IS_FROM (repl) = 1; + } if (access->grp_no_warning) TREE_NO_WARNING (repl) = 1; else @@ -4236,8 +4242,10 @@ replace_removed_params_ssa_names (gimple stmt, if (TREE_CODE (lhs) != SSA_NAME) return false; + decl = SSA_NAME_VAR (lhs); - if (TREE_CODE (decl) != PARM_DECL) + if (decl == NULL_TREE + || TREE_CODE (decl) != PARM_DECL) return false; adj = get_adjustment_for_base (adjustments, decl); diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c index 5001ced3abb..b8b1a51dd72 100644 --- a/gcc/tree-ssa-coalesce.c +++ b/gcc/tree-ssa-coalesce.c @@ -924,34 +924,6 @@ print_exprs (FILE *f, const char *str1, tree expr1, const char *str2, } -/* Called if a coalesce across and abnormal edge cannot be performed. PHI is - the phi node at fault, I is the argument index at fault. A message is - printed and compilation is then terminated. */ - -static inline void -abnormal_corrupt (gimple phi, int i) -{ - edge e = gimple_phi_arg_edge (phi, i); - tree res = gimple_phi_result (phi); - tree arg = gimple_phi_arg_def (phi, i); - - fprintf (stderr, " Corrupt SSA across abnormal edge BB%d->BB%d\n", - e->src->index, e->dest->index); - fprintf (stderr, "Argument %d (", i); - print_generic_expr (stderr, arg, TDF_SLIM); - if (TREE_CODE (arg) != SSA_NAME) - fprintf (stderr, ") is not an SSA_NAME.\n"); - else - { - gcc_assert (SSA_NAME_VAR (res) != SSA_NAME_VAR (arg)); - fprintf (stderr, ") does not have the same base variable as the result "); - print_generic_stmt (stderr, res, TDF_SLIM); - } - - internal_error ("SSA corruption"); -} - - /* Print a failure to coalesce a MUST_COALESCE pair X and Y. */ static inline void @@ -1007,25 +979,25 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy) { edge e = gimple_phi_arg_edge (phi, i); arg = PHI_ARG_DEF (phi, i); - if (TREE_CODE (arg) == SSA_NAME) - register_ssa_partition (map, arg); - if (TREE_CODE (arg) == SSA_NAME - && SSA_NAME_VAR (arg) == SSA_NAME_VAR (res)) - { + if (TREE_CODE (arg) != SSA_NAME) + continue; + + register_ssa_partition (map, arg); + if ((SSA_NAME_VAR (arg) == SSA_NAME_VAR (res) + && TREE_TYPE (arg) == TREE_TYPE (res)) + || (e->flags & EDGE_ABNORMAL)) + { saw_copy = true; bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (arg)); if ((e->flags & EDGE_ABNORMAL) == 0) { int cost = coalesce_cost_edge (e); if (cost == 1 && has_single_use (arg)) - add_cost_one_coalesce (cl, ver, SSA_NAME_VERSION (arg)); + add_cost_one_coalesce (cl, ver, SSA_NAME_VERSION (arg)); else add_coalesce (cl, ver, SSA_NAME_VERSION (arg), cost); } } - else - if (e->flags & EDGE_ABNORMAL) - abnormal_corrupt (phi, i); } if (saw_copy) bitmap_set_bit (used_in_copy, ver); @@ -1053,7 +1025,8 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy) if (gimple_assign_copy_p (stmt) && TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs1) == SSA_NAME - && SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs1)) + && SSA_NAME_VAR (lhs) == SSA_NAME_VAR (rhs1) + && TREE_TYPE (lhs) == TREE_TYPE (rhs1)) { v1 = SSA_NAME_VERSION (lhs); v2 = SSA_NAME_VERSION (rhs1); @@ -1103,7 +1076,8 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy) v1 = SSA_NAME_VERSION (outputs[match]); v2 = SSA_NAME_VERSION (input); - if (SSA_NAME_VAR (outputs[match]) == SSA_NAME_VAR (input)) + if (SSA_NAME_VAR (outputs[match]) == SSA_NAME_VAR (input) + && TREE_TYPE (outputs[match]) == TREE_TYPE (input)) { cost = coalesce_cost (REG_BR_PROB_BASE, optimize_bb_for_size_p (bb)); @@ -1130,13 +1104,15 @@ create_outofssa_var_map (coalesce_list_p cl, bitmap used_in_copy) if (var != NULL_TREE && is_gimple_reg (var)) { /* Add coalesces between all the result decls. */ - if (TREE_CODE (SSA_NAME_VAR (var)) == RESULT_DECL) + if (SSA_NAME_VAR (var) + && TREE_CODE (SSA_NAME_VAR (var)) == RESULT_DECL) { if (first == NULL_TREE) first = var; else { - gcc_assert (SSA_NAME_VAR (var) == SSA_NAME_VAR (first)); + gcc_assert (SSA_NAME_VAR (var) == SSA_NAME_VAR (first) + && TREE_TYPE (var) == TREE_TYPE (first)); v1 = SSA_NAME_VERSION (first); v2 = SSA_NAME_VERSION (var); bitmap_set_bit (used_in_copy, v1); @@ -1256,9 +1232,6 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl, int v1 = SSA_NAME_VERSION (res); int v2 = SSA_NAME_VERSION (arg); - if (SSA_NAME_VAR (arg) != SSA_NAME_VAR (res)) - abnormal_corrupt (phi, e->dest_idx); - if (debug) fprintf (debug, "Abnormal coalesce: "); @@ -1276,7 +1249,8 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl, var2 = ssa_name (y); /* Assert the coalesces have the same base variable. */ - gcc_assert (SSA_NAME_VAR (var1) == SSA_NAME_VAR (var2)); + gcc_assert (SSA_NAME_VAR (var1) == SSA_NAME_VAR (var2) + && TREE_TYPE (var1) == TREE_TYPE (var2)); if (debug) fprintf (debug, "Coalesce list: "); diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c index e02d7298031..82f8c64fe1c 100644 --- a/gcc/tree-ssa-copyrename.c +++ b/gcc/tree-ssa-copyrename.c @@ -143,11 +143,6 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) gcc_assert (p1 != NO_PARTITION); gcc_assert (p2 != NO_PARTITION); - rep1 = partition_to_var (map, p1); - rep2 = partition_to_var (map, p2); - root1 = SSA_NAME_VAR (rep1); - root2 = SSA_NAME_VAR (rep2); - if (p1 == p2) { if (debug) @@ -155,6 +150,13 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) return false; } + rep1 = partition_to_var (map, p1); + rep2 = partition_to_var (map, p2); + root1 = SSA_NAME_VAR (rep1); + root2 = SSA_NAME_VAR (rep2); + if (!root1 && !root2) + return false; + /* Don't coalesce if one of the variables occurs in an abnormal PHI. */ abnorm = (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep1) || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep2)); @@ -175,22 +177,24 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) } /* Never attempt to coalesce 2 different parameters. */ - if (TREE_CODE (root1) == PARM_DECL && TREE_CODE (root2) == PARM_DECL) + if ((root1 && TREE_CODE (root1) == PARM_DECL) + && (root2 && TREE_CODE (root2) == PARM_DECL)) { if (debug) fprintf (debug, " : 2 different PARM_DECLS. No coalesce.\n"); return false; } - if ((TREE_CODE (root1) == RESULT_DECL) != (TREE_CODE (root2) == RESULT_DECL)) + if ((root1 && TREE_CODE (root1) == RESULT_DECL) + != (root2 && TREE_CODE (root2) == RESULT_DECL)) { if (debug) fprintf (debug, " : One root a RESULT_DECL. No coalesce.\n"); return false; } - ign1 = TREE_CODE (root1) == VAR_DECL && DECL_IGNORED_P (root1); - ign2 = TREE_CODE (root2) == VAR_DECL && DECL_IGNORED_P (root2); + ign1 = !root1 || (TREE_CODE (root1) == VAR_DECL && DECL_IGNORED_P (root1)); + ign2 = !root2 || (TREE_CODE (root2) == VAR_DECL && DECL_IGNORED_P (root2)); /* Refrain from coalescing user variables, if requested. */ if (!ign1 && !ign2) @@ -211,9 +215,9 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) /* If both values have default defs, we can't coalesce. If only one has a tag, make sure that variable is the new root partition. */ - if (ssa_default_def (cfun, root1)) + if (root1 && ssa_default_def (cfun, root1)) { - if (ssa_default_def (cfun, root2)) + if (root2 && ssa_default_def (cfun, root2)) { if (debug) fprintf (debug, " : 2 default defs. No coalesce.\n"); @@ -225,18 +229,28 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) ign1 = false; } } - else if (ssa_default_def (cfun, root2)) + else if (root2 && ssa_default_def (cfun, root2)) { ign1 = true; ign2 = false; } + /* Do not coalesce if we cannot assign a symbol to the partition. */ + if (!(!ign2 && root2) + && !(!ign1 && root1)) + { + if (debug) + fprintf (debug, " : Choosen variable has no root. No coalesce.\n"); + return false; + } + /* Don't coalesce if the new chosen root variable would be read-only. If both ign1 && ign2, then the root var of the larger partition wins, so reject in that case if any of the root vars is TREE_READONLY. Otherwise reject only if the root var, on which replace_ssa_name_symbol will be called below, is readonly. */ - if ((TREE_READONLY (root1) && ign2) || (TREE_READONLY (root2) && ign1)) + if (((root1 && TREE_READONLY (root1)) && ign2) + || ((root2 && TREE_READONLY (root2)) && ign1)) { if (debug) fprintf (debug, " : Readonly variable. No coalesce.\n"); @@ -244,12 +258,12 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) } /* Don't coalesce if the two variables aren't type compatible . */ - if (!types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2)) + if (!types_compatible_p (TREE_TYPE (var1), TREE_TYPE (var2)) /* There is a disconnect between the middle-end type-system and VRP, avoid coalescing enum types with different bounds. */ - || ((TREE_CODE (TREE_TYPE (root1)) == ENUMERAL_TYPE - || TREE_CODE (TREE_TYPE (root2)) == ENUMERAL_TYPE) - && TREE_TYPE (root1) != TREE_TYPE (root2))) + || ((TREE_CODE (TREE_TYPE (var1)) == ENUMERAL_TYPE + || TREE_CODE (TREE_TYPE (var2)) == ENUMERAL_TYPE) + && TREE_TYPE (var1) != TREE_TYPE (var2))) { if (debug) fprintf (debug, " : Incompatible types. No coalesce.\n"); @@ -261,10 +275,12 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) /* Set the root variable of the partition to the better choice, if there is one. */ - if (!ign2) + if (!ign2 && root2) replace_ssa_name_symbol (partition_to_var (map, p3), root2); - else if (!ign1) + else if (!ign1 && root1) replace_ssa_name_symbol (partition_to_var (map, p3), root1); + else + gcc_unreachable (); if (debug) { diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 3edda1e378e..85c71fc4ad7 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -61,11 +61,11 @@ var_map_base_init (var_map map) { int x, num_part; tree var; - htab_t decl_to_index; + htab_t tree_to_index; struct tree_int_map *m, *mapstorage; num_part = num_var_partitions (map); - decl_to_index = htab_create (num_part, tree_decl_map_hash, + tree_to_index = htab_create (num_part, tree_map_base_hash, tree_int_map_eq, NULL); /* We can have at most num_part entries in the hash tables, so it's enough to allocate so many map elements once, saving some malloc @@ -82,10 +82,18 @@ var_map_base_init (var_map map) struct tree_int_map **slot; unsigned baseindex; var = partition_to_var (map, x); - var = SSA_NAME_VAR (var); + if (SSA_NAME_VAR (var)) + m->base.from = SSA_NAME_VAR (var); + else + /* This restricts what anonymous SSA names we can coalesce + as it restricts the sets we compute conflicts for. + Using TREE_TYPE to generate sets is the easies as + type equivalency also holds for SSA names with the same + underlying decl. */ + m->base.from = TREE_TYPE (var); /* If base variable hasn't been seen, set it up. */ - m->base.from = var; - slot = (struct tree_int_map **) htab_find_slot (decl_to_index, m, INSERT); + slot = (struct tree_int_map **) htab_find_slot (tree_to_index, + m, INSERT); if (!*slot) { baseindex = m - mapstorage; @@ -101,7 +109,7 @@ var_map_base_init (var_map map) map->num_basevars = m - mapstorage; free (mapstorage); - htab_delete (decl_to_index); + htab_delete (tree_to_index); } @@ -360,7 +368,12 @@ mark_all_vars_used_1 (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) tree b; if (TREE_CODE (t) == SSA_NAME) - t = SSA_NAME_VAR (t); + { + *walk_subtrees = 0; + t = SSA_NAME_VAR (t); + if (!t) + return NULL; + } if (IS_EXPR_CODE_CLASS (c) && (b = TREE_BLOCK (t)) != NULL) @@ -1240,12 +1253,13 @@ verify_live_on_entry (tree_live_info_p live) for (i = 0; i < (unsigned)num_var_partitions (map); i++) { basic_block tmp; - tree d; + tree d = NULL_TREE; bitmap loe; var = partition_to_var (map, i); stmt = SSA_NAME_DEF_STMT (var); tmp = gimple_bb (stmt); - d = ssa_default_def (cfun, SSA_NAME_VAR (var)); + if (SSA_NAME_VAR (var)) + d = ssa_default_def (cfun, SSA_NAME_VAR (var)); loe = live_on_entry (live, e->dest); if (loe && bitmap_bit_p (loe, i)) diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index e0d4bf21590..8894776ae8c 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -1919,9 +1919,6 @@ gen_lsm_tmp_name (tree ref) break; case SSA_NAME: - ref = SSA_NAME_VAR (ref); - /* Fallthru. */ - case VAR_DECL: case PARM_DECL: name = get_name (ref); diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c index ae3c32b1d67..c44567fd275 100644 --- a/gcc/tree-ssa-loop-ivopts.c +++ b/gcc/tree-ssa-loop-ivopts.c @@ -2819,6 +2819,9 @@ prepare_decl_rtl (tree *expr_p, int *ws, void *data) case SSA_NAME: *ws = 0; obj = SSA_NAME_VAR (*expr_p); + /* Defer handling of anonymous SSA_NAMEs to the expander. */ + if (!obj) + return NULL_TREE; if (!DECL_RTL_SET_P (obj)) x = gen_raw_REG (DECL_MODE (obj), (*regno)++); break; @@ -4966,6 +4969,7 @@ determine_iv_cost (struct ivopts_data *data, struct iv_cand *cand) The reason is to make debugging simpler; so this is not relevant for artificial ivs created by other optimization passes. */ if (cand->pos != IP_ORIGINAL + || !SSA_NAME_VAR (cand->var_before) || DECL_ARTIFICIAL (SSA_NAME_VAR (cand->var_before))) cost++; diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index 19a8eca268e..288e7a2b45b 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -875,7 +875,7 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor, enum tree_code exit_cmp; gimple phi_old_loop, phi_new_loop, phi_rest; gimple_stmt_iterator psi_old_loop, psi_new_loop; - tree init, next, new_init, var; + tree init, next, new_init; struct loop *new_loop; basic_block rest, exit_bb; edge old_entry, new_entry, old_latch, precond_edge, new_exit; @@ -995,17 +995,16 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor, if (TREE_CODE (next) == SSA_NAME && useless_type_conversion_p (TREE_TYPE (next), TREE_TYPE (init))) - var = SSA_NAME_VAR (next); + new_init = copy_ssa_name (next, NULL); else if (TREE_CODE (init) == SSA_NAME && useless_type_conversion_p (TREE_TYPE (init), TREE_TYPE (next))) - var = SSA_NAME_VAR (init); + new_init = copy_ssa_name (init, NULL); else if (useless_type_conversion_p (TREE_TYPE (next), TREE_TYPE (init))) - var = create_tmp_var (TREE_TYPE (next), "unrinittmp"); + new_init = make_temp_ssa_name (TREE_TYPE (next), NULL, "unrinittmp"); else - var = create_tmp_var (TREE_TYPE (init), "unrinittmp"); + new_init = make_temp_ssa_name (TREE_TYPE (init), NULL, "unrinittmp"); - new_init = make_ssa_name (var, NULL); phi_rest = create_phi_node (new_init, rest); add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index bae3cc1addc..842c392914d 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -2746,7 +2746,8 @@ visit_reference_op_load (tree lhs, tree op, gimple stmt) a new SSA_NAME we create. */ if (!result) { - result = make_ssa_name (SSA_NAME_VAR (lhs), gimple_build_nop ()); + result = make_temp_ssa_name (TREE_TYPE (lhs), gimple_build_nop (), + "vntemp"); /* Initialize value-number information properly. */ VN_INFO_GET (result)->valnum = result; VN_INFO (result)->value_id = get_next_value_id (); diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 2b38e44b2b9..5b185b6e129 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -2659,37 +2659,48 @@ lookup_vi_for_tree (tree t) static const char * alias_get_name (tree decl) { - const char *res; + const char *res = NULL; char *temp; int num_printed = 0; - if (DECL_ASSEMBLER_NAME_SET_P (decl)) - res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - else - res= get_name (decl); - if (res != NULL) - return res; - - res = "NULL"; if (!dump_file) - return res; + return "NULL"; if (TREE_CODE (decl) == SSA_NAME) { - num_printed = asprintf (&temp, "%s_%u", - alias_get_name (SSA_NAME_VAR (decl)), - SSA_NAME_VERSION (decl)); + res = get_name (decl); + if (res) + num_printed = asprintf (&temp, "%s_%u", res, SSA_NAME_VERSION (decl)); + else + num_printed = asprintf (&temp, "_%u", SSA_NAME_VERSION (decl)); + if (num_printed > 0) + { + res = ggc_strdup (temp); + free (temp); + } } else if (DECL_P (decl)) { - num_printed = asprintf (&temp, "D.%u", DECL_UID (decl)); + if (DECL_ASSEMBLER_NAME_SET_P (decl)) + res = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + else + { + res = get_name (decl); + if (!res) + { + num_printed = asprintf (&temp, "D.%u", DECL_UID (decl)); + if (num_printed > 0) + { + res = ggc_strdup (temp); + free (temp); + } + } + } } - if (num_printed > 0) - { - res = ggc_strdup (temp); - free (temp); - } - return res; + if (res != NULL) + return res; + + return "NULL"; } /* Find the variable id for tree T in the map. diff --git a/gcc/tree-ssa-ter.c b/gcc/tree-ssa-ter.c index 6e19e1f6edc..dbfa37cf7c4 100644 --- a/gcc/tree-ssa-ter.c +++ b/gcc/tree-ssa-ter.c @@ -498,10 +498,11 @@ process_replaceable (temp_expr_table_p tab, gimple stmt, int call_cnt) def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF); version = SSA_NAME_VERSION (def); - basevar = SSA_NAME_VAR (def); def_vars = BITMAP_ALLOC (NULL); - bitmap_set_bit (def_vars, DECL_UID (basevar)); + basevar = SSA_NAME_VAR (def); + if (basevar) + bitmap_set_bit (def_vars, DECL_UID (basevar)); /* Add this expression to the dependency list for each use partition. */ FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE) @@ -515,7 +516,7 @@ process_replaceable (temp_expr_table_p tab, gimple stmt, int call_cnt) bitmap_ior_into (def_vars, use_vars); BITMAP_FREE (tab->expr_decl_uids[var_version]); } - else + else if (SSA_NAME_VAR (var)) bitmap_set_bit (def_vars, DECL_UID (SSA_NAME_VAR (var))); } tab->expr_decl_uids[version] = def_vars; @@ -626,7 +627,8 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb) if (!bitmap_empty_p (vars)) FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter2, SSA_OP_DEF) { - if (bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def)))) + if (SSA_NAME_VAR (def) + && bitmap_bit_p (vars, DECL_UID (SSA_NAME_VAR (def)))) { same_root_var = true; break; diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index 49bf65d84a8..b5e1edffeb4 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -463,14 +463,16 @@ uncprop_into_successor_phis (basic_block bb) { gimple phi = gsi_stmt (gsi); tree arg = PHI_ARG_DEF (phi, e->dest_idx); + tree res = PHI_RESULT (phi); struct equiv_hash_elt equiv_hash_elt; void **slot; - /* If the argument is not an invariant, or refers to the same + /* If the argument is not an invariant, and refers to the same underlying variable as the PHI result, then there's no point in un-propagating the argument. */ if (!is_gimple_min_invariant (arg) - && SSA_NAME_VAR (arg) != SSA_NAME_VAR (PHI_RESULT (phi))) + && (SSA_NAME_VAR (arg) == SSA_NAME_VAR (res) + && TREE_TYPE (arg) == TREE_TYPE (res))) continue; /* Lookup this argument's value in the hash table. */ @@ -492,7 +494,8 @@ uncprop_into_successor_phis (basic_block bb) { tree equiv = VEC_index (tree, elt->equivalences, j); - if (SSA_NAME_VAR (equiv) == SSA_NAME_VAR (PHI_RESULT (phi))) + if (SSA_NAME_VAR (equiv) == SSA_NAME_VAR (res) + && TREE_TYPE (equiv) == TREE_TYPE (res)) { SET_PHI_ARG_DEF (phi, e->dest_idx, equiv); break; diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index fec095195e1..c65c58ccf30 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -83,18 +83,17 @@ ssa_undefined_value_p (tree t) { tree var = SSA_NAME_VAR (t); + if (!var) + ; /* Parameters get their initial value from the function entry. */ - if (TREE_CODE (var) == PARM_DECL) + else if (TREE_CODE (var) == PARM_DECL) return false; - /* When returning by reference the return address is actually a hidden parameter. */ - if (TREE_CODE (SSA_NAME_VAR (t)) == RESULT_DECL - && DECL_BY_REFERENCE (SSA_NAME_VAR (t))) + else if (TREE_CODE (var) == RESULT_DECL && DECL_BY_REFERENCE (var)) return false; - /* Hard register variables get their initial value from the ether. */ - if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) + else if (TREE_CODE (var) == VAR_DECL && DECL_HARD_REGISTER (var)) return false; /* The value is undefined iff its definition statement is empty. */ @@ -1948,6 +1947,8 @@ warn_uninitialized_phi (gimple phi, VEC(gimple, heap) **worklist, return; uninit_op = gimple_phi_arg_def (phi, MASK_FIRST_SET_BIT (uninit_opnds)); + if (SSA_NAME_VAR (uninit_op) == NULL_TREE) + return; warn_uninit (OPT_Wmaybe_uninitialized, uninit_op, SSA_NAME_VAR (uninit_op), SSA_NAME_VAR (uninit_op), "%qD may be used uninitialized in this function", diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index a03d3e6c199..5ea3bfd87f4 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -249,6 +249,13 @@ target_for_debug_bind (tree var) if (!MAY_HAVE_DEBUG_STMTS) return NULL_TREE; + if (TREE_CODE (var) == SSA_NAME) + { + var = SSA_NAME_VAR (var); + if (var == NULL_TREE) + return NULL_TREE; + } + if ((TREE_CODE (var) != VAR_DECL || VAR_DECL_IS_VIRTUAL_OPERAND (var)) && TREE_CODE (var) != PARM_DECL) @@ -622,7 +629,8 @@ verify_ssa_name (tree ssa_name, bool is_virtual) return true; } - if (TREE_TYPE (ssa_name) != TREE_TYPE (SSA_NAME_VAR (ssa_name))) + if (SSA_NAME_VAR (ssa_name) != NULL_TREE + && TREE_TYPE (ssa_name) != TREE_TYPE (ssa_name)) { error ("type mismatch between an SSA_NAME and its symbol"); return true; @@ -681,7 +689,8 @@ verify_def (basic_block bb, basic_block *definition_block, tree ssa_name, if (verify_ssa_name (ssa_name, is_virtual)) goto err; - if (TREE_CODE (SSA_NAME_VAR (ssa_name)) == RESULT_DECL + if (SSA_NAME_VAR (ssa_name) + && TREE_CODE (SSA_NAME_VAR (ssa_name)) == RESULT_DECL && DECL_BY_REFERENCE (SSA_NAME_VAR (ssa_name))) { error ("RESULT_DECL should be read only when DECL_BY_REFERENCE is set"); diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 9e7b1560143..57a1b482cea 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -120,7 +120,8 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt) gcc_assert (TREE_CODE (var) == VAR_DECL || TREE_CODE (var) == PARM_DECL - || TREE_CODE (var) == RESULT_DECL); + || TREE_CODE (var) == RESULT_DECL + || (TYPE_P (var) && is_gimple_reg_type (var))); /* If our free list has an element, then use it. */ if (!VEC_empty (tree, FREE_SSANAMES (fn))) @@ -143,8 +144,16 @@ make_ssa_name_fn (struct function *fn, tree var, gimple stmt) ssa_name_nodes_created++; } - TREE_TYPE (t) = TREE_TYPE (var); - SSA_NAME_VAR (t) = var; + if (TYPE_P (var)) + { + TREE_TYPE (t) = var; + SET_SSA_NAME_VAR_OR_IDENTIFIER (t, NULL_TREE); + } + else + { + TREE_TYPE (t) = TREE_TYPE (var); + SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var); + } SSA_NAME_DEF_STMT (t) = stmt; SSA_NAME_PTR_INFO (t) = NULL; SSA_NAME_IN_FREE_LIST (t) = 0; @@ -225,7 +234,7 @@ release_ssa_name (tree var) /* Hopefully this can go away once we have the new incremental SSA updating code installed. */ - SSA_NAME_VAR (var) = saved_ssa_name_var; + SET_SSA_NAME_VAR_OR_IDENTIFIER (var, saved_ssa_name_var); /* Note this SSA_NAME is now in the first list. */ SSA_NAME_IN_FREE_LIST (var) = 1; @@ -321,7 +330,17 @@ get_ptr_info (tree t) tree copy_ssa_name_fn (struct function *fn, tree name, gimple stmt) { - return make_ssa_name_fn (fn, SSA_NAME_VAR (name), stmt); + tree new_name; + + if (SSA_NAME_VAR (name)) + new_name = make_ssa_name_fn (fn, SSA_NAME_VAR (name), stmt); + else + { + new_name = make_ssa_name_fn (fn, TREE_TYPE (name), stmt); + SET_SSA_NAME_VAR_OR_IDENTIFIER (new_name, SSA_NAME_IDENTIFIER (name)); + } + + return new_name; } @@ -385,7 +404,7 @@ release_defs (gimple stmt) void replace_ssa_name_symbol (tree ssa_name, tree sym) { - SSA_NAME_VAR (ssa_name) = sym; + SET_SSA_NAME_VAR_OR_IDENTIFIER (ssa_name, sym); TREE_TYPE (ssa_name) = TREE_TYPE (sym); } diff --git a/gcc/tree.c b/gcc/tree.c index 1811299ec3f..6e864c38a23 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10868,6 +10868,13 @@ get_name (tree t) STRIP_NOPS (stripped_decl); if (DECL_P (stripped_decl) && DECL_NAME (stripped_decl)) return IDENTIFIER_POINTER (DECL_NAME (stripped_decl)); + else if (TREE_CODE (stripped_decl) == SSA_NAME) + { + tree name = SSA_NAME_IDENTIFIER (stripped_decl); + if (!name) + return NULL; + return IDENTIFIER_POINTER (name); + } else { switch (TREE_CODE (stripped_decl)) diff --git a/gcc/tree.h b/gcc/tree.h index 9a476072aa1..cc49629ca31 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1980,9 +1980,25 @@ struct GTY(()) tree_exp { /* SSA_NAME accessors. */ -/* Returns the variable being referenced. Once released, this is the - only field that can be relied upon. */ -#define SSA_NAME_VAR(NODE) SSA_NAME_CHECK (NODE)->ssa_name.var +/* Returns the IDENTIFIER_NODE giving the SSA name a name or NULL_TREE + if there is no name associated with it. */ +#define SSA_NAME_IDENTIFIER(NODE) \ + (SSA_NAME_CHECK (NODE)->ssa_name.var != NULL_TREE \ + ? (TREE_CODE ((NODE)->ssa_name.var) == IDENTIFIER_NODE \ + ? (NODE)->ssa_name.var \ + : DECL_NAME ((NODE)->ssa_name.var)) \ + : NULL_TREE) + +/* Returns the variable being referenced. This can be NULL_TREE for + temporaries not associated with any user variable. + Once released, this is the only field that can be relied upon. */ +#define SSA_NAME_VAR(NODE) \ + (SSA_NAME_CHECK (NODE)->ssa_name.var == NULL_TREE \ + || TREE_CODE ((NODE)->ssa_name.var) == IDENTIFIER_NODE \ + ? NULL_TREE : (NODE)->ssa_name.var) + +#define SET_SSA_NAME_VAR_OR_IDENTIFIER(NODE,VAR) \ + do { SSA_NAME_CHECK (NODE)->ssa_name.var = (VAR); } while (0) /* Returns the statement which defines this SSA name. */ #define SSA_NAME_DEF_STMT(NODE) SSA_NAME_CHECK (NODE)->ssa_name.def_stmt