This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
haifa and clobbers
- To: egcs-patches at egcs dot cygnus dot com
- Subject: haifa and clobbers
- From: Richard Henderson <rth at cygnus dot com>
- Date: Sun, 7 Mar 1999 11:20:43 -0800
Clobbers should not interfere with each other wrt scheduling;
removing this restriction allows for a bit more freedom in
slotting instructions.
Of course dependancies wrt uses or sets are still required.
This was reviewed by Jeff.
r~
* haifa-sched.c (reg_last_clobbers): New.
(reg_pending_clobbers, bb_reg_last_clobbers): New.
(compute_block_backward_dependences): Allocate memory for them.
(schedule_region): Likewise.
(sched_analyze_1): Clobbers don't interfere with one another.
They do interfere with sets ...
(sched_analyze_2): ... and uses.
(sched_analyze): Likewise.
(sched_analyze_insn): Update reg_last_clobbers appropriately.
Index: haifa-sched.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/haifa-sched.c,v
retrieving revision 1.81
diff -c -p -d -r1.81 haifa-sched.c
*** haifa-sched.c 1999/02/25 23:45:21 1.81
--- haifa-sched.c 1999/03/07 19:15:14
*************** static int current_block_num;
*** 251,257 ****
--- 251,259 ----
by splitting insns. */
static rtx *reg_last_uses;
static rtx *reg_last_sets;
+ static rtx *reg_last_clobbers;
static regset reg_pending_sets;
+ static regset reg_pending_clobbers;
static int reg_pending_sets_all;
/* Vector indexed by INSN_UID giving the original ordering of the insns. */
*************** static rtx last_scheduled_insn;
*** 1054,1059 ****
--- 1056,1062 ----
static rtx **bb_reg_last_uses;
static rtx **bb_reg_last_sets;
+ static rtx **bb_reg_last_clobbers;
static rtx *bb_pending_read_insns;
static rtx *bb_pending_read_mems;
*************** sched_analyze_1 (x, insn)
*** 3309,3314 ****
--- 3312,3318 ----
{
register int regno;
register rtx dest = SET_DEST (x);
+ enum rtx_code code = GET_CODE (x);
if (dest == 0)
return;
*************** sched_analyze_1 (x, insn)
*** 3358,3367 ****
for (u = reg_last_sets[regno + i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
! SET_REGNO_REG_SET (reg_pending_sets, regno + i);
! if ((call_used_regs[regno + i] || global_regs[regno + i]))
! /* Function calls clobber all call_used regs. */
for (u = last_function_call; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
}
--- 3362,3381 ----
for (u = reg_last_sets[regno + i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
! /* Clobbers need not be ordered with respect to one another,
! but sets must be ordered with respect to a pending clobber. */
! if (code == SET)
! {
! for (u = reg_last_clobbers[regno + i]; u; u = XEXP (u, 1))
! add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
! SET_REGNO_REG_SET (reg_pending_sets, regno + i);
! }
! else
! SET_REGNO_REG_SET (reg_pending_clobbers, regno + i);
! /* Function calls clobber all call_used regs. */
! if (global_regs[regno + i]
! || (code == SET && call_used_regs[regno + i]))
for (u = last_function_call; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
}
*************** sched_analyze_1 (x, insn)
*** 3377,3383 ****
for (u = reg_last_sets[regno]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
! SET_REGNO_REG_SET (reg_pending_sets, regno);
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
--- 3391,3400 ----
for (u = reg_last_sets[regno]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_OUTPUT);
! if (code == SET)
! SET_REGNO_REG_SET (reg_pending_sets, regno);
! else
! SET_REGNO_REG_SET (reg_pending_clobbers, regno);
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
*************** sched_analyze_2 (x, insn)
*** 3528,3533 ****
--- 3545,3554 ----
for (u = reg_last_sets[regno + i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+ /* ??? This should never happen. */
+ for (u = reg_last_clobbers[regno + i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
+
if ((call_used_regs[regno + i] || global_regs[regno + i]))
/* Function calls clobber all call_used regs. */
for (u = last_function_call; u; u = XEXP (u, 1))
*************** sched_analyze_2 (x, insn)
*** 3541,3546 ****
--- 3562,3571 ----
for (u = reg_last_sets[regno]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+ /* ??? This should never happen. */
+ for (u = reg_last_clobbers[regno]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
+
/* Pseudos that are REG_EQUIV to something may be replaced
by that during reloading. We need only add dependencies for
the address in the REG_EQUIV note. */
*************** sched_analyze_2 (x, insn)
*** 3631,3639 ****
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
- /* reg_last_sets[r] is now a list of insns */
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
--- 3656,3666 ----
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+
+ for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
*************** sched_analyze_insn (x, insn, loop_notes)
*** 3762,3770 ****
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
- /* reg_last_sets[r] is now a list of insns */
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
--- 3789,3799 ----
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+
+ for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
*************** sched_analyze_insn (x, insn, loop_notes)
*** 3773,3792 ****
}
EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
{
- /* reg_last_sets[r] is now a list of insns */
free_list (®_last_sets[i], &unused_insn_list);
reg_last_sets[i]
= alloc_INSN_LIST (insn, NULL_RTX);
});
CLEAR_REG_SET (reg_pending_sets);
if (reg_pending_sets_all)
{
for (i = 0; i < maxreg; i++)
{
- /* reg_last_sets[r] is now a list of insns */
free_list (®_last_sets[i], &unused_insn_list);
reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
}
--- 3802,3830 ----
}
+ /* Accumulate clobbers until the next set so that it will be output dependant
+ on all of them. At the next set we can clear the clobber list, since
+ subsequent sets will be output dependant on it. */
EXECUTE_IF_SET_IN_REG_SET (reg_pending_sets, 0, i,
{
free_list (®_last_sets[i], &unused_insn_list);
+ free_list (®_last_clobbers[i],
+ &unused_insn_list);
reg_last_sets[i]
= alloc_INSN_LIST (insn, NULL_RTX);
});
+ EXECUTE_IF_SET_IN_REG_SET (reg_pending_clobbers, 0, i,
+ {
+ reg_last_clobbers[i]
+ = alloc_INSN_LIST (insn, reg_last_clobbers[i]);
+ });
CLEAR_REG_SET (reg_pending_sets);
+ CLEAR_REG_SET (reg_pending_clobbers);
if (reg_pending_sets_all)
{
for (i = 0; i < maxreg; i++)
{
free_list (®_last_sets[i], &unused_insn_list);
reg_last_sets[i] = alloc_INSN_LIST (insn, NULL_RTX);
}
*************** sched_analyze (head, tail)
*** 3884,3892 ****
reg_last_uses[i] = 0;
- /* reg_last_sets[r] is now a list of insns */
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
--- 3922,3932 ----
reg_last_uses[i] = 0;
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), 0);
+
+ for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), 0);
}
reg_pending_sets_all = 1;
*************** sched_analyze (head, tail)
*** 3909,3918 ****
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
- /* reg_last_sets[r] is now a list of insns */
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
SET_REGNO_REG_SET (reg_pending_sets, i);
}
}
--- 3949,3961 ----
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
reg_last_uses[i] = 0;
for (u = reg_last_sets[i]; u; u = XEXP (u, 1))
add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
+ if (global_regs[i])
+ for (u = reg_last_clobbers[i]; u; u = XEXP (u, 1))
+ add_dependence (insn, XEXP (u, 0), REG_DEP_ANTI);
+
SET_REGNO_REG_SET (reg_pending_sets, i);
}
}
*************** compute_block_backward_dependences (bb)
*** 7232,7240 ****
--- 7275,7285 ----
{
reg_last_uses = (rtx *) alloca (max_reg * sizeof (rtx));
reg_last_sets = (rtx *) alloca (max_reg * sizeof (rtx));
+ reg_last_clobbers = (rtx *) alloca (max_reg * sizeof (rtx));
bzero ((char *) reg_last_uses, max_reg * sizeof (rtx));
bzero ((char *) reg_last_sets, max_reg * sizeof (rtx));
+ bzero ((char *) reg_last_clobbers, max_reg * sizeof (rtx));
pending_read_insns = 0;
pending_read_mems = 0;
*************** compute_block_backward_dependences (bb)
*** 7252,7257 ****
--- 7297,7303 ----
{
reg_last_uses = bb_reg_last_uses[bb];
reg_last_sets = bb_reg_last_sets[bb];
+ reg_last_clobbers = bb_reg_last_clobbers[bb];
pending_read_insns = bb_pending_read_insns[bb];
pending_read_mems = bb_pending_read_mems[bb];
*************** compute_block_backward_dependences (bb)
*** 7323,7328 ****
--- 7369,7384 ----
= alloc_INSN_LIST (XEXP (u, 0),
(bb_reg_last_sets[bb_succ])[reg]);
}
+
+ for (u = reg_last_clobbers[reg]; u; u = XEXP (u, 1))
+ {
+ if (find_insn_list (XEXP (u, 0), (bb_reg_last_clobbers[bb_succ])[reg]))
+ continue;
+
+ (bb_reg_last_clobbers[bb_succ])[reg]
+ = alloc_INSN_LIST (XEXP (u, 0),
+ (bb_reg_last_clobbers[bb_succ])[reg]);
+ }
}
/* mem read/write lists are inherited by bb_succ */
*************** compute_block_backward_dependences (bb)
*** 7397,7402 ****
--- 7453,7460 ----
3-5% on average. */
for (b = 0; b < max_reg; ++b)
{
+ if (reg_last_clobbers[b])
+ free_list (®_last_clobbers[b], &unused_insn_list);
if (reg_last_sets[b])
free_list (®_last_sets[b], &unused_insn_list);
if (reg_last_uses[b])
*************** compute_block_backward_dependences (bb)
*** 7408,7413 ****
--- 7466,7472 ----
{
bb_reg_last_uses[bb] = (rtx *) NULL_RTX;
bb_reg_last_sets[bb] = (rtx *) NULL_RTX;
+ bb_reg_last_clobbers[bb] = (rtx *) NULL_RTX;
}
}
*************** schedule_region (rgn)
*** 7560,7565 ****
--- 7619,7625 ----
current_blocks = RGN_BLOCKS (rgn);
reg_pending_sets = ALLOCA_REG_SET ();
+ reg_pending_clobbers = ALLOCA_REG_SET ();
reg_pending_sets_all = 0;
/* initializations for region data dependence analyisis */
*************** schedule_region (rgn)
*** 7571,7591 ****
bb_reg_last_uses = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
! init_rtx_vector (bb_reg_last_uses, space, current_nr_blocks, maxreg * sizeof (rtx *));
bb_reg_last_sets = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
! init_rtx_vector (bb_reg_last_sets, space, current_nr_blocks, maxreg * sizeof (rtx *));
bb_pending_read_insns = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_pending_read_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
! bb_pending_write_insns = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_pending_write_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
! bb_pending_lists_length = (int *) alloca (current_nr_blocks * sizeof (int));
! bb_last_pending_memory_flush = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_last_function_call = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
! bb_sched_before_next_call = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
init_rgn_data_dependences (current_nr_blocks);
}
--- 7631,7664 ----
bb_reg_last_uses = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
! init_rtx_vector (bb_reg_last_uses, space, current_nr_blocks,
! maxreg * sizeof (rtx *));
bb_reg_last_sets = (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
! init_rtx_vector (bb_reg_last_sets, space, current_nr_blocks,
! maxreg * sizeof (rtx *));
!
! bb_reg_last_clobbers =
! (rtx **) alloca (current_nr_blocks * sizeof (rtx *));
! space = (rtx *) alloca (current_nr_blocks * maxreg * sizeof (rtx));
! bzero ((char *) space, current_nr_blocks * maxreg * sizeof (rtx));
! init_rtx_vector (bb_reg_last_clobbers, space, current_nr_blocks,
! maxreg * sizeof (rtx *));
bb_pending_read_insns = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_pending_read_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
! bb_pending_write_insns =
! (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_pending_write_mems = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
! bb_pending_lists_length =
! (int *) alloca (current_nr_blocks * sizeof (int));
! bb_last_pending_memory_flush =
! (rtx *) alloca (current_nr_blocks * sizeof (rtx));
bb_last_function_call = (rtx *) alloca (current_nr_blocks * sizeof (rtx));
! bb_sched_before_next_call =
! (rtx *) alloca (current_nr_blocks * sizeof (rtx));
init_rgn_data_dependences (current_nr_blocks);
}
*************** schedule_region (rgn)
*** 7703,7708 ****
--- 7776,7782 ----
free_pending_lists ();
FREE_REG_SET (reg_pending_sets);
+ FREE_REG_SET (reg_pending_clobbers);
}
/* Subroutine of update_flow_info. Determines whether any new REG_NOTEs are