Bug 35404 - ra-conflict does not handle subregs optimally
Summary: ra-conflict does not handle subregs optimally
Status: ASSIGNED
Alias: None
Product: gcc
Classification: Unclassified
Component: rtl-optimization (show other bugs)
Version: 4.4.0
: P3 enhancement
Target Milestone: ---
Assignee: Vladimir Makarov
URL:
Keywords: ra
Depends on:
Blocks: 35413
  Show dependency treegraph
 
Reported: 2008-02-28 22:58 UTC by Ian Lance Taylor
Modified: 2023-10-27 17:54 UTC (History)
10 users (show)

See Also:
Host:
Target: x86-32
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-03-10 21:48:33


Attachments
Old patch for this issue (6.62 KB, patch)
2008-02-28 22:59 UTC, Ian Lance Taylor
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ian Lance Taylor 2008-02-28 22:58:34 UTC
I'm reporting this as an enhancement request to record a case where libcalls are still used in the compiler.

Consider this test case:

extern long long bar();
long long foo () { return bar () | bar (); }

Compile it with -O2 -fno-wide-types.  I'm using -fno-wide-types to permit using a simple test case; without that option, the same issue would arise for more complicated cases.

In the .lreg dump I see this:

(insn:HI 9 8 10 2 /home/iant/foo4.c:2 (parallel [
            (set (subreg:SI (reg:DI 61) 0)
                (ior:SI (subreg:SI (reg:DI 58 [ D.1180 ]) 0)
                    (subreg:SI (reg:DI 59 [ D.1179 ]) 0)))
            (clobber (reg:CC 17 flags))
        ]) 253 {*iorsi_1} (expr_list:REG_UNUSED (reg:CC 17 flags)
        (insn_list:REG_LIBCALL 12 (expr_list:REG_NO_CONFLICT (reg:DI 58 [ D.1180 ])
                (expr_list:REG_NO_CONFLICT (reg:DI 59 [ D.1179 ])
                    (nil))))))

(insn:HI 10 9 12 2 /home/iant/foo4.c:2 (parallel [
            (set (subreg:SI (reg:DI 61) 4)
                (ior:SI (subreg:SI (reg:DI 58 [ D.1180 ]) 4)
                    (subreg:SI (reg:DI 59 [ D.1179 ]) 4)))
            (clobber (reg:CC 17 flags))
        ]) 253 {*iorsi_1} (expr_list:REG_DEAD (reg:DI 59 [ D.1179 ])
        (expr_list:REG_DEAD (reg:DI 58 [ D.1180 ])
            (expr_list:REG_UNUSED (reg:CC 17 flags)
                (expr_list:REG_NO_CONFLICT (reg:DI 58 [ D.1180 ])
                    (expr_list:REG_NO_CONFLICT (reg:DI 59 [ D.1179 ])
                        (nil)))))))

(insn:HI 12 10 17 2 /home/iant/foo4.c:2 (set (reg:DI 61)
        (reg:DI 61)) 63 {*movdi_2} (insn_list:REG_RETVAL 9 (expr_list:REG_EQUAL (ior:DI (reg:DI 58 [ D.1180 ])
                (reg:DI 59 [ D.1179 ]))
            (nil))))

This is a libcall sequence which represent a no-conflict block.  It was created by emit_no_conflict_block.  It means that register 61 does not conflict with either register 58 or 59.

It is desirable to detect this fact in some other way.  If we can do that, then we have eliminated one case where we use libcalls.

If we can track subreg lifetimes, then we can detect that there is no conflicts.  Register 58 and 59 dies in insn 10.  Insn 10 does not refer to subreg 0 of either register.  Therefore, subreg 0 of both registers die in insn 9.  Therefore we can know that there is no conflict between register 61 and either register 58 or 59.

The code in ra-conflict.c tries to track subreg lifetimes.  However, it does not detect this case.  In the greg dump file, I see this:

;; 58 conflicts: 61 59 0 1 3
;; 59 conflicts: 61 58 0 1 3
;; 61 conflicts: 58 59 1 3 4

Ideally this should be

;; 58 conflicts: 59 0 1 3
;; 59 conflicts: 58 0 1 3
;; 61 conflicts: 1 3 4

I will attach an old patch I have which was able to make this sort of determination.  This patch is pre-DF, pre-ra-conflict, and is certainly not applicable today.
Comment 1 Ian Lance Taylor 2008-02-28 22:59:07 UTC
Created attachment 15244 [details]
Old patch for this issue
Comment 2 Ian Lance Taylor 2008-02-29 18:43:36 UTC
Whoops, you have to use to -fno-split-wide-types, not -fno-wide-types.  Sorry.
Comment 3 Steven Bosscher 2008-03-10 21:48:33 UTC
IRA does not handle this either with -fno-split-wide-types.  Left is IRA as-is with -O2 -fomit-frame-pointer.  Right is same options + -fno-split-wide-types.

	.file	"t.c"				.file	"t.c"
	.text					.text
	.p2align 4,,15				.p2align 4,,15
.globl _foo				.globl _foo
	.def	_foo;	.scl	2;		.def	_foo;	.scl	2;
_foo:					_foo:
	subl	$12, %esp			subl	$12, %esp
	movl	%ebx, 4(%esp)	      |		movl	%ebx, (%esp)
	movl	%esi, 8(%esp)	      |		movl	%esi, 4(%esp)
				      >		movl	%edi, 8(%esp)
				      >		call	_bar
				      >		movl	%eax, %esi
				      >		movl	%edx, %edi
	call	_bar				call	_bar
	movl	%eax, %ebx			movl	%eax, %ebx
				      >		orl	%esi, %ebx
	movl	%edx, %esi			movl	%edx, %esi
	call	_bar		      |		orl	%edi, %esi
	orl	%ebx, %eax	      |		movl	%ebx, %eax
	orl	%esi, %edx	      |		movl	8(%esp), %edi
	movl	4(%esp), %ebx	      |		movl	%esi, %edx
	movl	8(%esp), %esi	      |		movl	(%esp), %ebx
				      >		movl	4(%esp), %esi
	addl	$12, %esp			addl	$12, %esp
	ret					ret
	.def	_bar;	.scl	2;		.def	_bar;	.scl	2;
Comment 4 Andy Hutchinson 2008-04-13 19:15:03 UTC
Please look at PR35860. I believe this is same problem noted here. subreg-lowering triggering the regression due to worsened conflicts.

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35860
Comment 5 Kenneth Zadeck 2008-04-13 19:31:54 UTC
Subject: Re:  ra-conflict does not handle subregs
 optimally

hutchinsonandy at gcc dot gnu dot org wrote:
> ------- Comment #4 from hutchinsonandy at gcc dot gnu dot org  2008-04-13 19:15 -------
> Please look at PR35860. I believe this is same problem noted here.
> subreg-lowering triggering the regression due to worsened conflicts.
>
> http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35860
>
>
>   
In a couple of days i will have a patch ready for public examination 
that will fix the 35404 issue.
It does so by doing a more precise conflict building so that multiword 
registers can be packed on top of one another if they the "pieces" do 
not ever conflict.  

This is the info that is encoded in REG_NO_CONFLICT notes, but i have 
discovered that I find pairs of these even in places where no such 
notes/blocks were ever created.

I am in the testing process now on the part that makes global understand 
the info my conflict builder is building.  

Stevenb is working on a patch that takes local-alloc out of the loop and 
that will help also.    That is a more complex patch in that there are 
things in local that still have to be done.   

I have cc'ed my self and steven on this bugzilla and i will forward the 
patches to you as they become available and we can see if this solves 
your problems.

kenny



Comment 6 Andy Hutchinson 2008-04-13 19:47:24 UTC
That sounds great - it was one bug I was struggling with.

I can turn around a complete  test for AVR on mingw and Debian as soon as are ready.
Comment 7 Kenneth Zadeck 2008-04-25 21:34:39 UTC
any regressions, if any exist at all, must be addressed by vlad's new register allocator.
Comment 8 Bernhard Reutner-Fischer 2009-08-27 20:28:43 UTC
(In reply to comment #7)
> any regressions, if any exist at all, must be addressed by vlad's new register
> allocator.
> 
IRA is now on trunk, is this fixed on >4.4.x ?