OSDN Git Service

* config/h8300/h8300.md (*movsf_h8300h): Change to
[pf3gnuchains/gcc-fork.git] / gcc / flow.c
index 66c04ee..0dffb46 100644 (file)
@@ -136,7 +136,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "toplev.h"
 #include "recog.h"
 #include "expr.h"
-#include "ssa.h"
 #include "timevar.h"
 
 #include "obstack.h"
@@ -293,7 +292,6 @@ static void notice_stack_pointer_modification_1 (rtx, rtx, void *);
 static void notice_stack_pointer_modification (rtx);
 static void mark_reg (rtx, void *);
 static void mark_regs_live_at_end (regset);
-static int set_phi_alternative_reg (rtx, int, int, void *);
 static void calculate_global_regs_live (sbitmap, sbitmap, int);
 static void propagate_block_delete_insn (rtx);
 static rtx propagate_block_delete_libcall (rtx, rtx);
@@ -596,6 +594,9 @@ verify_local_live_at_start (regset new_live_at_start, basic_block bb)
    generates subregs of a multi-word pseudo, current life analysis will
    lose the kill.  So we _can_ have a pseudo go live.  How irritating.
 
+   It is also not true when a peephole decides that it doesn't need one
+   or more of the inputs.
+
    Including PROP_REG_INFO does not properly refresh regs_ever_live
    unless the caller resets it to zero.  */
 
@@ -1033,20 +1034,6 @@ mark_regs_live_at_end (regset set)
   diddle_return_value (mark_reg, set);
 }
 
-/* Callback function for for_each_successor_phi.  DATA is a regset.
-   Sets the SRC_REGNO, the regno of the phi alternative for phi node
-   INSN, in the regset.  */
-
-static int
-set_phi_alternative_reg (rtx insn ATTRIBUTE_UNUSED,
-                        int dest_regno ATTRIBUTE_UNUSED, int src_regno,
-                        void *data)
-{
-  regset live = (regset) data;
-  SET_REGNO_REG_SET (live, src_regno);
-  return 0;
-}
-
 /* Propagate global life info around the graph of basic blocks.  Begin
    considering blocks with their corresponding bit set in BLOCKS_IN.
    If BLOCKS_IN is null, consider it the universal set.
@@ -1208,14 +1195,6 @@ calculate_global_regs_live (sbitmap blocks_in, sbitmap blocks_out, int flags)
            SET_REGNO_REG_SET (new_live_at_end, PIC_OFFSET_TABLE_REGNUM);
        }
 
-      /* Regs used in phi nodes are not included in
-        global_live_at_start, since they are live only along a
-        particular edge.  Set those regs that are live because of a
-        phi node alternative corresponding to this particular block.  */
-      if (in_ssa_form)
-       for_each_successor_phi (bb, &set_phi_alternative_reg,
-                               new_live_at_end);
-
       if (bb == ENTRY_BLOCK_PTR)
        {
          COPY_REG_SET (bb->global_live_at_end, new_live_at_end);
@@ -1861,16 +1840,15 @@ init_propagate_block_info (basic_block bb, regset live, regset local_set,
                                       free_reg_cond_life_info);
   pbi->reg_cond_reg = BITMAP_XMALLOC ();
 
-  /* If this block ends in a conditional branch, for each register live
-     from one side of the branch and not the other, record the register
-     as conditionally dead.  */
+  /* If this block ends in a conditional branch, for each register
+     live from one side of the branch and not the other, record the
+     register as conditionally dead.  */
   if (GET_CODE (bb->end) == JUMP_INSN
       && any_condjump_p (bb->end))
     {
       regset_head diff_head;
       regset diff = INITIALIZE_REG_SET (diff_head);
       basic_block bb_true, bb_false;
-      rtx cond_true, cond_false, set_src;
       int i;
 
       /* Identify the successor blocks.  */
@@ -1898,53 +1876,59 @@ init_propagate_block_info (basic_block bb, regset live, regset local_set,
          bb_false = bb_true;
        }
 
-      /* Extract the condition from the branch.  */
-      set_src = SET_SRC (pc_set (bb->end));
-      cond_true = XEXP (set_src, 0);
-      cond_false = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
-                                  GET_MODE (cond_true), XEXP (cond_true, 0),
-                                  XEXP (cond_true, 1));
-      if (GET_CODE (XEXP (set_src, 1)) == PC)
-       {
-         rtx t = cond_false;
-         cond_false = cond_true;
-         cond_true = t;
-       }
-
       /* Compute which register lead different lives in the successors.  */
       if (bitmap_operation (diff, bb_true->global_live_at_start,
                            bb_false->global_live_at_start, BITMAP_XOR))
        {
+         /* Extract the condition from the branch.  */
+         rtx set_src = SET_SRC (pc_set (bb->end));
+         rtx cond_true = XEXP (set_src, 0);
          rtx reg = XEXP (cond_true, 0);
 
          if (GET_CODE (reg) == SUBREG)
            reg = SUBREG_REG (reg);
 
-         if (GET_CODE (reg) != REG)
-           abort ();
+         /* We can only track conditional lifetimes if the condition is
+            in the form of a comparison of a register against zero.  
+            If the condition is more complex than that, then it is safe
+            not to record any information.  */
+         if (GET_CODE (reg) == REG
+             && XEXP (cond_true, 1) == const0_rtx)
+           {
+             rtx cond_false
+               = gen_rtx_fmt_ee (reverse_condition (GET_CODE (cond_true)),
+                                 GET_MODE (cond_true), XEXP (cond_true, 0),
+                                 XEXP (cond_true, 1));
+             if (GET_CODE (XEXP (set_src, 1)) == PC)
+               {
+                 rtx t = cond_false;
+                 cond_false = cond_true;
+                 cond_true = t;
+               }
 
-         SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
+             SET_REGNO_REG_SET (pbi->reg_cond_reg, REGNO (reg));
 
-         /* For each such register, mark it conditionally dead.  */
-         EXECUTE_IF_SET_IN_REG_SET
-           (diff, 0, i,
-            {
-              struct reg_cond_life_info *rcli;
-              rtx cond;
+             /* For each such register, mark it conditionally dead.  */
+             EXECUTE_IF_SET_IN_REG_SET
+               (diff, 0, i,
+                {
+                  struct reg_cond_life_info *rcli;
+                  rtx cond;
 
-              rcli = xmalloc (sizeof (*rcli));
+                  rcli = xmalloc (sizeof (*rcli));
 
-              if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
-                cond = cond_false;
-              else
-                cond = cond_true;
-              rcli->condition = cond;
-              rcli->stores = const0_rtx;
-              rcli->orig_condition = cond;
+                  if (REGNO_REG_SET_P (bb_true->global_live_at_start, i))
+                    cond = cond_false;
+                  else
+                    cond = cond_true;
+                  rcli->condition = cond;
+                  rcli->stores = const0_rtx;
+                  rcli->orig_condition = cond;
 
-              splay_tree_insert (pbi->reg_cond_dead, i,
-                                 (splay_tree_value) rcli);
-            });
+                  splay_tree_insert (pbi->reg_cond_dead, i,
+                                     (splay_tree_value) rcli);
+                });
+           }
        }
 
       FREE_REG_SET (diff);
@@ -3903,14 +3887,6 @@ mark_used_regs (struct propagate_block_info *pbi, rtx x, rtx cond, rtx insn)
       x = COND_EXEC_CODE (x);
       goto retry;
 
-    case PHI:
-      /* We _do_not_ want to scan operands of phi nodes.  Operands of
-        a phi function are evaluated only when control reaches this
-        block along a particular edge.  Therefore, regs that appear
-        as arguments to phi should not be added to the global live at
-        start.  */
-      return;
-
     default:
       break;
     }