re PR rtl-optimization/11320 (Scheduler bug)
authorEric Botcazou <ebotcazou@libertysurf.fr>
Tue, 15 Jul 2003 13:02:21 +0000 (15:02 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Tue, 15 Jul 2003 13:02:21 +0000 (13:02 +0000)
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

gcc/ChangeLog
gcc/sched-deps.c
gcc/sched-ebb.c
gcc/sched-int.h
gcc/sched-rgn.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20030715-1.c [new file with mode: 0644]

index 788020b..7eaa150 100644 (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.
index cb85fea..f2d4fe6 100644 (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);
 }
index 0e316b5..dd9ec63 100644 (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
index 0ab0d65..8c3a405 100644 (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;
index cebb389..61ab056 100644 (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
index 90b25d8..d13c570 100644 (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.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030715-1.c b/gcc/testsuite/gcc.c-torture/execute/20030715-1.c
new file mode 100644 (file)
index 0000000..a2a28ce
--- /dev/null
@@ -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;
+}