UNSPEC_* handling in reg-stack.c

Uros Bizjak uros@kss-loka.si
Wed Apr 21 12:57:00 GMT 2004


Hello!

I have a question regarding UNSPEC_* handling in subst_stack_regs_pat() 
function in reg-stack.c. As it is now, UNSPEC_SIN handles its input and 
ouptut as:

        src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));
        emit_swap_insn (insn, regstack, *src1);

        src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
        ...
        if (src1_note)
          {
            replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
            regstack->top--;
            CLEAR_HARD_REG_BIT (regstack->reg_set, REGNO (*src1));
          }

I have made some test-cases that exercise this part of code, but input 
register was _never_ marked dead. This register is always replaced with 
its output, so reload pass always assings output and input to the same 
register. I would suggest changing this register handling to abort(), if 
input register is marked REG_DEAD. This would mean, that reload somehow 
failed:

        src1 = get_true_reg (&XVECEXP (pat_src, 0, 0));

        emit_swap_insn (insn, regstack, *src1);

        /* Input should never die, because it is
           replaced with output.  */
        src1_note = find_regno_note (insn, REG_DEAD, REGNO (*src1));
        if (src1_note)
          abort();

        if (STACK_REG_P (*dest))
          replace_reg (dest, FIRST_STACK_REG);

        replace_reg (src1, FIRST_STACK_REG);
        break;

I have introduced this change to UNSPEC_SIN & Co. input register 
handling, and also to input register of double-output UNSPEC_* 
instructions. The abort was never triggered, because reload pass always 
found appropriate input register (matched with the output register), 
that never dies. The situation is different in UNSPEC_FPATAN & Co., 
where second input register indeed dies, but it is unclear to me, why in 
this case we need:

        if (src1_note)  //redundant!!
          replace_reg (&XEXP (src1_note, 0), FIRST_STACK_REG);
        if (src2_note)
          replace_reg (&XEXP (src2_note, 0), FIRST_STACK_REG + 1);

I would like to introduce this change to handle double input, double 
output instructions (UNSPEC_FSCALE). UNSPEC_FSCALE is currently defined 
as "fscale;fstp %1" assembler, but with my prototype patch, "fstp %1" is 
generated automatically if one of UNSPEC_FSCALE outputs stays unused. 
(BTW: with TARGET_USE_FFREEP, when top fp register is marked REG_UNUSED, 
we could also emit "ffreep" instruction istead of "fstp").

Uros.



More information about the Gcc mailing list