OSDN Git Service

2008-01-16 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / sched-rgn.c
index 12f2e66..b340bd5 100644 (file)
@@ -320,16 +320,40 @@ is_cfg_nonregular (void)
   FOR_EACH_BB (b)
     FOR_BB_INSNS (b, insn)
       {
-       /* Check for labels referred to but (at least not directly) as
-          jump targets.  */
-       if (INSN_P (insn)
-           && find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
-         return 1;
+       rtx note, next, set, dest;
 
        /* If this function has a computed jump, then we consider the cfg
           not well structured.  */
        if (JUMP_P (insn) && computed_jump_p (insn))
          return 1;
+
+       if (!INSN_P (insn))
+         continue;
+
+       note = find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX);
+       if (note == NULL_RTX)
+         continue;
+
+       /* For that label not to be seen as a referred-to label, this
+          must be a single-set which is feeding a jump *only*.  This
+          could be a conditional jump with the label split off for
+          machine-specific reasons or a casesi/tablejump.  */
+       next = next_nonnote_insn (insn);
+       if (next == NULL_RTX
+           || !JUMP_P (next)
+           || (JUMP_LABEL (next) != XEXP (note, 0)
+               && find_reg_note (next, REG_LABEL_TARGET,
+                                 XEXP (note, 0)) == NULL_RTX)
+           || BLOCK_FOR_INSN (insn) != BLOCK_FOR_INSN (next))
+         return 1;
+
+       set = single_set (insn);
+       if (set == NULL_RTX)
+         return 1;
+
+       dest = SET_DEST (set);
+       if (!REG_P (dest) || !dead_or_set_p (next, dest))
+         return 1;
       }
 
   /* Unreachable loops with more than one basic block are detected