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]

Illegal schedule


In my backend GCC generates illegal scheduled code.

 After pass sched2, GCC generates:

;;	  0-->   486 R1=R3<<0x4                        :IF,ID,AD,RA,EX,WB
;;	  1-->   487 A0=R1+`buffer'                    :IF,ID,AD,RA,EX,WB
;;	  2-->   766 R0=abs(R7)                        :IF,ID,AD,RA,EX,WB
;;	  3-->   456 STATUS=cmp(R3,0x0)                :IF,ID,AD,RA,EX,WB
;;	  4-->   767 R0=R0-0x1                         :IF,ID,AD,RA,EX,WB
;;	  5-->   465 (!STATUS) [A6]=R7^0x1             :IF,ID,AD,RA,EX,(WB+one_memory_port)
;;	  6-->   469 R6=R6-R2                          :IF,ID,AD,RA,EX,WB
;;	  7-->   476 R7=R0 0>>0x1f                     :IF,ID,AD,RA,EX,WB
;;	  9-->   488 [A4]=zxn([A0])                    :IF,ID,(AD+two_memory_ports),RA,EX,(WB+two_memory_ports)
;;	 10-->   925 pc=L489                           :IF,ID,AD,RA,EX,WB

 The instructions 465 and 488 have a pipeline hazard, because they need 3 memory ports at some time, but there are only two ports. The unit reservation templates are:
(define_reservation "one_memory_port"  "(MP1 | MP2)")
(define_reservation "two_memory_ports" "(MP1 + MP2)")

 I checked my scheduler description, and I can't find an error. For GCC this hazard is ok, because GCC assumes the processor can stall the pipeline.

 But after branch-delay-slots filling the code is:

(insn 1001 767 1002 (sequence [
            (jump_insn 941 767 465 (set (pc)
                    (label_ref 489)) 119 {jump_to_immediate_long} (nil)
                (expr_list:REG_BR_PRED (const_int 14 [0xe])
                    (nil)))
            (insn:HI 465 941 469 (cond_exec (eq (reg:CC 48 STATUS)
                        (const_int 0 [0x0]))
                    (set (mem/s:SI (reg/f:SI 38 A6 [479]) [4 <variable>.MPS+0 S32 A32])
                        (xor:SI (reg/v:SI 7 R7 [orig:125 bit ] [125])
                            (const_int 1 [0x1])))) 205 {doloop_end+31} (nil)
                (nil))
            (insn:HI 469 465 476 (set (reg/v:SI 6 R6 [orig:124 value ] [124])
                    (minus:SI (reg/v:SI 6 R6 [orig:124 value ] [124])
                        (reg/v:SI 2 R2 [orig:107 0xa60range ] [107]))) 30 {subsi3_register_internal} (nil)
                (nil))
            (insn:HI 476 469 488 (set (reg/v:SI 7 R7 [orig:125 bit ] [125])
                    (lshiftrt:SI (reg:SI 0 R0 [473])
                        (const_int 31 [0x1f]))) 75 {lshrsi3_const5bit} (nil)
                (nil))
            (insn:HI 488 476 1002 (set (mem/s:SI (reg/f:SI 36 A4 [478]) [4 <variable>.state+0 S32 A32])
                    (zero_extend:SI (mem/s/u:HI (reg/f:SI 32 A0 [365]) [17 buffer S16 A16]))) 102 {zero_extendhisi2} (nil)
                (nil))
        ]) -1 (nil)
    (nil))

 The four instructions before the jump are placed into the delay slots, such that the delay slots are completely filled; but there is still the pipeline hazard, which can't be resolved by inserting NOPs now, because there are no free slots.

 Do I have to reorganize the code prior to slot filling? Do I have to make sure that some problematic instructions do not appear in slots?

Boris


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