OSDN Git Service

2008-09-26 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 27 Sep 2008 03:26:45 +0000 (03:26 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 27 Sep 2008 03:26:45 +0000 (03:26 +0000)
Revert:
        2008-09-25  Vladimir Makarov  <vmakarov@redhat.com>
* ira-lives.c:...
* doc/rtl.texi:...

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140721 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/doc/rtl.texi
gcc/ira-lives.c

index 456daf8..9b32387 100644 (file)
@@ -1,3 +1,10 @@
+2008-09-26  Vladimir Makarov  <vmakarov@redhat.com>
+
+       Revert:
+        2008-09-25  Vladimir Makarov  <vmakarov@redhat.com>
+       * ira-lives.c:...
+       * doc/rtl.texi:...
+
 2008-09-26  Adam Nemet  <anemet@caviumnetworks.com>
 
        * config/mips/mips.h (ISA_HAS_DMUL3, ISA_HAS_BADDU, ISA_HAS_BBIT,
index 984ee43..148e19d 100644 (file)
@@ -2930,13 +2930,12 @@ constituent instructions might not.
 When a @code{clobber} expression for a register appears inside a
 @code{parallel} with other side effects, the register allocator
 guarantees that the register is unoccupied both before and after that
-insn if the @samp{&} constraint is specified for at least one
-alternative (@pxref{Modifiers}) of the clobber.  However, the reload
-phase may allocate a register used for one of the inputs unless the
-@samp{&} constraint is specified for the selected alternative.  You
-can clobber either a specific hard register, a pseudo register, or a
-@code{scratch} expression; in the latter two cases, GCC will allocate
-a hard register that is available there for use as a temporary.
+insn.  However, the reload phase may allocate a register used for one of
+the inputs unless the @samp{&} constraint is specified for the selected
+alternative (@pxref{Modifiers}).  You can clobber either a specific hard
+register, a pseudo register, or a @code{scratch} expression; in the
+latter two cases, GCC will allocate a hard register that is available
+there for use as a temporary.
 
 For instructions that require a temporary register, you should use
 @code{scratch} instead of a pseudo-register because this will allow the
index e49860f..609708e 100644 (file)
@@ -209,15 +209,20 @@ clear_allocno_live (ira_allocno_t a)
   sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a));
 }
 
-/* Mark the register REG as live.  Store a 1 in hard_regs_live or
-   allocnos_live for this register or the corresponding allocno,
-   record how many consecutive hardware registers it actually
-   needs.  */
+/* Mark the register referenced by use or def REF as live
+   Store a 1 in hard_regs_live or allocnos_live for this register or
+   the corresponding allocno, record how many consecutive hardware
+   registers it actually needs.  */
+
 static void
-mark_reg_live (rtx reg)
+mark_ref_live (struct df_ref *ref)
 {
+  rtx reg;
   int regno;
 
+  reg = DF_REF_REG (ref);
+  if (GET_CODE (reg) == SUBREG)
+    reg = SUBREG_REG (reg);
   gcc_assert (REG_P (reg));
   regno = REGNO (reg);
 
@@ -264,25 +269,32 @@ mark_reg_live (rtx reg)
     }
 }
 
-/* Mark the register referenced by use or def REF as live.  */
-static void
-mark_ref_live (struct df_ref *ref)
+/* Return true if the definition described by DEF conflicts with the
+   instruction's inputs.  */
+static bool
+def_conflicts_with_inputs_p (struct df_ref *def)
 {
-  rtx reg;
-
-  reg = DF_REF_REG (ref);
-  if (GET_CODE (reg) == SUBREG)
-    reg = SUBREG_REG (reg);
-  mark_reg_live (reg);
+  /* Conservatively assume that the condition is true for all clobbers.  */
+  return DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER);
 }
 
-/* Mark the register REG as dead.  Store a 0 in hard_regs_live or
+/* Mark the register referenced by definition DEF as dead, if the
+   definition is a total one.  Store a 0 in hard_regs_live or
    allocnos_live for the register.  */
 static void
-mark_reg_dead (rtx reg)
+mark_ref_dead (struct df_ref *def)
 {
+  unsigned int i;
+  rtx reg;
   int regno;
 
+  if (DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL)
+      || DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL))
+    return;
+
+  reg = DF_REF_REG (def);
+  if (GET_CODE (reg) == SUBREG)
+    reg = SUBREG_REG (reg);
   gcc_assert (REG_P (reg));
   regno = REGNO (reg);
 
@@ -300,7 +312,6 @@ mark_reg_dead (rtx reg)
     }
   else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno))
     {
-      unsigned int i;
       int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
       enum reg_class cover_class;
 
@@ -332,71 +343,6 @@ mark_reg_dead (rtx reg)
     }
 }
 
-/* Mark the register referenced by definition DEF as dead, if the
-   definition is a total one.  */
-static void
-mark_ref_dead (struct df_ref *def)
-{
-  rtx reg;
-
-  if (DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL)
-      || DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL))
-    return;
-
-  reg = DF_REF_REG (def);
-  if (GET_CODE (reg) == SUBREG)
-    reg = SUBREG_REG (reg);
-  mark_reg_dead (reg);
-}
-
-/* Mark early clobber registers of the current INSN as live (if
-   LIVE_P) or dead.  Return true if there are such registers.  */
-static bool
-mark_early_clobbers (rtx insn, bool live_p)
-{
-  int alt;
-  int def;
-  struct df_ref **def_rec;
-  bool set_p = false;
-  bool asm_p = asm_noperands (PATTERN (insn)) >= 0;
-
-  if (asm_p)
-    for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
-      if (DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MUST_CLOBBER))
-       {
-         if (live_p)
-           mark_ref_live (*def_rec);
-         else
-           mark_ref_dead (*def_rec);
-         set_p = true;
-       }
-
-  for (def = 0; def < recog_data.n_operands; def++)
-    {
-      rtx dreg = recog_data.operand[def];
-      
-      if (GET_CODE (dreg) == SUBREG)
-       dreg = SUBREG_REG (dreg);
-      if (! REG_P (dreg))
-       continue;
-
-      for (alt = 0; alt < recog_data.n_alternatives; alt++)
-       if ((recog_op_alt[def][alt].earlyclobber)
-           && (recog_op_alt[def][alt].cl != NO_REGS))
-         break;
-
-      if (alt >= recog_data.n_alternatives)
-       continue;
-
-      if (live_p)
-       mark_reg_live (dreg);
-      else
-       mark_reg_dead (dreg);
-      set_p = true;
-    }
-  return set_p;
-}
-
 /* Checks that CONSTRAINTS permits to use only one hard register.  If
    it is so, the function returns the class of the hard register.
    Otherwise it returns NO_REGS.  */
@@ -634,7 +580,6 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
   bitmap_iterator bi;
   bitmap reg_live_out;
   unsigned int px;
-  bool set_p;
 
   bb = loop_tree_node->bb;
   if (bb != NULL)
@@ -753,7 +698,6 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
              }
          
          extract_insn (insn);
-         preprocess_constraints ();
          process_single_reg_class_operands (false, freq);
          
          /* See which defined values die here.  */
@@ -789,12 +733,19 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node)
          for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++)
            mark_ref_live (*use_rec);
 
-         set_p = mark_early_clobbers (insn, true);
+         /* If any defined values conflict with the inputs, mark those
+            defined values as live.  */
+         for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
+           if (def_conflicts_with_inputs_p (*def_rec))
+             mark_ref_live (*def_rec);
 
          process_single_reg_class_operands (true, freq);
          
-         if (set_p)
-           mark_early_clobbers (insn, false);
+         /* See which of the defined values we marked as live are dead
+            before the instruction.  */
+         for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
+           if (def_conflicts_with_inputs_p (*def_rec))
+             mark_ref_dead (*def_rec);
 
          curr_point++;
        }