Commit df92c640 by Steven Bosscher

ipa-pure-const.c (state_from_flags, [...]): Use current_function_name instead of…

ipa-pure-const.c (state_from_flags, [...]): Use current_function_name instead of lang_hooks.decl_printable_name.

	* ipa-pure-const.c (state_from_flags, local_pure_const): Use
	current_function_name instead of lang_hooks.decl_printable_name.

	* function.h (fndecl_name): New prototype.
	* function.c (fndecl_name): New function.
	* vecir.h (cgraph_node_p): New standard IR VEC type.
	* trans-mem.c (cgraph_node_p): No need anymore to define it here.
	* ipa-utils.h (ipa_get_nodes_in_cycle): New prototype.
	* ipa-utils.c (ipa_get_nodes_in_cycle): New function.
	* ipa-reference.c: Don't include langhooks.h, and certainly not twice.
	Fix many formatting issues (long lines, short lines, spacing, etc.).
	(get_static_name): Use fndecl_name.
	(dump_static_vars_set_to_file): New function split out from propagate.
	(union_static_var_sets): New function, union two sets and collapse
	to all_module_statics as quickly as possible.
	(intersect_static_var_sets): New function, similar to above.
	(copy_static_var_set): Renamed from copy_global_bitmap and rewritten
	to allocate a copy on the same bitmap_obstack as the source set.
	(propagate_bits): Simplify, and clarify by using union_static_var_sets.
	(generate_summary): Remove bm_temp.  Print UID of promotable globals.
	(read_write_all_from_decl): Use pass-by-reference, bless C++.
	(get_read_write_all_from_node): New function, split out from propagate.
	(propagate): Simplify and clarify with helper functions.  Use
	ipa_get_nodes_in_cycle to walk all nodes in a reduced node.
	(ipa_reference_read_optimization_summary): Use fndecl_name instead of
	lang_hooks.decl_printable_name.

	* rtl.h (print_rtl_single_with_indent): New prototype.
	* print-rtl.c (print_rtl_single_with_indent): New function.
	* cfghooks.h (empty_block_p, split_block_before_cond_jump): New hooks.
	* cfghooks.c (empty_block_p, split_block_before_cond_jump): Implement.
	* cfgrtl.c (rtl_block_empty_p, rtl_split_block_before_cond_jump):
	Implement RTL specific hooks.
	(rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): Register the new hooks.
	* tree-cfg.c (gimple_empty_block_p,
	gimple_split_block_before_cond_jump): Implement GIMPLE specific hooks.
	(gimple_cfg_hooks): Register the new hooks.
	* tree-ssa-phiopt.c (empty_block_p): Remove in favor of new hook.

From-SVN: r191255
parent 17742d62
2012-09-13 Steven Bosscher <steven@gcc.gnu.org>
* ipa-pure-const.c (state_from_flags, local_pure_const): Use
current_function_name instead of lang_hooks.decl_printable_name.
* function.h (fndecl_name): New prototype.
* function.c (fndecl_name): New function.
* vecir.h (cgraph_node_p): New standard IR VEC type.
* trans-mem.c (cgraph_node_p): No need anymore to define it here.
* ipa-utils.h (ipa_get_nodes_in_cycle): New prototype.
* ipa-utils.c (ipa_get_nodes_in_cycle): New function.
* ipa-reference.c: Don't include langhooks.h, and certainly not twice.
Fix many formatting issues (long lines, short lines, spacing, etc.).
(get_static_name): Use fndecl_name.
(dump_static_vars_set_to_file): New function split out from propagate.
(union_static_var_sets): New function, union two sets and collapse
to all_module_statics as quickly as possible.
(intersect_static_var_sets): New function, similar to above.
(copy_static_var_set): Renamed from copy_global_bitmap and rewritten
to allocate a copy on the same bitmap_obstack as the source set.
(propagate_bits): Simplify, and clarify by using union_static_var_sets.
(generate_summary): Remove bm_temp. Print UID of promotable globals.
(read_write_all_from_decl): Use pass-by-reference, bless C++.
(get_read_write_all_from_node): New function, split out from propagate.
(propagate): Simplify and clarify with helper functions. Use
ipa_get_nodes_in_cycle to walk all nodes in a reduced node.
(ipa_reference_read_optimization_summary): Use fndecl_name instead of
lang_hooks.decl_printable_name.
* rtl.h (print_rtl_single_with_indent): New prototype.
* print-rtl.c (print_rtl_single_with_indent): New function.
* cfghooks.h (empty_block_p, split_block_before_cond_jump): New hooks.
* cfghooks.c (empty_block_p, split_block_before_cond_jump): Implement.
* cfgrtl.c (rtl_block_empty_p, rtl_split_block_before_cond_jump):
Implement RTL specific hooks.
(rtl_cfg_hooks, cfg_layout_rtl_cfg_hooks): Register the new hooks.
* tree-cfg.c (gimple_empty_block_p,
gimple_split_block_before_cond_jump): Implement GIMPLE specific hooks.
(gimple_cfg_hooks): Register the new hooks.
* tree-ssa-phiopt.c (empty_block_p): Remove in favor of new hook.
2012-09-13 Richard Guenther <rguenther@suse.de>
* tree-ssa-sccvn.h (enum vn_kind): New.
......
......@@ -1306,3 +1306,21 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
bbs[i]->flags &= ~BB_DUPLICATED;
}
/* Return true if BB contains only labels or non-executable
instructions */
bool
empty_block_p (basic_block bb)
{
gcc_assert (cfg_hooks->empty_block_p);
return cfg_hooks->empty_block_p (bb);
}
/* Split a basic block if it ends with a conditional branch and if
the other part of the block is not empty. */
basic_block
split_block_before_cond_jump (basic_block bb)
{
gcc_assert (cfg_hooks->split_block_before_cond_jump);
return cfg_hooks->split_block_before_cond_jump (bb);
}
......@@ -138,6 +138,13 @@ struct cfg_hooks
/* Add PHI arguments queued in PENDINT_STMT list on edge E to edge
E->dest (only in tree-ssa loop versioning. */
void (*flush_pending_stmts) (edge);
/* True if a block contains no executable instructions. */
bool (*empty_block_p) (basic_block);
/* Split a basic block if it ends with a conditional branch and if
the other part of the block is not empty. */
basic_block (*split_block_before_cond_jump) (basic_block);
};
extern void verify_flow_info (void);
......@@ -166,6 +173,8 @@ extern bool predicted_by_p (const_basic_block bb, enum br_predictor predictor);
extern bool can_duplicate_block_p (const_basic_block);
extern basic_block duplicate_block (basic_block, edge, basic_block);
extern bool block_ends_with_call_p (basic_block bb);
extern bool empty_block_p (basic_block);
extern basic_block split_block_before_cond_jump (basic_block);
extern bool block_ends_with_condjump_p (const_basic_block bb);
extern int flow_call_edges_add (sbitmap);
extern void execute_on_growing_pred (edge);
......
......@@ -4120,6 +4120,51 @@ rtl_make_forwarder_block (edge fallthru ATTRIBUTE_UNUSED)
{
}
/* Return true if BB contains only labels or non-executable
instructions. */
static bool
rtl_block_empty_p (basic_block bb)
{
rtx insn;
if (bb == ENTRY_BLOCK_PTR || bb == EXIT_BLOCK_PTR)
return true;
FOR_BB_INSNS (bb, insn)
if (NONDEBUG_INSN_P (insn) && !any_uncondjump_p (insn))
return false;
return true;
}
/* Split a basic block if it ends with a conditional branch and if
the other part of the block is not empty. */
static basic_block
rtl_split_block_before_cond_jump (basic_block bb)
{
rtx insn;
rtx split_point = NULL;
rtx last = NULL;
bool found_code = false;
FOR_BB_INSNS (bb, insn)
{
if (any_condjump_p (insn))
split_point = last;
else if (NONDEBUG_INSN_P (insn))
found_code = true;
last = insn;
}
/* Did not find everything. */
if (found_code && split_point)
return split_block (bb, split_point)->dest;
else
return NULL;
}
/* Return 1 if BB ends with a call, possibly followed by some
instructions that must stay with the call, 0 otherwise. */
......@@ -4432,7 +4477,9 @@ struct cfg_hooks rtl_cfg_hooks = {
NULL, /* lv_add_condition_to_bb */
NULL, /* lv_adjust_loop_header_phi*/
NULL, /* extract_cond_bb_edges */
NULL /* flush_pending_stmts */
NULL, /* flush_pending_stmts */
rtl_block_empty_p, /* block_empty_p */
rtl_split_block_before_cond_jump, /* split_block_before_cond_jump */
};
/* Implementation of CFG manipulation for cfg layout RTL, where
......@@ -4470,7 +4517,9 @@ struct cfg_hooks cfg_layout_rtl_cfg_hooks = {
rtl_lv_add_condition_to_bb, /* lv_add_condition_to_bb */
NULL, /* lv_adjust_loop_header_phi*/
rtl_extract_cond_bb_edges, /* extract_cond_bb_edges */
NULL /* flush_pending_stmts */
NULL, /* flush_pending_stmts */
rtl_block_empty_p, /* block_empty_p */
rtl_split_block_before_cond_jump, /* split_block_before_cond_jump */
};
#include "gt-cfgrtl.h"
......@@ -6753,13 +6753,21 @@ reposition_prologue_and_epilogue_notes (void)
#endif /* HAVE_prologue or HAVE_epilogue */
}
/* Returns the name of function declared by FNDECL. */
const char *
fndecl_name (tree fndecl)
{
if (fndecl == NULL)
return "(nofn)";
return lang_hooks.decl_printable_name (fndecl, 2);
}
/* Returns the name of function FN. */
const char *
function_name (struct function *fn)
{
if (fn == NULL)
return "(nofn)";
return lang_hooks.decl_printable_name (fn->decl, 2);
tree fndecl = (fn == NULL) ? NULL : fn->decl;
return fndecl_name (fndecl);
}
/* Returns the name of the current function. */
......
......@@ -760,6 +760,7 @@ extern void clobber_return_register (void);
extern rtx get_arg_pointer_save_area (void);
/* Returns the name of the current function. */
extern const char *fndecl_name (tree);
extern const char *function_name (struct function *);
extern const char *current_function_name (void);
......
......@@ -192,6 +192,7 @@ warn_function_noreturn (tree decl)
= suggest_attribute (OPT_Wsuggest_attribute_noreturn, decl,
true, warned_about, "noreturn");
}
/* Init the function state. */
static void
......@@ -387,7 +388,7 @@ state_from_flags (enum pure_const_state_e *state, bool *looping,
else
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " neihter\n");
fprintf (dump_file, " neither\n");
*state = IPA_NEITHER;
*looping = true;
}
......@@ -1573,7 +1574,7 @@ local_pure_const (void)
warn_function_noreturn (cfun->decl);
if (dump_file)
fprintf (dump_file, "Function found to be noreturn: %s\n",
lang_hooks.decl_printable_name (current_function_decl, 2));
current_function_name ());
/* Update declaration and reduce profile to executed once. */
TREE_THIS_VOLATILE (current_function_decl) = 1;
......@@ -1597,8 +1598,7 @@ local_pure_const (void)
if (dump_file)
fprintf (dump_file, "Function found to be %sconst: %s\n",
l->looping ? "looping " : "",
lang_hooks.decl_printable_name (current_function_decl,
2));
current_function_name ());
}
else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
&& !l->looping)
......@@ -1610,8 +1610,7 @@ local_pure_const (void)
}
if (dump_file)
fprintf (dump_file, "Function found to be non-looping: %s\n",
lang_hooks.decl_printable_name (current_function_decl,
2));
current_function_name ());
}
break;
......@@ -1627,8 +1626,7 @@ local_pure_const (void)
if (dump_file)
fprintf (dump_file, "Function found to be %spure: %s\n",
l->looping ? "looping " : "",
lang_hooks.decl_printable_name (current_function_decl,
2));
current_function_name ());
}
else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
&& !l->looping)
......@@ -1640,8 +1638,7 @@ local_pure_const (void)
}
if (dump_file)
fprintf (dump_file, "Function found to be non-looping: %s\n",
lang_hooks.decl_printable_name (current_function_decl,
2));
current_function_name ());
}
break;
......@@ -1654,8 +1651,7 @@ local_pure_const (void)
changed = true;
if (dump_file)
fprintf (dump_file, "Function found to be nothrow: %s\n",
lang_hooks.decl_printable_name (current_function_decl,
2));
current_function_name ());
}
free (l);
if (changed)
......
......@@ -154,8 +154,11 @@ searchc (struct searchc_env* env, struct cgraph_node *v,
/* Topsort the call graph by caller relation. Put the result in ORDER.
The REDUCE flag is true if you want the cycles reduced to single nodes. Set
ALLOW_OVERWRITABLE if nodes with such availability should be included.
The REDUCE flag is true if you want the cycles reduced to single nodes.
You can use ipa_get_nodes_in_cycle to obtain a vector containing all real
call graph nodes in a reduced node.
Set ALLOW_OVERWRITABLE if nodes with such availability should be included.
IGNORE_EDGE, if non-NULL is a hook that may make some edges insignificant
for the topological sort. */
......@@ -231,6 +234,23 @@ ipa_free_postorder_info (void)
}
}
/* Get the set of nodes for the cycle in the reduced call graph starting
from NODE. */
VEC (cgraph_node_p, heap) *
ipa_get_nodes_in_cycle (struct cgraph_node *node)
{
VEC (cgraph_node_p, heap) *v = NULL;
struct ipa_dfs_info *node_dfs_info;
while (node)
{
VEC_safe_push (cgraph_node_p, heap, v, node);
node_dfs_info = (struct ipa_dfs_info *) node->symbol.aux;
node = node_dfs_info->next_cycle;
}
return v;
}
struct postorder_stack
{
struct cgraph_node *node;
......
......@@ -42,6 +42,7 @@ void ipa_print_order (FILE*, const char *, struct cgraph_node**, int);
int ipa_reduced_postorder (struct cgraph_node **, bool, bool,
bool (*ignore_edge) (struct cgraph_edge *));
void ipa_free_postorder_info (void);
VEC (cgraph_node_p, heap) *ipa_get_nodes_in_cycle (struct cgraph_node *);
int ipa_reverse_postorder (struct cgraph_node **);
tree get_base_var (tree);
......
......@@ -811,11 +811,27 @@ print_rtl (FILE *outf, const_rtx rtx_first)
int
print_rtl_single (FILE *outf, const_rtx x)
{
return print_rtl_single_with_indent (outf, x, 0);
}
/* Like print_rtl_single, except specify a file and indentation. */
int
print_rtl_single_with_indent (FILE *outf, const_rtx x, int ind)
{
int old_indent = indent;
char *s_indent = (char *) alloca ((size_t) ind + 1);
memset ((void *) s_indent, ' ', (size_t) ind);
s_indent[ind] = '\0';
indent = ind;
outfile = outf;
sawclose = 0;
fputs (s_indent, outfile);
fputs (print_rtx_head, outfile);
print_rtx (x);
putc ('\n', outf);
indent = old_indent;
return 1;
}
......
......@@ -2508,6 +2508,7 @@ extern void print_mem_expr (FILE *, const_tree);
extern void print_rtl (FILE *, const_rtx);
extern void print_simple_rtl (FILE *, const_rtx);
extern int print_rtl_single (FILE *, const_rtx);
extern int print_rtl_single_with_indent (FILE *, const_rtx, int);
extern void print_inline_rtx (FILE *, const_rtx, int);
/* In function.c */
......
......@@ -3582,11 +3582,6 @@ struct tm_ipa_cg_data
bool want_irr_scan_normal;
};
typedef struct cgraph_node *cgraph_node_p;
DEF_VEC_P (cgraph_node_p);
DEF_VEC_ALLOC_P (cgraph_node_p, heap);
typedef VEC (cgraph_node_p, heap) *cgraph_node_queue;
/* Return the ipa data associated with NODE, allocating zeroed memory
......
......@@ -5335,6 +5335,44 @@ gimple_move_block_after (basic_block bb, basic_block after)
}
/* Return TRUE if block BB has no executable statements, otherwise return
FALSE. */
bool
gimple_empty_block_p (basic_block bb)
{
/* BB must have no executable statements. */
gimple_stmt_iterator gsi = gsi_after_labels (bb);
if (phi_nodes (bb))
return false;
if (gsi_end_p (gsi))
return true;
if (is_gimple_debug (gsi_stmt (gsi)))
gsi_next_nondebug (&gsi);
return gsi_end_p (gsi);
}
/* Split a basic block if it ends with a conditional branch and if the
other part of the block is not empty. */
static basic_block
gimple_split_block_before_cond_jump (basic_block bb)
{
gimple last, split_point;
gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb);
if (gsi_end_p (gsi))
return NULL;
last = gsi_stmt (gsi);
if (gimple_code (last) != GIMPLE_COND
&& gimple_code (last) != GIMPLE_SWITCH)
return NULL;
gsi_prev_nondebug (&gsi);
split_point = gsi_stmt (gsi);
return split_block (bb, split_point)->dest;
}
/* Return true if basic_block can be duplicated. */
static bool
......@@ -7492,7 +7530,9 @@ struct cfg_hooks gimple_cfg_hooks = {
gimple_lv_add_condition_to_bb, /* lv_add_condition_to_bb */
gimple_lv_adjust_loop_header_phi, /* lv_adjust_loop_header_phi*/
extract_true_false_edges_from_block, /* extract_cond_bb_edges */
flush_pending_stmts /* flush_pending_stmts */
flush_pending_stmts, /* flush_pending_stmts */
gimple_empty_block_p, /* block_empty_p */
gimple_split_block_before_cond_jump, /* split_block_before_cond_jump */
};
......
......@@ -519,24 +519,6 @@ blocks_in_phiopt_order (void)
#undef VISITED_P
}
/* Return TRUE if block BB has no executable statements, otherwise return
FALSE. */
bool
empty_block_p (basic_block bb)
{
/* BB must have no executable statements. */
gimple_stmt_iterator gsi = gsi_after_labels (bb);
if (phi_nodes (bb))
return false;
if (gsi_end_p (gsi))
return true;
if (is_gimple_debug (gsi_stmt (gsi)))
gsi_next_nondebug (&gsi);
return gsi_end_p (gsi);
}
/* 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). */
......
......@@ -49,4 +49,9 @@ DEF_VEC_P(rtx);
DEF_VEC_ALLOC_P(rtx,heap);
DEF_VEC_ALLOC_P(rtx,gc);
/* A varray of call graph nodes. */
typedef struct cgraph_node *cgraph_node_p;
DEF_VEC_P (cgraph_node_p);
DEF_VEC_ALLOC_P (cgraph_node_p, heap);
#endif /* GCC_VECIR_H */
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