mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-05 13:51:00 +08:00
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:
parent
9fa0903819
commit
5a257872da
@ -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.
|
||||
|
@ -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 (®_last->clobbers);
|
||||
});
|
||||
CLEAR_REG_SET (&deps->reg_last_in_use);
|
||||
CLEAR_REG_SET (&deps->reg_conditional_sets);
|
||||
|
||||
free (deps->reg_last);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
35
gcc/testsuite/gcc.c-torture/execute/20030715-1.c
Normal file
35
gcc/testsuite/gcc.c-torture/execute/20030715-1.c
Normal 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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user