diff options
author | Alexandre Oliva <aoliva@redhat.com> | 2007-10-02 01:32:03 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@redhat.com> | 2007-10-02 01:32:03 +0000 |
commit | 0403d3b9089d9ddba688d093f5dffc26adf44ed7 (patch) | |
tree | 88d836db39318d2fd0073c04969ed91e0618908d /gcc | |
parent | 025038955a87ad9acd4df743bb302efd58e6923d (diff) |
* tree-ssa-copyrename.c (copy_rename_partition_coalesce):
Permit coalescing of user variables.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/var-tracking-assignments-branch@128937 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/tree-cfg.c | 13 | ||||
-rw-r--r-- | gcc/tree-inline.c | 111 |
2 files changed, 54 insertions, 70 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 320bc8ef61d..c15e81e20b4 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4258,11 +4258,18 @@ verify_stmts (void) tree t = PHI_ARG_DEF (phi, i); tree addr; + if (!t) + { + error ("missing PHI def"); + debug_generic_stmt (phi); + err |= true; + continue; + } /* Addressable variables do have SSA_NAMEs but they are not considered gimple values. */ - if (TREE_CODE (t) != SSA_NAME - && TREE_CODE (t) != FUNCTION_DECL - && !is_gimple_val (t)) + else if (TREE_CODE (t) != SSA_NAME + && TREE_CODE (t) != FUNCTION_DECL + && !is_gimple_val (t)) { error ("PHI def is not a GIMPLE value"); debug_generic_stmt (phi); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 9c459511b71..b860d880c70 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1018,7 +1018,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal we might want to change way build CFG pre-inlining to include all the possible edges then. */ static void -update_ssa_across_eh_edges (basic_block bb) +update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb, + bool can_throw, bool nonlocal_goto) { edge e; edge_iterator ei; @@ -1029,13 +1030,35 @@ update_ssa_across_eh_edges (basic_block bb) { tree phi; - gcc_assert (e->flags & EDGE_EH); + gcc_assert (e->flags & EDGE_ABNORMAL); + if (!nonlocal_goto) + gcc_assert (e->flags & EDGE_EH); + if (!can_throw) + gcc_assert (!(e->flags & EDGE_EH)); for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi)) { + edge re; + + /* There shouldn't be any PHI nodes in the ENTRY_BLOCK. */ + gcc_assert (!e->dest->aux); + gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi))); - mark_sym_for_renaming - (SSA_NAME_VAR (PHI_RESULT (phi))); + + if (!is_gimple_reg (PHI_RESULT (phi))) + { + mark_sym_for_renaming + (SSA_NAME_VAR (PHI_RESULT (phi))); + continue; + } + + re = find_edge (ret_bb, e->dest); + gcc_assert (re); + gcc_assert ((re->flags & (EDGE_EH | EDGE_ABNORMAL)) + == (e->flags & (EDGE_EH | EDGE_ABNORMAL))); + + SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), + USE_FROM_PTR (PHI_ARG_DEF_PTR_FROM_EDGE (phi, re))); } } } @@ -1044,7 +1067,7 @@ update_ssa_across_eh_edges (basic_block bb) accordingly. Edges will be taken care of later. Assume aux pointers to point to the copies of each BB. */ static void -copy_edges_for_bb (basic_block bb, int count_scale) +copy_edges_for_bb (basic_block bb, int count_scale, basic_block ret_bb) { basic_block new_bb = (basic_block) bb->aux; edge_iterator ei; @@ -1076,6 +1099,7 @@ copy_edges_for_bb (basic_block bb, int count_scale) for (bsi = bsi_start (new_bb); !bsi_end_p (bsi);) { tree copy_stmt; + bool can_throw, nonlocal_goto; copy_stmt = bsi_stmt (bsi); update_stmt (copy_stmt); @@ -1096,7 +1120,10 @@ copy_edges_for_bb (basic_block bb, int count_scale) into a COMPONENT_REF which doesn't. If the copy can throw, the original could also throw. */ - if (tree_can_throw_internal (copy_stmt)) + can_throw = tree_can_throw_internal (copy_stmt); + nonlocal_goto = tree_can_make_abnormal_goto (copy_stmt); + + if (can_throw || nonlocal_goto) { if (!bsi_end_p (bsi)) /* Note that bb's predecessor edges aren't necessarily @@ -1108,12 +1135,18 @@ copy_edges_for_bb (basic_block bb, int count_scale) new_bb->aux = e->src->aux; bsi = bsi_start (new_bb); } + } - make_eh_edges (copy_stmt); + if (can_throw) + make_eh_edges (copy_stmt); - if (gimple_in_ssa_p (cfun)) - update_ssa_across_eh_edges (bb_for_stmt (copy_stmt)); - } + if (nonlocal_goto) + make_abnormal_goto_edges (bb_for_stmt (copy_stmt), true); + + if ((can_throw || nonlocal_goto) + && gimple_in_ssa_p (cfun)) + update_ssa_across_abnormal_edges (bb_for_stmt (copy_stmt), ret_bb, + can_throw, nonlocal_goto); } } @@ -1285,7 +1318,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency, last = last_basic_block; /* Now that we've duplicated the blocks, duplicate their edges. */ FOR_ALL_BB_FN (bb, cfun_to_copy) - copy_edges_for_bb (bb, count_scale); + copy_edges_for_bb (bb, count_scale, exit_block_map); if (gimple_in_ssa_p (cfun)) FOR_ALL_BB_FN (bb, cfun_to_copy) copy_phis_for_bb (bb, id); @@ -2803,60 +2836,6 @@ has_abnormal_outgoing_edge_p (basic_block bb) return false; } -/* When a block from the inlined function contains a call with side-effects - in the middle gets inlined in a function with non-locals labels, the call - becomes a potential non-local goto so we need to add appropriate edge. */ - -static void -make_nonlocal_label_edges (void) -{ - block_stmt_iterator bsi; - basic_block bb; - - FOR_EACH_BB (bb) - { - for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) - { - tree stmt = bsi_stmt (bsi); - if (tree_can_make_abnormal_goto (stmt)) - { - if (stmt == bsi_stmt (bsi_last (bb))) - { - if (!has_abnormal_outgoing_edge_p (bb)) - make_abnormal_goto_edges (bb, true); - } - else - { - edge e = split_block (bb, stmt); - bb = e->src; - make_abnormal_goto_edges (bb, true); - } - break; - } - - /* Update PHIs on nonlocal goto receivers we (possibly) - just created new edges into. */ - if (TREE_CODE (stmt) == LABEL_EXPR - && gimple_in_ssa_p (cfun)) - { - tree target = LABEL_EXPR_LABEL (stmt); - if (DECL_NONLOCAL (target)) - { - tree phi; - - for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi)) - { - gcc_assert (SSA_NAME_OCCURS_IN_ABNORMAL_PHI - (PHI_RESULT (phi))); - mark_sym_for_renaming - (SSA_NAME_VAR (PHI_RESULT (phi))); - } - } - } - } - } -} - /* Expand calls to inline functions in the body of FN. */ unsigned int @@ -2935,8 +2914,6 @@ optimize_inline_calls (tree fn) cgraph_node_remove_callees (id.dst_node); fold_cond_expr_cond (); - if (current_function_has_nonlocal_label) - make_nonlocal_label_edges (); /* It would be nice to check SSA/CFG/statement consistency here, but it is not possible yet - the IPA passes might make various functions to not throw and they don't care to proactively update local EH info. This is |