re PR rtl-optimization/11320 (Scheduler bug)

PR optimization/11320
	* sched-int.h (struct deps) [reg_conditional_sets]: New field.
	(struct sched_info) [compute_jump_reg_dependencies]: New prototype.
	* sched-deps.c (sched_analyze_insn) [JUMP_INSN]: Update call to
	current_sched_info->compute_jump_reg_dependencies. Record which
	registers are used and which registers are set by the jump.
	Clear deps->reg_conditional_sets after a barrier.
	Set deps->reg_conditional_sets if the insn is a COND_EXEC.
	Clear deps->reg_conditional_sets if the insn is not a COND_EXEC.
	(init_deps): Initialize reg_conditional_sets.
	(free_deps): Clear reg_conditional_sets.
	* sched-ebb.c (compute_jump_reg_dependencies): New prototype.
	Mark registers live on entry of the fallthrough block and conditionally
	set as set by the jump. Mark registers live on entry of non-fallthrough
	blocks as used by the jump.
	* sched-rgn.c (compute_jump_reg_dependencies): New prototype.
	Mark new parameters as unused.

From-SVN: r69401
This commit is contained in:
Eric Botcazou 2003-07-15 15:02:21 +02:00 committed by Eric Botcazou
parent 9fa0903819
commit 5a257872da
7 changed files with 103 additions and 18 deletions

View File

@ -1,3 +1,23 @@
2003-07-15 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/11320
* sched-int.h (struct deps) [reg_conditional_sets]: New field.
(struct sched_info) [compute_jump_reg_dependencies]: New prototype.
* sched-deps.c (sched_analyze_insn) [JUMP_INSN]: Update call to
current_sched_info->compute_jump_reg_dependencies. Record which
registers are used and which registers are set by the jump.
Clear deps->reg_conditional_sets after a barrier.
Set deps->reg_conditional_sets if the insn is a COND_EXEC.
Clear deps->reg_conditional_sets if the insn is not a COND_EXEC.
(init_deps): Initialize reg_conditional_sets.
(free_deps): Clear reg_conditional_sets.
* sched-ebb.c (compute_jump_reg_dependencies): New prototype.
Mark registers live on entry of the fallthrough block and conditionally
set as set by the jump. Mark registers live on entry of non-fallthrough
blocks as used by the jump.
* sched-rgn.c (compute_jump_reg_dependencies): New prototype.
Mark new parameters as unused.
2003-07-15 Richard Sandiford <rsandifo@redhat.com>
* doc/invoke.texi: Resync MIPS -march documentation.

View File

@ -864,12 +864,14 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn, rtx loop_notes)
else
{
rtx pending, pending_mem;
regset_head tmp;
INIT_REG_SET (&tmp);
regset_head tmp_uses, tmp_sets;
INIT_REG_SET (&tmp_uses);
INIT_REG_SET (&tmp_sets);
(*current_sched_info->compute_jump_reg_dependencies) (insn, &tmp);
(*current_sched_info->compute_jump_reg_dependencies)
(insn, &deps->reg_conditional_sets, &tmp_uses, &tmp_sets);
/* Make latency of jump equal to 0 by using anti-dependence. */
EXECUTE_IF_SET_IN_REG_SET (&tmp, 0, i,
EXECUTE_IF_SET_IN_REG_SET (&tmp_uses, 0, i,
{
struct deps_reg *reg_last = &deps->reg_last[i];
add_dependence_list (insn, reg_last->sets, REG_DEP_ANTI);
@ -877,7 +879,10 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn, rtx loop_notes)
reg_last->uses_length++;
reg_last->uses = alloc_INSN_LIST (insn, reg_last->uses);
});
CLEAR_REG_SET (&tmp);
IOR_REG_SET (reg_pending_sets, &tmp_sets);
CLEAR_REG_SET (&tmp_uses);
CLEAR_REG_SET (&tmp_sets);
/* All memory writes and volatile reads must happen before the
jump. Non-volatile reads must happen before the jump iff
@ -984,6 +989,7 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn, rtx loop_notes)
}
flush_pending_lists (deps, insn, true, true);
CLEAR_REG_SET (&deps->reg_conditional_sets);
reg_pending_barrier = NOT_A_BARRIER;
}
else
@ -1015,6 +1021,7 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn, rtx loop_notes)
add_dependence_list (insn, reg_last->clobbers, REG_DEP_OUTPUT);
add_dependence_list (insn, reg_last->uses, REG_DEP_ANTI);
reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
SET_REGNO_REG_SET (&deps->reg_conditional_sets, i);
});
}
else
@ -1063,6 +1070,7 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn, rtx loop_notes)
reg_last->sets = alloc_INSN_LIST (insn, reg_last->sets);
reg_last->uses_length = 0;
reg_last->clobbers_length = 0;
CLEAR_REGNO_REG_SET (&deps->reg_conditional_sets, i);
});
}
@ -1385,6 +1393,7 @@ init_deps (struct deps *deps)
deps->reg_last = (struct deps_reg *)
xcalloc (max_reg, sizeof (struct deps_reg));
INIT_REG_SET (&deps->reg_last_in_use);
INIT_REG_SET (&deps->reg_conditional_sets);
deps->pending_read_insns = 0;
deps->pending_read_mems = 0;
@ -1426,6 +1435,7 @@ free_deps (struct deps *deps)
free_INSN_LIST_list (&reg_last->clobbers);
});
CLEAR_REG_SET (&deps->reg_last_in_use);
CLEAR_REG_SET (&deps->reg_conditional_sets);
free (deps->reg_last);
}

View File

@ -55,7 +55,7 @@ static int schedule_more_p (void);
static const char *ebb_print_insn (rtx, int);
static int rank (rtx, rtx);
static int contributes_to_priority (rtx, rtx);
static void compute_jump_reg_dependencies (rtx, regset);
static void compute_jump_reg_dependencies (rtx, regset, regset, regset);
static basic_block earliest_block_with_similiar_load (basic_block, rtx);
static void add_deps_for_risky_insns (rtx, rtx);
static basic_block schedule_ebb (rtx, rtx);
@ -163,20 +163,29 @@ contributes_to_priority (rtx next ATTRIBUTE_UNUSED,
return 1;
}
/* INSN is a JUMP_INSN. Store the set of registers that must be considered
to be set by this jump in SET. */
/* INSN is a JUMP_INSN, COND_SET is the set of registers that are
conditionally set before INSN. Store the set of registers that
must be considered as used by this jump in USED and that of
registers that must be considered as set in SET. */
static void
compute_jump_reg_dependencies (rtx insn, regset set)
compute_jump_reg_dependencies (rtx insn, regset cond_set, regset used,
regset set)
{
basic_block b = BLOCK_FOR_INSN (insn);
edge e;
for (e = b->succ; e; e = e->succ_next)
if ((e->flags & EDGE_FALLTHRU) == 0)
{
bitmap_operation (set, set, e->dest->global_live_at_start,
BITMAP_IOR);
}
if (e->flags & EDGE_FALLTHRU)
/* The jump may be a by-product of a branch that has been merged
in the main codepath after being conditionalized. Therefore
it may guard the fallthrough block from using a value that has
conditionally overwritten that of the main codepath. So we
consider that it restores the value of the main codepath. */
bitmap_operation (set, e->dest->global_live_at_start, cond_set,
BITMAP_AND);
else
bitmap_operation (used, used, e->dest->global_live_at_start,
BITMAP_IOR);
}
/* Used in schedule_insns to initialize current_sched_info for scheduling

View File

@ -112,6 +112,9 @@ struct deps
/* Element N is set for each register that has any nonzero element
in reg_last[N].{uses,sets,clobbers}. */
regset_head reg_last_in_use;
/* Element N is set for each register that is conditionally set. */
regset_head reg_conditional_sets;
};
/* This structure holds some state of the current scheduling pass, and
@ -148,7 +151,7 @@ struct sched_info
/* Called when computing dependencies for a JUMP_INSN. This function
should store the set of registers that must be considered as set by
the jump in the regset. */
void (*compute_jump_reg_dependencies) (rtx, regset);
void (*compute_jump_reg_dependencies) (rtx, regset, regset, regset);
/* The boundaries of the set of insns to be scheduled. */
rtx prev_head, next_tail;

View File

@ -1701,7 +1701,7 @@ static int schedule_more_p (void);
static const char *rgn_print_insn (rtx, int);
static int rgn_rank (rtx, rtx);
static int contributes_to_priority (rtx, rtx);
static void compute_jump_reg_dependencies (rtx, regset);
static void compute_jump_reg_dependencies (rtx, regset, regset, regset);
/* Return nonzero if there are more insns that should be scheduled. */
@ -1951,11 +1951,15 @@ contributes_to_priority (rtx next, rtx insn)
return BLOCK_NUM (next) == BLOCK_NUM (insn);
}
/* INSN is a JUMP_INSN. Store the set of registers that must be considered
to be set by this jump in SET. */
/* INSN is a JUMP_INSN, COND_SET is the set of registers that are
conditionally set before INSN. Store the set of registers that
must be considered as used by this jump in USED and that of
registers that must be considered as set in SET. */
static void
compute_jump_reg_dependencies (rtx insn ATTRIBUTE_UNUSED,
regset cond_exec ATTRIBUTE_UNUSED,
regset used ATTRIBUTE_UNUSED,
regset set ATTRIBUTE_UNUSED)
{
/* Nothing to do here, since we postprocess jumps in

View File

@ -1,3 +1,7 @@
2003-07-15 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.c-torture/execute/20030715-1.c: New test.
2003-07-14 Geoffrey Keating <geoffk@apple.com>
* gcc.dg/pch/inline-3.c: New file.

View File

@ -0,0 +1,35 @@
/* PR optimization/11320 */
/* Origin: Andreas Schwab <schwab@suse.de> */
/* Verify that the scheduler correctly computes the dependencies
in the presence of conditional instructions. */
int strcmp (const char *, const char *);
int ap_standalone;
const char *ap_check_cmd_context (void *a, int b)
{
return 0;
}
const char *server_type (void *a, void *b, char *arg)
{
const char *err = ap_check_cmd_context (a, 0x01|0x02|0x04|0x08|0x10);
if (err)
return err;
if (!strcmp (arg, "inetd"))
ap_standalone = 0;
else if (!strcmp (arg, "standalone"))
ap_standalone = 1;
else
return "ServerType must be either 'inetd' or 'standalone'";
return 0;
}
int main ()
{
server_type (0, 0, "standalone");
return 0;
}