This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [rfc] multi-word subreg lowering pass
- From: Rask Ingemann Lambertsen <rask at sygehus dot dk>
- To: Richard Henderson <rth at redhat dot com>, Björn Haase <bjoern dot m dot haase at web dot de>, gcc-patches at gcc dot gnu dot org
- Date: Sun, 2 Jul 2006 20:36:13 +0200
- Subject: Re: [rfc] multi-word subreg lowering pass
- References: <200505062218.15370.bjoern.m.haase@web.de> <20050507033326.GC23300@redhat.com>
On Fri, May 06, 2005 at 08:33:26PM -0700, Richard Henderson wrote:
> If the target leaves logical arithmetic to the middle end, this
> means that the posted example,
>
> long long foo(int x, long long y)
> {
> return x & y;
> }
>
> will decompose to
>
> (set (reg:SI 100) (reg:SI x))
> (set (reg:SI 101) (const_int 0))
> (set (reg:SI 102) (and:SI (reg:SI 100) (reg:SI ylow)))
> (set (reg:SI 103) (and:SI (reg:SI 101) (reg:SI yhigh)))
> (set (reg:SI eax) (reg:SI 102))
> (set (reg:SI edx) (reg:SI 103))
>
> which after cse and combine will be just perfect.
How do you prevent combine from reinserting the subregs into the insns?
Given the function
unsigned long foo (unsigned long long x, unsigned long y, unsigned long z)
{
unsigned long long t;
t = (unsigned long long) y * (unsigned long long) z;
if (x & 42)
t |= 3;
if (x)
t ^= x << 32;
return (t >> 32);
}
I see this in the life1 dump file:
(note 23 21 25 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
(insn 25 23 71 3 (parallel [
(set (reg:SI 73)
(ior:SI (subreg:SI (reg/v:DI 58 [ t ]) 0)
(const_int 3 [0x3])))
(clobber (reg:CC 17 flags))
]) 318 {*iorsi_1} (nil)
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil)))
(insn 71 25 72 3 (clobber (reg:DI 77 [+4 ])) -1 (nil)
(nil))
(insn 72 71 73 3 (set (subreg:SI (reg:DI 77 [+4 ]) 0)
(reg:SI 73)) 40 {*movsi_1} (insn_list:REG_DEP_TRUE 25 (insn_list:REG_DEP_TRUE 71 (nil)))
(expr_list:REG_DEAD (reg:SI 73)
(nil)))
(insn 73 72 29 3 (set (subreg:SI (reg:DI 77 [+4 ]) 4)
(subreg:SI (reg/v:DI 58 [ t ]) 4)) 40 {*movsi_1} (insn_list:REG_DEP_TRUE 72 (nil))
(expr_list:REG_DEAD (reg/v:DI 58 [ t ])
(nil)))
(insn 29 73 30 3 (set (reg/v:DI 58 [ t ])
(reg:DI 77 [+4 ])) 80 {*movdi_2} (insn_list:REG_DEP_TRUE 73 (nil))
(expr_list:REG_DEAD (reg:DI 77 [+4 ])
(nil)))
(code_label 30 29 31 4 2 "" [1 uses])
(note 31 30 33 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
And in the combine dump file:
(note 23 21 25 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
(note 25 23 71 3 NOTE_INSN_DELETED)
(insn 71 25 72 3 (clobber (reg:DI 77 [+4 ])) -1 (nil)
(nil))
(insn 72 71 73 3 (parallel [
(set (subreg:SI (reg:DI 77 [+4 ]) 0)
(ior:SI (subreg:SI (reg/v:DI 58 [ t ]) 0)
(const_int 3 [0x3])))
(clobber (reg:CC 17 flags))
]) 318 {*iorsi_1} (nil)
(expr_list:REG_UNUSED (reg:CC 17 flags)
(nil)))
(insn 73 72 29 3 (set (subreg:SI (reg:DI 77 [+4 ]) 4)
(subreg:SI (reg/v:DI 58 [ t ]) 4)) 40 {*movsi_1} (insn_list:REG_DEP_TRUE 72 (nil))
(expr_list:REG_DEAD (reg/v:DI 58 [ t ])
(nil)))
(insn 29 73 30 3 (set (reg/v:DI 58 [ t ])
(reg:DI 77 [+4 ])) 80 {*movdi_2} (insn_list:REG_DEP_TRUE 73 (nil))
(expr_list:REG_DEAD (reg:DI 77 [+4 ])
(nil)))
(code_label 30 29 31 4 2 "" [1 uses])
(note 31 30 33 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
Combine combines insn 25 and insn 72 into insn 72, undoing the efforts of
the subreg lowering pass.
--
Rask Ingemann Lambertsen