aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/function.c55
2 files changed, 55 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a7970e1..19085ed 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/function.c b/gcc/function.c
index e7f6afa..d2eab67 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -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;
}
}