This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug rtl-optimization/35404] New: ra-conflict does not handle subregs optimally
- From: "ian at airs dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 28 Feb 2008 22:58:34 -0000
- Subject: [Bug rtl-optimization/35404] New: ra-conflict does not handle subregs optimally
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
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.
--
Summary: ra-conflict does not handle subregs optimally
Product: gcc
Version: 4.4.0
Status: UNCONFIRMED
Severity: enhancement
Priority: P3
Component: rtl-optimization
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: ian at airs dot com
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35404