mirror of git://gcc.gnu.org/git/gcc.git
re PR middle-end/63155 (memory hog)
2018-10-05 Richard Biener <rguenther@suse.de> PR tree-optimization/63155 * tree-ssa-ccp.c (ccp_propagate::visit_phi): Avoid excess vertical space in dumpfiles. * tree-ssa-propagate.h (ssa_propagation_engine::process_ssa_edge_worklist): Remove. * tree-ssa-propagate.c (cfg_blocks_back): New global. (ssa_edge_worklist_back): Likewise. (curr_order): Likewise. (cfg_blocks_get): Remove abstraction. (cfg_blocks_add): Likewise. (cfg_blocks_empty_p): Likewise. (add_ssa_edge): Add to current or next worklist based on RPO index. (add_control_edge): Likewise. (ssa_propagation_engine::process_ssa_edge_worklist): Fold into ... (ssa_propagation_engine::ssa_propagate): ... here. Unify iteration from CFG and SSA edge worklist so we process everything in RPO order, prioritizing forward progress over iteration. (ssa_prop_init): Allocate new worklists, do not dump immediate uses. (ssa_prop_fini): Free new worklists. From-SVN: r264869
This commit is contained in:
parent
700adeb6fd
commit
f48bd5e43a
|
|
@ -1,3 +1,29 @@
|
||||||
|
2018-10-05 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR tree-optimization/63155
|
||||||
|
* tree-ssa-ccp.c (ccp_propagate::visit_phi): Avoid excess
|
||||||
|
vertical space in dumpfiles.
|
||||||
|
* tree-ssa-propagate.h
|
||||||
|
(ssa_propagation_engine::process_ssa_edge_worklist): Remove.
|
||||||
|
* tree-ssa-propagate.c (cfg_blocks_back): New global.
|
||||||
|
(ssa_edge_worklist_back): Likewise.
|
||||||
|
(curr_order): Likewise.
|
||||||
|
(cfg_blocks_get): Remove abstraction.
|
||||||
|
(cfg_blocks_add): Likewise.
|
||||||
|
(cfg_blocks_empty_p): Likewise.
|
||||||
|
(add_ssa_edge): Add to current or next worklist based on
|
||||||
|
RPO index.
|
||||||
|
(add_control_edge): Likewise.
|
||||||
|
(ssa_propagation_engine::process_ssa_edge_worklist): Fold
|
||||||
|
into ...
|
||||||
|
(ssa_propagation_engine::ssa_propagate): ... here. Unify
|
||||||
|
iteration from CFG and SSA edge worklist so we process
|
||||||
|
everything in RPO order, prioritizing forward progress
|
||||||
|
over iteration.
|
||||||
|
(ssa_prop_init): Allocate new worklists, do not dump
|
||||||
|
immediate uses.
|
||||||
|
(ssa_prop_fini): Free new worklists.
|
||||||
|
|
||||||
2018-10-05 Richard Biener <rguenther@suse.de>
|
2018-10-05 Richard Biener <rguenther@suse.de>
|
||||||
|
|
||||||
* tree-core.h (tree_block::abstract_flag): Remove.
|
* tree-core.h (tree_block::abstract_flag): Remove.
|
||||||
|
|
|
||||||
|
|
@ -1119,7 +1119,7 @@ ccp_propagate::visit_phi (gphi *phi)
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
{
|
{
|
||||||
fprintf (dump_file,
|
fprintf (dump_file,
|
||||||
"\n Argument #%d (%d -> %d %sexecutable)\n",
|
"\tArgument #%d (%d -> %d %sexecutable)\n",
|
||||||
i, e->src->index, e->dest->index,
|
i, e->src->index, e->dest->index,
|
||||||
(e->flags & EDGE_EXECUTABLE) ? "" : "not ");
|
(e->flags & EDGE_EXECUTABLE) ? "" : "not ");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,51 +108,26 @@
|
||||||
[3] Advanced Compiler Design and Implementation,
|
[3] Advanced Compiler Design and Implementation,
|
||||||
Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6 */
|
Steven Muchnick, Morgan Kaufmann, 1997, Section 12.6 */
|
||||||
|
|
||||||
/* Worklist of control flow edge destinations. This contains
|
/* Worklists of control flow edge destinations. This contains
|
||||||
the CFG order number of the blocks so we can iterate in CFG
|
the CFG order number of the blocks so we can iterate in CFG
|
||||||
order by visiting in bit-order. */
|
order by visiting in bit-order. We use two worklists to
|
||||||
|
first make forward progress before iterating. */
|
||||||
static bitmap cfg_blocks;
|
static bitmap cfg_blocks;
|
||||||
|
static bitmap cfg_blocks_back;
|
||||||
static int *bb_to_cfg_order;
|
static int *bb_to_cfg_order;
|
||||||
static int *cfg_order_to_bb;
|
static int *cfg_order_to_bb;
|
||||||
|
|
||||||
/* Worklist of SSA edges which will need reexamination as their
|
/* Worklists of SSA edges which will need reexamination as their
|
||||||
definition has changed. SSA edges are def-use edges in the SSA
|
definition has changed. SSA edges are def-use edges in the SSA
|
||||||
web. For each D-U edge, we store the target statement or PHI node
|
web. For each D-U edge, we store the target statement or PHI node
|
||||||
UID in a bitmap. UIDs order stmts in execution order. */
|
UID in a bitmap. UIDs order stmts in execution order. We use
|
||||||
|
two worklists to first make forward progress before iterating. */
|
||||||
static bitmap ssa_edge_worklist;
|
static bitmap ssa_edge_worklist;
|
||||||
|
static bitmap ssa_edge_worklist_back;
|
||||||
static vec<gimple *> uid_to_stmt;
|
static vec<gimple *> uid_to_stmt;
|
||||||
|
|
||||||
/* Return true if the block worklist empty. */
|
/* Current RPO index in the iteration. */
|
||||||
|
static int curr_order;
|
||||||
static inline bool
|
|
||||||
cfg_blocks_empty_p (void)
|
|
||||||
{
|
|
||||||
return bitmap_empty_p (cfg_blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Add a basic block to the worklist. The block must not be the ENTRY
|
|
||||||
or EXIT block. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
cfg_blocks_add (basic_block bb)
|
|
||||||
{
|
|
||||||
gcc_assert (bb != ENTRY_BLOCK_PTR_FOR_FN (cfun)
|
|
||||||
&& bb != EXIT_BLOCK_PTR_FOR_FN (cfun));
|
|
||||||
bitmap_set_bit (cfg_blocks, bb_to_cfg_order[bb->index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Remove a block from the worklist. */
|
|
||||||
|
|
||||||
static basic_block
|
|
||||||
cfg_blocks_get (void)
|
|
||||||
{
|
|
||||||
gcc_assert (!cfg_blocks_empty_p ());
|
|
||||||
int order_index = bitmap_first_set_bit (cfg_blocks);
|
|
||||||
bitmap_clear_bit (cfg_blocks, order_index);
|
|
||||||
return BASIC_BLOCK_FOR_FN (cfun, cfg_order_to_bb [order_index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* We have just defined a new value for VAR. If IS_VARYING is true,
|
/* We have just defined a new value for VAR. If IS_VARYING is true,
|
||||||
|
|
@ -182,8 +157,15 @@ add_ssa_edge (tree var)
|
||||||
& EDGE_EXECUTABLE))
|
& EDGE_EXECUTABLE))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (prop_simulate_again_p (use_stmt)
|
if (!prop_simulate_again_p (use_stmt))
|
||||||
&& bitmap_set_bit (ssa_edge_worklist, gimple_uid (use_stmt)))
|
continue;
|
||||||
|
|
||||||
|
bitmap worklist;
|
||||||
|
if (bb_to_cfg_order[gimple_bb (use_stmt)->index] < curr_order)
|
||||||
|
worklist = ssa_edge_worklist_back;
|
||||||
|
else
|
||||||
|
worklist = ssa_edge_worklist;
|
||||||
|
if (bitmap_set_bit (worklist, gimple_uid (use_stmt)))
|
||||||
{
|
{
|
||||||
uid_to_stmt[gimple_uid (use_stmt)] = use_stmt;
|
uid_to_stmt[gimple_uid (use_stmt)] = use_stmt;
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
|
@ -211,7 +193,11 @@ add_control_edge (edge e)
|
||||||
|
|
||||||
e->flags |= EDGE_EXECUTABLE;
|
e->flags |= EDGE_EXECUTABLE;
|
||||||
|
|
||||||
cfg_blocks_add (bb);
|
int bb_order = bb_to_cfg_order[bb->index];
|
||||||
|
if (bb_order < curr_order)
|
||||||
|
bitmap_set_bit (cfg_blocks_back, bb_order);
|
||||||
|
else
|
||||||
|
bitmap_set_bit (cfg_blocks, bb_order);
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
fprintf (dump_file, "Adding destination of edge (%d -> %d) to worklist\n",
|
fprintf (dump_file, "Adding destination of edge (%d -> %d) to worklist\n",
|
||||||
|
|
@ -318,33 +304,6 @@ ssa_propagation_engine::simulate_stmt (gimple *stmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Process an SSA edge worklist. WORKLIST is the SSA edge worklist to
|
|
||||||
drain. This pops statements off the given WORKLIST and processes
|
|
||||||
them until one statement was simulated or there are no more statements
|
|
||||||
on WORKLIST. We take a pointer to WORKLIST because it may be reallocated
|
|
||||||
when an SSA edge is added to it in simulate_stmt. Return true if a stmt
|
|
||||||
was simulated. */
|
|
||||||
|
|
||||||
void
|
|
||||||
ssa_propagation_engine::process_ssa_edge_worklist (void)
|
|
||||||
{
|
|
||||||
/* Process the next entry from the worklist. */
|
|
||||||
unsigned stmt_uid = bitmap_first_set_bit (ssa_edge_worklist);
|
|
||||||
bitmap_clear_bit (ssa_edge_worklist, stmt_uid);
|
|
||||||
gimple *stmt = uid_to_stmt[stmt_uid];
|
|
||||||
|
|
||||||
/* We should not have stmts in not yet simulated BBs on the worklist. */
|
|
||||||
gcc_assert (gimple_bb (stmt)->flags & BB_VISITED);
|
|
||||||
|
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
{
|
|
||||||
fprintf (dump_file, "\nSimulating statement: ");
|
|
||||||
print_gimple_stmt (dump_file, stmt, 0, dump_flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
simulate_stmt (stmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Simulate the execution of BLOCK. Evaluate the statement associated
|
/* Simulate the execution of BLOCK. Evaluate the statement associated
|
||||||
with each variable reference inside the block. */
|
with each variable reference inside the block. */
|
||||||
|
|
@ -422,6 +381,7 @@ ssa_prop_init (void)
|
||||||
|
|
||||||
/* Worklists of SSA edges. */
|
/* Worklists of SSA edges. */
|
||||||
ssa_edge_worklist = BITMAP_ALLOC (NULL);
|
ssa_edge_worklist = BITMAP_ALLOC (NULL);
|
||||||
|
ssa_edge_worklist_back = BITMAP_ALLOC (NULL);
|
||||||
|
|
||||||
/* Worklist of basic-blocks. */
|
/* Worklist of basic-blocks. */
|
||||||
bb_to_cfg_order = XNEWVEC (int, last_basic_block_for_fn (cfun) + 1);
|
bb_to_cfg_order = XNEWVEC (int, last_basic_block_for_fn (cfun) + 1);
|
||||||
|
|
@ -431,9 +391,7 @@ ssa_prop_init (void)
|
||||||
for (int i = 0; i < n; ++i)
|
for (int i = 0; i < n; ++i)
|
||||||
bb_to_cfg_order[cfg_order_to_bb[i]] = i;
|
bb_to_cfg_order[cfg_order_to_bb[i]] = i;
|
||||||
cfg_blocks = BITMAP_ALLOC (NULL);
|
cfg_blocks = BITMAP_ALLOC (NULL);
|
||||||
|
cfg_blocks_back = BITMAP_ALLOC (NULL);
|
||||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
|
||||||
dump_immediate_uses (dump_file);
|
|
||||||
|
|
||||||
/* Initially assume that every edge in the CFG is not executable.
|
/* Initially assume that every edge in the CFG is not executable.
|
||||||
(including the edges coming out of the entry block). Mark blocks
|
(including the edges coming out of the entry block). Mark blocks
|
||||||
|
|
@ -479,9 +437,11 @@ static void
|
||||||
ssa_prop_fini (void)
|
ssa_prop_fini (void)
|
||||||
{
|
{
|
||||||
BITMAP_FREE (cfg_blocks);
|
BITMAP_FREE (cfg_blocks);
|
||||||
|
BITMAP_FREE (cfg_blocks_back);
|
||||||
free (bb_to_cfg_order);
|
free (bb_to_cfg_order);
|
||||||
free (cfg_order_to_bb);
|
free (cfg_order_to_bb);
|
||||||
BITMAP_FREE (ssa_edge_worklist);
|
BITMAP_FREE (ssa_edge_worklist);
|
||||||
|
BITMAP_FREE (ssa_edge_worklist_back);
|
||||||
uid_to_stmt.release ();
|
uid_to_stmt.release ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -796,21 +756,62 @@ ssa_propagation_engine::ssa_propagate (void)
|
||||||
{
|
{
|
||||||
ssa_prop_init ();
|
ssa_prop_init ();
|
||||||
|
|
||||||
/* Iterate until the worklists are empty. */
|
curr_order = 0;
|
||||||
while (! cfg_blocks_empty_p ()
|
|
||||||
|| ! bitmap_empty_p (ssa_edge_worklist))
|
/* Iterate until the worklists are empty. We iterate both blocks
|
||||||
|
and stmts in RPO order, using sets of two worklists to first
|
||||||
|
complete the current iteration before iterating over backedges. */
|
||||||
|
while (1)
|
||||||
{
|
{
|
||||||
/* First simulate whole blocks. */
|
int next_block_order = (bitmap_empty_p (cfg_blocks)
|
||||||
if (! cfg_blocks_empty_p ())
|
? -1 : bitmap_first_set_bit (cfg_blocks));
|
||||||
|
int next_stmt_uid = (bitmap_empty_p (ssa_edge_worklist)
|
||||||
|
? -1 : bitmap_first_set_bit (ssa_edge_worklist));
|
||||||
|
if (next_block_order == -1 && next_stmt_uid == -1)
|
||||||
{
|
{
|
||||||
/* Pull the next block to simulate off the worklist. */
|
if (bitmap_empty_p (cfg_blocks_back)
|
||||||
basic_block dest_block = cfg_blocks_get ();
|
&& bitmap_empty_p (ssa_edge_worklist_back))
|
||||||
simulate_block (dest_block);
|
break;
|
||||||
|
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
fprintf (dump_file, "Regular worklists empty, now processing "
|
||||||
|
"backedge destinations\n");
|
||||||
|
std::swap (cfg_blocks, cfg_blocks_back);
|
||||||
|
std::swap (ssa_edge_worklist, ssa_edge_worklist_back);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then simulate from the SSA edge worklist. */
|
int next_stmt_bb_order = -1;
|
||||||
process_ssa_edge_worklist ();
|
gimple *next_stmt = NULL;
|
||||||
|
if (next_stmt_uid != -1)
|
||||||
|
{
|
||||||
|
next_stmt = uid_to_stmt[next_stmt_uid];
|
||||||
|
next_stmt_bb_order = bb_to_cfg_order[gimple_bb (next_stmt)->index];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pull the next block to simulate off the worklist if it comes first. */
|
||||||
|
if (next_block_order != -1
|
||||||
|
&& (next_stmt_bb_order == -1
|
||||||
|
|| next_block_order <= next_stmt_bb_order))
|
||||||
|
{
|
||||||
|
curr_order = next_block_order;
|
||||||
|
bitmap_clear_bit (cfg_blocks, next_block_order);
|
||||||
|
basic_block bb
|
||||||
|
= BASIC_BLOCK_FOR_FN (cfun, cfg_order_to_bb [next_block_order]);
|
||||||
|
simulate_block (bb);
|
||||||
|
}
|
||||||
|
/* Else simulate from the SSA edge worklist. */
|
||||||
|
else
|
||||||
|
{
|
||||||
|
curr_order = next_stmt_bb_order;
|
||||||
|
bitmap_clear_bit (ssa_edge_worklist, next_stmt_uid);
|
||||||
|
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||||
|
{
|
||||||
|
fprintf (dump_file, "\nSimulating statement: ");
|
||||||
|
print_gimple_stmt (dump_file, next_stmt, 0, dump_flags);
|
||||||
|
}
|
||||||
|
simulate_stmt (next_stmt);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ssa_prop_fini ();
|
ssa_prop_fini ();
|
||||||
|
|
|
||||||
|
|
@ -94,9 +94,7 @@ class ssa_propagation_engine
|
||||||
private:
|
private:
|
||||||
/* Internal implementation details. */
|
/* Internal implementation details. */
|
||||||
void simulate_stmt (gimple *stmt);
|
void simulate_stmt (gimple *stmt);
|
||||||
void process_ssa_edge_worklist (void);
|
|
||||||
void simulate_block (basic_block);
|
void simulate_block (basic_block);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class substitute_and_fold_engine
|
class substitute_and_fold_engine
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue