* Makefile.in (gcse.o): Now includes ggc.h.
authorkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 18 Feb 2001 23:56:34 +0000 (23:56 +0000)
committerkenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 18 Feb 2001 23:56:34 +0000 (23:56 +0000)
* gcse.c: Include ggc.h.
(want_to_gcse_p): Verify expression can be in SET as valid insn.
(try_replace_reg): Remove warning of uninitialize variable.
(process_insert_insn): Call invalid_insn_p to validate insn.
* recog.c (insn_invalid_p): Now global.
See if can make valid by adding CLOBBERs of SCRATCH only and do if so.
* recog.h (insn_invalid_p): New declaration.

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

gcc/ChangeLog
gcc/Makefile.in
gcc/gcse.c
gcc/recog.c
gcc/recog.h

index 9997edd..d159770 100644 (file)
@@ -1,5 +1,14 @@
 Sun Feb 18 15:45:17 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
+       * Makefile.in (gcse.o): Now includes ggc.h.
+       * gcse.c: Include ggc.h.
+       (want_to_gcse_p): Verify expression can be in SET as valid insn.
+       (try_replace_reg): Remove warning of uninitialize variable.
+       (process_insert_insn): Call invalid_insn_p to validate insn.
+       * recog.c (insn_invalid_p): Now global.
+       See if can make valid by adding CLOBBERs of SCRATCH only and do if so.
+       * recog.h (insn_invalid_p): New declaration.
+
        * jump.c (jump_optimize_1): Only define reversed_code #ifdef HAVE_trap.
 
        * config/sparc/sparc.c (eligible_for_epilogue_delay): Don't put
index 304fbd1..671107b 100644 (file)
@@ -1423,7 +1423,7 @@ cse.o : cse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h flags.h \
    real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h output.h function.h \
    $(BASIC_BLOCK_H) $(GGC_H)
 gcse.o : gcse.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) hard-reg-set.h \
-   flags.h real.h insn-config.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \
+   flags.h real.h insn-config.h ggc.h $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) \
    function.h output.h toplev.h
 sibcall.o : sibcall.c $(CONFIG_H) system.h $(RTL_H) $(REGS_H) function.h \
    hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H)
index 5bb8680..a5c552c 100644 (file)
@@ -159,6 +159,7 @@ Boston, MA 02111-1307, USA.  */
 #include "output.h"
 #include "function.h"
 #include "expr.h" 
+#include "ggc.h"
 
 #include "obstack.h"
 #define obstack_chunk_alloc gmalloc
@@ -1187,13 +1188,17 @@ static int *reg_last_set;
 static int mem_first_set;
 static int mem_last_set;
 
-/* Perform a quick check whether X, the source of a set, is something
-   we want to consider for GCSE.  */
+/* See whether X, the source of a set, is something we want to consider for
+   GCSE.  */
 
 static int
 want_to_gcse_p (x)
      rtx x;
 {
+  static rtx test_insn = 0;
+  int num_clobbers = 0;
+  int icode;
+
   switch (GET_CODE (x))
     {
     case REG:
@@ -1207,7 +1212,31 @@ want_to_gcse_p (x)
       break;
     }
 
-  return 1;
+  /* If this is a valid operand, we are OK.  If it's VOIDmode, we aren't.  */
+  if (general_operand (x, GET_MODE (x)))
+    return 1;
+  else if (GET_MODE (x) == VOIDmode)
+    return 0;
+
+  /* Otherwise, check if we can make a valid insn from it.  First initialize
+     our test insn if we haven't already.  */
+  if (test_insn == 0)
+    {
+      test_insn
+       = make_insn_raw (gen_rtx_SET (VOIDmode,
+                                     gen_rtx_REG (word_mode,
+                                                  FIRST_PSEUDO_REGISTER * 2),
+                                     const0_rtx));
+      NEXT_INSN (test_insn) = PREV_INSN (test_insn) = 0;
+      ggc_add_rtx_root (&test_insn, 1);
+    }
+
+  /* Now make an insn like the one we would make when GCSE'ing and see if
+     valid.  */
+  PUT_MODE (SET_DEST (PATTERN (test_insn)), GET_MODE (x));
+  SET_SRC (PATTERN (test_insn)) = x;
+  return ((icode = recog (PATTERN (test_insn), test_insn, &num_clobbers)) >= 0
+         && (num_clobbers == 0 || ! added_clobbers_hard_reg_p (icode)));
 }
 
 /* Return non-zero if the operands of expression X are unchanged from the
@@ -3612,7 +3641,7 @@ try_replace_reg (from, to, insn)
      rtx from, to, insn;
 {
   rtx note = find_reg_equal_equiv_note (insn);
-  rtx src;
+  rtx src = 0;
   int success = 0;
   rtx set = single_set (insn);
 
@@ -3640,10 +3669,10 @@ try_replace_reg (from, to, insn)
   if (!success)
     success = validate_replace_src (from, to, insn);
 
-  /* We've failed to do replacement, have a single SET, and don't already
-     have a note, two to add a REG_EQUAL note to not lose information.  */
+  /* If we've failed to do replacement, have a single SET, and don't already
+     have a note, add a REG_EQUAL note to not lose information.  */
   if (!success && note == 0 && set != 0)
-    note= REG_NOTES (insn)
+    note = REG_NOTES (insn)
       = gen_rtx_EXPR_LIST (REG_EQUAL, src, REG_NOTES (insn));
 
   /* If there is already a NOTE, update the expression in it with our
@@ -4265,13 +4294,22 @@ process_insert_insn (expr)
      struct expr *expr;
 {
   rtx reg = expr->reaching_reg;
-  rtx pat, copied_expr;
-  rtx first_new_insn;
+  rtx exp = copy_rtx (expr->expr);
+  rtx pat;
 
   start_sequence ();
-  copied_expr = copy_rtx (expr->expr);
-  emit_move_insn (reg, copied_expr);
-  first_new_insn = get_insns ();
+
+  /* If the expression is something that's an operand, like a constant,
+     just copy it to a register.  */
+  if (general_operand (exp, GET_MODE (reg)))
+    emit_move_insn (reg, exp);
+
+  /* Otherwise, make a new insn to compute this expression and make sure the
+     insn will be recognized (this also adds any needed CLOBBERs).  Copy the
+     expression to make sure we don't have any sharing issues.  */
+  if (insn_invalid_p (emit_insn (gen_rtx_SET (VOIDmode, reg, exp))))
+    abort ();
+  
   pat = gen_sequence ();
   end_sequence ();
 
index d6cdf54..bf8a3e3 100644 (file)
@@ -58,7 +58,6 @@ Boston, MA 02111-1307, USA.  */
 static void validate_replace_rtx_1     PARAMS ((rtx *, rtx, rtx, rtx));
 static rtx *find_single_use_1          PARAMS ((rtx, rtx *));
 static rtx *find_constant_term_loc     PARAMS ((rtx *));
-static int insn_invalid_p              PARAMS ((rtx));
 static void validate_replace_src_1     PARAMS ((rtx *, void *));
 
 /* Nonzero means allow operands to be volatile.
@@ -217,7 +216,7 @@ validate_change (object, loc, new, in_group)
   if (in_group == 0 && num_changes != 0)
     abort ();
 
-  *loc = new;
+   *loc = new;
 
   /* Save the information describing this change.  */
   if (num_changes >= changes_allocated)
@@ -260,18 +259,43 @@ validate_change (object, loc, new, in_group)
 /* This subroutine of apply_change_group verifies whether the changes to INSN
    were valid; i.e. whether INSN can still be recognized.  */
 
-static int
+int
 insn_invalid_p (insn)
      rtx insn;
 {
-  int icode = recog_memoized (insn);
+  rtx pat = PATTERN (insn);
+  int num_clobbers = 0;
+  /* If we are before reload and the pattern is a SET, see if we can add
+     clobbers.  */
+  int icode = recog (pat, insn,
+                    (GET_CODE (pat) == SET
+                     && ! reload_completed && ! reload_in_progress)
+                    ? &num_clobbers : NULL_PTR);
   int is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
 
-  if (is_asm && ! check_asm_operands (PATTERN (insn)))
-    return 1;
-  if (! is_asm && icode < 0)
+  
+  /* If this is an asm and the operand aren't legal, then fail.  Likewise if
+     this is not an asm and the insn wasn't recognized.  */
+  if ((is_asm && ! check_asm_operands (PATTERN (insn)))
+      || (!is_asm && icode < 0))
     return 1;
 
+  /* If we have to add CLOBBERs, fail if we have to add ones that reference
+     hard registers since our callers can't know if they are live or not.
+     Otherwise, add them.  */
+  if (num_clobbers > 0)
+    {
+      rtx newpat;
+
+      if (added_clobbers_hard_reg_p (icode))
+       return 1;
+
+      newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (num_clobbers + 1));
+      XVECEXP (newpat, 0, 0) = pat;
+      add_clobbers (newpat, icode);
+      PATTERN (insn) = pat = newpat;
+    }
+
   /* After reload, verify that all constraints are satisfied.  */
   if (reload_completed)
     {
@@ -281,6 +305,7 @@ insn_invalid_p (insn)
        return 1;
     }
 
+  INSN_CODE (insn) = icode;
   return 0;
 }
 
@@ -744,9 +769,11 @@ validate_replace_rtx_group (from, to, insn)
 
 /* Function called by note_uses to replace used subexpressions.  */
 struct validate_replace_src_data
-  {
-    rtx from, to, insn;
-  };
+{
+  rtx from;                    /* Old RTX */
+  rtx to;                      /* New RTX */
+  rtx insn;                    /* Insn in which substitution is occurring.  */
+};
 
 static void
 validate_replace_src_1 (x, data)
index b59d664..e15a423 100644 (file)
@@ -77,6 +77,7 @@ extern int recog_memoized_1           PARAMS ((rtx));
 extern int check_asm_operands          PARAMS ((rtx));
 extern int asm_operand_ok              PARAMS ((rtx, const char *));
 extern int validate_change             PARAMS ((rtx, rtx *, rtx, int));
+extern int insn_invalid_p              PARAMS ((rtx));
 extern int apply_change_group          PARAMS ((void));
 extern int num_validated_changes       PARAMS ((void));
 extern void cancel_changes             PARAMS ((int));