Commit a3710436 by Jan Hubicka Committed by Jan Hubicka

tree.c (list_equal_p): New function.

	* tree.c (list_equal_p): New function.
	* tree.h (list_equal_p): Declare.
	* coretypes.h (edge_def, edge, const_edge, basic_block_def
	basic_block_def, basic_block, const_basic_block): New.
	* tree-eh.c (make_eh_edge): EH edges are not abnormal.
	(redirect_eh_edge): New function.
	(make_eh_edge_update_phi): EH edges are not abnormal.
	* except.c: Include tree-flow.h.
	(list_match): New function.
	(eh_region_replaceable_by_p): New function.
	(replace_region): New function.
	(hash_type_list): New function.
	(hash_eh_region): New function.
	(eh_regions_equal_p): New function.
	(merge_peers): New function.
	(remove_unreachable_regions): Verify EH tree when checking;
	merge peers.
	(copy_eh_region_1): New function.
	(copy_eh_region): New function.
	(push_reachable_handler): New function.
	(build_post_landing_pads, dw2_build_landing_pads): Be ready for
	regions without label but with live RESX.
	* except.h (redirect_eh_edge_to_label): New.
	* tree-flow.h (redirect_eh_edge): New.
	* coretypes.h (edge_def, edge, const_edge, basic_block_def
	basic_block_def, basic_block, const_basic_block): Remove.
	* Makefile.in (except.o): Add dependency on tree-flow.h
	* tree-cfg.c (gimple_redirect_edge_and_branch): Handle EH edges.
	* basic-block.h (edge, const_edge, basic_block, const_basic_block):
	Remove.

From-SVN: r146776
parent 3764d512
2009-04-25 Jan Hubicka <jh@suse.cz>
* tree.c (list_equal_p): New function.
* tree.h (list_equal_p): Declare.
* coretypes.h (edge_def, edge, const_edge, basic_block_def
basic_block_def, basic_block, const_basic_block): New.
* tree-eh.c (make_eh_edge): EH edges are not abnormal.
(redirect_eh_edge): New function.
(make_eh_edge_update_phi): EH edges are not abnormal.
* except.c: Include tree-flow.h.
(list_match): New function.
(eh_region_replaceable_by_p): New function.
(replace_region): New function.
(hash_type_list): New function.
(hash_eh_region): New function.
(eh_regions_equal_p): New function.
(merge_peers): New function.
(remove_unreachable_regions): Verify EH tree when checking;
merge peers.
(copy_eh_region_1): New function.
(copy_eh_region): New function.
(push_reachable_handler): New function.
(build_post_landing_pads, dw2_build_landing_pads): Be ready for
regions without label but with live RESX.
* except.h (redirect_eh_edge_to_label): New.
* tree-flow.h (redirect_eh_edge): New.
* coretypes.h (edge_def, edge, const_edge, basic_block_def
basic_block_def, basic_block, const_basic_block): Remove.
* Makefile.in (except.o): Add dependency on tree-flow.h
* tree-cfg.c (gimple_redirect_edge_and_branch): Handle EH edges.
* basic-block.h (edge, const_edge, basic_block, const_basic_block):
Remove.
2009-04-25 Eric Botcazou <ebotcazou@adacore.com> 2009-04-25 Eric Botcazou <ebotcazou@adacore.com>
PR bootstrap/39645 PR bootstrap/39645
......
...@@ -2525,7 +2525,7 @@ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ ...@@ -2525,7 +2525,7 @@ except.o : except.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \ langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \
dwarf2asm.h dwarf2out.h $(TOPLEV_H) $(HASHTAB_H) intl.h $(GGC_H) \ dwarf2asm.h dwarf2out.h $(TOPLEV_H) $(HASHTAB_H) intl.h $(GGC_H) \
gt-$(EXCEPT_H) $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) dwarf2.h \ gt-$(EXCEPT_H) $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) dwarf2.h \
$(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TIMEVAR_H) $(TARGET_H) $(TM_P_H) $(TREE_PASS_H) $(TIMEVAR_H) $(TREE_FLOW_H)
expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \ $(TREE_H) $(FLAGS_H) $(FUNCTION_H) $(REGS_H) $(EXPR_H) $(OPTABS_H) \
libfuncs.h $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \ libfuncs.h $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \
......
...@@ -147,8 +147,6 @@ struct GTY(()) edge_def { ...@@ -147,8 +147,6 @@ struct GTY(()) edge_def {
in profile.c */ in profile.c */
}; };
typedef struct edge_def *edge;
typedef const struct edge_def *const_edge;
DEF_VEC_P(edge); DEF_VEC_P(edge);
DEF_VEC_ALLOC_P(edge,gc); DEF_VEC_ALLOC_P(edge,gc);
DEF_VEC_ALLOC_P(edge,heap); DEF_VEC_ALLOC_P(edge,heap);
...@@ -277,9 +275,6 @@ struct GTY(()) gimple_bb_info { ...@@ -277,9 +275,6 @@ struct GTY(()) gimple_bb_info {
gimple_seq phi_nodes; gimple_seq phi_nodes;
}; };
typedef struct basic_block_def *basic_block;
typedef const struct basic_block_def *const_basic_block;
DEF_VEC_P(basic_block); DEF_VEC_P(basic_block);
DEF_VEC_ALLOC_P(basic_block,gc); DEF_VEC_ALLOC_P(basic_block,gc);
DEF_VEC_ALLOC_P(basic_block,heap); DEF_VEC_ALLOC_P(basic_block,heap);
......
...@@ -97,6 +97,12 @@ enum tls_model { ...@@ -97,6 +97,12 @@ enum tls_model {
TLS_MODEL_LOCAL_EXEC TLS_MODEL_LOCAL_EXEC
}; };
struct edge_def;
typedef struct edge_def *edge;
typedef const struct edge_def *const_edge;
struct basic_block_def;
typedef struct basic_block_def *basic_block;
typedef const struct basic_block_def *const_basic_block;
#else #else
struct _dont_use_rtx_here_; struct _dont_use_rtx_here_;
......
...@@ -278,4 +278,5 @@ extern void set_eh_throw_stmt_table (struct function *, struct htab *); ...@@ -278,4 +278,5 @@ extern void set_eh_throw_stmt_table (struct function *, struct htab *);
extern void remove_unreachable_regions (sbitmap, sbitmap); extern void remove_unreachable_regions (sbitmap, sbitmap);
extern VEC(int,heap) * label_to_region_map (void); extern VEC(int,heap) * label_to_region_map (void);
extern int num_eh_regions (void); extern int num_eh_regions (void);
extern struct eh_region *redirect_eh_edge_to_label (struct edge_def *, tree, bool, bool, int);
extern int get_next_region_sharing_label (int); extern int get_next_region_sharing_label (int);
2009-04-25 Jan Hubicka <jh@suse.cz>
* g++.dg/tree-ssa/ehcleanup-1.C: Update.
2009-04-25 Janus Weil <janus@gcc.gnu.org> 2009-04-25 Janus Weil <janus@gcc.gnu.org>
PR fortran/39688 PR fortran/39688
......
// { dg-options "-O2 -fdump-tree-ehcleanup1" } // { dg-options "-O2 -fdump-tree-ehcleanup1-details" }
extern void can_throw (); extern void can_throw ();
class a class a
{ {
......
...@@ -4800,6 +4800,9 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest) ...@@ -4800,6 +4800,9 @@ gimple_redirect_edge_and_branch (edge e, basic_block dest)
if (e->dest == dest) if (e->dest == dest)
return NULL; return NULL;
if (e->flags & EDGE_EH)
return redirect_eh_edge (e, dest);
gsi = gsi_last_bb (bb); gsi = gsi_last_bb (bb);
stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi); stmt = gsi_end_p (gsi) ? NULL : gsi_stmt (gsi);
......
...@@ -1962,7 +1962,7 @@ make_eh_edge (struct eh_region *region, void *data) ...@@ -1962,7 +1962,7 @@ make_eh_edge (struct eh_region *region, void *data)
src = gimple_bb (stmt); src = gimple_bb (stmt);
dst = label_to_block (lab); dst = label_to_block (lab);
make_edge (src, dst, EDGE_ABNORMAL | EDGE_EH); make_edge (src, dst, EDGE_EH);
} }
/* See if STMT is call that might be inlined. */ /* See if STMT is call that might be inlined. */
...@@ -2019,6 +2019,50 @@ make_eh_edges (gimple stmt) ...@@ -2019,6 +2019,50 @@ make_eh_edges (gimple stmt)
EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE; EDGE_SUCC (bb, 0)->probability = REG_BR_PROB_BASE;
} }
/* Redirect EH edge E to NEW_BB. */
edge
redirect_eh_edge (edge e, basic_block new_bb)
{
gimple stmt = gsi_stmt (gsi_last_bb (e->src));
int region_nr, new_region_nr;
bool is_resx;
bool inlinable = false;
tree label = gimple_block_label (new_bb);
struct eh_region *r;
if (gimple_code (stmt) == GIMPLE_RESX)
{
region_nr = gimple_resx_region (stmt);
is_resx = true;
}
else
{
region_nr = lookup_stmt_eh_region (stmt);
gcc_assert (region_nr >= 0);
is_resx = false;
inlinable = inlinable_call_p (stmt);
}
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Redirecting EH edge %i->%i to %i, region %i, resx %i\n",
e->src->index, e->dest->index, new_bb->index, region_nr, is_resx);
r = redirect_eh_edge_to_label (e, label, is_resx, inlinable, region_nr);
new_region_nr = get_eh_region_number (r);
if (new_region_nr != region_nr)
{
if (is_resx)
gimple_resx_set_region (stmt, new_region_nr);
else
{
remove_stmt_from_eh_region (stmt);
add_stmt_to_eh_region (stmt, new_region_nr);
}
}
e = ssa_redirect_edge (e, new_bb);
return e;
}
static bool mark_eh_edge_found_error; static bool mark_eh_edge_found_error;
/* Mark edge make_eh_edge would create for given region by setting it aux /* Mark edge make_eh_edge would create for given region by setting it aux
...@@ -2702,7 +2746,9 @@ tree_remove_unreachable_handlers (void) ...@@ -2702,7 +2746,9 @@ tree_remove_unreachable_handlers (void)
SET_BIT (reachable, region); SET_BIT (reachable, region);
} }
if (gimple_code (stmt) == GIMPLE_RESX) if (gimple_code (stmt) == GIMPLE_RESX)
SET_BIT (reachable, gimple_resx_region (stmt)); SET_BIT (reachable,
VEC_index (eh_region, cfun->eh->region_array,
gimple_resx_region (stmt))->region_number);
if ((region = lookup_stmt_eh_region (stmt)) >= 0) if ((region = lookup_stmt_eh_region (stmt)) >= 0)
SET_BIT (contains_stmt, region); SET_BIT (contains_stmt, region);
} }
...@@ -2937,7 +2983,7 @@ make_eh_edge_and_update_phi (struct eh_region *region, void *data) ...@@ -2937,7 +2983,7 @@ make_eh_edge_and_update_phi (struct eh_region *region, void *data)
} }
dominance_info_invalidated = true; dominance_info_invalidated = true;
e2 = find_edge (info->bb_to_remove, dst); e2 = find_edge (info->bb_to_remove, dst);
e = make_edge (src, dst, EDGE_ABNORMAL | EDGE_EH); e = make_edge (src, dst, EDGE_EH);
e->aux = e; e->aux = e;
gcc_assert (e2); gcc_assert (e2);
for (si = gsi_start_phis (dst); !gsi_end_p (si); gsi_next (&si)) for (si = gsi_start_phis (dst); !gsi_end_p (si); gsi_next (&si))
...@@ -3091,7 +3137,11 @@ cleanup_empty_eh (basic_block bb, VEC(int,heap) * label_to_region) ...@@ -3091,7 +3137,11 @@ cleanup_empty_eh (basic_block bb, VEC(int,heap) * label_to_region)
is really dead. */ is really dead. */
if (found && !has_non_eh_preds) if (found && !has_non_eh_preds)
remove_eh_region (region); {
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Empty EH handler %i removed.\n", region);
remove_eh_region (region);
}
else if (!removed_some) else if (!removed_some)
return false; return false;
......
...@@ -32,13 +32,6 @@ along with GCC; see the file COPYING3. If not see ...@@ -32,13 +32,6 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-reference.h" #include "ipa-reference.h"
#include "tree-ssa-alias.h" #include "tree-ssa-alias.h"
/* Forward declare structures for the garbage collector GTY markers. */
#ifndef GCC_BASIC_BLOCK_H
struct edge_def;
typedef struct edge_def *edge;
struct basic_block_def;
typedef struct basic_block_def *basic_block;
#endif
struct static_var_ann_d; struct static_var_ann_d;
...@@ -974,5 +967,6 @@ unsigned int execute_fixup_cfg (void); ...@@ -974,5 +967,6 @@ unsigned int execute_fixup_cfg (void);
void swap_tree_operands (gimple, tree *, tree *); void swap_tree_operands (gimple, tree *, tree *);
int least_common_multiple (int, int); int least_common_multiple (int, int);
edge redirect_eh_edge (edge e, basic_block new_bb);
#endif /* _TREE_FLOW_H */ #endif /* _TREE_FLOW_H */
...@@ -9320,4 +9320,16 @@ block_ultimate_origin (const_tree block) ...@@ -9320,4 +9320,16 @@ block_ultimate_origin (const_tree block)
} }
} }
/* Return true if T1 and T2 are equivalent lists. */
bool
list_equal_p (const_tree t1, const_tree t2)
{
for (; t1 && t2; t1 = TREE_CHAIN (t1) , t2 = TREE_CHAIN (t2))
if (TREE_VALUE (t1) != TREE_VALUE (t2))
return false;
return !t1 && !t2;
}
#include "gt-tree.h" #include "gt-tree.h"
...@@ -5134,6 +5134,7 @@ struct GTY(()) tree_map_base { ...@@ -5134,6 +5134,7 @@ struct GTY(()) tree_map_base {
extern int tree_map_base_eq (const void *, const void *); extern int tree_map_base_eq (const void *, const void *);
extern unsigned int tree_map_base_hash (const void *); extern unsigned int tree_map_base_hash (const void *);
extern int tree_map_base_marked_p (const void *); extern int tree_map_base_marked_p (const void *);
extern bool list_equal_p (const_tree, const_tree);
/* Map from a tree to another tree. */ /* Map from a tree to another tree. */
......
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