diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a7970e19b11..19085ed17bb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Wed Oct 28 16:46:07 1998 Andreas Schwab + + * 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 * dwarfout.c (dwarfout_file_scope_decl): If DECL_CONTEXT, don't abort diff --git a/gcc/function.c b/gcc/function.c index e7f6afacdb5..d2eab67b61e 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 (®_NOTES (insn), NULL_RTX, 0, 0); + purge_addressof_replacements = 0; } }