This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Questions about peephole2
- From: Peter Barada <pbarada at mail dot wm dot sps dot mot dot com>
- To: gcc at gcc dot gnu dot org
- Date: Wed, 17 Apr 2002 16:22:08 -0400
- Subject: Questions about peephole2
I've been adding in FPU support for ColdFire, and the following code:
double a;
void foo(unsigned int b)
{
a += b;
}
produces:
.section .rodata
.align 4
.LC0:
.double 0r4.29496729600000000000e9
.text
.globl foo
.type foo,@function
foo:
move.l 4(%sp),%d0 | 4 movsi_cfv4/1
lea a,%a0 | 11 movsi_cfv4/1
fmove.l %d0,%fp0 | 14 floatsidf2_v4e
tst.l %d0 | 16 *m68k.md:353
jbge .L2 | 17 bge
lea .LC0,%a1 | 35 movsi_cfv4/1
fmove.d (%a1),%fp1 | 36 movdf_v4e/1
fadd.d %fp1,%fp0 | 20 adddf3_v4e
.L2:
fadd.d (%a0),%fp0 | 26 adddf3_v4e
fmove.d %fp0,(%a0) | 39 movdf_v4e/2
rts
Insn 36 could be folded into insn 20 if it is known that %fp1 dies at
the end of instruction 20, producing the code:
fadd.d (%a1),%fp0 | 20 adddf3_v4e
The rtl looks like:
(insn 35 31 36 (set:DF (reg:SI 9 %a1)
(symbol_ref/u:SI ("*.LC0"))) 41 {movsi_cfv4} (nil)
(nil))
(insn 36 35 20 (set:DF (reg:DF 17 %fp1)
(mem:DF (reg:SI 9 %a1) 0)) 57 {movdf_v4e} (insn_list 35 (nil))
(expr_list:REG_DEAD (reg:SI 9 %a1)
(nil)))
(insn 20 36 21 (set (reg:DF 16 %fp0 [34])
(plus:DF (reg:DF 16 %fp0 [34])
(reg:DF 17 %fp1))) 141 {adddf3_v4e} (insn_list 36 (nil))
(expr_list:REG_DEAD (reg:DF 17 %fp1)
(nil)))
Which shows that %fp1 dies in insn 20. I tried to write a peephole2
pattern:
;;
;; Here's a peeople pattern to deal with the code created by the
;; reload patterns for float.
;;
;; As an example, a += 1.0 becomes:
;;
;; lea a,%a0
;; fmove.d (%a0),%fp0
;; lea .LC1, %a0
;; fmove.d (%a0),%fp1 <-- can be merged into follwing if %fp1 is dead
;; fadd.d %fp1,%fp0
;;
(define_peephole2
[(set (match_operand:DF 0 "register_operand" "")
(mem:DF (match_operand:SI 1 "register_operand" "")))
(set (match_operand:DF 2 "register_operand" "")
(plus:DF (match_dup 2)
(match_dup 0)))]
"find_regno_note (insn, REG_DEAD, REGNO (operands[0]))
&& REGNO (operands[0]) != REGNO (operands[2])
&& (REGNO (operands[0]) >= 16 && REGNO (operands[0]) < 24)
&& (REGNO (operands[1]) >= 8 && REGNO (operands[1]) < 16)
&& (REGNO (operands[2]) >= 16 && REGNO (operands[2]) < 24)"
[(set (match_dup 2)
(plus:DF (match_dup 2)
(mem:DF (match_dup 1))))]
"")
Which to me looks correct, but it doesn't match since 'insn' at the
point that find_regno_note is called is insn 36, not insn 20 as I'd
expect.
Should I use NEXT_INSN (insn) to get to the appropriate instruction?
What's the best way to solve this?
--
Peter Barada Peter.Barada@motorola.com
Wizard 781-852-2768 (direct)
WaveMark Solutions(wholly owned by Motorola) 781-270-0193 (fax)