summaryrefslogtreecommitdiffstats
path: root/gcc/unroll.c
diff options
context:
space:
mode:
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1997-08-11 20:07:24 +0000
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>1997-08-11 20:07:24 +0000
commitea0cb7ae5f6f719c7b651fd31451921e2528bea9 (patch)
tree070833bf20a821eb8d3cb38069e95b6e7b7b9bc6 /gcc/unroll.c
parent4b9aed89bf62bbb194c293844ffbee2c76a17726 (diff)
downloadppe42-gcc-ea0cb7ae5f6f719c7b651fd31451921e2528bea9.tar.gz
ppe42-gcc-ea0cb7ae5f6f719c7b651fd31451921e2528bea9.zip
* Integrate alias analysis changes from jfc@mit.edu
* Makefile.in (OBJS): Add alias.o (alias.o): Add dependencies. * alias.c: New file. * sched.c: Remove alias analysis code. It lives in alias.c now. (reg_last_uses_size): Declare. (sched_analyze_2): Add new arguments to true_dependence. (sched_analyze_insn): Use reg_last_uses_size instead of max_reg. (schedule_block): Initialize reg_last_uses_size. (schedule_insns): Always call init_alias_analysis. * calls.c (expand_call): Note calls to malloc, calloc, and realloc; mark return value from such functions as a pointer and keep track of them for alias analysis. If a return value from a function is a pointer, mark it as such. * combine.c (distribute_notes): Handle REG_NOALIAS. * cse.c (struct write_data): Delete. No longer needed. (invalidate): Don't call set_nonvarying_address_components anymore. Use true_dependence to decide if an entry should be removed from the hash table. (invalidate_memory): Remove WRITES argument, simplify appropriately. Fix all callers. (note_mem_written): Similarly for WRITE_PTR argument. (invalidate_from_clobbers): Similarly for W argument. (invalidate_for_call): Remove memory elements from the hash table. (refers_to_mem_p, cse_rtx_addr_varies_p): Deleted. (cse_rtx_varies_p): New function. Derived from old cse_rtx_addr_varies_p. (cse_insn): Remove WRITES_MEMORY and INIT variables and all references. Don't call note_mem_written anymore. Stack pushes invalidate the stack pointer if PUSH_ROUNDING is defined. No longer need to call cse_rtx_addr_varies_p to decide if a MEM should be invalidated. (skipped_writes_memory): Remove variable. (invalidate_skipped_set): Simplify and wewrite to use invalidate_memory. (invalidate_skipped_block): Simplify for new alias analysis code. (cse_set_around_loop): Likewise. (cse_main): Call init_alias_analysis. * flags.h (flag_alias_check, flag_argument_noalias): Declare. * toplev.c (flag_alias_check, flag_argument_noalias): Define. (f_options): Add new alias checking arguments. (main): Set flag_alias_check when optimizing. * local_alloc (validate_equiv_mem_from_store): Add new arguments to true_dependence. (memref_referenced_p): Likewise. * loop.c (NUM_STORES): Increase to 30. (prescan_loop): Only non-constant calls set unknown_address_altered. (invariant_p): Add new arguments to true_dependence. (record_giv): Initialize unrolled and shared fields. (emit_iv_add_mult): Call record_base_value as needed. * loop.h (struct induction): Add unrolled and shared fields. * unroll.c (unroll_loop): Call record_base_value as needed. (copy_loop_body): Likewise. (final_biv_value): Likewise. (final_giv_value): Likewise. (find_splittable_regs): Likewise. Only create one new pseudo if we have multiple address GIVs that were combined with the same dst_reg GIV. Note when a new register is created due to unrolling. * rtl.c (reg_note_name): Add REG_NOALIAS. * rtl.h (enum reg_note): Similarly. (rtx_varies_p, may_trap_p, side_effects_p): Declare. (volatile_refs_p, volatile_insn_p, remove_note): Likewise. (note_stores, refers_to_regno_p, reg_overlap_mentioned_p): Likewise. (true_dependence, read_dependence, anti_dependence): Likewise. (output_dependence, init_alias_analysis, end_alias_analysis): Likewise. (mark_user_reg, mark_reg_pointer): Likewise. jfc's alias analysis code. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14768 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/unroll.c')
-rw-r--r--gcc/unroll.c56
1 files changed, 39 insertions, 17 deletions
diff --git a/gcc/unroll.c b/gcc/unroll.c
index 23bf6d372c1..46339988ede 100644
--- a/gcc/unroll.c
+++ b/gcc/unroll.c
@@ -1046,8 +1046,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
if (local_regno[j])
- map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
-
+ {
+ map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
+ record_base_value (REGNO (map->reg_map[j]),
+ regno_reg_rtx[j]);
+ }
/* The last copy needs the compare/branch insns at the end,
so reset copy_end here if the loop ends with a conditional
branch. */
@@ -1191,7 +1194,11 @@ unroll_loop (loop_end, insn_count, loop_start, end_insert_before,
for (j = FIRST_PSEUDO_REGISTER; j < max_reg_before_loop; j++)
if (local_regno[j])
- map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
+ {
+ map->reg_map[j] = gen_reg_rtx (GET_MODE (regno_reg_rtx[j]));
+ record_base_value (REGNO (map->reg_map[j]),
+ regno_reg_rtx[j]);
+ }
/* If loop starts with a branch to the test, then fix it so that
it points to the test of the first unrolled copy of the loop. */
@@ -1691,7 +1698,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
/* Check for shared address givs, and avoid
incrementing the shared pseudo reg more than
once. */
- if (! tv->same_insn)
+ if (! tv->same_insn && ! tv->shared)
{
/* tv->dest_reg may actually be a (PLUS (REG)
(CONST)) here, so we must call plus_constant
@@ -1817,6 +1824,7 @@ copy_loop_body (copy_start, copy_end, map, exit_label, last_iteration,
tem = gen_reg_rtx (GET_MODE (giv_src_reg));
giv_dest_reg = tem;
map->reg_map[regno] = tem;
+ record_base_value (REGNO (tem), giv_src_reg);
}
else
map->reg_map[regno] = giv_src_reg;
@@ -2505,7 +2513,8 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
|| ! invariant_p (bl->initial_value)))
{
rtx tem = gen_reg_rtx (bl->biv->mode);
-
+
+ record_base_value (REGNO (tem), bl->biv->add_val);
emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
loop_start);
@@ -2562,6 +2571,8 @@ find_splittable_regs (unroll_type, loop_start, loop_end, end_insert_before,
this insn will always be executed, no matter how the loop
exits. */
rtx tem = gen_reg_rtx (bl->biv->mode);
+ record_base_value (REGNO (tem), bl->biv->add_val);
+
emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
loop_start);
emit_insn_before (gen_move_insn (bl->biv->src_reg,
@@ -2737,6 +2748,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
{
rtx tem = gen_reg_rtx (bl->biv->mode);
+ record_base_value (REGNO (tem), bl->biv->add_val);
emit_insn_before (gen_move_insn (tem, bl->biv->src_reg),
loop_start);
biv_initial_value = tem;
@@ -2778,6 +2790,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
|| GET_CODE (XEXP (value, 1)) != CONST_INT))
{
rtx tem = gen_reg_rtx (v->mode);
+ record_base_value (REGNO (tem), v->add_val);
emit_iv_add_mult (bl->initial_value, v->mult_val,
v->add_val, tem, loop_start);
value = tem;
@@ -2796,16 +2809,9 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
what we want for split addr regs. We always create a new
register for the split addr giv, just to be safe. */
- /* ??? If there are multiple address givs which have been
- combined with the same dest_reg giv, then we may only need
- one new register for them. Pulling out constants below will
- catch some of the common cases of this. Currently, I leave
- the work of simplifying multiple address givs to the
- following cse pass. */
-
- /* As a special case, if we have multiple identical address givs
- within a single instruction, then we do use a single pseudo
- reg for both. This is necessary in case one is a match_dup
+ /* If we have multiple identical address givs within a
+ single instruction, then use a single pseudo reg for
+ both. This is necessary in case one is a match_dup
of the other. */
v->const_adjust = 0;
@@ -2818,12 +2824,26 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
"Sharing address givs in insn %d\n",
INSN_UID (v->insn));
}
+ /* If multiple address GIVs have been combined with the
+ same dest_reg GIV, do not create a new register for
+ each. */
+ else if (unroll_type != UNROLL_COMPLETELY
+ && v->giv_type == DEST_ADDR
+ && v->same && v->same->giv_type == DEST_ADDR
+ && v->same->unrolled)
+ {
+ v->dest_reg = v->same->dest_reg;
+ v->shared = 1;
+ }
else if (unroll_type != UNROLL_COMPLETELY)
{
/* If not completely unrolling the loop, then create a new
register to hold the split value of the DEST_ADDR giv.
Emit insn to initialize its value before loop start. */
- tem = gen_reg_rtx (v->mode);
+
+ rtx tem = gen_reg_rtx (v->mode);
+ record_base_value (REGNO (tem), v->add_val);
+ v->unrolled = 1;
/* If the address giv has a constant in its new_reg value,
then this constant can be pulled out and put in value,
@@ -2834,7 +2854,7 @@ find_splittable_givs (bl, unroll_type, loop_start, loop_end, increment,
{
v->dest_reg
= plus_constant (tem, INTVAL (XEXP (v->new_reg,1)));
-
+
/* Only succeed if this will give valid addresses.
Try to validate both the first and the last
address resulting from loop unrolling, if
@@ -3130,6 +3150,7 @@ final_biv_value (bl, loop_start, loop_end)
case it is needed later. */
tem = gen_reg_rtx (bl->biv->mode);
+ record_base_value (REGNO (tem), bl->biv->add_val);
/* Make sure loop_end is not the last insn. */
if (NEXT_INSN (loop_end) == 0)
emit_note_after (NOTE_INSN_DELETED, loop_end);
@@ -3228,6 +3249,7 @@ final_giv_value (v, loop_start, loop_end)
/* Put the final biv value in tem. */
tem = gen_reg_rtx (bl->biv->mode);
+ record_base_value (REGNO (tem), bl->biv->add_val);
emit_iv_add_mult (increment, GEN_INT (loop_n_iterations),
bl->initial_value, tem, insert_before);
OpenPOWER on IntegriCloud