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]

Re: Incorrect use of anti-dependency to order instructions in the DFA scheduler


Daniel Towner <daniel.towner@picochip.com> writes:

> 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.

You unfortunately can't rely on the DFA scheduler to do proper VLIW
instruction bundling.  The scheduler thinks that every instruction
runs separately.  It doesn't understand the notion of two or more
instructions running in parallel.  The scheduler also doesn't
understand that in a typical VLIW machine every instruction slot must
be occupied by an instruction, even if only a NOP.  You generally have
to do actual instruction bundling in a separate machine dependent pass
which tracks dependencies when deciding whether to bundle
instructions.

This is slightly awkward when bundling instructions with a branch
instruction at the start of a bundle.  In the output of the scheduler,
the instructions which follow the branch are expected to be executed
after the branch.  One technique to get around this (other than doing
a lot of rescheduling in the bundling pass) is to use define_delay to
pretend that branch instructions have a delay slot.  The delay slot
filling pass will then find instructions whose dependencies permit
them to be bundled with a branch instruction.  Your bundling pass will
then find them in the right place to bundle them--i.e., just after the
branch instruction.

Ian


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