[llvm-commits] Target independent VLIW Packetizer

Andrew Trick atrick at apple.com
Mon Feb 6 18:16:09 PST 2012


On Feb 6, 2012, at 12:06 AM, Sundeep <sundeepk at codeaurora.org> wrote:
> I have been working on a target independent VLIW packetizer in LLVM. On VLIW
> machines, an instruction packet represents a group of instructions which can
> be executed in parallel. The compiler is responsible for identifying
> independent machine instructions and grouping those together into packets.
> The VLIW packetizer in LLVM is implemented as follows:
> 
> Implementation Details:
> 
> 1. The VLIW packetizer is implemented after all target specific passes are
> run. This ensures that all pseudo instructions and spill code is enumerated
> before packetization.
> 
> 2. The VLIW packetizer extends "ScheduleDAGInstrs" class. The Packetizer
> uses "BuildSchedGraph" API to build dependence graph. The dependence graph
> along with deterministic finite automaton (DFA) is used to group independent
> instructions into packets.
> 
> 3. The instruction packets are finalized using "finalizeBundle" API. This
> API inserts BUNDLE instructions and updates each packet instruction with
> "insideBundle" bit.
> 
> 4. The Hexagon backend assembly printer is updated to handle BUNDLE
> instruction and print packet semantics correctly. Other VLIW targets will
> also have to update the assembly printer.
> 
> The VLIW packetizer roughly implements the following algorithm:
> 
>  1 Instantiate DFA resource tracker
>  2 For all basic blocks (BB) in Machine Function
>  3 do
>  4   reset DFA
>  5   CurrentPacket = {}
>  6   For all machine instructions (I) in BB
>  7   do
>  8     avail = DFA.IsAvailable(I)
>  9     if (avail == true) {
> 10       For all machine instructions (Ip) in CurrentPacket
> 11       do
> 12         if (DependenceGraph.HasDependence(I, Ip)) {
> 13           if (Target.CanPruneDependence(I, Ip)) {
> 14             // End current packet
> 15             finalizeBundle
> 16             reset DFA
> 17             reset CurrentPacket
> 18           }
> 19         }
> 20       done
> 21     }
> 22     else {
> 23       // End current packet
> 24       finalizeBundle
> 25       reset DFA
> 26       reset CurrentPacket
> 27     }
> 28
> 29     // Add I to CurrentPacket
> 30     CurrentPacket.Add(I)
> 31   done
> 32 done
> 
> I have already verified that it builds and runs regression test suites clean
> on x86. I attaching the initial patch for review and comments.

It's nice that you're generalizing the implementation so that it can be extended later and serve as a starting point for similar targets. I understand you've put a lot of work into that aspect. However, it's also important to keep different features of the code generator self contained. For example, we should only add hooks to common target headers when they're generally applicable, and not specific to VLIW support. It's also important to have a consistent scheduling/bundling strategy in the target independent code. Eventually, Hexagon will have to move to the new scheudling/bundling framework. Until then, the inconsistent bits (i.e. packetizing late) need to be confined to the Hexagon target.

Let me set a few specific goals for this patch:

1. Don't touch TargetInstrInfo.h. Only the scheduler or packetizer itself should include ScheduleDAG.h. If we need to later, we can make the packetizer extensible by providing hook within the packetizer itself. Other targets can implement the packetizer interface to exploit those hooks.

2. Don't touch LLVMTargetMachine.cpp. We have a preEmit hook already that will work for you. For now, you can keep your command line options target-local. Later we can share the option across multiple targets of it makes sense. TargetPassConfig will handle that. It's not something you need to worry about now.

3. Don't add any new target-independent passes. It's good to provide stand alone utilties that can be used by multiple targets, such as DFAPacketizer and VLIWScheduler. However, I don't see much value in providing a driver loop that can be shared across targets. Targets provide their own scheduling/packetizing pass and share various scheduling utilties bottom-up. In particular, a target can extend ScheduleDAGInstrs or DFAPacketizer within it own pass. If we see that multiple targets really do need a pass that runs at the same time with identical drivers, then we can consider declaring it a "target-independent" pass at that time. I realize there's existing code that doesn't necessarily follow this strategy. We're working on cleaning it up, so it's particularly important not exacerbate the problem at this time.

Here's my suggestion for now. Any code that should be shared by multiple targets that both use DFAPacketizer can go in DFAPacketizer.(h|cpp). For example, you can put the VLIWPacketizerList subclass of ScheduleDAGInstrs there. I don't see anything in VLIWPacketizerList that's inconstitent with the general MachineInstrBundle design. You can then create a new HexagonVLIWPacketizer pass within your target and add it during preEmit.

-Andy



More information about the llvm-commits mailing list