[multiple changes]
2005-04-22 Diego Novillo <dnovillo@redhat.com> * Makefile.in (tree-into-ssa.o): Add dependency on PARAMS_H. * lambda-code.c (perfect_nestify): Mark virtual operands in the moved statement for renaming. * params.def (PARAM_MIN_VIRTUAL_MAPPINGS): Define. (PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO): Define. * params.h (MIN_VIRTUAL_MAPPINGS): Define. (VIRTUAL_MAPPINGS_TO_SYMS_RATIO): Define. * tree-flow.h (struct var_ann_d): Update comments. (rewrite_to_new_ssa_names_bb, rewrite_to_new_ssa_names, allocate_ssa_names, find_phi_node_for, dump_tree_ssa, debug_tree_ssa, debug_def_blocks, dump_tree_ssa_stats, debug_tree_ssa_stats, rewrite_ssa_into_ssa, dump_repl_tbl, debug_repl_tbl, dump_names_replaced_by, debug_names_replaced_by): Remove declarations. (delete_update_ssa, get_current_def, set_current_def): Declare. (rewrite_into_loop_closed_ssa): Add new argument. Update all callers. * tree-into-ssa.c: Include params.h. (old_virtual_ssa_names): Remove. Update all users. (need_to_replace_names_p): Remove. Update all users. (struct update_ssa_stats_d): Declare. (update_ssa_stats): New local. (dump_tree_ssa, debug_tree_ssa, debug_def_blocks, dump_tree_ssa_stats, debug_tree_ssa_stats, dump_update_ssa, debug_update_ssa, dump_names_replaced_by, debug_names_replaced_by): Declare. (get_current_def, set current_def): Make extern. (is_old_name, is_new_name): Protect against references past the end of the sets. (add_new_name_mapping): Assert that OLD and NEW are different SSA names for the same symbol. When adding a virtual mapping, update stats for virtual mapping heuristic. (insert_phi_nodes_for): If UPDATE_P is true, create the LHS of the new PHI by duplicating SSA name VAR. (insert_phi_nodes_1): Remove. Update all users. (insert_phi_nodes): Remove second argument. Update all users. (maybe_replace_use, maybe_replace_def): New. (rewrite_update_stmt): Call them. (mark_def_interesting): Remove calls to is_gimple_reg. (prepare_phi_args_for_update): Remove. Update all users. (prepare_block_for_update): Only process virtual operands and GIMPLE registers in normal form. (prepare_use_sites_for): New. (prepare_names_to_update): Rename from prepare_def_sites. Call prepare_use_sites_for. (dump_update_ssa): Rename from dump_repl_tbl. Update all users. Show statistics for virtual mapping heuristic. (debug_update_ssa): Rename from debug_debug_repl_tbl. (init_update_ssa): Initialize UPDATE_SSA_STATS. (delete_update_ssa): Make extern. (mark_set_for_renaming): If the set is empty, do nothing. (release_ssa_name_after_update_ssa): Update comment. (insert_updated_phi_nodes_for): Do not remove existing PHI nodes for symbols. (switch_virtuals_to_full_rewrite_p): New. (switch_virtuals_to_full_rewrite): New. (update_ssa): Call them. Clear REWRITE_THIS_STMT and REGISTER_DEFS_IN_THIS_STMT for every statement before updating. If all the names in NEW_SSA_NAMES have been marked for removal, do nothing. Only start at the top of the CFG if there are symbols in SYMS_TO_RENAME. (ssa_rewrite_finalize_block): Remove. (ssa_register_new_def): Remove. (ssa_rewrite_stmt): Remove. (ssa_rewrite_phi_arguments): Remove. (ssa_rewrite_initialize_block): Remove. (ssa_mark_def_sites): Remove. (ssa_mark_def_sites_initialize_block): Remove. (ssa_mark_phi_uses): Remove. (rewrite_ssa_into_ssa): Remove. * tree-phinodes.c (find_phi_node_for): Remove. * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely): Call update_ssa. * tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops): Remove calls to verify_dominators and verify_loop_structure. (tree_unswitch_single_loop): Call update_ssa. * tree-ssa.c (verify_ssa): Assert that need_ssa_update_p returns false. Call verify_stmts. (delete_tree_ssa): Assert that need_ssa_update_p returns false. * tree-vect-transform.c (vect_transform_loop): Call update_ssa. * tree-vectorizer.c (allocate_new_names, rename_def_op, free_new_names): Remove. Update all users. (rename_use_op): Call get_current_def. (rename_variables_in_bb): Do not handle any real or virtual definition. (slpeel_update_phis_for_duplicate_loop): Call get_current_def and set_current_def instead of using SSA_NAME_AUX. (slpeel_update_phi_nodes_for_guard2): Reformat comments. (slpeel_can_duplicate_loop_p): Call need_ssa_update_p, ssa_names_to_replace and delete_update_ssa. * doc/invoke.texi: Document --param min-virtual-mappings and --param virtual-mappings-ratio. 2005-04-22 Zdenek Dvorak <dvorakz@suse.cz> Diego Novillo <dnovillo@redhat.com> * tree-cfg.c (tree_duplicate_bb): Call create_new_def_for for newly created PHI nodes. Call create_new_def_for for every new V_MAY_DEF and V_MUST_DEF on the copied statement. (struct ssa_name_map_entry): Remove. (ssa_name_map_entry_hash): Remove. (ssa_name_map_entry_eq): Remove. (allocate_ssa_names): Remove. (rewrite_to_new_ssa_names_def): Remove. (rewrite_to_new_ssa_names_use): Remove. (rewrite_to_new_ssa_names_bb): Remove. (rewrite_to_new_ssa_names): Remove. (tree_duplicate_sese_region): Remove variables ver, definitions, phi, ssa_name_map and bi. Call need_ssa_update_p instead of any_marked_for_rewrite_p. Call update_ssa. * tree-ssa-dom.c (tree_ssa_dominator_optimize): Call update_ssa instead of rewrite_ssa_into_ssa. * tree-ssa-loop-manip.c (add_exit_phis_edge): Call create_new_def_for. (find_uses_to_rename_use): Add argument 'need_phis'. (find_uses_to_rename_stmt): Do not scan virtual operands. (find_uses_to_rename): Only scan PHI nodes for non-virtual names. (rewrite_into_loop_closed_ssa): Call update_ssa. (check_loop_closed_ssa_use): Ignore virtual operands. (check_loop_closed_ssa_stmt): Likewise. (verify_loop_closed_ssa): Do nothing if CURRENT_LOOPS is NULL. (rename_variables, set_phi_def_stmts): Remove. (tree_duplicate_loop_to_header_edge): Reformat comment. Remove variables BB, I and DEFINITIONS. Call need_ssa_update_p. Call update_ssa. (lv_adjust_loop_header_phi): Reformat comment. * tree-ssanames.c (ssa_names_to_rewrite): Remove. (marked_for_rewrite_p, any_marked_for_rewrite_p, mark_for_rewrite, unmark_all_for_rewrite, marked_ssa_names): Remove. Update all users. (release_ssa_name): If VAR has been registered for SSA updating, do nothing. * tree-vrp.c (new_ssa_names, old_ssa_names): Remove. (build_assert_expr_for): Call register_new_name_mapping. (insert_range_assertions): Update call to update_ssa. * tree.h (mark_for_rewrite, unmark_all_for_rewrite, marked_for_rewrite_p, any_marked_for_rewrite_p, marked_ssa_names): Remove. From-SVN: r98599
This commit is contained in:
parent
be240c882f
commit
84d658141e
155
gcc/ChangeLog
155
gcc/ChangeLog
|
@ -1,3 +1,158 @@
|
|||
2005-04-22 Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
* Makefile.in (tree-into-ssa.o): Add dependency on PARAMS_H.
|
||||
* lambda-code.c (perfect_nestify): Mark virtual operands in
|
||||
the moved statement for renaming.
|
||||
* params.def (PARAM_MIN_VIRTUAL_MAPPINGS): Define.
|
||||
(PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO): Define.
|
||||
* params.h (MIN_VIRTUAL_MAPPINGS): Define.
|
||||
(VIRTUAL_MAPPINGS_TO_SYMS_RATIO): Define.
|
||||
* tree-flow.h (struct var_ann_d): Update comments.
|
||||
(rewrite_to_new_ssa_names_bb, rewrite_to_new_ssa_names,
|
||||
allocate_ssa_names, find_phi_node_for, dump_tree_ssa,
|
||||
debug_tree_ssa, debug_def_blocks, dump_tree_ssa_stats,
|
||||
debug_tree_ssa_stats, rewrite_ssa_into_ssa,
|
||||
dump_repl_tbl, debug_repl_tbl, dump_names_replaced_by,
|
||||
debug_names_replaced_by): Remove declarations.
|
||||
(delete_update_ssa, get_current_def, set_current_def): Declare.
|
||||
(rewrite_into_loop_closed_ssa): Add new argument. Update
|
||||
all callers.
|
||||
* tree-into-ssa.c: Include params.h.
|
||||
(old_virtual_ssa_names): Remove. Update all users.
|
||||
(need_to_replace_names_p): Remove. Update all users.
|
||||
(struct update_ssa_stats_d): Declare.
|
||||
(update_ssa_stats): New local.
|
||||
(dump_tree_ssa, debug_tree_ssa, debug_def_blocks,
|
||||
dump_tree_ssa_stats, debug_tree_ssa_stats,
|
||||
dump_update_ssa, debug_update_ssa,
|
||||
dump_names_replaced_by, debug_names_replaced_by): Declare.
|
||||
(get_current_def, set current_def): Make extern.
|
||||
(is_old_name, is_new_name): Protect against references
|
||||
past the end of the sets.
|
||||
(add_new_name_mapping): Assert that OLD and NEW are
|
||||
different SSA names for the same symbol.
|
||||
When adding a virtual mapping, update stats for virtual
|
||||
mapping heuristic.
|
||||
(insert_phi_nodes_for): If UPDATE_P is true, create the
|
||||
LHS of the new PHI by duplicating SSA name VAR.
|
||||
(insert_phi_nodes_1): Remove. Update all users.
|
||||
(insert_phi_nodes): Remove second argument. Update all
|
||||
users.
|
||||
(maybe_replace_use, maybe_replace_def): New.
|
||||
(rewrite_update_stmt): Call them.
|
||||
(mark_def_interesting): Remove calls to is_gimple_reg.
|
||||
(prepare_phi_args_for_update): Remove. Update all users.
|
||||
(prepare_block_for_update): Only process virtual operands
|
||||
and GIMPLE registers in normal form.
|
||||
(prepare_use_sites_for): New.
|
||||
(prepare_names_to_update): Rename from prepare_def_sites.
|
||||
Call prepare_use_sites_for.
|
||||
(dump_update_ssa): Rename from dump_repl_tbl.
|
||||
Update all users.
|
||||
Show statistics for virtual mapping heuristic.
|
||||
(debug_update_ssa): Rename from debug_debug_repl_tbl.
|
||||
(init_update_ssa): Initialize UPDATE_SSA_STATS.
|
||||
(delete_update_ssa): Make extern.
|
||||
(mark_set_for_renaming): If the set is empty, do nothing.
|
||||
(release_ssa_name_after_update_ssa): Update comment.
|
||||
(insert_updated_phi_nodes_for): Do not remove existing
|
||||
PHI nodes for symbols.
|
||||
(switch_virtuals_to_full_rewrite_p): New.
|
||||
(switch_virtuals_to_full_rewrite): New.
|
||||
(update_ssa): Call them.
|
||||
Clear REWRITE_THIS_STMT and REGISTER_DEFS_IN_THIS_STMT
|
||||
for every statement before updating.
|
||||
If all the names in NEW_SSA_NAMES have been marked for
|
||||
removal, do nothing.
|
||||
Only start at the top of the CFG if there are symbols in
|
||||
SYMS_TO_RENAME.
|
||||
(ssa_rewrite_finalize_block): Remove.
|
||||
(ssa_register_new_def): Remove.
|
||||
(ssa_rewrite_stmt): Remove.
|
||||
(ssa_rewrite_phi_arguments): Remove.
|
||||
(ssa_rewrite_initialize_block): Remove.
|
||||
(ssa_mark_def_sites): Remove.
|
||||
(ssa_mark_def_sites_initialize_block): Remove.
|
||||
(ssa_mark_phi_uses): Remove.
|
||||
(rewrite_ssa_into_ssa): Remove.
|
||||
* tree-phinodes.c (find_phi_node_for): Remove.
|
||||
* tree-ssa-loop-ivcanon.c (try_unroll_loop_completely):
|
||||
Call update_ssa.
|
||||
* tree-ssa-loop-unswitch.c (tree_ssa_unswitch_loops):
|
||||
Remove calls to verify_dominators and
|
||||
verify_loop_structure.
|
||||
(tree_unswitch_single_loop): Call update_ssa.
|
||||
* tree-ssa.c (verify_ssa): Assert that need_ssa_update_p
|
||||
returns false.
|
||||
Call verify_stmts.
|
||||
(delete_tree_ssa): Assert that need_ssa_update_p returns
|
||||
false.
|
||||
* tree-vect-transform.c (vect_transform_loop): Call update_ssa.
|
||||
* tree-vectorizer.c (allocate_new_names, rename_def_op,
|
||||
free_new_names): Remove. Update all users.
|
||||
(rename_use_op): Call get_current_def.
|
||||
(rename_variables_in_bb): Do not handle any real or
|
||||
virtual definition.
|
||||
(slpeel_update_phis_for_duplicate_loop): Call
|
||||
get_current_def and set_current_def instead of using
|
||||
SSA_NAME_AUX.
|
||||
(slpeel_update_phi_nodes_for_guard2): Reformat comments.
|
||||
(slpeel_can_duplicate_loop_p): Call need_ssa_update_p,
|
||||
ssa_names_to_replace and delete_update_ssa.
|
||||
* doc/invoke.texi: Document --param min-virtual-mappings
|
||||
and --param virtual-mappings-ratio.
|
||||
|
||||
2005-04-22 Zdenek Dvorak <dvorakz@suse.cz>
|
||||
Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
* tree-cfg.c (tree_duplicate_bb): Call create_new_def_for
|
||||
for newly created PHI nodes.
|
||||
Call create_new_def_for for every new V_MAY_DEF and
|
||||
V_MUST_DEF on the copied statement.
|
||||
(struct ssa_name_map_entry): Remove.
|
||||
(ssa_name_map_entry_hash): Remove.
|
||||
(ssa_name_map_entry_eq): Remove.
|
||||
(allocate_ssa_names): Remove.
|
||||
(rewrite_to_new_ssa_names_def): Remove.
|
||||
(rewrite_to_new_ssa_names_use): Remove.
|
||||
(rewrite_to_new_ssa_names_bb): Remove.
|
||||
(rewrite_to_new_ssa_names): Remove.
|
||||
(tree_duplicate_sese_region): Remove variables ver,
|
||||
definitions, phi, ssa_name_map and bi.
|
||||
Call need_ssa_update_p instead of any_marked_for_rewrite_p.
|
||||
Call update_ssa.
|
||||
* tree-ssa-dom.c (tree_ssa_dominator_optimize): Call
|
||||
update_ssa instead of rewrite_ssa_into_ssa.
|
||||
* tree-ssa-loop-manip.c (add_exit_phis_edge): Call
|
||||
create_new_def_for.
|
||||
(find_uses_to_rename_use): Add argument 'need_phis'.
|
||||
(find_uses_to_rename_stmt): Do not scan virtual operands.
|
||||
(find_uses_to_rename): Only scan PHI nodes for
|
||||
non-virtual names.
|
||||
(rewrite_into_loop_closed_ssa): Call update_ssa.
|
||||
(check_loop_closed_ssa_use): Ignore virtual operands.
|
||||
(check_loop_closed_ssa_stmt): Likewise.
|
||||
(verify_loop_closed_ssa): Do nothing if CURRENT_LOOPS is
|
||||
NULL.
|
||||
(rename_variables, set_phi_def_stmts): Remove.
|
||||
(tree_duplicate_loop_to_header_edge): Reformat comment.
|
||||
Remove variables BB, I and DEFINITIONS.
|
||||
Call need_ssa_update_p.
|
||||
Call update_ssa.
|
||||
(lv_adjust_loop_header_phi): Reformat comment.
|
||||
* tree-ssanames.c (ssa_names_to_rewrite): Remove.
|
||||
(marked_for_rewrite_p, any_marked_for_rewrite_p,
|
||||
mark_for_rewrite, unmark_all_for_rewrite,
|
||||
marked_ssa_names): Remove. Update all users.
|
||||
(release_ssa_name): If VAR has been registered for SSA
|
||||
updating, do nothing.
|
||||
* tree-vrp.c (new_ssa_names, old_ssa_names): Remove.
|
||||
(build_assert_expr_for): Call register_new_name_mapping.
|
||||
(insert_range_assertions): Update call to update_ssa.
|
||||
* tree.h (mark_for_rewrite, unmark_all_for_rewrite,
|
||||
marked_for_rewrite_p, any_marked_for_rewrite_p,
|
||||
marked_ssa_names): Remove.
|
||||
|
||||
2005-04-22 Jeff Law <law@redhat.com>
|
||||
|
||||
* tree-ssa-dom.c (block_defs_stack): Remove, no longer needed.
|
||||
|
|
|
@ -1635,7 +1635,7 @@ tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
|||
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h diagnostic.h \
|
||||
errors.h toplev.h function.h $(TIMEVAR_H) \
|
||||
$(TM_H) coretypes.h $(TREE_DUMP_H) langhooks.h domwalk.h tree-pass.h \
|
||||
$(GGC_H)
|
||||
$(GGC_H) $(PARAMS_H)
|
||||
tree-outof-ssa.o : tree-outof-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
|
||||
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) output.h diagnostic.h \
|
||||
errors.h toplev.h function.h $(TIMEVAR_H) \
|
||||
|
|
|
@ -5827,6 +5827,18 @@ Small integer constants can use a shared data structure, reducing the
|
|||
compiler's memory usage and increasing its speed. This sets the maximum
|
||||
value of a shared integer constant's. The default value is 256.
|
||||
|
||||
@item min-virtual-mappings
|
||||
Specifies the minimum number of virtual mappings in the incremental
|
||||
SSA updater that should be registered to trigger the virtual mappings
|
||||
heuristic defined by virtual-mappings-ratio. The default value is
|
||||
100.
|
||||
|
||||
@item virtual-mappings-ratio
|
||||
If the number of virtual mappings is virtual-mappings-ratio bigger
|
||||
than the number of virtual symbols to be updated, then the incremental
|
||||
SSA updater switches to a full update for those symbols. The default
|
||||
ratio is 3.
|
||||
|
||||
@end table
|
||||
@end table
|
||||
|
||||
|
|
|
@ -2443,7 +2443,9 @@ perfect_nestify (struct loops *loops,
|
|||
incremented when we do. */
|
||||
for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi);)
|
||||
{
|
||||
tree stmt = bsi_stmt (bsi);
|
||||
ssa_op_iter i;
|
||||
tree n, stmt = bsi_stmt (bsi);
|
||||
|
||||
if (stmt == exit_condition
|
||||
|| not_interesting_stmt (stmt)
|
||||
|| stmt_is_bumper_for_loop (loop, stmt))
|
||||
|
@ -2451,11 +2453,19 @@ perfect_nestify (struct loops *loops,
|
|||
bsi_next (&bsi);
|
||||
continue;
|
||||
}
|
||||
|
||||
replace_uses_of_x_with_y (stmt, oldivvar, ivvar);
|
||||
bsi_move_before (&bsi, &tobsi);
|
||||
|
||||
/* If the statement has any virtual operands, they may
|
||||
need to be rewired because the original loop may
|
||||
still reference them. */
|
||||
FOR_EACH_SSA_TREE_OPERAND (n, stmt, i, SSA_OP_ALL_VIRTUALS)
|
||||
mark_sym_for_renaming (SSA_NAME_VAR (n));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free (bbs);
|
||||
return perfect_nest_p (loop);
|
||||
}
|
||||
|
|
|
@ -443,6 +443,30 @@ DEFPARAM (PARAM_INTEGER_SHARE_LIMIT,
|
|||
"The upper bound for sharing integer constants",
|
||||
256, 2, 2)
|
||||
|
||||
/* Incremental SSA updates for virtual operands may be very slow if
|
||||
there is a large number of mappings to process. In those cases, it
|
||||
is faster to rewrite the virtual symbols from scratch as if they
|
||||
had been recently introduced. This heuristic cannot be applied to
|
||||
SSA mappings for real SSA names, only symbols kept in FUD chains.
|
||||
|
||||
PARAM_MIN_VIRTUAL_MAPPINGS specifies the minimum number of virtual
|
||||
mappings that should be registered to trigger the heuristic.
|
||||
|
||||
PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO specifies the ratio between
|
||||
mappings and symbols. If the number of virtual mappings is
|
||||
PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO bigger than the number of
|
||||
virtual symbols to be updated, then the updater switches to a full
|
||||
update for those symbols. */
|
||||
DEFPARAM (PARAM_MIN_VIRTUAL_MAPPINGS,
|
||||
"min-virtual-mappings",
|
||||
"Minimum number of virtual mappings to consider switching to full virtual renames",
|
||||
100, 0, 0)
|
||||
|
||||
DEFPARAM (PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO,
|
||||
"virtual-mappings-ratio",
|
||||
"Ratio between virtual mappings and virtual symbols to do full virtual renames",
|
||||
3, 0, 0)
|
||||
|
||||
/*
|
||||
Local variables:
|
||||
mode:c
|
||||
|
|
|
@ -139,4 +139,8 @@ typedef enum compiler_param
|
|||
PARAM_VALUE (PARAM_INTEGER_SHARE_LIMIT)
|
||||
#define MAX_LAST_VALUE_RTL \
|
||||
PARAM_VALUE (PARAM_MAX_LAST_VALUE_RTL)
|
||||
#define MIN_VIRTUAL_MAPPINGS \
|
||||
PARAM_VALUE (PARAM_MIN_VIRTUAL_MAPPINGS)
|
||||
#define VIRTUAL_MAPPINGS_TO_SYMS_RATIO \
|
||||
PARAM_VALUE (PARAM_VIRTUAL_MAPPINGS_TO_SYMS_RATIO)
|
||||
#endif /* ! GCC_PARAMS_H */
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
2005-04-22 Diego Novillo <dnovillo@redhat.com>
|
||||
|
||||
* gcc.dg/tree-ssa/ltrans-4.c: Fix typo in dg-options.
|
||||
|
||||
2005-04-22 Jeff Law <law@redhat.com>
|
||||
|
||||
* gcc.dg/uninit-5.c: Remove xfails.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-O20 -ftree-loop-linear -fdump-tree-ltrans-all" } */
|
||||
/* { dg-options "-O2 -ftree-loop-linear -fdump-tree-ltrans-all" } */
|
||||
|
||||
double u[1782225];
|
||||
int foo(int N, int *res)
|
||||
|
|
276
gcc/tree-cfg.c
276
gcc/tree-cfg.c
|
@ -963,7 +963,7 @@ cleanup_tree_cfg_loop (void)
|
|||
/* This usually does nothing. But sometimes parts of cfg that originally
|
||||
were inside a loop get out of it due to edge removal (since they
|
||||
become unreachable by back edges from latch). */
|
||||
rewrite_into_loop_closed_ssa (changed_bbs);
|
||||
rewrite_into_loop_closed_ssa (changed_bbs, TODO_update_ssa);
|
||||
|
||||
BITMAP_FREE (changed_bbs);
|
||||
|
||||
|
@ -4698,6 +4698,7 @@ tree_can_duplicate_bb_p (basic_block bb ATTRIBUTE_UNUSED)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Create a duplicate of the basic block BB. NOTE: This does not
|
||||
preserve SSA form. */
|
||||
|
||||
|
@ -4706,45 +4707,49 @@ tree_duplicate_bb (basic_block bb)
|
|||
{
|
||||
basic_block new_bb;
|
||||
block_stmt_iterator bsi, bsi_tgt;
|
||||
tree phi, val;
|
||||
ssa_op_iter op_iter;
|
||||
tree phi;
|
||||
|
||||
new_bb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
|
||||
|
||||
/* First copy the phi nodes. We do not copy phi node arguments here,
|
||||
since the edges are not ready yet. Keep the chain of phi nodes in
|
||||
the same order, so that we can add them later. */
|
||||
/* Copy the PHI nodes. We ignore PHI node arguments here because
|
||||
the incoming edges have not been setup yet. */
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
{
|
||||
mark_for_rewrite (PHI_RESULT (phi));
|
||||
create_phi_node (PHI_RESULT (phi), new_bb);
|
||||
tree copy = create_phi_node (PHI_RESULT (phi), new_bb);
|
||||
create_new_def_for (PHI_RESULT (copy), copy, PHI_RESULT_PTR (copy));
|
||||
}
|
||||
|
||||
/* Keep the chain of PHI nodes in the same order so that they can be
|
||||
updated by ssa_redirect_edge. */
|
||||
set_phi_nodes (new_bb, phi_reverse (phi_nodes (new_bb)));
|
||||
|
||||
bsi_tgt = bsi_start (new_bb);
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
tree stmt = bsi_stmt (bsi);
|
||||
tree copy;
|
||||
def_operand_p def_p;
|
||||
ssa_op_iter op_iter;
|
||||
tree stmt, copy;
|
||||
|
||||
stmt = bsi_stmt (bsi);
|
||||
if (TREE_CODE (stmt) == LABEL_EXPR)
|
||||
continue;
|
||||
|
||||
FOR_EACH_SSA_TREE_OPERAND (val, stmt, op_iter, SSA_OP_ALL_DEFS)
|
||||
mark_for_rewrite (val);
|
||||
|
||||
/* Create a new copy of STMT and duplicate STMT's virtual
|
||||
operands. */
|
||||
copy = unshare_expr (stmt);
|
||||
|
||||
/* Copy also the virtual operands. */
|
||||
get_stmt_ann (copy);
|
||||
copy_virtual_operands (copy, stmt);
|
||||
|
||||
bsi_insert_after (&bsi_tgt, copy, BSI_NEW_STMT);
|
||||
copy_virtual_operands (copy, stmt);
|
||||
|
||||
/* Create new names for all the definitions created by COPY and
|
||||
add replacement mappings for each new name. */
|
||||
FOR_EACH_SSA_DEF_OPERAND (def_p, copy, op_iter, SSA_OP_ALL_DEFS)
|
||||
create_new_def_for (DEF_FROM_PTR (def_p), copy, def_p);
|
||||
}
|
||||
|
||||
return new_bb;
|
||||
}
|
||||
|
||||
|
||||
/* Basic block BB_COPY was created by code duplication. Add phi node
|
||||
arguments for edges going out of BB_COPY. The blocks that were
|
||||
duplicated have rbi->duplicated set to one. */
|
||||
|
@ -4788,8 +4793,6 @@ add_phi_args_after_copy_bb (basic_block bb_copy)
|
|||
phi = phi_next, phi_copy = PHI_CHAIN (phi_copy))
|
||||
{
|
||||
phi_next = PHI_CHAIN (phi);
|
||||
|
||||
gcc_assert (PHI_RESULT (phi) == PHI_RESULT (phi_copy));
|
||||
def = PHI_ARG_DEF_FROM_EDGE (phi, e);
|
||||
add_phi_arg (phi_copy, def, e_copy);
|
||||
}
|
||||
|
@ -4815,193 +4818,6 @@ add_phi_args_after_copy (basic_block *region_copy, unsigned n_region)
|
|||
region_copy[i]->rbi->duplicated = 0;
|
||||
}
|
||||
|
||||
/* Maps the old ssa name FROM_NAME to TO_NAME. */
|
||||
|
||||
struct ssa_name_map_entry
|
||||
{
|
||||
tree from_name;
|
||||
tree to_name;
|
||||
};
|
||||
|
||||
/* Hash function for ssa_name_map_entry. */
|
||||
|
||||
static hashval_t
|
||||
ssa_name_map_entry_hash (const void *entry)
|
||||
{
|
||||
const struct ssa_name_map_entry *en = entry;
|
||||
return SSA_NAME_VERSION (en->from_name);
|
||||
}
|
||||
|
||||
/* Equality function for ssa_name_map_entry. */
|
||||
|
||||
static int
|
||||
ssa_name_map_entry_eq (const void *in_table, const void *ssa_name)
|
||||
{
|
||||
const struct ssa_name_map_entry *en = in_table;
|
||||
|
||||
return en->from_name == ssa_name;
|
||||
}
|
||||
|
||||
/* Allocate duplicates of ssa names in list DEFINITIONS and store the mapping
|
||||
to MAP. */
|
||||
|
||||
void
|
||||
allocate_ssa_names (bitmap definitions, htab_t *map)
|
||||
{
|
||||
tree name;
|
||||
struct ssa_name_map_entry *entry;
|
||||
PTR *slot;
|
||||
unsigned ver;
|
||||
bitmap_iterator bi;
|
||||
|
||||
if (!*map)
|
||||
*map = htab_create (10, ssa_name_map_entry_hash,
|
||||
ssa_name_map_entry_eq, free);
|
||||
EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
|
||||
{
|
||||
name = ssa_name (ver);
|
||||
slot = htab_find_slot_with_hash (*map, name, SSA_NAME_VERSION (name),
|
||||
INSERT);
|
||||
if (*slot)
|
||||
entry = *slot;
|
||||
else
|
||||
{
|
||||
entry = xmalloc (sizeof (struct ssa_name_map_entry));
|
||||
entry->from_name = name;
|
||||
*slot = entry;
|
||||
}
|
||||
entry->to_name = duplicate_ssa_name (name, SSA_NAME_DEF_STMT (name));
|
||||
}
|
||||
}
|
||||
|
||||
/* Rewrite the definition DEF in statement STMT to new ssa name as specified
|
||||
by the mapping MAP. */
|
||||
|
||||
static void
|
||||
rewrite_to_new_ssa_names_def (def_operand_p def, tree stmt, htab_t map)
|
||||
{
|
||||
tree name = DEF_FROM_PTR (def);
|
||||
struct ssa_name_map_entry *entry;
|
||||
|
||||
gcc_assert (TREE_CODE (name) == SSA_NAME);
|
||||
|
||||
entry = htab_find_with_hash (map, name, SSA_NAME_VERSION (name));
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
SET_DEF (def, entry->to_name);
|
||||
SSA_NAME_DEF_STMT (entry->to_name) = stmt;
|
||||
}
|
||||
|
||||
/* Rewrite the USE to new ssa name as specified by the mapping MAP. */
|
||||
|
||||
static void
|
||||
rewrite_to_new_ssa_names_use (use_operand_p use, htab_t map)
|
||||
{
|
||||
tree name = USE_FROM_PTR (use);
|
||||
struct ssa_name_map_entry *entry;
|
||||
|
||||
if (TREE_CODE (name) != SSA_NAME)
|
||||
return;
|
||||
|
||||
entry = htab_find_with_hash (map, name, SSA_NAME_VERSION (name));
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
SET_USE (use, entry->to_name);
|
||||
}
|
||||
|
||||
/* Rewrite the ssa names in basic block BB to new ones as specified by the
|
||||
mapping MAP. */
|
||||
|
||||
void
|
||||
rewrite_to_new_ssa_names_bb (basic_block bb, htab_t map)
|
||||
{
|
||||
unsigned i;
|
||||
edge e;
|
||||
edge_iterator ei;
|
||||
tree phi, stmt;
|
||||
block_stmt_iterator bsi;
|
||||
use_optype uses;
|
||||
vuse_optype vuses;
|
||||
def_optype defs;
|
||||
v_may_def_optype v_may_defs;
|
||||
v_must_def_optype v_must_defs;
|
||||
stmt_ann_t ann;
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->preds)
|
||||
if (e->flags & EDGE_ABNORMAL)
|
||||
break;
|
||||
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
{
|
||||
rewrite_to_new_ssa_names_def (PHI_RESULT_PTR (phi), phi, map);
|
||||
if (e)
|
||||
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (PHI_RESULT (phi)) = 1;
|
||||
}
|
||||
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
stmt = bsi_stmt (bsi);
|
||||
ann = stmt_ann (stmt);
|
||||
|
||||
uses = USE_OPS (ann);
|
||||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
rewrite_to_new_ssa_names_use (USE_OP_PTR (uses, i), map);
|
||||
|
||||
defs = DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_DEFS (defs); i++)
|
||||
rewrite_to_new_ssa_names_def (DEF_OP_PTR (defs, i), stmt, map);
|
||||
|
||||
vuses = VUSE_OPS (ann);
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
rewrite_to_new_ssa_names_use (VUSE_OP_PTR (vuses, i), map);
|
||||
|
||||
v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
|
||||
{
|
||||
rewrite_to_new_ssa_names_use
|
||||
(V_MAY_DEF_OP_PTR (v_may_defs, i), map);
|
||||
rewrite_to_new_ssa_names_def
|
||||
(V_MAY_DEF_RESULT_PTR (v_may_defs, i), stmt, map);
|
||||
}
|
||||
|
||||
v_must_defs = V_MUST_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
|
||||
{
|
||||
rewrite_to_new_ssa_names_def
|
||||
(V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt, map);
|
||||
rewrite_to_new_ssa_names_use
|
||||
(V_MUST_DEF_KILL_PTR (v_must_defs, i), map);
|
||||
}
|
||||
}
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
|
||||
{
|
||||
rewrite_to_new_ssa_names_use
|
||||
(PHI_ARG_DEF_PTR_FROM_EDGE (phi, e), map);
|
||||
|
||||
if (e->flags & EDGE_ABNORMAL)
|
||||
{
|
||||
tree op = PHI_ARG_DEF_FROM_EDGE (phi, e);
|
||||
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Rewrite the ssa names in N_REGION blocks REGION to the new ones as specified
|
||||
by the mapping MAP. */
|
||||
|
||||
void
|
||||
rewrite_to_new_ssa_names (basic_block *region, unsigned n_region, htab_t map)
|
||||
{
|
||||
unsigned r;
|
||||
|
||||
for (r = 0; r < n_region; r++)
|
||||
rewrite_to_new_ssa_names_bb (region[r], map);
|
||||
}
|
||||
|
||||
/* Duplicates a REGION (set of N_REGION basic blocks) with just a single
|
||||
important exit edge EXIT. By important we mean that no SSA name defined
|
||||
inside region is live over the other exit edges of the region. All entry
|
||||
|
@ -5017,16 +4833,12 @@ tree_duplicate_sese_region (edge entry, edge exit,
|
|||
basic_block *region, unsigned n_region,
|
||||
basic_block *region_copy)
|
||||
{
|
||||
unsigned i, n_doms, ver;
|
||||
unsigned i, n_doms;
|
||||
bool free_region_copy = false, copying_header = false;
|
||||
struct loop *loop = entry->dest->loop_father;
|
||||
edge exit_copy;
|
||||
bitmap definitions;
|
||||
tree phi;
|
||||
basic_block *doms;
|
||||
htab_t ssa_name_map = NULL;
|
||||
edge redirected;
|
||||
bitmap_iterator bi;
|
||||
|
||||
if (!can_copy_bbs_p (region, n_region))
|
||||
return false;
|
||||
|
@ -5035,7 +4847,6 @@ tree_duplicate_sese_region (edge entry, edge exit,
|
|||
missuses of the functions. I.e. if you ask to copy something weird,
|
||||
it will work, but the state of structures probably will not be
|
||||
correct. */
|
||||
|
||||
for (i = 0; i < n_region; i++)
|
||||
{
|
||||
/* We do not handle subloops, i.e. all the blocks must belong to the
|
||||
|
@ -5072,7 +4883,7 @@ tree_duplicate_sese_region (edge entry, edge exit,
|
|||
free_region_copy = true;
|
||||
}
|
||||
|
||||
gcc_assert (!any_marked_for_rewrite_p ());
|
||||
gcc_assert (!need_ssa_update_p ());
|
||||
|
||||
/* Record blocks outside the region that are duplicated by something
|
||||
inside. */
|
||||
|
@ -5080,7 +4891,6 @@ tree_duplicate_sese_region (edge entry, edge exit,
|
|||
n_doms = get_dominated_by_region (CDI_DOMINATORS, region, n_region, doms);
|
||||
|
||||
copy_bbs (region, n_region, region_copy, &exit, 1, &exit_copy, loop);
|
||||
definitions = marked_ssa_names ();
|
||||
|
||||
if (copying_header)
|
||||
{
|
||||
|
@ -5094,49 +4904,27 @@ tree_duplicate_sese_region (edge entry, edge exit,
|
|||
flush_pending_stmts (entry);
|
||||
|
||||
/* Concerning updating of dominators: We must recount dominators
|
||||
for entry block and its copy. Anything that is outside of the region, but
|
||||
was dominated by something inside needs recounting as well. */
|
||||
for entry block and its copy. Anything that is outside of the
|
||||
region, but was dominated by something inside needs recounting as
|
||||
well. */
|
||||
set_immediate_dominator (CDI_DOMINATORS, entry->dest, entry->src);
|
||||
doms[n_doms++] = entry->dest->rbi->original;
|
||||
iterate_fix_dominators (CDI_DOMINATORS, doms, n_doms);
|
||||
free (doms);
|
||||
|
||||
/* Add the other phi node arguments. */
|
||||
/* Add the other PHI node arguments. */
|
||||
add_phi_args_after_copy (region_copy, n_region);
|
||||
|
||||
/* Add phi nodes for definitions at exit. TODO -- once we have immediate
|
||||
uses, it should be possible to emit phi nodes just for definitions that
|
||||
are used outside region. */
|
||||
EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
|
||||
{
|
||||
tree name = ssa_name (ver);
|
||||
|
||||
phi = create_phi_node (name, exit->dest);
|
||||
add_phi_arg (phi, name, exit);
|
||||
add_phi_arg (phi, name, exit_copy);
|
||||
|
||||
SSA_NAME_DEF_STMT (name) = phi;
|
||||
}
|
||||
|
||||
/* And create new definitions inside region and its copy. TODO -- once we
|
||||
have immediate uses, it might be better to leave definitions in region
|
||||
unchanged, create new ssa names for phi nodes on exit, and rewrite
|
||||
the uses, to avoid changing the copied region. */
|
||||
allocate_ssa_names (definitions, &ssa_name_map);
|
||||
rewrite_to_new_ssa_names (region, n_region, ssa_name_map);
|
||||
allocate_ssa_names (definitions, &ssa_name_map);
|
||||
rewrite_to_new_ssa_names (region_copy, n_region, ssa_name_map);
|
||||
htab_delete (ssa_name_map);
|
||||
/* Update the SSA web. */
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
if (free_region_copy)
|
||||
free (region_copy);
|
||||
|
||||
unmark_all_for_rewrite ();
|
||||
BITMAP_FREE (definitions);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Dump FUNCTION_DECL FN to file FILE using FLAGS (see TDF_* in tree.h) */
|
||||
|
||||
void
|
||||
|
|
|
@ -253,15 +253,11 @@ struct var_ann_d GTY(())
|
|||
tree default_def;
|
||||
|
||||
/* During into-ssa and the dominator optimizer, this field holds the
|
||||
current version of this variable (an SSA_NAME).
|
||||
|
||||
This was previously two varrays (one in into-ssa the other in the
|
||||
dominator optimizer). That is wasteful, particularly since the
|
||||
dominator optimizer calls into-ssa resulting in having two varrays
|
||||
live at the same time and this can happen for each call to the
|
||||
dominator optimizer. */
|
||||
current version of this variable (an SSA_NAME). */
|
||||
tree current_def;
|
||||
|
||||
/* If this variable is a structure, this fields holds a list of
|
||||
symbols representing each of the fields of the structure. */
|
||||
subvar_t subvars;
|
||||
};
|
||||
|
||||
|
@ -540,9 +536,6 @@ extern bool tree_duplicate_sese_region (edge, edge, basic_block *, unsigned,
|
|||
basic_block *);
|
||||
extern void add_phi_args_after_copy_bb (basic_block);
|
||||
extern void add_phi_args_after_copy (basic_block *, unsigned);
|
||||
extern void rewrite_to_new_ssa_names_bb (basic_block, struct htab *);
|
||||
extern void rewrite_to_new_ssa_names (basic_block *, unsigned, htab_t);
|
||||
extern void allocate_ssa_names (bitmap, struct htab **);
|
||||
extern bool tree_purge_dead_eh_edges (basic_block);
|
||||
extern bool tree_purge_all_dead_eh_edges (bitmap);
|
||||
extern tree gimplify_val (block_stmt_iterator *, tree, tree);
|
||||
|
@ -565,7 +558,6 @@ extern tree create_phi_node (tree, basic_block);
|
|||
extern void add_phi_arg (tree, tree, edge);
|
||||
extern void remove_phi_args (edge);
|
||||
extern void remove_phi_node (tree, tree);
|
||||
extern tree find_phi_node_for (basic_block, tree, tree *);
|
||||
extern tree phi_reverse (tree);
|
||||
extern void dump_dfa_stats (FILE *);
|
||||
extern void debug_dfa_stats (void);
|
||||
|
@ -612,11 +604,6 @@ typedef bool (*walk_use_def_chains_fn) (tree, tree, void *);
|
|||
|
||||
/* In tree-ssa.c */
|
||||
extern void init_tree_ssa (void);
|
||||
extern void dump_tree_ssa (FILE *);
|
||||
extern void debug_tree_ssa (void);
|
||||
extern void debug_def_blocks (void);
|
||||
extern void dump_tree_ssa_stats (FILE *);
|
||||
extern void debug_tree_ssa_stats (void);
|
||||
extern edge ssa_redirect_edge (edge, basic_block);
|
||||
extern void flush_pending_stmts (edge);
|
||||
extern bool tree_ssa_useless_type_conversion (tree);
|
||||
|
@ -628,23 +615,20 @@ extern void walk_use_def_chains (tree, walk_use_def_chains_fn, void *, bool);
|
|||
extern bool stmt_references_memory_p (tree);
|
||||
|
||||
/* In tree-into-ssa.c */
|
||||
extern void rewrite_ssa_into_ssa (void);
|
||||
|
||||
void update_ssa (unsigned);
|
||||
void delete_update_ssa (void);
|
||||
void register_new_name_mapping (tree, tree);
|
||||
tree create_new_def_for (tree, tree, def_operand_p);
|
||||
bool need_ssa_update_p (void);
|
||||
bool name_registered_for_update_p (tree);
|
||||
bitmap ssa_names_to_replace (void);
|
||||
void release_ssa_name_after_update_ssa (tree name);
|
||||
void dump_repl_tbl (FILE *);
|
||||
void debug_repl_tbl (void);
|
||||
void dump_names_replaced_by (FILE *, tree);
|
||||
void debug_names_replaced_by (tree);
|
||||
void compute_global_livein (bitmap, bitmap);
|
||||
tree duplicate_ssa_name (tree, tree);
|
||||
void mark_sym_for_renaming (tree);
|
||||
void mark_set_for_renaming (bitmap);
|
||||
tree get_current_def (tree);
|
||||
void set_current_def (tree, tree);
|
||||
|
||||
/* In tree-ssa-ccp.c */
|
||||
bool fold_stmt (tree *);
|
||||
|
@ -724,7 +708,7 @@ tree find_loop_niter_by_eval (struct loop *, edge *);
|
|||
void estimate_numbers_of_iterations (struct loops *);
|
||||
tree can_count_iv_in_wider_type (struct loop *, tree, tree, tree, tree);
|
||||
void free_numbers_of_iterations_estimates (struct loops *);
|
||||
void rewrite_into_loop_closed_ssa (bitmap);
|
||||
void rewrite_into_loop_closed_ssa (bitmap, unsigned);
|
||||
void verify_loop_closed_ssa (void);
|
||||
void loop_commit_inserts (void);
|
||||
bool for_each_index (tree *, bool (*) (tree, tree *, void *), void *);
|
||||
|
|
1308
gcc/tree-into-ssa.c
1308
gcc/tree-into-ssa.c
File diff suppressed because it is too large
Load Diff
|
@ -373,6 +373,5 @@ linear_transform_loops (struct loops *loops)
|
|||
VEC_free (tree, heap, oldivs);
|
||||
VEC_free (tree, heap, invariants);
|
||||
scev_reset ();
|
||||
update_ssa (TODO_update_ssa);
|
||||
rewrite_into_loop_closed_ssa (NULL);
|
||||
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa_full_phi);
|
||||
}
|
||||
|
|
|
@ -466,30 +466,6 @@ remove_phi_node (tree phi, tree prev)
|
|||
}
|
||||
|
||||
|
||||
/* Find the first PHI node P in basic block BB for symbol SYM. If
|
||||
PREV_P is given, the PHI node preceding P is stored in *PREV_P. */
|
||||
|
||||
tree
|
||||
find_phi_node_for (basic_block bb, tree sym, tree *prev_p)
|
||||
{
|
||||
tree phi;
|
||||
|
||||
if (prev_p)
|
||||
*prev_p = NULL_TREE;
|
||||
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
{
|
||||
if (SSA_NAME_VAR (PHI_RESULT (phi)) == sym)
|
||||
return phi;
|
||||
|
||||
if (prev_p)
|
||||
*prev_p = phi;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
|
||||
/* Reverse the order of PHI nodes in the chain PHI.
|
||||
Return the new head of the chain (old last PHI node). */
|
||||
|
||||
|
|
|
@ -474,7 +474,7 @@ tree_ssa_dominator_optimize (void)
|
|||
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
rewrite_ssa_into_ssa ();
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
/* Reinitialize the various tables. */
|
||||
bitmap_clear (nonzero_vars);
|
||||
|
|
|
@ -136,7 +136,7 @@ copy_loop_headers (void)
|
|||
loops = loop_optimizer_init (dump_file);
|
||||
if (!loops)
|
||||
return;
|
||||
rewrite_into_loop_closed_ssa (NULL);
|
||||
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
|
||||
|
||||
/* We do not try to keep the information about irreducible regions
|
||||
up-to-date. */
|
||||
|
|
|
@ -757,14 +757,8 @@ move_computations (void)
|
|||
fini_walk_dominator_tree (&walk_data);
|
||||
|
||||
loop_commit_inserts ();
|
||||
|
||||
if (need_ssa_update_p ())
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
/* The movement of LI code may cause violation of loop closed SSA
|
||||
form invariants. TODO -- avoid these rewrites completely.
|
||||
Information in virtual phi nodes is sufficient for it. */
|
||||
rewrite_into_loop_closed_ssa (NULL);
|
||||
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
|
||||
}
|
||||
|
||||
/* Checks whether the statement defining variable *INDEX can be hoisted
|
||||
|
|
|
@ -185,6 +185,8 @@ try_unroll_loop_completely (struct loops *loops ATTRIBUTE_UNUSED,
|
|||
COND_EXPR_COND (cond) = do_exit;
|
||||
update_stmt (cond);
|
||||
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "Unrolled loop %d completely.\n", loop->num);
|
||||
|
||||
|
|
|
@ -5416,10 +5416,8 @@ tree_ssa_iv_optimize (struct loops *loops)
|
|||
FOR_EACH_BB (bb)
|
||||
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
|
||||
update_stmt (bsi_stmt (si));
|
||||
|
||||
update_ssa (TODO_update_ssa);
|
||||
}
|
||||
|
||||
rewrite_into_loop_closed_ssa (NULL);
|
||||
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
|
||||
tree_ssa_iv_optimize_finalize (loops, &data);
|
||||
}
|
||||
|
|
|
@ -139,11 +139,9 @@ add_exit_phis_edge (basic_block exit, tree use)
|
|||
return;
|
||||
|
||||
phi = create_phi_node (use, exit);
|
||||
|
||||
create_new_def_for (PHI_RESULT (phi), phi, PHI_RESULT_PTR (phi));
|
||||
FOR_EACH_EDGE (e, ei, exit->preds)
|
||||
add_phi_arg (phi, use, e);
|
||||
|
||||
SSA_NAME_DEF_STMT (use) = def_stmt;
|
||||
}
|
||||
|
||||
/* Add exit phis for VAR that is used in LIVEIN.
|
||||
|
@ -215,10 +213,11 @@ get_loops_exits (void)
|
|||
|
||||
/* For USE in BB, if it is used outside of the loop it is defined in,
|
||||
mark it for rewrite. Record basic block BB where it is used
|
||||
to USE_BLOCKS. */
|
||||
to USE_BLOCKS. Record the ssa name index to NEED_PHIS bitmap. */
|
||||
|
||||
static void
|
||||
find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks)
|
||||
find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks,
|
||||
bitmap need_phis)
|
||||
{
|
||||
unsigned ver;
|
||||
basic_block def_bb;
|
||||
|
@ -227,6 +226,10 @@ find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks)
|
|||
if (TREE_CODE (use) != SSA_NAME)
|
||||
return;
|
||||
|
||||
/* We don't need to keep virtual operands in loop-closed form. */
|
||||
if (!is_gimple_reg (use))
|
||||
return;
|
||||
|
||||
ver = SSA_NAME_VERSION (use);
|
||||
def_bb = bb_for_stmt (SSA_NAME_DEF_STMT (use));
|
||||
if (!def_bb)
|
||||
|
@ -241,31 +244,32 @@ find_uses_to_rename_use (basic_block bb, tree use, bitmap *use_blocks)
|
|||
use_blocks[ver] = BITMAP_ALLOC (NULL);
|
||||
bitmap_set_bit (use_blocks[ver], bb->index);
|
||||
|
||||
if (!flow_bb_inside_loop_p (def_loop, bb))
|
||||
mark_for_rewrite (use);
|
||||
bitmap_set_bit (need_phis, ver);
|
||||
}
|
||||
|
||||
/* For uses in STMT, mark names that are used outside of the loop they are
|
||||
defined to rewrite. Record the set of blocks in that the ssa
|
||||
names are defined to USE_BLOCKS. */
|
||||
names are defined to USE_BLOCKS and the ssa names themselves to
|
||||
NEED_PHIS. */
|
||||
|
||||
static void
|
||||
find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks)
|
||||
find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks, bitmap need_phis)
|
||||
{
|
||||
ssa_op_iter iter;
|
||||
tree var;
|
||||
basic_block bb = bb_for_stmt (stmt);
|
||||
|
||||
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
|
||||
find_uses_to_rename_use (bb, var, use_blocks);
|
||||
find_uses_to_rename_use (bb, var, use_blocks, need_phis);
|
||||
}
|
||||
|
||||
/* Marks names that are used in BB and outside of the loop they are
|
||||
defined in for rewrite. Records the set of blocks in that the ssa
|
||||
names are defined to USE_BLOCKS. */
|
||||
names are defined to USE_BLOCKS. Record the SSA names that will
|
||||
need exit PHIs in NEED_PHIS. */
|
||||
|
||||
static void
|
||||
find_uses_to_rename_bb (basic_block bb, bitmap *use_blocks)
|
||||
find_uses_to_rename_bb (basic_block bb, bitmap *use_blocks, bitmap need_phis)
|
||||
{
|
||||
block_stmt_iterator bsi;
|
||||
edge e;
|
||||
|
@ -275,10 +279,10 @@ find_uses_to_rename_bb (basic_block bb, bitmap *use_blocks)
|
|||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
for (phi = phi_nodes (e->dest); phi; phi = PHI_CHAIN (phi))
|
||||
find_uses_to_rename_use (bb, PHI_ARG_DEF_FROM_EDGE (phi, e),
|
||||
use_blocks);
|
||||
use_blocks, need_phis);
|
||||
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
find_uses_to_rename_stmt (bsi_stmt (bsi), use_blocks);
|
||||
find_uses_to_rename_stmt (bsi_stmt (bsi), use_blocks, need_phis);
|
||||
}
|
||||
|
||||
/* Marks names that are used outside of the loop they are defined in
|
||||
|
@ -287,24 +291,24 @@ find_uses_to_rename_bb (basic_block bb, bitmap *use_blocks)
|
|||
scan only blocks in this set. */
|
||||
|
||||
static void
|
||||
find_uses_to_rename (bitmap changed_bbs, bitmap *use_blocks)
|
||||
find_uses_to_rename (bitmap changed_bbs, bitmap *use_blocks, bitmap need_phis)
|
||||
{
|
||||
basic_block bb;
|
||||
unsigned index;
|
||||
bitmap_iterator bi;
|
||||
|
||||
if (changed_bbs)
|
||||
if (changed_bbs && !bitmap_empty_p (changed_bbs))
|
||||
{
|
||||
EXECUTE_IF_SET_IN_BITMAP (changed_bbs, 0, index, bi)
|
||||
{
|
||||
find_uses_to_rename_bb (BASIC_BLOCK (index), use_blocks);
|
||||
find_uses_to_rename_bb (BASIC_BLOCK (index), use_blocks, need_phis);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FOR_EACH_BB (bb)
|
||||
{
|
||||
find_uses_to_rename_bb (bb, use_blocks);
|
||||
find_uses_to_rename_bb (bb, use_blocks, need_phis);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -336,43 +340,42 @@ find_uses_to_rename (bitmap changed_bbs, bitmap *use_blocks)
|
|||
base 99 and step 1.
|
||||
|
||||
If CHANGED_BBS is not NULL, we look for uses outside loops only in
|
||||
the basic blocks in this set. */
|
||||
the basic blocks in this set.
|
||||
|
||||
UPDATE_FLAG is used in the call to update_ssa. See
|
||||
TODO_update_ssa* for documentation. */
|
||||
|
||||
void
|
||||
rewrite_into_loop_closed_ssa (bitmap changed_bbs)
|
||||
rewrite_into_loop_closed_ssa (bitmap changed_bbs, unsigned update_flag)
|
||||
{
|
||||
bitmap loop_exits = get_loops_exits ();
|
||||
bitmap *use_blocks;
|
||||
unsigned i;
|
||||
bitmap names_to_rename;
|
||||
unsigned i, old_num_ssa_names;
|
||||
bitmap names_to_rename = BITMAP_ALLOC (NULL);
|
||||
|
||||
gcc_assert (!any_marked_for_rewrite_p ());
|
||||
/* If the pass has caused the SSA form to be out-of-date, update it
|
||||
now. */
|
||||
update_ssa (update_flag);
|
||||
|
||||
use_blocks = xcalloc (num_ssa_names, sizeof (bitmap));
|
||||
old_num_ssa_names = num_ssa_names;
|
||||
use_blocks = xcalloc (old_num_ssa_names, sizeof (bitmap));
|
||||
|
||||
/* Find the uses outside loops. */
|
||||
find_uses_to_rename (changed_bbs, use_blocks);
|
||||
find_uses_to_rename (changed_bbs, use_blocks, names_to_rename);
|
||||
|
||||
if (!any_marked_for_rewrite_p ())
|
||||
{
|
||||
free (use_blocks);
|
||||
BITMAP_FREE (loop_exits);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Add the phi nodes on exits of the loops for the names we need to
|
||||
/* Add the PHI nodes on exits of the loops for the names we need to
|
||||
rewrite. */
|
||||
names_to_rename = marked_ssa_names ();
|
||||
add_exit_phis (names_to_rename, use_blocks, loop_exits);
|
||||
|
||||
for (i = 0; i < num_ssa_names; i++)
|
||||
for (i = 0; i < old_num_ssa_names; i++)
|
||||
BITMAP_FREE (use_blocks[i]);
|
||||
free (use_blocks);
|
||||
BITMAP_FREE (loop_exits);
|
||||
BITMAP_FREE (names_to_rename);
|
||||
|
||||
/* Do the rewriting. */
|
||||
rewrite_ssa_into_ssa ();
|
||||
/* Fix up all the names found to be used outside their original
|
||||
loops. */
|
||||
update_ssa (TODO_update_ssa);
|
||||
}
|
||||
|
||||
/* Check invariants of the loop closed ssa form for the USE in BB. */
|
||||
|
@ -383,7 +386,7 @@ check_loop_closed_ssa_use (basic_block bb, tree use)
|
|||
tree def;
|
||||
basic_block def_bb;
|
||||
|
||||
if (TREE_CODE (use) != SSA_NAME)
|
||||
if (TREE_CODE (use) != SSA_NAME || !is_gimple_reg (use))
|
||||
return;
|
||||
|
||||
def = SSA_NAME_DEF_STMT (use);
|
||||
|
@ -400,7 +403,7 @@ check_loop_closed_ssa_stmt (basic_block bb, tree stmt)
|
|||
ssa_op_iter iter;
|
||||
tree var;
|
||||
|
||||
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES)
|
||||
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
|
||||
check_loop_closed_ssa_use (bb, var);
|
||||
}
|
||||
|
||||
|
@ -414,6 +417,9 @@ verify_loop_closed_ssa (void)
|
|||
tree phi;
|
||||
unsigned i;
|
||||
|
||||
if (current_loops == NULL)
|
||||
return;
|
||||
|
||||
verify_ssa (false);
|
||||
|
||||
FOR_EACH_BB (bb)
|
||||
|
@ -566,53 +572,15 @@ copy_phi_node_args (unsigned first_new_block)
|
|||
BASIC_BLOCK (i)->rbi->duplicated = 0;
|
||||
}
|
||||
|
||||
/* Renames variables in the area copied by tree_duplicate_loop_to_header_edge.
|
||||
FIRST_NEW_BLOCK is the first block in the copied area. DEFINITIONS is
|
||||
a bitmap of all ssa names defined inside the loop. */
|
||||
|
||||
static void
|
||||
rename_variables (unsigned first_new_block, bitmap definitions)
|
||||
{
|
||||
unsigned i, copy_number = 0;
|
||||
basic_block bb;
|
||||
htab_t ssa_name_map = NULL;
|
||||
/* The same as cfgloopmanip.c:duplicate_loop_to_header_edge, but also
|
||||
updates the PHI nodes at start of the copied region. In order to
|
||||
achieve this, only loops whose exits all lead to the same location
|
||||
are handled.
|
||||
|
||||
for (i = first_new_block; i < (unsigned) last_basic_block; i++)
|
||||
{
|
||||
bb = BASIC_BLOCK (i);
|
||||
|
||||
/* We assume that first come all blocks from the first copy, then all
|
||||
blocks from the second copy, etc. */
|
||||
if (copy_number != (unsigned) bb->rbi->copy_number)
|
||||
{
|
||||
allocate_ssa_names (definitions, &ssa_name_map);
|
||||
copy_number = bb->rbi->copy_number;
|
||||
}
|
||||
|
||||
rewrite_to_new_ssa_names_bb (bb, ssa_name_map);
|
||||
}
|
||||
|
||||
htab_delete (ssa_name_map);
|
||||
}
|
||||
|
||||
/* Sets SSA_NAME_DEF_STMT for results of all phi nodes in BB. */
|
||||
|
||||
static void
|
||||
set_phi_def_stmts (basic_block bb)
|
||||
{
|
||||
tree phi;
|
||||
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
SSA_NAME_DEF_STMT (PHI_RESULT (phi)) = phi;
|
||||
}
|
||||
|
||||
/* The same as cfgloopmanip.c:duplicate_loop_to_header_edge, but also updates
|
||||
ssa. In order to achieve this, only loops whose exits all lead to the same
|
||||
location are handled.
|
||||
|
||||
FIXME: we create some degenerate phi nodes that could be avoided by copy
|
||||
propagating them instead. Unfortunately this is not completely
|
||||
straightforward due to problems with constant folding. */
|
||||
Notice that we do not completely update the SSA web after
|
||||
duplication. The caller is responsible for calling update_ssa
|
||||
after the loop has been duplicated. */
|
||||
|
||||
bool
|
||||
tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
|
||||
|
@ -622,9 +590,6 @@ tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
|
|||
unsigned int *n_to_remove, int flags)
|
||||
{
|
||||
unsigned first_new_block;
|
||||
basic_block bb;
|
||||
unsigned i;
|
||||
bitmap definitions;
|
||||
|
||||
if (!(loops->state & LOOPS_HAVE_SIMPLE_LATCHES))
|
||||
return false;
|
||||
|
@ -635,8 +600,6 @@ tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
|
|||
verify_loop_closed_ssa ();
|
||||
#endif
|
||||
|
||||
gcc_assert (!any_marked_for_rewrite_p ());
|
||||
|
||||
first_new_block = last_basic_block;
|
||||
if (!duplicate_loop_to_header_edge (loop, e, loops, ndupl, wont_exit,
|
||||
orig, to_remove, n_to_remove, flags))
|
||||
|
@ -648,31 +611,7 @@ tree_duplicate_loop_to_header_edge (struct loop *loop, edge e,
|
|||
/* Copy the phi node arguments. */
|
||||
copy_phi_node_args (first_new_block);
|
||||
|
||||
/* Rename the variables. */
|
||||
definitions = marked_ssa_names ();
|
||||
rename_variables (first_new_block, definitions);
|
||||
unmark_all_for_rewrite ();
|
||||
BITMAP_FREE (definitions);
|
||||
|
||||
/* For some time we have the identical ssa names as results in multiple phi
|
||||
nodes. When phi node is resized, it sets SSA_NAME_DEF_STMT of its result
|
||||
to the new copy. This means that we cannot easily ensure that the ssa
|
||||
names defined in those phis are pointing to the right one -- so just
|
||||
recompute SSA_NAME_DEF_STMT for them. */
|
||||
|
||||
for (i = first_new_block; i < (unsigned) last_basic_block; i++)
|
||||
{
|
||||
bb = BASIC_BLOCK (i);
|
||||
set_phi_def_stmts (bb);
|
||||
if (bb->rbi->copy_number == 1)
|
||||
set_phi_def_stmts (bb->rbi->original);
|
||||
}
|
||||
|
||||
scev_reset ();
|
||||
#ifdef ENABLE_CHECKING
|
||||
verify_loop_closed_ssa ();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,10 +101,6 @@ tree_ssa_unswitch_loops (struct loops *loops)
|
|||
continue;
|
||||
|
||||
changed |= tree_unswitch_single_loop (loops, loop, 0);
|
||||
#ifdef ENABLE_CHECKING
|
||||
verify_dominators (CDI_DOMINATORS);
|
||||
verify_loop_structure (loops);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (changed)
|
||||
|
@ -260,6 +256,9 @@ tree_unswitch_single_loop (struct loops *loops, struct loop *loop, int num)
|
|||
if (!nloop)
|
||||
return changed;
|
||||
|
||||
/* Update the SSA form after unswitching. */
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
/* Invoke itself on modified loops. */
|
||||
tree_unswitch_single_loop (loops, nloop, num + 1);
|
||||
tree_unswitch_single_loop (loops, loop, num + 1);
|
||||
|
|
|
@ -40,7 +40,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|||
|
||||
/* The loop tree currently optimized. */
|
||||
|
||||
struct loops *current_loops;
|
||||
struct loops *current_loops = NULL;
|
||||
|
||||
/* Initializes the loop structures. DUMP is the file to that the details
|
||||
about the analysis should be dumped. */
|
||||
|
@ -53,8 +53,7 @@ tree_loop_optimizer_init (FILE *dump)
|
|||
if (!loops)
|
||||
return NULL;
|
||||
|
||||
update_ssa (TODO_update_ssa);
|
||||
rewrite_into_loop_closed_ssa (NULL);
|
||||
rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
|
||||
|
||||
return loops;
|
||||
}
|
||||
|
|
|
@ -644,6 +644,10 @@ verify_ssa (bool check_modified_stmt)
|
|||
enum dom_state orig_dom_state = dom_computed[CDI_DOMINATORS];
|
||||
bitmap names_defined_in_bb = BITMAP_ALLOC (NULL);
|
||||
|
||||
gcc_assert (!need_ssa_update_p ());
|
||||
|
||||
verify_stmts ();
|
||||
|
||||
timevar_push (TV_TREE_SSA_VERIFY);
|
||||
|
||||
/* Keep track of SSA names present in the IL. */
|
||||
|
@ -751,9 +755,7 @@ verify_ssa (bool check_modified_stmt)
|
|||
}
|
||||
|
||||
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
|
||||
{
|
||||
bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
|
||||
}
|
||||
bitmap_set_bit (names_defined_in_bb, SSA_NAME_VERSION (op));
|
||||
}
|
||||
|
||||
bitmap_clear (names_defined_in_bb);
|
||||
|
@ -763,6 +765,7 @@ verify_ssa (bool check_modified_stmt)
|
|||
verify_alias_info ();
|
||||
|
||||
free (definition_block);
|
||||
|
||||
/* Restore the dominance information to its prior known state, so
|
||||
that we do not perturb the compiler's subsequent behavior. */
|
||||
if (orig_dom_state == DOM_NONE)
|
||||
|
@ -835,6 +838,7 @@ delete_tree_ssa (void)
|
|||
addressable_vars = NULL;
|
||||
modified_noreturn_calls = NULL;
|
||||
aliases_computed_p = false;
|
||||
gcc_assert (!need_ssa_update_p ());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -61,9 +61,6 @@ Boston, MA 02111-1307, USA. */
|
|||
/* Array of all SSA_NAMEs used in the function. */
|
||||
varray_type ssa_names;
|
||||
|
||||
/* Bitmap of ssa names marked for rewriting. */
|
||||
static bitmap ssa_names_to_rewrite;
|
||||
|
||||
/* Free list of SSA_NAMEs. This list is wiped at the end of each function
|
||||
after we leave SSA form. */
|
||||
static GTY (()) tree free_ssanames;
|
||||
|
@ -77,54 +74,6 @@ unsigned int ssa_name_nodes_reused;
|
|||
unsigned int ssa_name_nodes_created;
|
||||
#endif
|
||||
|
||||
/* Returns true if ssa name VAR is marked for rewrite. */
|
||||
|
||||
bool
|
||||
marked_for_rewrite_p (tree var)
|
||||
{
|
||||
return bitmap_bit_p (ssa_names_to_rewrite, SSA_NAME_VERSION (var));
|
||||
}
|
||||
|
||||
/* Returns true if any ssa name is marked for rewrite. */
|
||||
|
||||
bool
|
||||
any_marked_for_rewrite_p (void)
|
||||
{
|
||||
if (!ssa_names_to_rewrite)
|
||||
return false;
|
||||
|
||||
return !bitmap_empty_p (ssa_names_to_rewrite);
|
||||
}
|
||||
|
||||
/* Mark ssa name VAR for rewriting. */
|
||||
|
||||
void
|
||||
mark_for_rewrite (tree var)
|
||||
{
|
||||
bitmap_set_bit (ssa_names_to_rewrite, SSA_NAME_VERSION (var));
|
||||
}
|
||||
|
||||
/* Unmark all ssa names marked for rewrite. */
|
||||
|
||||
void
|
||||
unmark_all_for_rewrite (void)
|
||||
{
|
||||
bitmap_clear (ssa_names_to_rewrite);
|
||||
}
|
||||
|
||||
/* Return the bitmap of ssa names to rewrite. Copy the bitmap,
|
||||
so that the optimizers cannot access internals directly */
|
||||
|
||||
bitmap
|
||||
marked_ssa_names (void)
|
||||
{
|
||||
bitmap ret = BITMAP_ALLOC (NULL);
|
||||
|
||||
bitmap_copy (ret, ssa_names_to_rewrite);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Initialize management of SSA_NAMEs. */
|
||||
|
||||
void
|
||||
|
@ -138,7 +87,6 @@ init_ssanames (void)
|
|||
large. */
|
||||
VARRAY_PUSH_TREE (ssa_names, NULL_TREE);
|
||||
free_ssanames = NULL;
|
||||
ssa_names_to_rewrite = BITMAP_ALLOC (NULL);
|
||||
}
|
||||
|
||||
/* Finalize management of SSA_NAMEs. */
|
||||
|
@ -146,7 +94,6 @@ init_ssanames (void)
|
|||
void
|
||||
fini_ssanames (void)
|
||||
{
|
||||
BITMAP_FREE (ssa_names_to_rewrite);
|
||||
ggc_free (ssa_names);
|
||||
ssa_names = NULL;
|
||||
free_ssanames = NULL;
|
||||
|
@ -237,11 +184,13 @@ release_ssa_name (tree var)
|
|||
if (var == var_ann (SSA_NAME_VAR (var))->default_def)
|
||||
return;
|
||||
|
||||
/* If the ssa name is marked for rewriting, it may have multiple definitions,
|
||||
but we may happen to remove just one of them. So do not remove the
|
||||
ssa name now. */
|
||||
if (marked_for_rewrite_p (var))
|
||||
return;
|
||||
/* If VAR has been registered for SSA updating, don't remove it.
|
||||
After update_ssa has run, the name will be released. */
|
||||
if (name_registered_for_update_p (var))
|
||||
{
|
||||
release_ssa_name_after_update_ssa (var);
|
||||
return;
|
||||
}
|
||||
|
||||
/* release_ssa_name can be called multiple times on a single SSA_NAME.
|
||||
However, it should only end up on our free list one time. We
|
||||
|
@ -304,7 +253,7 @@ duplicate_ssa_name (tree name, tree stmt)
|
|||
|
||||
|
||||
/* Creates a duplicate of the ptr_info_def at PTR_INFO for use by
|
||||
the ssa name NAME. */
|
||||
the SSA name NAME. */
|
||||
|
||||
void
|
||||
duplicate_ssa_name_ptr_info (tree name, struct ptr_info_def *ptr_info)
|
||||
|
|
|
@ -1991,6 +1991,11 @@ vect_transform_loop (loop_vec_info loop_vinfo,
|
|||
|
||||
slpeel_make_loop_iterate_ntimes (loop, ratio);
|
||||
|
||||
/* The memory tags and pointers in vectorized statements need to
|
||||
have their SSA forms updated. FIXME, why can't this be delayed
|
||||
until all the loops have been transformed? */
|
||||
update_ssa (TODO_update_ssa);
|
||||
|
||||
if (vect_print_dump_info (REPORT_VECTORIZED_LOOPS, LOOP_LOC (loop_vinfo)))
|
||||
fprintf (vect_dump, "LOOP VECTORIZED.");
|
||||
}
|
||||
|
|
|
@ -159,11 +159,8 @@ static void slpeel_update_phi_nodes_for_guard2
|
|||
(edge, struct loop *, bool, basic_block *);
|
||||
static edge slpeel_add_loop_guard (basic_block, tree, basic_block, basic_block);
|
||||
|
||||
static void allocate_new_names (bitmap);
|
||||
static void rename_use_op (use_operand_p);
|
||||
static void rename_def_op (def_operand_p, tree);
|
||||
static void rename_variables_in_bb (basic_block);
|
||||
static void free_new_names (bitmap);
|
||||
static void rename_variables_in_loop (struct loop *);
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -188,72 +185,25 @@ unsigned int vect_loops_num;
|
|||
*************************************************************************/
|
||||
|
||||
|
||||
/* For each definition in DEFINITIONS this function allocates
|
||||
new ssa name. */
|
||||
|
||||
static void
|
||||
allocate_new_names (bitmap definitions)
|
||||
{
|
||||
unsigned ver;
|
||||
bitmap_iterator bi;
|
||||
|
||||
EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
|
||||
{
|
||||
tree def = ssa_name (ver);
|
||||
tree *new_name_ptr = xmalloc (sizeof (tree));
|
||||
|
||||
bool abnormal = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def);
|
||||
|
||||
*new_name_ptr = duplicate_ssa_name (def, SSA_NAME_DEF_STMT (def));
|
||||
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (*new_name_ptr) = abnormal;
|
||||
|
||||
SSA_NAME_AUX (def) = new_name_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Renames the use *OP_P. */
|
||||
|
||||
static void
|
||||
rename_use_op (use_operand_p op_p)
|
||||
{
|
||||
tree *new_name_ptr;
|
||||
tree new_name;
|
||||
|
||||
if (TREE_CODE (USE_FROM_PTR (op_p)) != SSA_NAME)
|
||||
return;
|
||||
|
||||
new_name_ptr = SSA_NAME_AUX (USE_FROM_PTR (op_p));
|
||||
new_name = get_current_def (USE_FROM_PTR (op_p));
|
||||
|
||||
/* Something defined outside of the loop. */
|
||||
if (!new_name_ptr)
|
||||
if (!new_name)
|
||||
return;
|
||||
|
||||
/* An ordinary ssa name defined in the loop. */
|
||||
|
||||
SET_USE (op_p, *new_name_ptr);
|
||||
}
|
||||
|
||||
|
||||
/* Renames the def *OP_P in statement STMT. */
|
||||
|
||||
static void
|
||||
rename_def_op (def_operand_p op_p, tree stmt)
|
||||
{
|
||||
tree *new_name_ptr;
|
||||
|
||||
if (TREE_CODE (DEF_FROM_PTR (op_p)) != SSA_NAME)
|
||||
return;
|
||||
|
||||
new_name_ptr = SSA_NAME_AUX (DEF_FROM_PTR (op_p));
|
||||
|
||||
/* Something defined outside of the loop. */
|
||||
if (!new_name_ptr)
|
||||
return;
|
||||
|
||||
/* An ordinary ssa name defined in the loop. */
|
||||
|
||||
SET_DEF (op_p, *new_name_ptr);
|
||||
SSA_NAME_DEF_STMT (DEF_FROM_PTR (op_p)) = stmt;
|
||||
SET_USE (op_p, new_name);
|
||||
}
|
||||
|
||||
|
||||
|
@ -268,7 +218,6 @@ rename_variables_in_bb (basic_block bb)
|
|||
stmt_ann_t ann;
|
||||
use_optype uses;
|
||||
vuse_optype vuses;
|
||||
def_optype defs;
|
||||
v_may_def_optype v_may_defs;
|
||||
v_must_def_optype v_must_defs;
|
||||
unsigned i;
|
||||
|
@ -276,9 +225,6 @@ rename_variables_in_bb (basic_block bb)
|
|||
edge_iterator ei;
|
||||
struct loop *loop = bb->loop_father;
|
||||
|
||||
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
|
||||
rename_def_op (PHI_RESULT_PTR (phi), phi);
|
||||
|
||||
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
|
||||
{
|
||||
stmt = bsi_stmt (bsi);
|
||||
|
@ -288,27 +234,17 @@ rename_variables_in_bb (basic_block bb)
|
|||
for (i = 0; i < NUM_USES (uses); i++)
|
||||
rename_use_op (USE_OP_PTR (uses, i));
|
||||
|
||||
defs = DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_DEFS (defs); i++)
|
||||
rename_def_op (DEF_OP_PTR (defs, i), stmt);
|
||||
|
||||
vuses = VUSE_OPS (ann);
|
||||
for (i = 0; i < NUM_VUSES (vuses); i++)
|
||||
rename_use_op (VUSE_OP_PTR (vuses, i));
|
||||
|
||||
v_may_defs = V_MAY_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
|
||||
{
|
||||
rename_use_op (V_MAY_DEF_OP_PTR (v_may_defs, i));
|
||||
rename_def_op (V_MAY_DEF_RESULT_PTR (v_may_defs, i), stmt);
|
||||
}
|
||||
rename_use_op (V_MAY_DEF_OP_PTR (v_may_defs, i));
|
||||
|
||||
v_must_defs = V_MUST_DEF_OPS (ann);
|
||||
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
|
||||
{
|
||||
rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
|
||||
rename_def_op (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt);
|
||||
}
|
||||
rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
|
||||
}
|
||||
|
||||
FOR_EACH_EDGE (e, ei, bb->succs)
|
||||
|
@ -321,27 +257,6 @@ rename_variables_in_bb (basic_block bb)
|
|||
}
|
||||
|
||||
|
||||
/* Releases the structures holding the new ssa names. */
|
||||
|
||||
static void
|
||||
free_new_names (bitmap definitions)
|
||||
{
|
||||
unsigned ver;
|
||||
bitmap_iterator bi;
|
||||
|
||||
EXECUTE_IF_SET_IN_BITMAP (definitions, 0, ver, bi)
|
||||
{
|
||||
tree def = ssa_name (ver);
|
||||
|
||||
if (SSA_NAME_AUX (def))
|
||||
{
|
||||
free (SSA_NAME_AUX (def));
|
||||
SSA_NAME_AUX (def) = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Renames variables in new generated LOOP. */
|
||||
|
||||
static void
|
||||
|
@ -370,7 +285,7 @@ static void
|
|||
slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
|
||||
struct loop *new_loop, bool after)
|
||||
{
|
||||
tree *new_name_ptr, new_ssa_name;
|
||||
tree new_ssa_name;
|
||||
tree phi_new, phi_orig;
|
||||
tree def;
|
||||
edge orig_loop_latch = loop_latch_edge (orig_loop);
|
||||
|
@ -422,13 +337,12 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
|
|||
if (TREE_CODE (def) != SSA_NAME)
|
||||
continue;
|
||||
|
||||
new_name_ptr = SSA_NAME_AUX (def);
|
||||
if (!new_name_ptr)
|
||||
new_ssa_name = get_current_def (def);
|
||||
if (!new_ssa_name)
|
||||
/* Something defined outside of the loop. */
|
||||
continue;
|
||||
|
||||
/* An ordinary ssa name defined in the loop. */
|
||||
new_ssa_name = *new_name_ptr;
|
||||
add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
|
||||
|
||||
/* step 3 (case 1). */
|
||||
|
@ -565,9 +479,9 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
|
|||
new_merge
|
||||
next_bb
|
||||
|
||||
The ssa-names defined in the original loop have an SSA_NAME_AUX pointer
|
||||
that records the corresponding new ssa-name used in the new duplicated
|
||||
loop copy.
|
||||
The SSA names defined in the original loop have a current
|
||||
reaching definition that that records the corresponding new
|
||||
ssa-name used in the new duplicated loop copy.
|
||||
*/
|
||||
|
||||
/* Function slpeel_update_phi_nodes_for_guard1
|
||||
|
@ -603,7 +517,6 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
|
|||
{
|
||||
tree orig_phi, new_phi;
|
||||
tree update_phi, update_phi2;
|
||||
tree *new_name_ptr, *new_name_ptr2;
|
||||
tree guard_arg, loop_arg;
|
||||
basic_block new_merge_bb = guard_edge->dest;
|
||||
edge e = EDGE_SUCC (new_merge_bb, 0);
|
||||
|
@ -656,31 +569,28 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
|
|||
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
|
||||
SET_PHI_ARG_DEF (update_phi2, new_exit_e->dest_idx, PHI_RESULT (new_phi));
|
||||
|
||||
/* 2.4. Record the newly created name in SSA_NAME_AUX.
|
||||
/* 2.4. Record the newly created name with set_current_def.
|
||||
We want to find a name such that
|
||||
name = *(SSA_NAME_AUX (orig_loop_name))
|
||||
and to set its SSA_NAME_AUX as follows:
|
||||
*(SSA_NAME_AUX (name)) = new_phi_name
|
||||
name = get_current_def (orig_loop_name)
|
||||
and to set its current definition as follows:
|
||||
set_current_def (name, new_phi_name)
|
||||
|
||||
If LOOP is a new loop then loop_arg is already the name we're
|
||||
looking for. If LOOP is the original loop, then loop_arg is
|
||||
the orig_loop_name and the relevant name is recorded in its
|
||||
SSA_NAME_AUX */
|
||||
current reaching definition. */
|
||||
if (is_new_loop)
|
||||
current_new_name = loop_arg;
|
||||
else
|
||||
{
|
||||
new_name_ptr = SSA_NAME_AUX (loop_arg);
|
||||
gcc_assert (new_name_ptr);
|
||||
current_new_name = *new_name_ptr;
|
||||
current_new_name = get_current_def (loop_arg);
|
||||
gcc_assert (current_new_name);
|
||||
}
|
||||
#ifdef ENABLE_CHECKING
|
||||
gcc_assert (! SSA_NAME_AUX (current_new_name));
|
||||
gcc_assert (get_current_def (current_new_name) == NULL_TREE);
|
||||
#endif
|
||||
|
||||
new_name_ptr2 = xmalloc (sizeof (tree));
|
||||
*new_name_ptr2 = PHI_RESULT (new_phi);
|
||||
SSA_NAME_AUX (current_new_name) = new_name_ptr2;
|
||||
set_current_def (current_new_name, PHI_RESULT (new_phi));
|
||||
bitmap_set_bit (*defs, SSA_NAME_VERSION (current_new_name));
|
||||
}
|
||||
|
||||
|
@ -720,13 +630,12 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
|
|||
{
|
||||
tree orig_phi, new_phi;
|
||||
tree update_phi, update_phi2;
|
||||
tree *new_name_ptr, *new_name_ptr2;
|
||||
tree guard_arg, loop_arg;
|
||||
basic_block new_merge_bb = guard_edge->dest;
|
||||
edge e = EDGE_SUCC (new_merge_bb, 0);
|
||||
basic_block update_bb = e->dest;
|
||||
edge new_exit_e;
|
||||
tree orig_def;
|
||||
tree orig_def, orig_def_new_name;
|
||||
tree new_name, new_name2;
|
||||
tree arg;
|
||||
|
||||
|
@ -741,7 +650,7 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
|
|||
{
|
||||
orig_phi = update_phi;
|
||||
orig_def = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
|
||||
new_name_ptr = SSA_NAME_AUX (orig_def);
|
||||
orig_def_new_name = get_current_def (orig_def);
|
||||
arg = NULL_TREE;
|
||||
|
||||
/** 1. Handle new-merge-point phis **/
|
||||
|
@ -751,19 +660,17 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
|
|||
new_merge_bb);
|
||||
|
||||
/* 1.2. NEW_MERGE_BB has two incoming edges: GUARD_EDGE and the exit-edge
|
||||
of LOOP. Set the two phi args in NEW_PHI for these edges: */
|
||||
of LOOP. Set the two PHI args in NEW_PHI for these edges: */
|
||||
new_name = orig_def;
|
||||
new_name2 = NULL_TREE;
|
||||
if (new_name_ptr)
|
||||
if (orig_def_new_name)
|
||||
{
|
||||
new_name = *new_name_ptr;
|
||||
new_name_ptr2 = SSA_NAME_AUX (new_name);
|
||||
if (new_name_ptr2)
|
||||
/* Some variables have both loop-entry-phis and loop-exit-phis.
|
||||
Such variables were given yet newer names by phis placed in
|
||||
guard_bb by slpeel_update_phi_nodes_for_guard1. I.e:
|
||||
new_name2 = SSA_NAME_AUX (SSA_NAME_AUX (orig_name)). */
|
||||
new_name2 = *new_name_ptr2;
|
||||
new_name = orig_def_new_name;
|
||||
/* Some variables have both loop-entry-phis and loop-exit-phis.
|
||||
Such variables were given yet newer names by phis placed in
|
||||
guard_bb by slpeel_update_phi_nodes_for_guard1. I.e:
|
||||
new_name2 = get_current_def (get_current_def (orig_name)). */
|
||||
new_name2 = get_current_def (new_name);
|
||||
}
|
||||
|
||||
if (is_new_loop)
|
||||
|
@ -804,20 +711,22 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
|
|||
|
||||
/** 3. Handle loop-closed-ssa-form phis for first loop **/
|
||||
|
||||
/* 3.1. Find the relevant names that need an exit-phi in GUARD_BB, i.e.
|
||||
names for which slpeel_update_phi_nodes_for_guard1 had not already
|
||||
created a phi node. This is the case for names that are used outside
|
||||
/* 3.1. Find the relevant names that need an exit-phi in
|
||||
GUARD_BB, i.e. names for which
|
||||
slpeel_update_phi_nodes_for_guard1 had not already created a
|
||||
phi node. This is the case for names that are used outside
|
||||
the loop (and therefore need an exit phi) but are not updated
|
||||
across loop iterations (and therefore don't have a loop-header-phi).
|
||||
across loop iterations (and therefore don't have a
|
||||
loop-header-phi).
|
||||
|
||||
slpeel_update_phi_nodes_for_guard1 is responsible for creating
|
||||
loop-exit phis in GUARD_BB for names that have a loop-header-phi. When
|
||||
such a phi is created we also record the new name in SSA_NAME_AUX. If
|
||||
this new name exists, then guard_arg was set to this new name
|
||||
(see 1.2 above). Therefore, if guard_arg is not this new name, this is
|
||||
an indication that an exit-phi in GUARD_BB was not yet created, so we
|
||||
take care of it here.
|
||||
*/
|
||||
slpeel_update_phi_nodes_for_guard1 is responsible for
|
||||
creating loop-exit phis in GUARD_BB for names that have a
|
||||
loop-header-phi. When such a phi is created we also record
|
||||
the new name in its current definition. If this new name
|
||||
exists, then guard_arg was set to this new name (see 1.2
|
||||
above). Therefore, if guard_arg is not this new name, this
|
||||
is an indication that an exit-phi in GUARD_BB was not yet
|
||||
created, so we take care of it here. */
|
||||
if (guard_arg == new_name2)
|
||||
continue;
|
||||
arg = guard_arg;
|
||||
|
@ -1059,7 +968,7 @@ slpeel_can_duplicate_loop_p (struct loop *loop, edge e)
|
|||
tree orig_cond = get_loop_exit_condition (loop);
|
||||
block_stmt_iterator loop_exit_bsi = bsi_last (exit_e->src);
|
||||
|
||||
if (any_marked_for_rewrite_p ())
|
||||
if (need_ssa_update_p ())
|
||||
return false;
|
||||
|
||||
if (loop->inner
|
||||
|
@ -1214,8 +1123,7 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
|
|||
second_loop = loop;
|
||||
}
|
||||
|
||||
definitions = marked_ssa_names ();
|
||||
allocate_new_names (definitions);
|
||||
definitions = ssa_names_to_replace ();
|
||||
slpeel_update_phis_for_duplicate_loop (loop, new_loop, e == exit_e);
|
||||
rename_variables_in_loop (new_loop);
|
||||
|
||||
|
@ -1296,9 +1204,8 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop, struct loops *loops,
|
|||
if (update_first_loop_count)
|
||||
slpeel_make_loop_iterate_ntimes (first_loop, first_niters);
|
||||
|
||||
free_new_names (definitions);
|
||||
BITMAP_FREE (definitions);
|
||||
unmark_all_for_rewrite ();
|
||||
delete_update_ssa ();
|
||||
|
||||
return new_loop;
|
||||
}
|
||||
|
|
|
@ -2833,13 +2833,6 @@ extern void replace_ssa_name_symbol (tree, tree);
|
|||
extern void ssanames_print_statistics (void);
|
||||
#endif
|
||||
|
||||
extern void mark_for_rewrite (tree);
|
||||
extern void unmark_all_for_rewrite (void);
|
||||
extern bool marked_for_rewrite_p (tree);
|
||||
extern bool any_marked_for_rewrite_p (void);
|
||||
extern struct bitmap_head_def *marked_ssa_names (void);
|
||||
|
||||
|
||||
/* Return the (unique) IDENTIFIER_NODE node for a given name.
|
||||
The name is supplied as a char *. */
|
||||
|
||||
|
|
Loading…
Reference in New Issue