diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-08-11 20:07:24 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1997-08-11 20:07:24 +0000 |
commit | ea0cb7ae5f6f719c7b651fd31451921e2528bea9 (patch) | |
tree | 070833bf20a821eb8d3cb38069e95b6e7b7b9bc6 /gcc/unroll.c | |
parent | 4b9aed89bf62bbb194c293844ffbee2c76a17726 (diff) | |
download | ppe42-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.c | 56 |
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); |