DFAPacketizer.cpp revision 953be893e8cffa0ef9bf410036cd96aeb526e98a
1dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//=- llvm/CodeGen/DFAPacketizer.cpp - DFA Packetizer for VLIW -*- C++ -*-=====//
2dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//
3dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//                     The LLVM Compiler Infrastructure
4dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//
5dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// This file is distributed under the University of Illinois Open Source
6dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// License. See LICENSE.TXT for details.
7dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//
8dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//===----------------------------------------------------------------------===//
9dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// This class implements a deterministic finite automaton (DFA) based
10dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// packetizing mechanism for VLIW architectures. It provides APIs to
11dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// determine whether there exists a legal mapping of instructions to
12dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// functional unit assignments in a packet. The DFA is auto-generated from
13dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// the target's Schedule.td file.
14dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//
15dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// A DFA consists of 3 major elements: states, inputs, and transitions. For
16dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// the packetizing mechanism, the input is the set of instruction classes for
17dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// a target. The state models all possible combinations of functional unit
18dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// consumption for a given set of instructions in a packet. A transition
19dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// models the addition of an instruction to a packet. In the DFA constructed
20dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// by this class, if an instruction can be added to a packet, then a valid
21dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// transition exists from the corresponding state. Invalid transitions
22dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// indicate that the instruction cannot be added to the current packet.
23dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//
24dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//===----------------------------------------------------------------------===//
25dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
26ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick#include "ScheduleDAGInstrs.h"
27dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta#include "llvm/CodeGen/DFAPacketizer.h"
28dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta#include "llvm/CodeGen/MachineInstr.h"
29ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick#include "llvm/CodeGen/MachineInstrBundle.h"
30ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick#include "llvm/Target/TargetInstrInfo.h"
31dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta#include "llvm/MC/MCInstrItineraries.h"
32dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasguptausing namespace llvm;
33dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
34dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman DasguptaDFAPacketizer::DFAPacketizer(const InstrItineraryData *I, const int (*SIT)[2],
35464f3a332f81364ee09794f9502f0b25671149c6Sebastian Pop                             const unsigned *SET):
36dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  InstrItins(I), CurrentState(0), DFAStateInputTable(SIT),
37dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  DFAStateEntryTable(SET) {}
38dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
39dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
40dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//
41f6f77e90a18142e196cbc2a6ee87cdf7461b17dfSebastian Pop// ReadTable - Read the DFA transition table and update CachedTable.
42dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//
43dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// Format of the transition tables:
44dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// DFAStateInputTable[][2] = pairs of <Input, Transition> for all valid
45dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//                           transitions
46dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// DFAStateEntryTable[i] = Index of the first entry in DFAStateInputTable
47dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//                         for the ith state
48dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta//
49dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasguptavoid DFAPacketizer::ReadTable(unsigned int state) {
50dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  unsigned ThisState = DFAStateEntryTable[state];
51dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  unsigned NextStateInTable = DFAStateEntryTable[state+1];
52dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  // Early exit in case CachedTable has already contains this
53f6f77e90a18142e196cbc2a6ee87cdf7461b17dfSebastian Pop  // state's transitions.
54dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  if (CachedTable.count(UnsignPair(state,
55dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta                                   DFAStateInputTable[ThisState][0])))
56dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta    return;
57dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
58dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  for (unsigned i = ThisState; i < NextStateInTable; i++)
59dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta    CachedTable[UnsignPair(state, DFAStateInputTable[i][0])] =
60dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta      DFAStateInputTable[i][1];
61dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta}
62dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
63dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
64dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// canReserveResources - Check if the resources occupied by a MCInstrDesc
65f6f77e90a18142e196cbc2a6ee87cdf7461b17dfSebastian Pop// are available in the current state.
66464f3a332f81364ee09794f9502f0b25671149c6Sebastian Popbool DFAPacketizer::canReserveResources(const llvm::MCInstrDesc *MID) {
67dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  unsigned InsnClass = MID->getSchedClass();
68464f3a332f81364ee09794f9502f0b25671149c6Sebastian Pop  const llvm::InstrStage *IS = InstrItins->beginStage(InsnClass);
69dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  unsigned FuncUnits = IS->getUnits();
70dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  UnsignPair StateTrans = UnsignPair(CurrentState, FuncUnits);
71dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  ReadTable(CurrentState);
72dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  return (CachedTable.count(StateTrans) != 0);
73dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta}
74dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
75dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
76dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// reserveResources - Reserve the resources occupied by a MCInstrDesc and
77f6f77e90a18142e196cbc2a6ee87cdf7461b17dfSebastian Pop// change the current state to reflect that change.
78464f3a332f81364ee09794f9502f0b25671149c6Sebastian Popvoid DFAPacketizer::reserveResources(const llvm::MCInstrDesc *MID) {
79dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  unsigned InsnClass = MID->getSchedClass();
80464f3a332f81364ee09794f9502f0b25671149c6Sebastian Pop  const llvm::InstrStage *IS = InstrItins->beginStage(InsnClass);
81dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  unsigned FuncUnits = IS->getUnits();
82dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  UnsignPair StateTrans = UnsignPair(CurrentState, FuncUnits);
83dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  ReadTable(CurrentState);
84dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  assert(CachedTable.count(StateTrans) != 0);
85dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  CurrentState = CachedTable[StateTrans];
86dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta}
87dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
88dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
89dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// canReserveResources - Check if the resources occupied by a machine
90f6f77e90a18142e196cbc2a6ee87cdf7461b17dfSebastian Pop// instruction are available in the current state.
91464f3a332f81364ee09794f9502f0b25671149c6Sebastian Popbool DFAPacketizer::canReserveResources(llvm::MachineInstr *MI) {
92464f3a332f81364ee09794f9502f0b25671149c6Sebastian Pop  const llvm::MCInstrDesc &MID = MI->getDesc();
93dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  return canReserveResources(&MID);
94dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta}
95dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta
96dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta// reserveResources - Reserve the resources occupied by a machine
97f6f77e90a18142e196cbc2a6ee87cdf7461b17dfSebastian Pop// instruction and change the current state to reflect that change.
98464f3a332f81364ee09794f9502f0b25671149c6Sebastian Popvoid DFAPacketizer::reserveResources(llvm::MachineInstr *MI) {
99464f3a332f81364ee09794f9502f0b25671149c6Sebastian Pop  const llvm::MCInstrDesc &MID = MI->getDesc();
100dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta  reserveResources(&MID);
101dc81e5da271ed394e2029c83458773c4ae2fc5f4Anshuman Dasgupta}
102ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
10368c36e0c26d6abc6e19ac66a24061d8c4a187767Andrew Tricknamespace {
104ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// DefaultVLIWScheduler - This class extends ScheduleDAGInstrs and overrides
105ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// Schedule method to build the dependence graph.
106e746186ed4f61bf5eba13112cb8419c95cf58e52Andrew Trick//
10792fc97afa742000aeb81d862abbaaba50b27a000Benjamin Kramer// ScheduleDAGInstrs has LLVM_LIBRARY_VISIBILITY so we have to reference it as
10892fc97afa742000aeb81d862abbaaba50b27a000Benjamin Kramer// an opaque pointer in VLIWPacketizerList.
109ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trickclass DefaultVLIWScheduler : public ScheduleDAGInstrs {
110ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trickpublic:
111ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI,
112e746186ed4f61bf5eba13112cb8419c95cf58e52Andrew Trick                       MachineDominatorTree &MDT, bool IsPostRA);
113ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  // Schedule - Actual scheduling work.
114953be893e8cffa0ef9bf410036cd96aeb526e98aAndrew Trick  void schedule();
115ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick};
11692fc97afa742000aeb81d862abbaaba50b27a000Benjamin Kramer} // end anonymous namespace
117e746186ed4f61bf5eba13112cb8419c95cf58e52Andrew Trick
118ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew TrickDefaultVLIWScheduler::DefaultVLIWScheduler(
119ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT,
120ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  bool IsPostRA) :
121ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  ScheduleDAGInstrs(MF, MLI, MDT, IsPostRA) {
122ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
123ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
124953be893e8cffa0ef9bf410036cd96aeb526e98aAndrew Trickvoid DefaultVLIWScheduler::schedule() {
125ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  // Build the scheduling graph.
126953be893e8cffa0ef9bf410036cd96aeb526e98aAndrew Trick  buildSchedGraph(0);
127ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
128ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
129ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// VLIWPacketizerList Ctor
130ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew TrickVLIWPacketizerList::VLIWPacketizerList(
131ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  MachineFunction &MF, MachineLoopInfo &MLI, MachineDominatorTree &MDT,
132ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  bool IsPostRA) : TM(MF.getTarget()), MF(MF)  {
133ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  TII = TM.getInstrInfo();
134ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  ResourceTracker = TII->CreateTargetScheduleState(&TM, 0);
13592fc97afa742000aeb81d862abbaaba50b27a000Benjamin Kramer  SchedulerImpl = new DefaultVLIWScheduler(MF, MLI, MDT, IsPostRA);
136ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
137ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
138ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// VLIWPacketizerList Dtor
139ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew TrickVLIWPacketizerList::~VLIWPacketizerList() {
14092fc97afa742000aeb81d862abbaaba50b27a000Benjamin Kramer  delete (DefaultVLIWScheduler *)SchedulerImpl;
141ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  delete ResourceTracker;
142ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
143ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
144ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// ignorePseudoInstruction - ignore pseudo instructions.
145ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trickbool VLIWPacketizerList::ignorePseudoInstruction(MachineInstr *MI,
146ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick                                                 MachineBasicBlock *MBB) {
147ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  if (MI->isDebugValue())
148ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    return true;
149ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
150ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  if (TII->isSchedulingBoundary(MI, MBB, MF))
151ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    return true;
152ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
153ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  return false;
154ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
155ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
156ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// isSoloInstruction - return true if instruction I must end previous
157ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// packet.
158ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trickbool VLIWPacketizerList::isSoloInstruction(MachineInstr *I) {
159ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  if (I->isInlineAsm())
160ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    return true;
161ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
162ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  return false;
163ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
164ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
165ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// addToPacket - Add I to the current packet and reserve resource.
166ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trickvoid VLIWPacketizerList::addToPacket(MachineInstr *MI) {
167ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  CurrentPacketMIs.push_back(MI);
168ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  ResourceTracker->reserveResources(MI);
169ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
170ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
171ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// endPacket - End the current packet, bundle packet instructions and reset
172ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// DFA state.
173ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trickvoid VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
174ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick                                         MachineInstr *I) {
175ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  if (CurrentPacketMIs.size() > 1) {
176ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    MachineInstr *MIFirst = CurrentPacketMIs.front();
177ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    finalizeBundle(*MBB, MIFirst, I);
178ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  }
179ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  CurrentPacketMIs.clear();
180ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  ResourceTracker->clearResources();
181ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
182ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
183ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick// PacketizeMIs - Bundle machine instructions into packets.
184ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trickvoid VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
185ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick                                      MachineBasicBlock::iterator BeginItr,
186ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick                                      MachineBasicBlock::iterator EndItr) {
18792fc97afa742000aeb81d862abbaaba50b27a000Benjamin Kramer  DefaultVLIWScheduler *Scheduler = (DefaultVLIWScheduler *)SchedulerImpl;
18847c144505b9be28ed22c626b3a407c11dba2fec5Andrew Trick  Scheduler->enterRegion(MBB, BeginItr, EndItr, MBB->size());
189953be893e8cffa0ef9bf410036cd96aeb526e98aAndrew Trick  Scheduler->schedule();
19047c144505b9be28ed22c626b3a407c11dba2fec5Andrew Trick  Scheduler->exitRegion();
191ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
192ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  // Remember scheduling units.
19392fc97afa742000aeb81d862abbaaba50b27a000Benjamin Kramer  SUnits = Scheduler->SUnits;
194ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
195ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  // Generate MI -> SU map.
196ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  std::map <MachineInstr*, SUnit*> MIToSUnit;
197ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  for (unsigned i = 0, e = SUnits.size(); i != e; ++i) {
198ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    SUnit *SU = &SUnits[i];
199ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    MIToSUnit[SU->getInstr()] = SU;
200ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  }
201ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
202ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  // The main packetizer loop.
203ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  for (; BeginItr != EndItr; ++BeginItr) {
204ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    MachineInstr *MI = BeginItr;
205ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
206ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    // Ignore pseudo instructions.
207ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    if (ignorePseudoInstruction(MI, MBB))
208ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick      continue;
209ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
210ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    // End the current packet if needed.
211ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    if (isSoloInstruction(MI)) {
212ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick      endPacket(MBB, MI);
213ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick      continue;
214ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    }
215ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
216ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    SUnit *SUI = MIToSUnit[MI];
217ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    assert(SUI && "Missing SUnit Info!");
218ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
219ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    // Ask DFA if machine resource is available for MI.
220ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    bool ResourceAvail = ResourceTracker->canReserveResources(MI);
221ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    if (ResourceAvail) {
222ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick      // Dependency check for MI with instructions in CurrentPacketMIs.
223ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick      for (std::vector<MachineInstr*>::iterator VI = CurrentPacketMIs.begin(),
224ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick           VE = CurrentPacketMIs.end(); VI != VE; ++VI) {
225ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick        MachineInstr *MJ = *VI;
226ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick        SUnit *SUJ = MIToSUnit[MJ];
227ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick        assert(SUJ && "Missing SUnit Info!");
228ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
229ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick        // Is it legal to packetize SUI and SUJ together.
230ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick        if (!isLegalToPacketizeTogether(SUI, SUJ)) {
231ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick          // Allow packetization if dependency can be pruned.
232ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick          if (!isLegalToPruneDependencies(SUI, SUJ)) {
233ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick            // End the packet if dependency cannot be pruned.
234ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick            endPacket(MBB, MI);
235ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick            break;
236ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick          } // !isLegalToPruneDependencies.
237ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick        } // !isLegalToPacketizeTogether.
238ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick      } // For all instructions in CurrentPacketMIs.
239ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    } else {
240ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick      // End the packet if resource is not available.
241ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick      endPacket(MBB, MI);
242ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    }
243ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
244ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    // Add MI to the current packet.
245ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick    addToPacket(MI);
246ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  } // For all instructions in BB.
247ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick
248ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  // End any packet left behind.
249ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick  endPacket(MBB, EndItr);
250ebafa0c61170682ec0d7025f46f187a164b0db7eAndrew Trick}
251