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]

Forcing REG_DEAD?


Hi,

Is there a way to force the compiler to consider an operand dead?

Specifically, I've got the RL78 backend to generate SET1 and CLR1 instructions to set and clear individual bits. These instructions can either work on the contents of a specific memory address, or indirectly by putting the memory address into the HL register.

If more than one bit in a given byte should be set or cleared, the compiler uses the indirect alternative but in most cases this actually leads to larger code especially if not all bit operations on any given memory address are performed sequentially (e.g. 'clear bit 3 of address X, set bit 6 of address Y, set bit 1 of address X').

--------------------------------------------------------
typedef struct {
   unsigned char no0 :1;
   unsigned char no1 :1;
   unsigned char no2 :1;
   unsigned char no3 :1;
   unsigned char no4 :1;
   unsigned char no5 :1;
   unsigned char no6 :1;
   unsigned char no7 :1;
} __BITS8;

#define MEMREG (*(volatile __BITS8*)0xFFF0C)

void test()
{
   MEMREG.no1 = 1;
   MEMREG.no2 = 0;
}
--------------------------------------------------------

Produces:

  28                             	_test:
  29 0000 36 0C FF                		movw	hl, #-244
  30 0003 71 92                   		set1	[hl].1
  31 0005 71 A3                   		clr1	[hl].2
  32 0007 D7                      		ret

Where this would be more efficient (and in real-world situations much more so):

  28                             	_test:
  29 0000 71 1A 0C                		set1	0xfff0c.1
  30 0003 71 2B 0C                		clr1	0xfff0c.2
  31 0006 D7                      		ret



The problem seems to be during the combine phase. With the second MEMREG line commented out:

--------------------------------------------------------
Trying 9 -> 10:
Successfully matched this instruction:
(set (mem/v/j:QI (reg/f:HI 44) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16]) (ior:QI (mem/v/j:QI (reg/f:HI 44) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16])
        (const_int 2 [0x2])))
deferring deletion of insn with uid = 9.
modifying insn i3    10: [r44:HI]=[r44:HI]|0x2
      REG_DEAD r44:HI
deferring rescan insn with uid = 10.

Trying 6 -> 10:
Successfully matched this instruction:
(set (mem/v/j:QI (const_int -244 [0xffffffffffffff0c]) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16]) (ior:QI (mem/v/j:QI (const_int -244 [0xffffffffffffff0c]) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16])
        (const_int 2 [0x2])))
deferring deletion of insn with uid = 6.
modifying insn i3    10: [0xffffffffffffff0c]=[0xffffffffffffff0c]|0x2
deferring rescan insn with uid = 10.
starting the processing of deferred insns
rescanning insn with uid = 10.
ending the processing of deferred insns
--------------------------------------------------------

With both lines active:

--------------------------------------------------------
Trying 9 -> 10:
Successfully matched this instruction:
(set (mem/v/j:QI (reg/f:HI 44) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16]) (ior:QI (mem/v/j:QI (reg/f:HI 44) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16])
        (const_int 2 [0x2])))
deferring deletion of insn with uid = 9.
modifying insn i3    10: [r44:HI]=[r44:HI]|0x2
deferring rescan insn with uid = 10.

Trying 6 -> 10:
Failed to match this instruction:
(parallel [
(set (mem/v/j:QI (const_int -244 [0xffffffffffffff0c]) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16]) (ior:QI (mem/v/j:QI (const_int -244 [0xffffffffffffff0c]) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16])
                (const_int 2 [0x2])))
        (set (reg/f:HI 44)
            (const_int -244 [0xffffffffffffff0c]))
    ])
Failed to match this instruction:
(parallel [
(set (mem/v/j:QI (const_int -244 [0xffffffffffffff0c]) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16]) (ior:QI (mem/v/j:QI (const_int -244 [0xffffffffffffff0c]) [3 MEM[(volatile struct __BITS8 *)65292B].no1+0 S1 A16])
                (const_int 2 [0x2])))
        (set (reg/f:HI 44)
            (const_int -244 [0xffffffffffffff0c]))
    ])
--------------------------------------------------------

The second example leaves the destination operand 'alive', and fails to find a match for the direct-addressing alternative.

Is there any way of preventing the compiler going with the indirect alternative? Can a 'parallel' match be defined in the machine description that indicates the '(set (reg/f:HI...' should be discarded?

Thanks in advance,

Richard.


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