From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32071 invoked by alias); 3 Oct 2007 16:54:41 -0000 Received: (qmail 32063 invoked by uid 22791); 3 Oct 2007 16:54:41 -0000 X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.31) with ESMTP; Wed, 03 Oct 2007 16:54:38 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.1) with ESMTP id l93GsVoY002721; Wed, 3 Oct 2007 12:54:36 -0400 Received: from pobox.corp.redhat.com (pobox.corp.redhat.com [10.11.255.20]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l93GsVuE011614; Wed, 3 Oct 2007 12:54:31 -0400 Received: from free.oliva.athome.lsd.ic.unicamp.br (vpn-15-19.rdu.redhat.com [10.11.15.19]) by pobox.corp.redhat.com (8.13.1/8.13.1) with ESMTP id l93GsTAo008537; Wed, 3 Oct 2007 12:54:30 -0400 Received: from free.oliva.athome.lsd.ic.unicamp.br (localhost.localdomain [127.0.0.1]) by free.oliva.athome.lsd.ic.unicamp.br (8.14.1/8.13.8) with ESMTP id l93GsPRf008583; Wed, 3 Oct 2007 13:54:25 -0300 Received: (from aoliva@localhost) by free.oliva.athome.lsd.ic.unicamp.br (8.14.1/8.13.5/Submit) id l93GsPml008582; Wed, 3 Oct 2007 13:54:25 -0300 To: "Richard Guenther" Cc: gcc-patches@gcc.gnu.org Subject: Re: [vtab (and trunk?)] fix fallout from SSA-coalescing user variables References: <84fc9c000710020219w4128a866xe8f36fe7fd464bb0@mail.gmail.com> From: Alexandre Oliva Errors-To: aoliva@oliva.athome.lsd.ic.unicamp.br Date: Wed, 03 Oct 2007 16:54:00 -0000 In-Reply-To: <84fc9c000710020219w4128a866xe8f36fe7fd464bb0@mail.gmail.com> (Richard Guenther's message of "Tue\, 2 Oct 2007 11\:19\:53 +0200") Message-ID: User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2007-10/txt/msg00187.txt.bz2 --=-=-= Content-length: 363 On Oct 2, 2007, "Richard Guenther" wrote: > I think you need to update the comment before > update_ssa_across_abnormal_edges. Can you take care of > bootstrapping/testing this, check if it fixes PR33572 and add the > testcase? Done, here's the patch for mainline. Bootstrapped and regtested on x86_64-linux-gnu, no regressions. --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=gcc-debug-coalesce-inline-fallout.patch Content-length: 8938 for gcc/ChangeLog from Alexandre Oliva PR tree-optimization/33572 * tree-cfg.c (verify_stmts): Check for missing PHI defs. * tree-inline.c (update_ssa_across_eh_edges): Renamed to... (update_ssa_across_abnormal_edges): ... this. Set slots in the return PHI node. (copy_edges_for_bb): Handle nonlocal label edges. (make_nonlocal_label_edges): Deleted. (optimize_inline_calls): Don't call it. for gcc/testsuite/ChangeLog from Alexandre Oliva PR tree-optimization/33572 * g++.dg/tree-ssa/pr33572.C: New. Index: gcc/tree-inline.c =================================================================== --- gcc/tree-inline.c.orig 2007-10-02 22:00:02.000000000 -0300 +++ gcc/tree-inline.c 2007-10-02 22:22:35.000000000 -0300 @@ -1009,16 +1009,19 @@ copy_bb (copy_body_data *id, basic_block across EH edges from basic block within inlined functions destinating to landing pads in function we inline into. - The function mark PHI_RESULT of such PHI nodes for renaming; it is - safe the EH edges are abnormal and SSA_NAME_OCCURS_IN_ABNORMAL_PHI - must be set. This means, that there will be no overlapping live ranges + The function fills in PHI_RESULTs of such PHI nodes if they refer + to gimple regs. Otherwise, the function mark PHI_RESULT of such + PHI nodes for renaming. For non-gimple regs, renaming is safe: the + EH edges are abnormal and SSA_NAME_OCCURS_IN_ABNORMAL_PHI must be + set, and this means that there will be no overlapping live ranges for the underlying symbol. This might change in future if we allow redirecting of EH edges and 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 +1032,35 @@ update_ssa_across_eh_edges (basic_block { 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 +1069,7 @@ update_ssa_across_eh_edges (basic_block 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 +1101,7 @@ copy_edges_for_bb (basic_block bb, int c 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 +1122,10 @@ copy_edges_for_bb (basic_block bb, int c 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 +1137,18 @@ copy_edges_for_bb (basic_block bb, int c 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 +1320,7 @@ copy_cfg_body (copy_body_data * id, gcov 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 +2838,6 @@ has_abnormal_outgoing_edge_p (basic_bloc 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 +2916,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 Index: gcc/tree-cfg.c =================================================================== --- gcc/tree-cfg.c.orig 2007-10-02 22:00:02.000000000 -0300 +++ gcc/tree-cfg.c 2007-10-02 22:16:45.000000000 -0300 @@ -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); Index: gcc/testsuite/g++.dg/tree-ssa/pr33572.C =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ gcc/testsuite/g++.dg/tree-ssa/pr33572.C 2007-10-02 22:16:45.000000000 -0300 @@ -0,0 +1,39 @@ +/* { dg-do run } */ +/* { dg-options "-O" } */ + +namespace __gnu_cxx { + template struct __pool { + void _M_reclaim_block(char* p, unsigned long bytes); + }; +} + +struct vector { + ~vector() { deallocate(0); } + void deallocate(int* p) { + if (p) { + static __gnu_cxx::__pool pool; + pool._M_reclaim_block((char*)0, 0); + } + } +}; + +struct Foo { virtual void f() { } }; + +struct auto_ptr { + Foo* ptr; + auto_ptr() : ptr(0) { } + ~auto_ptr() { delete ptr; } + Foo* release() { Foo* tmp = ptr; ptr = 0; return tmp; } + void reset(Foo* p) { ptr = p; } +}; + +int main(int argc, char**) { + auto_ptr foo; + if (argc) { + foo.reset(new Foo()); + } else { + vector v; + } + Foo* p = foo.release(); + p->f(); +} --=-=-= Content-length: 249 -- Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/ FSF Latin America Board Member http://www.fsfla.org/ Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org} Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org} --=-=-=--