This is the mail archive of the gcc@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]
Other format: [Raw text]

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)


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