diff options
author | Bin Cheng <bin.cheng@arm.com> | 2018-05-25 10:35:44 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2018-05-25 10:35:44 +0000 |
commit | e3bfa3775a7714fc5c5a8fee06e2c0f42c1fcd34 (patch) | |
tree | 24d850051850f9a7fea69c5a4e13e800d0166ddf /gcc/tree-ssa-coalesce.c | |
parent | 34f7080eb0d738c4f27d7990907172eb907055be (diff) | |
download | gcc-e3bfa3775a7714fc5c5a8fee06e2c0f42c1fcd34.zip gcc-e3bfa3775a7714fc5c5a8fee06e2c0f42c1fcd34.tar.gz gcc-e3bfa3775a7714fc5c5a8fee06e2c0f42c1fcd34.tar.bz2 |
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
Diffstat (limited to 'gcc/tree-ssa-coalesce.c')
-rw-r--r-- | gcc/tree-ssa-coalesce.c | 317 |
1 files changed, 111 insertions, 206 deletions
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c index 5cc0aca..e4f576f 100644 --- a/gcc/tree-ssa-coalesce.c +++ b/gcc/tree-ssa-coalesce.c @@ -879,7 +879,7 @@ build_ssa_conflict_graph (tree_live_info_p liveinfo) live = new_live_track (map); - FOR_EACH_BB_FN (bb, cfun) + for (unsigned i = 0; liveinfo->map->vec_bbs.iterate (i, &bb); ++i) { /* Start with live on exit temporaries. */ live_track_init (live, live_on_exit (liveinfo, bb)); @@ -944,6 +944,8 @@ build_ssa_conflict_graph (tree_live_info_p liveinfo) { gphi *phi = gsi.phi (); tree result = PHI_RESULT (phi); + if (virtual_operand_p (result)) + continue; if (live_track_live_p (live, result)) live_track_process_def (live, result, graph); } @@ -1012,48 +1014,9 @@ fail_abnormal_edge_coalesce (int x, int y) internal_error ("SSA corruption"); } -/* 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); -} - -/* 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); -} - -/* Register VAR's default def in MAP. */ - -static void -register_default_def (tree var, void *arg ATTRIBUTE_UNUSED) -{ - if (!is_gimple_reg (var)) - return; - - tree ssa = ssa_default_def (cfun, var); - gcc_assert (ssa); -} - /* If VAR is an SSA_NAME associated with a PARM_DECL or a RESULT_DECL, and the DECL's default def is unused (i.e., it was introduced by - create_default_def), mark VAR and the default def for + create_default_def for out-of-ssa), mark VAR and the default def for coalescing. */ static void @@ -1070,32 +1033,25 @@ coalesce_with_default (tree var, coalesce_list *cl, bitmap used_in_copy) add_cost_one_coalesce (cl, SSA_NAME_VERSION (ssa), SSA_NAME_VERSION (var)); bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (var)); - /* Default defs will have their used_in_copy bits set at the end of - create_outofssa_var_map. */ + /* Default defs will have their used_in_copy bits set at the beginning of + populate_coalesce_list_for_outofssa. */ } -/* This function creates a var_map for the current function as well as creating - a coalesce list for use later in the out of ssa process. */ -static var_map -create_outofssa_var_map (coalesce_list *cl, bitmap used_in_copy) +/* Given var_map MAP for a region, this function creates and returns a coalesce + list as well as recording related ssa names in USED_IN_COPIES for use later + in the out-of-ssa or live range computation process. */ + +static coalesce_list * +create_coalesce_list_for_region (var_map map, bitmap used_in_copy) { gimple_stmt_iterator gsi; basic_block bb; - tree var; + coalesce_list *cl = create_coalesce_list (); gimple *stmt; - tree first; - var_map map; int v1, v2, cost; - unsigned i; - - for_all_parms (create_default_def, NULL); - - map = init_var_map (num_ssa_names); - - for_all_parms (register_default_def, NULL); - FOR_EACH_BB_FN (bb, cfun) + for (unsigned j = 0; map->vec_bbs.iterate (j, &bb); ++j) { tree arg; @@ -1110,6 +1066,8 @@ create_outofssa_var_map (coalesce_list *cl, bitmap used_in_copy) bool saw_copy = false; res = gimple_phi_result (phi); + if (virtual_operand_p (res)) + continue; ver = SSA_NAME_VERSION (res); /* Register ssa_names and coalesces between the args and the result @@ -1249,8 +1207,44 @@ create_outofssa_var_map (coalesce_list *cl, bitmap used_in_copy) } } - /* Now process result decls and live on entry variables for entry into - the coalesce list. */ + return cl; +} + + +/* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */ + +struct ssa_name_var_hash : nofree_ptr_hash <tree_node> +{ + static inline hashval_t hash (const tree_node *); + static inline int equal (const tree_node *, const tree_node *); +}; + +inline hashval_t +ssa_name_var_hash::hash (const_tree n) +{ + return DECL_UID (SSA_NAME_VAR (n)); +} + +inline int +ssa_name_var_hash::equal (const tree_node *n1, const tree_node *n2) +{ + return SSA_NAME_VAR (n1) == SSA_NAME_VAR (n2); +} + + +/* This function populates coalesce list CL as well as recording related ssa + names in USED_IN_COPIES for use later in the out-of-ssa process. */ + +static void +populate_coalesce_list_for_outofssa (coalesce_list *cl, bitmap used_in_copy) +{ + tree var; + tree first; + int v1, v2, cost; + unsigned i; + + /* Process result decls and live on entry variables for entry into the + coalesce list. */ first = NULL_TREE; FOR_EACH_SSA_NAME (i, var, cfun) { @@ -1285,7 +1279,46 @@ create_outofssa_var_map (coalesce_list *cl, bitmap used_in_copy) } } - return map; + /* If this optimization is disabled, we need to coalesce all the + names originating from the same SSA_NAME_VAR so debug info + remains undisturbed. */ + if (!flag_tree_coalesce_vars) + { + tree a; + hash_table<ssa_name_var_hash> ssa_name_hash (10); + + FOR_EACH_SSA_NAME (i, a, cfun) + { + if (SSA_NAME_VAR (a) + && !DECL_IGNORED_P (SSA_NAME_VAR (a)) + && (!has_zero_uses (a) || !SSA_NAME_IS_DEFAULT_DEF (a) + || !VAR_P (SSA_NAME_VAR (a)))) + { + tree *slot = ssa_name_hash.find_slot (a, INSERT); + + if (!*slot) + *slot = a; + else + { + /* If the variable is a PARM_DECL or a RESULT_DECL, we + _require_ that all the names originating from it be + coalesced, because there must be a single partition + containing all the names so that it can be assigned + the canonical RTL location of the DECL safely. + If in_lto_p, a function could have been compiled + originally with optimizations and only the link + performed at -O0, so we can't actually require it. */ + const int cost + = (TREE_CODE (SSA_NAME_VAR (a)) == VAR_DECL || in_lto_p) + ? MUST_COALESCE_COST - 1 : MUST_COALESCE_COST; + add_coalesce (cl, SSA_NAME_VERSION (a), + SSA_NAME_VERSION (*slot), cost); + bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (a)); + bitmap_set_bit (used_in_copy, SSA_NAME_VERSION (*slot)); + } + } + } + } } @@ -1384,13 +1417,15 @@ coalesce_partitions (var_map map, ssa_conflicts *graph, coalesce_list *cl, gsi_next (&gsi)) { gphi *phi = gsi.phi (); + tree res = PHI_RESULT (phi); + if (virtual_operand_p (res)) + continue; tree arg = PHI_ARG_DEF (phi, e->dest_idx); if (SSA_NAME_IS_DEFAULT_DEF (arg) && (!SSA_NAME_VAR (arg) || TREE_CODE (SSA_NAME_VAR (arg)) != PARM_DECL)) continue; - tree res = PHI_RESULT (phi); int v1 = SSA_NAME_VERSION (res); int v2 = SSA_NAME_VERSION (arg); @@ -1420,27 +1455,6 @@ coalesce_partitions (var_map map, ssa_conflicts *graph, coalesce_list *cl, } -/* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */ - -struct ssa_name_var_hash : nofree_ptr_hash <tree_node> -{ - static inline hashval_t hash (const tree_node *); - static inline int equal (const tree_node *, const tree_node *); -}; - -inline hashval_t -ssa_name_var_hash::hash (const_tree n) -{ - return DECL_UID (SSA_NAME_VAR (n)); -} - -inline int -ssa_name_var_hash::equal (const tree_node *n1, const tree_node *n2) -{ - return SSA_NAME_VAR (n1) == SSA_NAME_VAR (n2); -} - - /* Output partition map MAP with coalescing plan PART to file F. */ void @@ -1629,8 +1643,9 @@ compute_optimized_partition_bases (var_map map, bitmap used_in_copies, /* And also with abnormal edges. */ basic_block bb; edge e; + unsigned i; edge_iterator ei; - FOR_EACH_BB_FN (bb, cfun) + for (i = 0; map->vec_bbs.iterate (i, &bb); ++i) { FOR_EACH_EDGE (e, ei, bb->preds) if (e->flags & EDGE_ABNORMAL) @@ -1640,14 +1655,15 @@ compute_optimized_partition_bases (var_map map, bitmap used_in_copies, gsi_next (&gsi)) { gphi *phi = gsi.phi (); + tree res = PHI_RESULT (phi); + if (virtual_operand_p (res)) + continue; tree arg = PHI_ARG_DEF (phi, e->dest_idx); if (SSA_NAME_IS_DEFAULT_DEF (arg) && (!SSA_NAME_VAR (arg) || TREE_CODE (SSA_NAME_VAR (arg)) != PARM_DECL)) continue; - tree res = PHI_RESULT (phi); - int p1 = partition_find (tentative, var_to_partition (map, res)); int p2 = partition_find (tentative, var_to_partition (map, arg)); @@ -1675,7 +1691,6 @@ compute_optimized_partition_bases (var_map map, bitmap used_in_copies, between all SSA versions that ended up in the same potential coalesce partition. */ bitmap_iterator bi; - unsigned i; EXECUTE_IF_SET_IN_BITMAP (used_in_copies, 0, i, bi) { int pidx = var_to_partition (map, ssa_name (i)); @@ -1784,62 +1799,22 @@ compute_samebase_partition_bases (var_map map) free (mapstorage); } -/* Reduce the number of copies by coalescing variables in the function. Return - a partition map with the resulting coalesces. */ +/* Given an initial var_map MAP, coalesce variables and return a partition map + with the resulting coalesce. Note that this function is called in either + live range computation context or out-of-ssa context, indicated by MAP. */ -extern var_map -coalesce_ssa_name (void) +extern void +coalesce_ssa_name (var_map map) { tree_live_info_p liveinfo; ssa_conflicts *graph; coalesce_list *cl; auto_bitmap used_in_copies; - var_map map; - unsigned int i; - tree a; - cl = create_coalesce_list (); - map = create_outofssa_var_map (cl, used_in_copies); + cl = create_coalesce_list_for_region (map, used_in_copies); + if (map->outofssa_p) + populate_coalesce_list_for_outofssa (cl, used_in_copies); - /* If this optimization is disabled, we need to coalesce all the - names originating from the same SSA_NAME_VAR so debug info - remains undisturbed. */ - if (!flag_tree_coalesce_vars) - { - hash_table<ssa_name_var_hash> ssa_name_hash (10); - - FOR_EACH_SSA_NAME (i, a, cfun) - { - if (SSA_NAME_VAR (a) - && !DECL_IGNORED_P (SSA_NAME_VAR (a)) - && (!has_zero_uses (a) || !SSA_NAME_IS_DEFAULT_DEF (a) - || !VAR_P (SSA_NAME_VAR (a)))) - { - tree *slot = ssa_name_hash.find_slot (a, INSERT); - - if (!*slot) - *slot = a; - else - { - /* If the variable is a PARM_DECL or a RESULT_DECL, we - _require_ that all the names originating from it be - coalesced, because there must be a single partition - containing all the names so that it can be assigned - the canonical RTL location of the DECL safely. - If in_lto_p, a function could have been compiled - originally with optimizations and only the link - performed at -O0, so we can't actually require it. */ - const int cost - = (TREE_CODE (SSA_NAME_VAR (a)) == VAR_DECL || in_lto_p) - ? MUST_COALESCE_COST - 1 : MUST_COALESCE_COST; - add_coalesce (cl, SSA_NAME_VERSION (a), - SSA_NAME_VERSION (*slot), cost); - bitmap_set_bit (used_in_copies, SSA_NAME_VERSION (a)); - bitmap_set_bit (used_in_copies, SSA_NAME_VERSION (*slot)); - } - } - } - } if (dump_file && (dump_flags & TDF_DETAILS)) dump_var_map (dump_file, map); @@ -1853,7 +1828,7 @@ coalesce_ssa_name (void) if (num_var_partitions (map) < 1) { delete_coalesce_list (cl); - return map; + return; } if (dump_file && (dump_flags & TDF_DETAILS)) @@ -1890,75 +1865,5 @@ coalesce_ssa_name (void) delete_coalesce_list (cl); ssa_conflicts_delete (graph); - - return map; } -/* 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. */ - -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. */ - -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; -} |