diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1df5bc44bc6..a64f5fc8d47 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2013-10-02 Andrew MacLeod + + * tree-flow.h: Remove some prototypes. + * tree-ssa-dce.c (mark_virtual_operand_for_renaming, + mark_virtual_phi_result_for_renaming): Move to tree-into-ssa.c. + * tree-into-ssa.c (mark_virtual_operand_for_renaming, + mark_virtual_phi_result_for_renaming): Relocate here. + * tree-into-ssa.h: Add prototypes. + * tree-ssa-phiopt.c: (tree_ssa_phiopt_worker) Use + single_pred_before_succ_order. + (blocks_in_phiopt_order): Rename and move to cfganal.c. + (nonfreeing_call_p) Move to gimple.c. + * cfganal.c (single_pred_before_succ_order): Move and renamed from + tree-ssa-phiopt.c. + * basic-block.h (single_pred_before_succ_order): Add prototype. + * gimple.c (nonfreeing_call_p): Relocate here. + * gimple.h: Add prototype. + * tree-ssa-ifcombine.c: Include tree-ssa-phiopt.h. + * tree-ssa-dom.h: New file. Relocate prototypes here. + * tree-ssa.h: Include tree-ssa-dom.h. + 2013-10-02 Uros Bizjak * config/i386/x-i386 (driver-i386.o): Remove header dependencies. diff --git a/gcc/basic-block.h b/gcc/basic-block.h index acb5ea8d54a..f51de82f6c2 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -803,6 +803,7 @@ extern int dfs_enumerate_from (basic_block, int, basic_block *, int, const void *); extern void compute_dominance_frontiers (struct bitmap_head_def *); extern bitmap compute_idf (bitmap, struct bitmap_head_def *); +extern basic_block * single_pred_before_succ_order (void); /* In cfgrtl.c */ extern rtx block_label (basic_block); diff --git a/gcc/cfganal.c b/gcc/cfganal.c index 56853b9be13..762eea4ca04 100644 --- a/gcc/cfganal.c +++ b/gcc/cfganal.c @@ -1465,3 +1465,56 @@ bitmap_union_of_preds (sbitmap dst, sbitmap *src, basic_block b) *r++ |= *p++; } } + +/* Returns the list of basic blocks in the function in an order that guarantees + that if a block X has just a single predecessor Y, then Y is after X in the + ordering. */ + +basic_block * +single_pred_before_succ_order (void) +{ + basic_block x, y; + basic_block *order = XNEWVEC (basic_block, n_basic_blocks); + unsigned n = n_basic_blocks - NUM_FIXED_BLOCKS; + unsigned np, i; + sbitmap visited = sbitmap_alloc (last_basic_block); + +#define MARK_VISITED(BB) (bitmap_set_bit (visited, (BB)->index)) +#define VISITED_P(BB) (bitmap_bit_p (visited, (BB)->index)) + + bitmap_clear (visited); + + MARK_VISITED (ENTRY_BLOCK_PTR); + FOR_EACH_BB (x) + { + if (VISITED_P (x)) + continue; + + /* Walk the predecessors of x as long as they have precisely one + predecessor and add them to the list, so that they get stored + after x. */ + for (y = x, np = 1; + single_pred_p (y) && !VISITED_P (single_pred (y)); + y = single_pred (y)) + np++; + for (y = x, i = n - np; + single_pred_p (y) && !VISITED_P (single_pred (y)); + y = single_pred (y), i++) + { + order[i] = y; + MARK_VISITED (y); + } + order[i] = y; + MARK_VISITED (y); + + gcc_assert (i == n - 1); + n -= np; + } + + sbitmap_free (visited); + gcc_assert (n == 0); + return order; + +#undef MARK_VISITED +#undef VISITED_P +} diff --git a/gcc/gimple.c b/gcc/gimple.c index 26c78c806b5..dbcfa3ab3d1 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -4418,4 +4418,27 @@ gimple_can_coalesce_p (tree name1, tree name2) return false; } + +/* Return true when CALL is a call stmt that definitely doesn't + free any memory or makes it unavailable otherwise. */ +bool +nonfreeing_call_p (gimple call) +{ + if (gimple_call_builtin_p (call, BUILT_IN_NORMAL) + && gimple_call_flags (call) & ECF_LEAF) + switch (DECL_FUNCTION_CODE (gimple_call_fndecl (call))) + { + /* Just in case these become ECF_LEAF in the future. */ + case BUILT_IN_FREE: + case BUILT_IN_TM_FREE: + case BUILT_IN_REALLOC: + case BUILT_IN_STACK_RESTORE: + return false; + default: + return true; + } + + return false; +} + #include "gt-gimple.h" diff --git a/gcc/gimple.h b/gcc/gimple.h index 3ac59af9da9..e7021a40a05 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1054,6 +1054,7 @@ extern tree gimple_boolify (tree); extern gimple_predicate rhs_predicate_for (tree); extern tree canonicalize_cond_expr_cond (tree); extern void dump_decl_set (FILE *, bitmap); +extern bool nonfreeing_call_p (gimple); /* In omp-low.c. */ extern tree omp_reduction_init (tree, tree); diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index bbd1a15dd71..db7f3467203 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -244,13 +244,6 @@ extern basic_block move_sese_region_to_fn (struct function *, basic_block, void remove_edge_and_dominated_blocks (edge); bool tree_node_can_be_shared (tree); -/* In tree-ssa-dom.c */ -extern void dump_dominator_optimization_stats (FILE *); -extern void debug_dominator_optimization_stats (void); -int loop_depth_of_name (tree); -tree degenerate_phi_result (gimple); -bool simple_iv_increment_p (gimple); - /* In tree-ssa-loop-ch.c */ bool do_while_loop_p (struct loop *); @@ -296,10 +289,6 @@ struct tree_niter_desc enum tree_code cmp; }; -/* In tree-ssa-phiopt.c */ -bool empty_block_p (basic_block); -basic_block *blocks_in_phiopt_order (void); -bool nonfreeing_call_p (gimple); /* In tree-ssa-loop*.c */ @@ -359,10 +348,6 @@ void tree_transform_and_unroll_loop (struct loop *, unsigned, bool contains_abnormal_ssa_name_p (tree); bool stmt_dominates_stmt_p (gimple, gimple); -/* In tree-ssa-dce.c */ -void mark_virtual_operand_for_renaming (tree); -void mark_virtual_phi_result_for_renaming (gimple); - /* In tree-ssa-threadedge.c */ extern void threadedge_initialize_values (void); extern void threadedge_finalize_values (void); diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 2f5ac69251e..5a04ee7924f 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -2869,6 +2869,46 @@ mark_virtual_operands_for_renaming (struct function *fn) fn->gimple_df->rename_vops = 1; } +/* Replace all uses of NAME by underlying variable and mark it + for renaming. This assumes the defining statement of NAME is + going to be removed. */ + +void +mark_virtual_operand_for_renaming (tree name) +{ + tree name_var = SSA_NAME_VAR (name); + bool used = false; + imm_use_iterator iter; + use_operand_p use_p; + gimple stmt; + + gcc_assert (VAR_DECL_IS_VIRTUAL_OPERAND (name_var)); + FOR_EACH_IMM_USE_STMT (stmt, iter, name) + { + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + SET_USE (use_p, name_var); + used = true; + } + if (used) + mark_virtual_operands_for_renaming (cfun); +} + +/* Replace all uses of the virtual PHI result by its underlying variable + and mark it for renaming. This assumes the PHI node is going to be + removed. */ + +void +mark_virtual_phi_result_for_renaming (gimple phi) +{ + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "Marking result for renaming : "); + print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); + fprintf (dump_file, "\n"); + } + + mark_virtual_operand_for_renaming (gimple_phi_result (phi)); +} /* Return true if there is any work to be done by update_ssa for function FN. */ diff --git a/gcc/tree-into-ssa.h b/gcc/tree-into-ssa.h index 0c44f046697..c87fb63c351 100644 --- a/gcc/tree-into-ssa.h +++ b/gcc/tree-into-ssa.h @@ -25,6 +25,8 @@ extern void set_current_def (tree, tree); void delete_update_ssa (void); tree create_new_def_for (tree, gimple, def_operand_p); void mark_virtual_operands_for_renaming (struct function *); +void mark_virtual_operand_for_renaming (tree); +void mark_virtual_phi_result_for_renaming (gimple); bool need_ssa_update_p (struct function *); bool name_registered_for_update_p (tree); void release_ssa_name_after_update_ssa (tree); diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index c20a13a04c8..7b0cd2819bc 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -907,48 +907,6 @@ propagate_necessity (bool aggressive) } } -/* Replace all uses of NAME by underlying variable and mark it - for renaming. This assumes the defining statement of NAME is - going to be removed. */ - -void -mark_virtual_operand_for_renaming (tree name) -{ - tree name_var = SSA_NAME_VAR (name); - bool used = false; - imm_use_iterator iter; - use_operand_p use_p; - gimple stmt; - - gcc_assert (VAR_DECL_IS_VIRTUAL_OPERAND (name_var)); - FOR_EACH_IMM_USE_STMT (stmt, iter, name) - { - FOR_EACH_IMM_USE_ON_STMT (use_p, iter) - SET_USE (use_p, name_var); - used = true; - } - if (used) - mark_virtual_operands_for_renaming (cfun); -} - -/* Replace all uses of the virtual PHI result by its underlying variable - and mark it for renaming. This assumes the PHI node is going to be - removed. */ - -void -mark_virtual_phi_result_for_renaming (gimple phi) -{ - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "Marking result for renaming : "); - print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); - fprintf (dump_file, "\n"); - } - - mark_virtual_operand_for_renaming (gimple_phi_result (phi)); -} - - /* Remove dead PHI nodes from block BB. */ static bool diff --git a/gcc/tree-ssa-dom.h b/gcc/tree-ssa-dom.h new file mode 100644 index 00000000000..89742b03a0e --- /dev/null +++ b/gcc/tree-ssa-dom.h @@ -0,0 +1,29 @@ +/* Header file for SSA dominator optimizations. + Copyright (C) 2013 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_TREE_SSA_DOM_H +#define GCC_TREE_SSA_DOM_H + +extern void dump_dominator_optimization_stats (FILE *); +extern void debug_dominator_optimization_stats (void); +extern int loop_depth_of_name (tree); +extern bool simple_iv_increment_p (gimple); +extern tree degenerate_phi_result (gimple); + +#endif /* GCC_TREE_SSA_DOM_H */ diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index 2a7745194e3..268275e3968 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -624,7 +624,7 @@ tree_ssa_ifcombine (void) bool cfg_changed = false; int i; - bbs = blocks_in_phiopt_order (); + bbs = single_pred_before_succ_order (); calculate_dominance_info (CDI_DOMINATORS); for (i = 0; i < n_basic_blocks - NUM_FIXED_BLOCKS; ++i) diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index c39419f0716..8e1ddab1245 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -308,7 +308,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads) This ensures that we collapse inner ifs before visiting the outer ones, and also that we do not try to visit a removed block. */ - bb_order = blocks_in_phiopt_order (); + bb_order = single_pred_before_succ_order (); n = n_basic_blocks - NUM_FIXED_BLOCKS; for (i = 0; i < n; i++) @@ -476,59 +476,6 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads) return 0; } -/* Returns the list of basic blocks in the function in an order that guarantees - that if a block X has just a single predecessor Y, then Y is after X in the - ordering. */ - -basic_block * -blocks_in_phiopt_order (void) -{ - basic_block x, y; - basic_block *order = XNEWVEC (basic_block, n_basic_blocks); - unsigned n = n_basic_blocks - NUM_FIXED_BLOCKS; - unsigned np, i; - sbitmap visited = sbitmap_alloc (last_basic_block); - -#define MARK_VISITED(BB) (bitmap_set_bit (visited, (BB)->index)) -#define VISITED_P(BB) (bitmap_bit_p (visited, (BB)->index)) - - bitmap_clear (visited); - - MARK_VISITED (ENTRY_BLOCK_PTR); - FOR_EACH_BB (x) - { - if (VISITED_P (x)) - continue; - - /* Walk the predecessors of x as long as they have precisely one - predecessor and add them to the list, so that they get stored - after x. */ - for (y = x, np = 1; - single_pred_p (y) && !VISITED_P (single_pred (y)); - y = single_pred (y)) - np++; - for (y = x, i = n - np; - single_pred_p (y) && !VISITED_P (single_pred (y)); - y = single_pred (y), i++) - { - order[i] = y; - MARK_VISITED (y); - } - order[i] = y; - MARK_VISITED (y); - - gcc_assert (i == n - 1); - n -= np; - } - - sbitmap_free (visited); - gcc_assert (n == 0); - return order; - -#undef MARK_VISITED -#undef VISITED_P -} - /* Replace PHI node element whose edge is E in block BB with variable NEW. Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK is known to have two edges, one of which must reach BB). */ @@ -1353,28 +1300,6 @@ add_or_mark_expr (basic_block bb, tree exp, } } -/* Return true when CALL is a call stmt that definitely doesn't - free any memory or makes it unavailable otherwise. */ -bool -nonfreeing_call_p (gimple call) -{ - if (gimple_call_builtin_p (call, BUILT_IN_NORMAL) - && gimple_call_flags (call) & ECF_LEAF) - switch (DECL_FUNCTION_CODE (gimple_call_fndecl (call))) - { - /* Just in case these become ECF_LEAF in the future. */ - case BUILT_IN_FREE: - case BUILT_IN_TM_FREE: - case BUILT_IN_REALLOC: - case BUILT_IN_STACK_RESTORE: - return false; - default: - return true; - } - - return false; -} - class nontrapping_dom_walker : public dom_walker { public: diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h index 5ec7007ee92..8456a0f8c6a 100644 --- a/gcc/tree-ssa.h +++ b/gcc/tree-ssa.h @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see #include "gimple-ssa.h" #include "ssa-iterators.h" #include "tree-ssanames.h" +#include "tree-ssa-dom.h" #include "tree-flow.h" /* Mapping for redirected edges. */