Kaz Kojima <[EMAIL PROTECTED]> writes:
> --- ORIG/trunk/gcc/calls.c 2005-10-29 06:52:11.000000000 +0900
> +++ LOCAL/trunk/gcc/calls.c 2005-11-03 09:15:47.000000000 +0900
> @@ -2774,6 +2774,17 @@ expand_call (tree exp, rtx target, int i
> emit_insn (insns);
> valreg = temp;
> }
> + /* We have to copy a return value in a CLASS_LIKELY_SPILLED hard
> + reg to a plain register, even for pure functions. */
> + else if (pass && (flags & ECF_PURE)
> + && REGNO (valreg) < FIRST_PSEUDO_REGISTER
> + && CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (valreg))))
> + {
> + rtx temp = gen_reg_rtx (GET_MODE (valreg));
> +
> + emit_move_insn (temp, valreg);
> + valreg = temp;
> + }
>
> /* For calls to `setjmp', etc., inform flow.c it should complain
> if nonvolatile values are live. For functions that cannot return,
I don't see what this has to do with pure functions.
It seems to me that instead you want to put something here:
else if (target
&& GET_MODE (target) == TYPE_MODE (TREE_TYPE (exp))
&& GET_MODE (target) == GET_MODE (valreg))
{
/* TARGET and VALREG cannot be equal at this point because the
latter would not have REG_FUNCTION_VALUE_P true, while the
former would if it were referring to the same register.
If they refer to the same register, this move will be a no-op,
except when function inlining is being done. */
emit_move_insn (target, valreg);
i.e.
if (REG_P (valreg)
&& HARD_REGISTER_P (valreg)
&& CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (REGNO (valreg))))
valreg = copy_to_reg (valreg);
emit_move_insn (target, valreg);
Ian