Commit e3bfa377 by Bin Cheng Committed by Bin Cheng

tree-outof-ssa.c (tree-ssa.h, tree-dfa.h): Include header files.

	* tree-outof-ssa.c (tree-ssa.h, tree-dfa.h): Include header files.
	(create_default_def, for_all_parms): Moved from tree-ssa-coalesce.c.
	(parm_default_def_partition_arg): Ditto.
	(set_parm_default_def_partition): Ditto.
	(get_parm_default_def_partitions): Ditto and make it static.
	(get_undefined_value_partitions): Ditto and make it static.
	(remove_ssa_form): Refactor call to init_var_map here.
	* tree-ssa-coalesce.c (build_ssa_conflict_graph): Support live range
	computation for loop region.
	(coalesce_partitions, compute_optimized_partition_bases): Ditto.
	(register_default_def): Delete.
	(for_all_parms, create_default_def): Move to tree-outof-ssa.c.
	(parm_default_def_partition_arg): Ditto.
	(set_parm_default_def_partition): Ditto.
	(get_parm_default_def_partitions): Ditto and make it static.
	(get_undefined_value_partitions): Ditto and make it static.
	(coalesce_with_default, coalesce_with_default): Update comment.
	(create_coalesce_list_for_region): New func factored out from
	create_outofssa_var_map.
	(populate_coalesce_list_for_outofssa): New func factored out from
	create_outofssa_var_map and coalesce_ssa_name.
	(create_outofssa_var_map): Delete.
	(coalesce_ssa_name): Refactor to support live range computation.
	* tree-ssa-coalesce.h (coalesce_ssa_name): Change decl.
	(get_parm_default_def_partitions): Delete.
	(get_undefined_value_partitions): Ditto.
	* tree-ssa-live.c (init_var_map, delete_var_map): Support live range
	computation for loop region.
	(new_tree_live_info, loe_visit_block): Ditto.
	(live_worklist, set_var_live_on_entry): Ditto.
	(calculate_live_on_exit, verify_live_on_entry): Ditto.
	* tree-ssa-live.h (struct _var_map): New fields.
	(init_var_map): Change decl.
	(region_contains_p): New.

From-SVN: r260747
parent 34f7080e
2018-05-25 Bin Cheng <bin.cheng@arm.com>
* tree-outof-ssa.c (tree-ssa.h, tree-dfa.h): Include header files.
(create_default_def, for_all_parms): Moved from tree-ssa-coalesce.c.
(parm_default_def_partition_arg): Ditto.
(set_parm_default_def_partition): Ditto.
(get_parm_default_def_partitions): Ditto and make it static.
(get_undefined_value_partitions): Ditto and make it static.
(remove_ssa_form): Refactor call to init_var_map here.
* tree-ssa-coalesce.c (build_ssa_conflict_graph): Support live range
computation for loop region.
(coalesce_partitions, compute_optimized_partition_bases): Ditto.
(register_default_def): Delete.
(for_all_parms, create_default_def): Move to tree-outof-ssa.c.
(parm_default_def_partition_arg): Ditto.
(set_parm_default_def_partition): Ditto.
(get_parm_default_def_partitions): Ditto and make it static.
(get_undefined_value_partitions): Ditto and make it static.
(coalesce_with_default, coalesce_with_default): Update comment.
(create_coalesce_list_for_region): New func factored out from
create_outofssa_var_map.
(populate_coalesce_list_for_outofssa): New func factored out from
create_outofssa_var_map and coalesce_ssa_name.
(create_outofssa_var_map): Delete.
(coalesce_ssa_name): Refactor to support live range computation.
* tree-ssa-coalesce.h (coalesce_ssa_name): Change decl.
(get_parm_default_def_partitions): Delete.
(get_undefined_value_partitions): Ditto.
* tree-ssa-live.c (init_var_map, delete_var_map): Support live range
computation for loop region.
(new_tree_live_info, loe_visit_block): Ditto.
(live_worklist, set_var_live_on_entry): Ditto.
(calculate_live_on_exit, verify_live_on_entry): Ditto.
* tree-ssa-live.h (struct _var_map): New fields.
(init_var_map): Change decl.
(region_contains_p): New.
2018-05-25 Bin Cheng <bin.cheng@arm.com>
* tree-ssa-live.h (live_merge_and_clear): Delete.
2018-05-25 Richard Biener <rguenther@suse.de>
......
......@@ -27,10 +27,12 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "cfghooks.h"
#include "ssa.h"
#include "tree-ssa.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "tree-dfa.h"
#include "stor-layout.h"
#include "cfgrtl.h"
#include "cfganal.h"
......@@ -888,6 +890,102 @@ rewrite_trees (var_map map)
}
}
/* Create a default def for VAR. */
static void
create_default_def (tree var, void *arg ATTRIBUTE_UNUSED)
{
if (!is_gimple_reg (var))
return;
tree ssa = get_or_create_ssa_default_def (cfun, var);
gcc_assert (ssa);
}
/* Call CALLBACK for all PARM_DECLs and RESULT_DECLs for which
assign_parms may ask for a default partition. */
static void
for_all_parms (void (*callback)(tree var, void *arg), void *arg)
{
for (tree var = DECL_ARGUMENTS (current_function_decl); var;
var = DECL_CHAIN (var))
callback (var, arg);
if (!VOID_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
callback (DECL_RESULT (current_function_decl), arg);
if (cfun->static_chain_decl)
callback (cfun->static_chain_decl, arg);
}
/* We need to pass two arguments to set_parm_default_def_partition,
but for_all_parms only supports one. Use a pair. */
typedef std::pair<var_map, bitmap> parm_default_def_partition_arg;
/* Set in ARG's PARTS bitmap the bit corresponding to the partition in
ARG's MAP containing VAR's default def. */
static void
set_parm_default_def_partition (tree var, void *arg_)
{
parm_default_def_partition_arg *arg = (parm_default_def_partition_arg *)arg_;
var_map map = arg->first;
bitmap parts = arg->second;
if (!is_gimple_reg (var))
return;
tree ssa = ssa_default_def (cfun, var);
gcc_assert (ssa);
int version = var_to_partition (map, ssa);
gcc_assert (version != NO_PARTITION);
bool changed = bitmap_set_bit (parts, version);
gcc_assert (changed);
}
/* Allocate and return a bitmap that has a bit set for each partition
that contains a default def for a parameter. */
static bitmap
get_parm_default_def_partitions (var_map map)
{
bitmap parm_default_def_parts = BITMAP_ALLOC (NULL);
parm_default_def_partition_arg
arg = std::make_pair (map, parm_default_def_parts);
for_all_parms (set_parm_default_def_partition, &arg);
return parm_default_def_parts;
}
/* Allocate and return a bitmap that has a bit set for each partition
that contains an undefined value. */
static bitmap
get_undefined_value_partitions (var_map map)
{
bitmap undefined_value_parts = BITMAP_ALLOC (NULL);
for (unsigned int i = 1; i < num_ssa_names; i++)
{
tree var = ssa_name (i);
if (var
&& !virtual_operand_p (var)
&& !has_zero_uses (var)
&& ssa_undefined_value_p (var))
{
const int p = var_to_partition (map, var);
if (p != NO_PARTITION)
bitmap_set_bit (undefined_value_parts, p);
}
}
return undefined_value_parts;
}
/* Given the out-of-ssa info object SA (with prepared partitions)
eliminate all phi nodes in all basic blocks. Afterwards no
basic block will have phi nodes anymore and there are possibly
......@@ -945,7 +1043,9 @@ remove_ssa_form (bool perform_ter, struct ssaexpand *sa)
bitmap values = NULL;
var_map map;
map = coalesce_ssa_name ();
for_all_parms (create_default_def, NULL);
map = init_var_map (num_ssa_names);
coalesce_ssa_name (map);
/* Return to viewing the variable list as just all reference variables after
coalescing has been performed. */
......
......@@ -20,9 +20,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_SSA_COALESCE_H
#define GCC_TREE_SSA_COALESCE_H
extern var_map coalesce_ssa_name (void);
extern void coalesce_ssa_name (var_map);
extern bool gimple_can_coalesce_p (tree, tree);
extern bitmap get_parm_default_def_partitions (var_map);
extern bitmap get_undefined_value_partitions (var_map);
#endif /* GCC_TREE_SSA_COALESCE_H */
......@@ -71,10 +71,12 @@ var_map_base_fini (var_map map)
map->num_basevars = 0;
}
}
/* Create a variable partition map of SIZE, initialize and return it. */
/* Create a variable partition map of SIZE for region, initialize and return
it. Region is a loop if LOOP is non-NULL, otherwise is the current
function. */
var_map
init_var_map (int size)
init_var_map (int size, struct loop *loop)
{
var_map map;
......@@ -87,6 +89,27 @@ init_var_map (int size)
map->partition_size = size;
map->num_basevars = 0;
map->partition_to_base_index = NULL;
map->vec_bbs = vNULL;
if (loop)
{
map->bmp_bbs = BITMAP_ALLOC (NULL);
map->outofssa_p = false;
basic_block *bbs = get_loop_body_in_dom_order (loop);
for (unsigned i = 0; i < loop->num_nodes; ++i)
{
bitmap_set_bit (map->bmp_bbs, bbs[i]->index);
map->vec_bbs.safe_push (bbs[i]);
}
free (bbs);
}
else
{
map->bmp_bbs = NULL;
map->outofssa_p = true;
basic_block bb;
FOR_EACH_BB_FN (bb, cfun)
map->vec_bbs.safe_push (bb);
}
return map;
}
......@@ -100,6 +123,9 @@ delete_var_map (var_map map)
partition_delete (map->var_partition);
free (map->partition_to_view);
free (map->view_to_partition);
if (map->bmp_bbs)
BITMAP_FREE (map->bmp_bbs);
map->vec_bbs.release ();
free (map);
}
......@@ -901,13 +927,14 @@ new_tree_live_info (var_map map)
bitmap_obstack_initialize (&live->livein_obstack);
bitmap_obstack_initialize (&live->liveout_obstack);
live->livein = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
FOR_EACH_BB_FN (bb, cfun)
bitmap_initialize (&live->livein[bb->index], &live->livein_obstack);
live->liveout = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
FOR_EACH_BB_FN (bb, cfun)
bitmap_initialize (&live->liveout[bb->index], &live->liveout_obstack);
live->livein = XCNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
live->liveout = XCNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
for (unsigned i = 0; map->vec_bbs.iterate (i, &bb); ++i)
{
bitmap_initialize (&live->livein[bb->index], &live->livein_obstack);
bitmap_initialize (&live->liveout[bb->index], &live->liveout_obstack);
}
live->work_stack = XNEWVEC (int, last_basic_block_for_fn (cfun));
live->stack_top = live->work_stack;
......@@ -960,7 +987,7 @@ loe_visit_block (tree_live_info_p live, basic_block bb, sbitmap visited)
FOR_EACH_EDGE (e, ei, bb->preds)
{
pred_bb = e->src;
if (pred_bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
if (!region_contains_p (live->map, pred_bb))
continue;
/* Variables live-on-entry from BB that aren't defined in the
predecessor block. This should be the live on entry vars to pred.
......@@ -993,9 +1020,10 @@ live_worklist (tree_live_info_p live)
bitmap_clear (visited);
/* Visit all the blocks in reverse order and propagate live on entry values
/* Visit region's blocks in reverse order and propagate live on entry values
into the predecessors blocks. */
FOR_EACH_BB_REVERSE_FN (bb, cfun)
for (unsigned i = live->map->vec_bbs.length () - 1;
live->map->vec_bbs.iterate (i, &bb); --i)
loe_visit_block (live, bb, visited);
/* Process any blocks which require further iteration. */
......@@ -1030,7 +1058,7 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
{
def_bb = gimple_bb (stmt);
/* Mark defs in liveout bitmap temporarily. */
if (def_bb)
if (def_bb && region_contains_p (live->map, def_bb))
bitmap_set_bit (&live->liveout[def_bb->index], p);
}
else
......@@ -1054,11 +1082,8 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
defined in that block, or whether its live on entry. */
int index = PHI_ARG_INDEX_FROM_USE (use);
edge e = gimple_phi_arg_edge (as_a <gphi *> (use_stmt), index);
if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
{
if (e->src != def_bb)
add_block = e->src;
}
if (e->src != def_bb && region_contains_p (live->map, e->src))
add_block = e->src;
}
else if (is_gimple_debug (use_stmt))
continue;
......@@ -1066,7 +1091,7 @@ set_var_live_on_entry (tree ssa_name, tree_live_info_p live)
{
/* If its not defined in this block, its live on entry. */
basic_block use_bb = gimple_bb (use_stmt);
if (use_bb != def_bb)
if (use_bb != def_bb && region_contains_p (live->map, use_bb))
add_block = use_bb;
}
......@@ -1095,7 +1120,7 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
edge_iterator ei;
/* live on entry calculations used liveout vectors for defs, clear them. */
FOR_EACH_BB_FN (bb, cfun)
for (unsigned i = 0; liveinfo->map->vec_bbs.iterate (i, &bb); ++i)
bitmap_clear (&liveinfo->liveout[bb->index]);
/* Set all the live-on-exit bits for uses in PHIs. */
......@@ -1108,6 +1133,8 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gphi *phi = gsi.phi ();
if (virtual_operand_p (gimple_phi_result (phi)))
continue;
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree t = PHI_ARG_DEF (phi, i);
......@@ -1120,14 +1147,17 @@ calculate_live_on_exit (tree_live_info_p liveinfo)
if (p == NO_PARTITION)
continue;
e = gimple_phi_arg_edge (phi, i);
if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
if (region_contains_p (liveinfo->map, e->src))
bitmap_set_bit (&liveinfo->liveout[e->src->index], p);
}
}
if (!region_contains_p (liveinfo->map, bb))
continue;
/* Add each successors live on entry to this bock live on exit. */
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
if (region_contains_p (liveinfo->map, e->dest))
bitmap_ior_into (&liveinfo->liveout[bb->index],
live_on_entry (liveinfo, e->dest));
}
......@@ -1314,7 +1344,7 @@ verify_live_on_entry (tree_live_info_p live)
FOR_EACH_EDGE (e, ei, bb->succs)
{
int entry_block = e->dest->index;
if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
if (!region_contains_p (live->map, e->dest))
continue;
for (i = 0; i < (unsigned)num_var_partitions (map); i++)
{
......@@ -1380,6 +1410,8 @@ verify_live_on_entry (tree_live_info_p live)
gsi_next (&gsi))
{
gphi *phi = gsi.phi ();
if (virtual_operand_p (gimple_phi_result (phi)))
continue;
for (z = 0; z < gimple_phi_num_args (phi); z++)
if (var == gimple_phi_arg_def (phi, z))
{
......
......@@ -62,13 +62,25 @@ typedef struct _var_map
/* Map of partitions numbers to base variable table indexes. */
int *partition_to_base_index;
/* Bitmap of basic block. It describes the region within which the analysis
is done. Using pointer avoids allocating memory in out-of-ssa case. */
bitmap bmp_bbs;
/* Vector of basic block in the region. */
vec<basic_block> vec_bbs;
/* True if this map is for out-of-ssa, otherwise for live range
computation. When for out-of-ssa, it also means the var map is computed
for whole current function. */
bool outofssa_p;
} *var_map;
/* Value used to represent no partition number. */
#define NO_PARTITION -1
extern var_map init_var_map (int);
extern var_map init_var_map (int, struct loop* = NULL);
extern void delete_var_map (var_map);
extern int var_union (var_map, tree, tree);
extern void partition_view_normal (var_map);
......@@ -82,6 +94,19 @@ extern void debug (_var_map &ref);
extern void debug (_var_map *ptr);
/* Return TRUE if region of the MAP contains basic block BB. */
inline bool
region_contains_p (var_map map, basic_block bb)
{
/* It's possible that the function is called with ENTRY_BLOCK/EXIT_BLOCK. */
if (map->outofssa_p)
return (bb->index != ENTRY_BLOCK && bb->index != EXIT_BLOCK);
return bitmap_bit_p (map->bmp_bbs, bb->index);
}
/* Return number of partitions in MAP. */
static inline unsigned
......
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