Hi all,
I maintain a port for a 16-bit VLIW machine, and I have encountered a
problem with the DFA instruction scheduler. Consider the following two
instructions:
BNE someLabel
STW R5,(R3) 0 // Mem[R3] := R5
The second instruction will only be executed if the branch isn't taken.
However, when I switch on the DFA scheduler, the memory store is
scheduled in the same cycle as the branch, using VLIW:
BNE someLabel \ STW R5,R3(0)
which obviously changes the meaning of the code, as the store is now
always performed, whereas previously it was conditional. I believe that
this incorrect schedule is caused because an anti-dependence is used to
enforce the ordering of the two instructions, and a VLIW machine allows
anti-dependent instructions to be scheduled in the same cycle. I have
attached the RTL code showing this anti-dependency below.
The problem isn't limited to having a memory store instruction following
the branch. I see the same problem with other types of instruction as well.
Why is an anti-dependence used to enforce the ordering of the branch and
the subsequent instruction? What type of dependency should I use
instead, and if I changed it, would this break other ports?
thanks,
dan.
============================================================================
Daniel Towner
picoChip Designs Ltd, Riverside Buildings, 108, Walcot Street, BATH, BA1 5BG
[EMAIL PROTECTED]
+44 (0) 7786 702589
;#(jump_insn:TI 80 78 102 2 (parallel [
;# (set (pc)
;# (if_then_else (compare:HI (reg:CC 16 pseudoCC)
;# (const_int 0 [0x0]))
;# (pc)
;# (label_ref 93)))
;# (use (const_int 72 [0x48]))
;# ]) 11 {*reversed_branch} (insn_list:REG_DEP_TRUE 79
(insn_list:REG_DEP_ANTI 19
(nil)))
;# (expr_list:REG_DEAD (reg:CC 16 pseudoCC)
;# (expr_list:REG_BR_PROB (const_int 1490 [0x5d2])
;# (nil))))
BEQ _L15 \ // (Reversed branch) ;# 80 *reversed_branch
[length
= 6]
;#(insn 31 102 98 3 (set (mem/v/i:HI (reg:HI 3 R3 [4]) [2 dwt+0 S2 A16])
;# (reg:HI 5 R5)) 15 {movhi} (insn_list:REG_DEP_TRUE 78
(insn_list:REG_DEP_TRUE 1
9 (insn_list:REG_DEP_ANTI 80 (nil))))
;# (expr_list:REG_DEAD (reg:HI 5 R5)
;# (nil)))
STW R5,(R3)0 // Mem((R3)0{byte}) := R5 ;# 31 movhi/5
[length
= 4]