re PR rtl-optimization/38518 (Excessive compile time with -O3)

2014-01-17  Richard Biener  <rguenther@suse.de>

	PR rtl-optimization/38518
	* df.h (df_analyze_loop): Declare.
	* df-core.c: Include cfgloop.h.
	(df_analyze_1): Split out main part of df_analyze.
	(df_analyze): Adjust.
	(loop_inverted_post_order_compute): New function.
	(loop_post_order_compute): Likewise.
	(df_analyze_loop): New function avoiding whole-function
	postorder computes.
	* loop-invariant.c (find_defs): Use df_analyze_loop.
	(find_invariants): Adjust.
	* loop-iv.c (iv_analysis_loop_init): Use df_analyze_loop.

From-SVN: r206702
This commit is contained in:
Richard Biener 2014-01-17 10:47:59 +00:00 committed by Richard Biener
parent cc3a9f0d47
commit 7be64667c1
5 changed files with 228 additions and 70 deletions

View File

@ -1,3 +1,18 @@
2014-01-17 Richard Biener <rguenther@suse.de>
PR rtl-optimization/38518
* df.h (df_analyze_loop): Declare.
* df-core.c: Include cfgloop.h.
(df_analyze_1): Split out main part of df_analyze.
(df_analyze): Adjust.
(loop_inverted_post_order_compute): New function.
(loop_post_order_compute): Likewise.
(df_analyze_loop): New function avoiding whole-function
postorder computes.
* loop-invariant.c (find_defs): Use df_analyze_loop.
(find_invariants): Adjust.
* loop-iv.c (iv_analysis_loop_init): Use df_analyze_loop.
2014-01-17 Zhenqiang Chen <zhenqiang.chen@arm.com>
* config/arm/arm.c (arm_v7m_tune): Set max_insns_skipped to 2.

View File

@ -393,6 +393,7 @@ are write-only operations.
#include "df.h"
#include "tree-pass.h"
#include "params.h"
#include "cfgloop.h"
static void *df_get_bb_info (struct dataflow *, unsigned int);
static void df_set_bb_info (struct dataflow *, unsigned int, void *);
@ -1225,23 +1226,13 @@ df_analyze_problem (struct dataflow *dflow,
}
/* Analyze dataflow info for the basic blocks specified by the bitmap
BLOCKS, or for the whole CFG if BLOCKS is zero. */
/* Analyze dataflow info. */
void
df_analyze (void)
static void
df_analyze_1 (void)
{
bitmap current_all_blocks = BITMAP_ALLOC (&df_bitmap_obstack);
bool everything;
int i;
free (df->postorder);
free (df->postorder_inverted);
df->postorder = XNEWVEC (int, last_basic_block_for_fn (cfun));
df->postorder_inverted = XNEWVEC (int, last_basic_block_for_fn (cfun));
df->n_blocks = post_order_compute (df->postorder, true, true);
df->n_blocks_inverted = inverted_post_order_compute (df->postorder_inverted);
/* These should be the same. */
gcc_assert (df->n_blocks == df->n_blocks_inverted);
@ -1258,36 +1249,6 @@ df_analyze (void)
#endif
df_verify ();
for (i = 0; i < df->n_blocks; i++)
bitmap_set_bit (current_all_blocks, df->postorder[i]);
#ifdef ENABLE_CHECKING
/* Verify that POSTORDER_INVERTED only contains blocks reachable from
the ENTRY block. */
for (i = 0; i < df->n_blocks_inverted; i++)
gcc_assert (bitmap_bit_p (current_all_blocks, df->postorder_inverted[i]));
#endif
/* Make sure that we have pruned any unreachable blocks from these
sets. */
if (df->analyze_subset)
{
everything = false;
bitmap_and_into (df->blocks_to_analyze, current_all_blocks);
df->n_blocks = df_prune_to_subcfg (df->postorder,
df->n_blocks, df->blocks_to_analyze);
df->n_blocks_inverted = df_prune_to_subcfg (df->postorder_inverted,
df->n_blocks_inverted,
df->blocks_to_analyze);
BITMAP_FREE (current_all_blocks);
}
else
{
everything = true;
df->blocks_to_analyze = current_all_blocks;
current_all_blocks = NULL;
}
/* Skip over the DF_SCAN problem. */
for (i = 1; i < df->num_problems_defined; i++)
{
@ -1307,7 +1268,7 @@ df_analyze (void)
}
}
if (everything)
if (!df->analyze_subset)
{
BITMAP_FREE (df->blocks_to_analyze);
df->blocks_to_analyze = NULL;
@ -1318,6 +1279,208 @@ df_analyze (void)
#endif
}
/* Analyze dataflow info. */
void
df_analyze (void)
{
bitmap current_all_blocks = BITMAP_ALLOC (&df_bitmap_obstack);
int i;
free (df->postorder);
free (df->postorder_inverted);
df->postorder = XNEWVEC (int, last_basic_block_for_fn (cfun));
df->postorder_inverted = XNEWVEC (int, last_basic_block_for_fn (cfun));
df->n_blocks = post_order_compute (df->postorder, true, true);
df->n_blocks_inverted = inverted_post_order_compute (df->postorder_inverted);
for (i = 0; i < df->n_blocks; i++)
bitmap_set_bit (current_all_blocks, df->postorder[i]);
#ifdef ENABLE_CHECKING
/* Verify that POSTORDER_INVERTED only contains blocks reachable from
the ENTRY block. */
for (i = 0; i < df->n_blocks_inverted; i++)
gcc_assert (bitmap_bit_p (current_all_blocks, df->postorder_inverted[i]));
#endif
/* Make sure that we have pruned any unreachable blocks from these
sets. */
if (df->analyze_subset)
{
bitmap_and_into (df->blocks_to_analyze, current_all_blocks);
df->n_blocks = df_prune_to_subcfg (df->postorder,
df->n_blocks, df->blocks_to_analyze);
df->n_blocks_inverted = df_prune_to_subcfg (df->postorder_inverted,
df->n_blocks_inverted,
df->blocks_to_analyze);
BITMAP_FREE (current_all_blocks);
}
else
{
df->blocks_to_analyze = current_all_blocks;
current_all_blocks = NULL;
}
df_analyze_1 ();
}
/* Compute the reverse top sort order of the sub-CFG specified by LOOP.
Returns the number of blocks which is always loop->num_nodes. */
static int
loop_post_order_compute (int *post_order, struct loop *loop)
{
edge_iterator *stack;
int sp;
int post_order_num = 0;
bitmap visited;
/* Allocate stack for back-tracking up CFG. */
stack = XNEWVEC (edge_iterator, loop->num_nodes + 1);
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
visited = BITMAP_ALLOC (NULL);
/* Push the first edge on to the stack. */
stack[sp++] = ei_start (loop_preheader_edge (loop)->src->succs);
while (sp)
{
edge_iterator ei;
basic_block src;
basic_block dest;
/* Look at the edge on the top of the stack. */
ei = stack[sp - 1];
src = ei_edge (ei)->src;
dest = ei_edge (ei)->dest;
/* Check if the edge destination has been visited yet and mark it
if not so. */
if (flow_bb_inside_loop_p (loop, dest)
&& bitmap_set_bit (visited, dest->index))
{
if (EDGE_COUNT (dest->succs) > 0)
/* Since the DEST node has been visited for the first
time, check its successors. */
stack[sp++] = ei_start (dest->succs);
else
post_order[post_order_num++] = dest->index;
}
else
{
if (ei_one_before_end_p (ei)
&& src != loop_preheader_edge (loop)->src)
post_order[post_order_num++] = src->index;
if (!ei_one_before_end_p (ei))
ei_next (&stack[sp - 1]);
else
sp--;
}
}
free (stack);
BITMAP_FREE (visited);
return post_order_num;
}
/* Compute the reverse top sort order of the inverted sub-CFG specified
by LOOP. Returns the number of blocks which is always loop->num_nodes. */
static int
loop_inverted_post_order_compute (int *post_order, struct loop *loop)
{
basic_block bb;
edge_iterator *stack;
int sp;
int post_order_num = 0;
bitmap visited;
/* Allocate stack for back-tracking up CFG. */
stack = XNEWVEC (edge_iterator, loop->num_nodes + 1);
sp = 0;
/* Allocate bitmap to track nodes that have been visited. */
visited = BITMAP_ALLOC (NULL);
/* Put all latches into the initial work list. In theory we'd want
to start from loop exits but then we'd have the special case of
endless loops. It doesn't really matter for DF iteration order and
handling latches last is probably even better. */
stack[sp++] = ei_start (loop->header->preds);
bitmap_set_bit (visited, loop->header->index);
/* The inverted traversal loop. */
while (sp)
{
edge_iterator ei;
basic_block pred;
/* Look at the edge on the top of the stack. */
ei = stack[sp - 1];
bb = ei_edge (ei)->dest;
pred = ei_edge (ei)->src;
/* Check if the predecessor has been visited yet and mark it
if not so. */
if (flow_bb_inside_loop_p (loop, pred)
&& bitmap_set_bit (visited, pred->index))
{
if (EDGE_COUNT (pred->preds) > 0)
/* Since the predecessor node has been visited for the first
time, check its predecessors. */
stack[sp++] = ei_start (pred->preds);
else
post_order[post_order_num++] = pred->index;
}
else
{
if (flow_bb_inside_loop_p (loop, bb)
&& ei_one_before_end_p (ei))
post_order[post_order_num++] = bb->index;
if (!ei_one_before_end_p (ei))
ei_next (&stack[sp - 1]);
else
sp--;
}
}
free (stack);
BITMAP_FREE (visited);
return post_order_num;
}
/* Analyze dataflow info for the basic blocks contained in LOOP. */
void
df_analyze_loop (struct loop *loop)
{
free (df->postorder);
free (df->postorder_inverted);
df->postorder = XNEWVEC (int, loop->num_nodes);
df->postorder_inverted = XNEWVEC (int, loop->num_nodes);
df->n_blocks = loop_post_order_compute (df->postorder, loop);
df->n_blocks_inverted
= loop_inverted_post_order_compute (df->postorder_inverted, loop);
gcc_assert ((unsigned) df->n_blocks == loop->num_nodes);
gcc_assert ((unsigned) df->n_blocks_inverted == loop->num_nodes);
bitmap blocks = BITMAP_ALLOC (&df_bitmap_obstack);
for (int i = 0; i < df->n_blocks; ++i)
bitmap_set_bit (blocks, df->postorder[i]);
df_set_blocks (blocks);
BITMAP_FREE (blocks);
df_analyze_1 ();
}
/* Return the number of basic blocks from the last call to df_analyze. */

View File

@ -900,7 +900,8 @@ extern void df_set_blocks (bitmap);
extern void df_remove_problem (struct dataflow *);
extern void df_finish_pass (bool);
extern void df_analyze_problem (struct dataflow *, bitmap, int *, int);
extern void df_analyze (void);
extern void df_analyze ();
extern void df_analyze_loop (struct loop *);
extern int df_get_n_blocks (enum df_flow_dir);
extern int *df_get_postorder (enum df_flow_dir);
extern void df_simple_dataflow (enum df_flow_dir, df_init_function,

View File

@ -652,14 +652,8 @@ may_assign_reg_p (rtx x)
BODY. */
static void
find_defs (struct loop *loop, basic_block *body)
find_defs (struct loop *loop)
{
unsigned i;
bitmap blocks = BITMAP_ALLOC (NULL);
for (i = 0; i < loop->num_nodes; i++)
bitmap_set_bit (blocks, body[i]->index);
if (dump_file)
{
fprintf (dump_file,
@ -670,9 +664,8 @@ find_defs (struct loop *loop, basic_block *body)
df_remove_problem (df_chain);
df_process_deferred_rescans ();
df_chain_add_problem (DF_UD_CHAIN);
df_set_blocks (blocks);
df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
df_analyze ();
df_analyze_loop (loop);
check_invariant_table_size ();
if (dump_file)
@ -682,8 +675,6 @@ find_defs (struct loop *loop, basic_block *body)
"*****ending processing of loop %d ******\n",
loop->num);
}
BITMAP_FREE (blocks);
}
/* Creates a new invariant for definition DEF in INSN, depending on invariants
@ -1005,7 +996,7 @@ find_invariants (struct loop *loop)
compute_always_reached (loop, body, may_exit, always_reached);
compute_always_reached (loop, body, has_exit, always_executed);
find_defs (loop, body);
find_defs (loop);
find_invariants_body (loop, body, always_reached, always_executed);
merge_identical_invariants ();

View File

@ -278,10 +278,6 @@ clear_iv_info (void)
void
iv_analysis_loop_init (struct loop *loop)
{
basic_block *body = get_loop_body_in_dom_order (loop), bb;
bitmap blocks = BITMAP_ALLOC (NULL);
unsigned i;
current_loop = loop;
/* Clear the information from the analysis of the previous loop. */
@ -294,11 +290,6 @@ iv_analysis_loop_init (struct loop *loop)
else
clear_iv_info ();
for (i = 0; i < loop->num_nodes; i++)
{
bb = body[i];
bitmap_set_bit (blocks, bb->index);
}
/* Get rid of the ud chains before processing the rescans. Then add
the problem back. */
df_remove_problem (df_chain);
@ -306,14 +297,11 @@ iv_analysis_loop_init (struct loop *loop)
df_set_flags (DF_RD_PRUNE_DEAD_DEFS);
df_chain_add_problem (DF_UD_CHAIN);
df_note_add_problem ();
df_set_blocks (blocks);
df_analyze ();
df_analyze_loop (loop);
if (dump_file)
df_dump_region (dump_file);
check_iv_ref_table_size ();
BITMAP_FREE (blocks);
free (body);
}
/* Finds the definition of REG that dominates loop latch and stores