This is the mail archive of the gcc-patches@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]

UNSPEC vs. CLOBBER followed by (set (subreg ...))



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")])
============================================================

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