+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.
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);
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
}
flush_pending_lists (deps, insn, true, true);
+ CLEAR_REG_SET (&deps->reg_conditional_sets);
reg_pending_barrier = NOT_A_BARRIER;
}
else
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
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);
});
}
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;
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);
}
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);
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
/* 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
/* 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;
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. */
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
+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.
--- /dev/null
+/* 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;
+}