summaryrefslogtreecommitdiff
path: root/gcc/loop-invariant.c
diff options
context:
space:
mode:
authorzadeck <zadeck@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-11 12:57:18 +0000
committerzadeck <zadeck@138bc75d-0d04-0410-961f-82ee72b054a4>2006-01-11 12:57:18 +0000
commite011eba9edce426cbde12b0b43cd4b274b2172d0 (patch)
tree458130d4608c530b1bd76381cc853507472b4512 /gcc/loop-invariant.c
parentbef994231589eb141452b52e2159aa5cab657c3c (diff)
downloadgcc-e011eba9edce426cbde12b0b43cd4b274b2172d0.tar.gz
2005-01-11 Danny Berlin <dberlin@dberlin.org>
Kenneth Zadeck <zadeck@naturalbridge.com> * df.h (DF_SCAN, DF_RU, DF_RD, DF_LR, DF_UR, DF_UREC, DF_CHAIN, DF_RI, DF_LAST_PROBLEM_PLUS1, DF_DU_CHAIN, DF_UD_CHAIN, DF_REF_TYPE_NAMES, DF_HARD_REGS, DF_EQUIV_NOTES, DF_SUBREGS, DF_SCAN_BB_INFO, DF_RU_BB_INFO, DF_RD_BB_INFO, DF_LR_BB_INFO, DF_UR_BB_INFO, DF_UREC_BB_INFO, DF_LIVE_IN, DF_LIVE_OUT, DF_RA_LIVE_IN, DF_RA_LIVE_OUT, DF_UPWARD_LIVE_IN, DF_UPWARD_LIVE_OUT, DF_REF_REAL_REG, DF_REF_REGNO, DF_REF_REAL_LOC, DF_REF_REG, DF_REF_LOC, DF_REF_BB, DF_REF_BBNO, DF_REF_INSN, DF_REF_INSN_UID, DF_REF_TYPE, DF_REF_CHAIN, DF_REF_ID, DF_REF_FLAGS, DF_REF_NEXT_REG, DF_REF_PREV_REG, DF_REF_NEXT_REF, DF_REF_DATA, DF_REF_REG_DEF_P, DF_REF_REG_USE_P, DF_REF_REG_MEM_STORE_P, DF_REF_REG_MEM_LOAD_P, DF_REF_REG_MEM_P, DF_DEFS_SIZE, DF_DEFS_GET, DF_DEFS_SET, DF_USES_SIZE, DF_USES_GET, DF_USES_SET, DF_REG_SIZE, DF_REG_DEF_GET, DF_REG_DEF_SET, DF_REG_USE_GET, DF_REG_USE_SET, DF_REGNO_FIRST_DEF, DF_REGNO_LAST_USE, DF_INSN_SIZE, DF_INSN_GET, DF_INSN_SET, DF_INSN_CONTAINS_ASM, DF_INSN_LUID, DF_INSN_DEFS, DF_INSN_USES, DF_INSN_UID_GET, DF_INSN_UID_LUID, DF_INSN_UID_DEFS, DF_INSN_UID_USES, DF_SCAN_INITIAL, DF_SCAN_GLOBAL, DF_SCAN_POST_ALLOC): New macros. (df_flow_dir, df_ref_type, df_ref_flags, df_alloc_function, df_free_bb_function, df_local_compute_function, df_init_function, df_dataflow_function, df_confluence_function_0, df_confluence_function_n, df_transfer_function, df_finalizer_function, df_free_function, df_dump_problem_function, df_problem, dataflow, df_insn_info, df_reg_info, df_ref, df_link, df_ref_info, df, df_map, df_scan_bb_info, df_ru_bb_info, df_ru_bb_info, df_rd_bb_info, df_lr_bb_info, df_ur_bb_info, df_urec_bb_info, ) New types. (df_invalidated_by_call, df_all_hard_regs, df_state) New public variables. (df_init, df_add_problem, df_set_blocks, df_finish, df_analyze, df_analyze_simple_change_some_blocks, df_analyze_simple_change_one_block, df_compact_blocks, df_bb_replace, df_bb_regno_last_use_find, df_bb_regno_first_def_find, df_bb_regno_last_def_find, df_insn_regno_def_p, df_find_def, df_find_use, df_iterative_dataflow, df_dump, df_chain_dump, df_refs_chain_dump, df_regs_chain_dump, df_insn_debug, df_insn_debug_regno, df_regno_debug, df_ref_debug, debug_df_insn, debug_df_regno, debug_df_reg, debug_df_defno, debug_df_useno, debug_df_ref, debug_df_chain, df_get_dependent_problem, df_chain_create, df_chain_unlink, df_chain_copy, df_get_live_in, df_get_live_out, df_grow_bb_info, df_chain_dump, df_print_bb_index, df_ru_add_problem, df_ru_get_bb_info, df_rd_add_problem, df_rd_get_bb_info, df_lr_add_problem, df_lr_get_bb_info, df_ur_add_problem, df_ur_get_bb_info, df_urec_add_problem, df_urec_get_bb_info, df_chain_add_problem, df_ri_add_problem, df_reg_lifetime, df_scan_get_bb_info, df_scan_add_problem, df_rescan_blocks, df_ref_create, df_get_artificial_defs, df_get_artificial_uses, df_reg_chain_create, df_reg_chain_unlink, df_ref_remove, df_insn_refs_delete, df_refs_delete, df_reorganize_refs, df_set_state, df_hard_reg_init, df_read_modify_subreg_p) New public functions. * df-core.c: The core dataflow solver and glue routines for rtl dataflow. (df_init, df_add_problem, df_set_blocks, df_finish, df_hybrid_search_forward, df_hybrid_search_backward, df_iterative_dataflow, df_prune_to_subcfg, df_analyze_problem, df_analyze, df_get_bb_info, df_set_bb_info, df_bb_replace, df_bb_regno_last_use_find, df_bb_regno_first_def_find, df_bb_regno_last_def_find, df_insn_regno_def_p, df_find_def, df_reg_defined, df_find_use, df_reg_used, df_dump, df_refs_chain_dump, df_regs_chain_dump, df_insn_debug, df_insn_debug_regno, df_regno_debug, df_ref_debug, debug_df_insn, debug_df_reg, debug_df_regno, debug_df_ref debug_df_defno, debug_df_useno, reset_df_after_reload): New functions. * df-scan.c: The scanning fuctions, once in df.c, completely rewritten so that they now fully model the functionality of register usage at the backend. (df_scan_free_internal, df_scan_get_bb_info, df_scan_set_bb_info, df_scan_free_bb_info, df_scan_alloc, df_scan_free, df_scan_dump, df_scan_add_problem, df_grow_reg_info, df_grow_ref_info, df_grow_insn_info, df_rescan_blocks, df_ref_create, df_get_artificial_defs, df_get_artificial_uses, df_reg_chain_create, df_ref_unlink, df_reg_chain_unlink, df_ref_remove, df_insn_create_insn_record, df_insn_refs_delete, df_refs_delete, df_reorganize_refs, df_set_state, df_ref_create_structure, df_ref_record, df_read_modify_subreg_p, df_def_record_1, df_defs_record, df_uses_record, df_insn_contains_asm_1, df_insn_contains_asm, df_insn_refs_record, df_has_eh_preds, df_bb_refs_record, df_refs_record, df_mark_reg, df_record_exit_block_uses, df_hard_reg_init): New functions. * df-problems.c: Seven concrete dataflow problems that use the scanning in df-scan.c and are solved by the engine in df-core.c. (df_get_dependent_problem, df_chain_create, df_chain_unlink, df_chain_copy, df_get_live_in, df_get_live_out, df_grow_bb_info, df_chain_dump, df_print_bb_index, df_ref_bitmap, df_set_seen, df_unset_seen, df_ru_get_bb_info, df_ru_set_bb_info, df_ru_free_bb_info, df_ru_alloc, df_ru_bb_local_compute_process_def, df_ru_bb_local_compute_process_use, df_ru_bb_local_compute, df_ru_local_compute, df_ru_init_solution, df_ru_confluence_n, df_ru_transfer_function, df_ru_free, df_ru_dump, df_ru_add_problem, df_rd_get_bb_info, df_rd_set_bb_info, df_rd_free_bb_info, df_rd_alloc, df_rd_bb_local_compute_process_def, df_rd_bb_local_compute, df_rd_local_compute, df_rd_init_solution, df_rd_confluence_n, df_rd_transfer_function, df_rd_free, df_rd_dump, df_rd_add_problem, df_lr_get_bb_info, df_lr_set_bb_info, df_lr_free_bb_info, df_lr_alloc, df_lr_bb_local_compute, df_lr_local_compute, df_lr_init, df_lr_confluence_0, df_lr_confluence_n, df_lr_transfer_function, df_lr_free, df_lr_dump, df_lr_add_problem, df_ur_get_bb_info, df_ur_set_bb_info, df_ur_free_bb_info, df_ur_alloc, df_ur_bb_local_compute, df_ur_local_compute, df_ur_init, df_ur_local_finalize, df_ur_confluence_n, df_ur_transfer_function, df_ur_free, df_ur_dump, df_ur_add_problem, df_urec_get_bb_info, df_urec_set_bb_info, df_urec_free_bb_info, df_urec_alloc, df_urec_mark_reg_change, df_urec_check_earlyclobber, df_urec_mark_reg_use_for_earlyclobber, df_urec_mark_reg_use_for_earlyclobber_1, df_urec_bb_local_compute, df_urec_local_compute, df_urec_init, df_urec_local_finalize, df_urec_confluence_n, df_urec_transfer_function, df_urec_free, df_urec_dump, df_urec_add_problem, df_chain_alloc, df_chain_create_bb_process_use, df_chain_create_bb, df_chain_finalize, df_chain_free, df_chains_dump, df_chain_add_problem, df_ri_alloc, df_ri_bb_compute, df_ri_compute, df_ri_free, df_ri_dump, df_ri_add_problem, df_reg_lifetime): New functions. * df.c: Deleted file. * ddg.c (create_ddg_dep_no_link, build_inter_loop_deps): Made code consistent with new df api. * modulo-sched.c (sms_schedule, rest_of_handle_sms, rest_of_handle_sms): Ditto. * web.c (unionfind_union, union_defs, entry_register, web_main): Ditto. * loop_invariant.c (invariant_for_use, hash_invariant_expr_1, invariant_expr_equal_p, find_defs, check_dependencies, find_invariant_insn, find_invariants_to_move, move_invariant_reg, free_inv_motion_data, move_loop_invariants): Ditto. * sched-deps.c (sched_analyze_1): Ditto. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109577 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop-invariant.c')
-rw-r--r--gcc/loop-invariant.c68
1 files changed, 31 insertions, 37 deletions
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 8c3f2d23512..96d216e2672 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -1,5 +1,5 @@
/* RTL-level loop invariant motion.
- Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
This file is part of GCC.
@@ -153,7 +153,7 @@ static VEC(invariant_p,heap) *invariants;
/* The dataflow object. */
-static struct df *df;
+static struct df *df = NULL;
/* Test for possibility of invariantness of X. */
@@ -226,10 +226,10 @@ check_maybe_invariant (rtx x)
invariant. */
static struct invariant *
-invariant_for_use (struct ref *use)
+invariant_for_use (struct df_ref *use)
{
struct df_link *defs;
- struct ref *def;
+ struct df_ref *def;
basic_block bb = BLOCK_FOR_INSN (use->insn), def_bb;
defs = DF_REF_CHAIN (use);
@@ -255,7 +255,7 @@ hash_invariant_expr_1 (rtx insn, rtx x)
const char *fmt;
hashval_t val = code;
int do_not_record_p;
- struct ref *use;
+ struct df_ref *use;
struct invariant *inv;
switch (code)
@@ -306,7 +306,7 @@ invariant_expr_equal_p (rtx insn1, rtx e1, rtx insn2, rtx e2)
enum rtx_code code = GET_CODE (e1);
int i, j;
const char *fmt;
- struct ref *use1, *use2;
+ struct df_ref *use1, *use2;
struct invariant *inv1 = NULL, *inv2 = NULL;
rtx sub1, sub2;
@@ -600,7 +600,8 @@ find_defs (struct loop *loop, basic_block *body)
for (i = 0; i < loop->num_nodes; i++)
bitmap_set_bit (blocks, body[i]->index);
- df_analyze_subcfg (df, blocks, DF_UD_CHAIN | DF_HARD_REGS | DF_EQUIV_NOTES);
+ df_set_blocks (df, blocks);
+ df_analyze (df);
BITMAP_FREE (blocks);
}
@@ -673,16 +674,14 @@ record_use (struct def *def, rtx *use, rtx insn)
static bool
check_dependencies (rtx insn, bitmap depends_on)
{
- struct df_link *uses, *defs;
- struct ref *use, *def;
+ struct df_link *defs;
+ struct df_ref *use, *def;
basic_block bb = BLOCK_FOR_INSN (insn), def_bb;
struct def *def_data;
struct invariant *inv;
- for (uses = DF_INSN_USES (df, insn); uses; uses = uses->next)
+ for (use = DF_INSN_GET (df, insn)->uses; use; use = use->next_ref)
{
- use = uses->ref;
-
defs = DF_REF_CHAIN (use);
if (!defs)
continue;
@@ -718,7 +717,7 @@ check_dependencies (rtx insn, bitmap depends_on)
static void
find_invariant_insn (rtx insn, bool always_reached, bool always_executed)
{
- struct ref *ref;
+ struct df_ref *ref;
struct def *def;
bitmap depends_on;
rtx set, dest;
@@ -781,13 +780,11 @@ find_invariant_insn (rtx insn, bool always_reached, bool always_executed)
static void
record_uses (rtx insn)
{
- struct df_link *uses;
- struct ref *use;
+ struct df_ref *use;
struct invariant *inv;
- for (uses = DF_INSN_USES (df, insn); uses; uses = uses->next)
+ for (use = DF_INSN_GET (df, insn)->uses; use; use = use->next_ref)
{
- use = uses->ref;
inv = invariant_for_use (use);
if (inv)
record_use (inv->def, DF_REF_LOC (use), DF_REF_INSN (use));
@@ -1025,6 +1022,7 @@ find_invariants_to_move (void)
{
unsigned i, regs_used, n_inv_uses, regs_needed = 0, new_regs;
struct invariant *inv = NULL;
+ unsigned int n_regs = DF_REG_SIZE (df);
if (!VEC_length (invariant_p, invariants))
return;
@@ -1037,7 +1035,7 @@ find_invariants_to_move (void)
here to stand for induction variables etc. that we do not detect. */
regs_used = 2;
- for (i = 0; i < df->n_regs; i++)
+ for (i = 0; i < n_regs; i++)
{
if (!DF_REGNO_FIRST_DEF (df, i) && DF_REGNO_LAST_USE (df, i))
{
@@ -1098,8 +1096,7 @@ move_invariant_reg (struct loop *loop, unsigned invno)
need to create a temporary register. */
set = single_set (inv->insn);
reg = gen_reg_rtx (GET_MODE (SET_DEST (set)));
- df_pattern_emit_after (df, gen_move_insn (SET_DEST (set), reg),
- BLOCK_FOR_INSN (inv->insn), inv->insn);
+ emit_insn_after (gen_move_insn (SET_DEST (set), reg), inv->insn);
/* If the SET_DEST of the invariant insn is a reg, we can just move
the insn out of the loop. Otherwise, we have to use gen_move_insn
@@ -1108,13 +1105,11 @@ move_invariant_reg (struct loop *loop, unsigned invno)
{
SET_DEST (set) = reg;
reorder_insns (inv->insn, inv->insn, BB_END (preheader));
- df_insn_modify (df, preheader, inv->insn);
}
else
{
- df_pattern_emit_after (df, gen_move_insn (reg, SET_SRC (set)),
- preheader, BB_END (preheader));
- df_insn_delete (df, BLOCK_FOR_INSN (inv->insn), inv->insn);
+ emit_insn_after (gen_move_insn (reg, SET_SRC (set)), BB_END (preheader));
+ delete_insn (inv->insn);
}
}
else
@@ -1122,9 +1117,8 @@ move_invariant_reg (struct loop *loop, unsigned invno)
move_invariant_reg (loop, repr->invno);
reg = repr->reg;
set = single_set (inv->insn);
- df_pattern_emit_after (df, gen_move_insn (SET_DEST (set), reg),
- BLOCK_FOR_INSN (inv->insn), inv->insn);
- df_insn_delete (df, BLOCK_FOR_INSN (inv->insn), inv->insn);
+ emit_insn_after (gen_move_insn (SET_DEST (set), reg), inv->insn);
+ delete_insn (inv->insn);
}
inv->reg = reg;
@@ -1135,10 +1129,7 @@ move_invariant_reg (struct loop *loop, unsigned invno)
if (inv->def)
{
for (use = inv->def->uses; use; use = use->next)
- {
- *use->pos = reg;
- df_insn_modify (df, BLOCK_FOR_INSN (use->insn), use->insn);
- }
+ *use->pos = reg;
}
}
@@ -1174,20 +1165,22 @@ free_inv_motion_data (void)
struct def *def;
struct invariant *inv;
- for (i = 0; i < df->n_defs; i++)
+ for (i = 0; i < DF_DEFS_SIZE (df); i++)
{
- if (!df->defs[i])
+ struct df_ref * ref = DF_DEFS_GET (df, i);
+ if (!ref)
continue;
- inv = DF_REF_DATA (df->defs[i]);
+ inv = DF_REF_DATA (ref);
if (!inv)
continue;
+
def = inv->def;
gcc_assert (def != NULL);
free_use_list (def->uses);
free (def);
- DF_REF_DATA (df->defs[i]) = NULL;
+ DF_REF_DATA (ref) = NULL;
}
for (i = 0; VEC_iterate (invariant_p, invariants, i, inv); i++)
@@ -1231,8 +1224,9 @@ move_loop_invariants (struct loops *loops)
struct loop *loop;
unsigned i;
- df = df_init ();
-
+ df = df_init (DF_HARD_REGS | DF_EQUIV_NOTES);
+ df_chain_add_problem (df, DF_UD_CHAIN);
+
/* Process the loops, innermost first. */
loop = loops->tree_root;
while (loop->inner)