Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
authorAndreas Schwab <schwab@issan.cs.uni-dortmund.de>
Wed, 28 Oct 1998 16:46:46 +0000 (16:46 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Wed, 28 Oct 1998 16:46:46 +0000 (08:46 -0800)
Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
        * function.c (purge_addressof_1): Instead of aborting when a
        bitfield insertion as a replacement for (MEM (ADDRESSOF)) does not
        work just put the ADDRESSOF on stack.  Otherwise remember all such
        successfull replacements, so that exactly the same replacements
        can be made on the REG_NOTEs.  Remove the special case for CALL
        insns again.
        (purge_addressof_replacements): New variable.
        (purge_addressof): Clear it at end.

From-SVN: r23405

gcc/ChangeLog
gcc/function.c

index a7970e19b11caf29e52566e884a0c96bbaaa7c96..19085ed17bb3d999127297e68f9e17f0b11be6fd 100644 (file)
@@ -1,3 +1,14 @@
+Wed Oct 28 16:46:07 1998  Andreas Schwab  <schwab@issan.cs.uni-dortmund.de>
+    
+       * function.c (purge_addressof_1): Instead of aborting when a
+       bitfield insertion as a replacement for (MEM (ADDRESSOF)) does not
+       work just put the ADDRESSOF on stack.  Otherwise remember all such
+       successfull replacements, so that exactly the same replacements
+       can be made on the REG_NOTEs.  Remove the special case for CALL
+       insns again.
+       (purge_addressof_replacements): New variable.
+       (purge_addressof): Clear it at end.
+
 Wed Oct 28 14:06:49 1998  Jim Wilson  <wilson@cygnus.com>
 
        * dwarfout.c (dwarfout_file_scope_decl): If DECL_CONTEXT, don't abort
index e7f6afacdb5a9d350ec802d1d103013ab1aad74a..d2eab67b61ee8c36b7f4de7eab975678500f5e5b 100644 (file)
@@ -2818,6 +2818,10 @@ put_addressof_into_stack (r)
                      TREE_USED (decl) || DECL_INITIAL (decl) != 0);
 }
 
+/* List of replacements made below in purge_addressof_1 when creating
+   bitfield insertions.  */
+static rtx purge_addressof_replacements;
+
 /* Helper function for purge_addressof.  See if the rtx expression at *LOC
    in INSN needs to be changed.  If FORCE, always put any ADDRESSOFs into
    the stack.  */
@@ -2880,6 +2884,25 @@ purge_addressof_1 (loc, insn, force, store)
        {
          int size_x, size_sub;
 
+         if (!insn)
+           {
+             /* When processing REG_NOTES look at the list of
+                replacements done on the insn to find the register that X
+                was replaced by.  */
+             rtx tem;
+
+             for (tem = purge_addressof_replacements; tem != NULL_RTX;
+                  tem = XEXP (XEXP (tem, 1), 1))
+               if (rtx_equal_p (x, XEXP (tem, 0)))
+                 {
+                   *loc = XEXP (XEXP (tem, 1), 0);
+                   return;
+                 }
+
+             /* There should always be such a replacement.  */
+             abort ();
+           }
+
          size_x = GET_MODE_BITSIZE (GET_MODE (x));
          size_sub = GET_MODE_BITSIZE (GET_MODE (sub));
 
@@ -2895,12 +2918,15 @@ purge_addressof_1 (loc, insn, force, store)
 
              if (store)
                {
-                 /* If we can't replace with a register, be afraid.  */
-
                  start_sequence ();
                  val = gen_reg_rtx (GET_MODE (x));
                  if (! validate_change (insn, loc, val, 0))
-                   abort ();
+                   {
+                     /* Discard the current sequence and put the
+                        ADDRESSOF on stack.  */
+                     end_sequence ();
+                     goto give_up;
+                   }
                  seq = gen_sequence ();
                  end_sequence ();
                  emit_insn_before (seq, insn);
@@ -2922,21 +2948,33 @@ purge_addressof_1 (loc, insn, force, store)
                                           GET_MODE_SIZE (GET_MODE (sub)),
                                           GET_MODE_SIZE (GET_MODE (sub)));
 
-                 /* If we can't replace with a register, be afraid.  */
                  if (! validate_change (insn, loc, val, 0))
-                   abort ();
+                   {
+                     /* Discard the current sequence and put the
+                        ADDRESSOF on stack.  */
+                     end_sequence ();
+                     goto give_up;
+                   }
 
                  seq = gen_sequence ();
                  end_sequence ();
                  emit_insn_before (seq, insn);
                }
 
+             /* Remember the replacement so that the same one can be done
+                on the REG_NOTES.  */
+             purge_addressof_replacements
+               = gen_rtx_EXPR_LIST (VOIDmode, x,
+                                    gen_rtx_EXPR_LIST (VOIDmode, val,
+                                                       purge_addressof_replacements));
+
              /* We replaced with a reg -- all done.  */
              return;
            }
        }
       else if (validate_change (insn, loc, sub, 0))
        goto restart;
+    give_up:;
       /* else give up and put it into the stack */
     }
   else if (code == ADDRESSOF)
@@ -2950,12 +2988,6 @@ purge_addressof_1 (loc, insn, force, store)
       purge_addressof_1 (&SET_SRC (x), insn, force, 0);
       return;
     }
-  else if (code == CALL)
-    {
-      purge_addressof_1 (&XEXP (x, 0), insn, 1, 0);
-      purge_addressof_1 (&XEXP (x, 1), insn, force, 0);
-      return;
-    }
 
   /* Scan all subexpressions. */
   fmt = GET_RTX_FORMAT (code);
@@ -2985,6 +3017,7 @@ purge_addressof (insns)
        purge_addressof_1 (&PATTERN (insn), insn,
                           asm_noperands (PATTERN (insn)) > 0, 0);
        purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0);
+       purge_addressof_replacements = 0;
       }
 }
 \f