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:
parent
cc3a9f0d47
commit
7be64667c1
@ -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.
|
||||
|
251
gcc/df-core.c
251
gcc/df-core.c
@ -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. */
|
||||
|
||||
|
3
gcc/df.h
3
gcc/df.h
@ -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,
|
||||
|
@ -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 ();
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user