/* CFG cleanup for trees.
- Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
tree_forwarder_block_p (basic_block bb, bool phi_wanted)
{
gimple_stmt_iterator gsi;
- edge_iterator ei;
- edge e, succ;
- basic_block dest;
/* BB must have a single outgoing edge. */
if (single_succ_p (bb) != 1
gcc_assert (bb != ENTRY_BLOCK_PTR);
#endif
+ /* There should not be an edge coming from entry, or an EH edge. */
+ {
+ edge_iterator ei;
+ edge e;
+
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (e->src == ENTRY_BLOCK_PTR || (e->flags & EDGE_EH))
+ return false;
+ }
+
/* Now walk through the statements backward. We can ignore labels,
anything else means this is not a forwarder block. */
for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi))
return false;
break;
+ /* ??? For now, hope there's a corresponding debug
+ assignment at the destination. */
+ case GIMPLE_DEBUG:
+ break;
+
default:
return false;
}
}
- if (find_edge (ENTRY_BLOCK_PTR, bb))
- return false;
-
if (current_loops)
{
basic_block dest;
if (dest->loop_father->header == dest)
return false;
}
-
- /* If we have an EH edge leaving this block, make sure that the
- destination of this block has only one predecessor. This ensures
- that we don't get into the situation where we try to remove two
- forwarders that go to the same basic block but are handlers for
- different EH regions. */
- succ = single_succ_edge (bb);
- dest = succ->dest;
- FOR_EACH_EDGE (e, ei, bb->preds)
- {
- if (e->flags & EDGE_EH)
- {
- if (!single_pred_p (dest))
- return false;
- }
- }
-
return true;
}
gsi_next (&gsi))
{
gimple phi = gsi_stmt (gsi);
- add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s);
+ source_location l = gimple_phi_arg_location_from_edge (phi, succ);
+ add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s, l);
}
}
}
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
label = gsi_stmt (gsi);
- gcc_assert (gimple_code (label) == GIMPLE_LABEL);
+ gcc_assert (gimple_code (label) == GIMPLE_LABEL
+ || is_gimple_debug (label));
gsi_remove (&gsi, false);
- gsi_insert_before (&gsi_to, label, GSI_CONTINUE_LINKING);
+ gsi_insert_before (&gsi_to, label, GSI_SAME_STMT);
}
}
{
gimple phi = gsi_stmt (gsi);
tree def = gimple_phi_arg_def (phi, succ->dest_idx);
+ source_location locus = gimple_phi_arg_location_from_edge (phi, succ);
if (TREE_CODE (def) == SSA_NAME)
{
if (def == old_arg)
{
def = new_arg;
+ locus = redirect_edge_var_map_location (vm);
break;
}
}
}
- add_phi_arg (phi, def, s);
+ add_phi_arg (phi, def, s, locus);
}
redirect_edge_var_map_clear (e);