This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

UNSPEC_* handling in reg-stack.c


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]