This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
UNSPEC vs. CLOBBER followed by (set (subreg ...))
- To: gcc-patches at gcc dot gnu dot org
- Subject: UNSPEC vs. CLOBBER followed by (set (subreg ...))
- From: Geoff Keating <geoffk at cygnus dot com>
- Date: Mon, 24 Jan 2000 12:38:39 -0800
For the following trivial code:
int foo(double d) { return d; }
we used to generate RTL like this:
(insn 21 10 23 (clobber (reg:DI 84)) -1 (nil)
(nil))
(insn 23 21 22 (set (reg:SI 85)
(unspec[
(const_int 0 [0x0])
] 11)) 296 {*floatsidf2_loadaddr} (nil)
(nil))
(insn 22 23 24 (set (subreg:SI (reg:DI 84) 0)
(fix:SI (reg:DF 33 f1))) 308 {*fctiwz} (insn_list:REG_DEP_OUTPUT 21 (nil))
(expr_list:REG_DEAD (reg:DF 33 f1)
(nil)))
(insn 24 22 25 (set (reg:DI 76 fpmem)
(unspec[
(reg:DI 84)
(reg:SI 85)
] 15)) 303 {*fix_truncdfsi2_store} (insn_list 23 (insn_list 22 (nil)))
(expr_list:REG_DEAD (reg:DI 84)
(nil)))
(insn 25 24 13 (set (reg/i:SI 3 r3)
(unspec[
(reg:DI 76 fpmem)
(reg:SI 85)
] 16)) 304 {*fix_truncdfsi2_load} (insn_list 23 (insn_list 24 (nil)))
(expr_list:REG_DEAD (reg:SI 85)
(expr_list:REG_DEAD (reg:DI 76 fpmem)
(nil))))
but when I modified it I didn't include the CLOBBER at the top,
which was generating inefficient code from lreg/greg/reload:
(insn 22 11 24 (set (subreg:SI (reg:DI 84) 0)
(fix:SI (reg:DF 33 f1))) 302 {fctiwz} (nil)
(expr_list:REG_DEAD (reg:DF 33 f1)
(nil)))
(insn 24 22 26 (set (mem:DI (plus:SI (reg:SI 31 r31)
(const_int 8 [0x8])) 0)
(reg:DI 84)) 442 {*movdi_32} (insn_list 22 (nil))
(expr_list:REG_DEAD (reg:DI 84)
(nil)))
(insn 26 24 27 (set (reg/i:SI 3 r3)
(mem:SI (plus:SI (reg:SI 31 r31)
(const_int 12 [0xc])) 0)) 420 {movsi+1} (insn_list 24 (nil))
(nil))
---of course, this has register 84 still live at the top of this
sequence of code, so lreg won't allocate it and reload does some truly
strange stuff; it ends up allocating it in memory (!).
I don't believe that a CLOBBER followed by (set (subreg ...)) will be
optimized worse than an UNSPEC, so the rs6000 port now generates
(insn 22 11 24 (set (reg:DI 84)
(unspec:DI[
(fix:SI (reg:DF 33 f1))
] 10)) 302 {fctiwz} (nil)
(expr_list:REG_EQUIV (mem:DI (plus:SI (reg:SI 31 r31)
(const_int 8 [0x8])) 0)
(expr_list:REG_DEAD (reg:DF 33 f1)
(nil))))
(insn 24 22 26 (set (mem:DI (plus:SI (reg:SI 31 r31)
(const_int 8 [0x8])) 0)
(reg:DI 84)) 442 {*movdi_32} (insn_list 22 (nil))
(expr_list:REG_DEAD (reg:DI 84)
(nil)))
(insn 26 24 27 (set (reg/i:SI 3 r3)
(mem:SI (plus:SI (reg:SI 31 r31)
(const_int 12 [0xc])) 0)) 420 {movsi+1} (insn_list 24 (nil))
(nil))
for the same operation. I'd be interested to hear if anyone out there
doesn't share my belief :-).
I'll commit it when the tests finish (unless it breaks something, of
course).
--
- Geoffrey Keating <geoffk@cygnus.com>
===File ~/patches/cygnus/rs6000-fctiwzunspec.patch==========
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/Attic/ChangeLog,v
retrieving revision 1.1.2.21
diff -p -u -u -p -r1.1.2.21 ChangeLog
--- ChangeLog 2000/01/22 03:32:48 1.1.2.21
+++ ChangeLog 2000/01/24 20:19:02
@@ -1,3 +1,9 @@
+2000-01-24 Geoffrey Keating <geoffk@cygnus.com>
+
+ * rs6000.md (fctiwz): Use (set (reg) (unspec:DI [(fix:SI ...)]))
+ rather than (set (subreg:SI (reg)) (fix:SI ...)) so that register
+ allocation knows (reg) is dead before the insn.
+
2000-01-21 Geoff Keating <geoffk@cygnus.com>
* rs6000.md (movsi_to_cr): Correct typo in output template.
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.79.2.10
diff -p -u -u -p -r1.79.2.10 rs6000.md
--- rs6000.md 2000/01/22 03:32:48 1.79.2.10
+++ rs6000.md 2000/01/24 20:19:02
@@ -30,6 +30,7 @@
;; 7 clobber SP for NT
;; 7 address of the TOC (more-or-less)
;; 8 movsi_got
+;; 10 fctiwz
;; 19 movesi_from_cr
;; 20 movesi_to_cr
@@ -4420,9 +4421,13 @@
rs6000_trunc_used = 1;
}")
+; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] 10))
+; rather than (set (subreg:SI (reg)) (fix:SI ...))
+; because the first makes it clear that operand 0 is not live
+; before the instruction.
(define_insn "fctiwz"
- [(set (subreg:SI (match_operand:DI 0 "gpc_reg_operand" "=f") 0)
- (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))]
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
+ (unspec:DI [(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))] 10))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
"{fcirz|fctiwz} %0,%1"
[(set_attr "type" "fp")])
============================================================