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

Reply via email to