Commit e9705dc5 by Alexandre Oliva Committed by Alexandre Oliva

re PR tree-optimization/33572 (wrong code with -O)

gcc/ChangeLog:
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.
gcc/testsuite/ChangeLog:
PR tree-optimization/33572
* g++.dg/torture/pr33572.C: New.

From-SVN: r129051
parent ac5ba373
2007-10-06 Alexandre Oliva <aoliva@redhat.com>
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.
2007-10-05 Hans-Peter Nilsson <hp@axis.com>
* gthr-single.h: Revert last change.
2007-10-06 Alexandre Oliva <aoliva@redhat.com>
PR tree-optimization/33572
* g++.dg/torture/pr33572.C: New.
2007-10-06 Tobias Schlter <tobi@gcc.gnu.org>
PR fortran/25076
// { dg-do run }
namespace __gnu_cxx {
template<bool> 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<true> 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();
}
......@@ -4279,11 +4279,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);
......
......@@ -1009,16 +1009,19 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale, int count_scal
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 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 +1069,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 +1101,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 +1122,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 +1137,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 +1320,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 +2838,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 +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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment