xref: /aosp_15_r20/external/llvm/lib/CodeGen/DFAPacketizer.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //=- llvm/CodeGen/DFAPacketizer.cpp - DFA Packetizer for VLIW -*- C++ -*-=====//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker // This class implements a deterministic finite automaton (DFA) based
10*9880d681SAndroid Build Coastguard Worker // packetizing mechanism for VLIW architectures. It provides APIs to
11*9880d681SAndroid Build Coastguard Worker // determine whether there exists a legal mapping of instructions to
12*9880d681SAndroid Build Coastguard Worker // functional unit assignments in a packet. The DFA is auto-generated from
13*9880d681SAndroid Build Coastguard Worker // the target's Schedule.td file.
14*9880d681SAndroid Build Coastguard Worker //
15*9880d681SAndroid Build Coastguard Worker // A DFA consists of 3 major elements: states, inputs, and transitions. For
16*9880d681SAndroid Build Coastguard Worker // the packetizing mechanism, the input is the set of instruction classes for
17*9880d681SAndroid Build Coastguard Worker // a target. The state models all possible combinations of functional unit
18*9880d681SAndroid Build Coastguard Worker // consumption for a given set of instructions in a packet. A transition
19*9880d681SAndroid Build Coastguard Worker // models the addition of an instruction to a packet. In the DFA constructed
20*9880d681SAndroid Build Coastguard Worker // by this class, if an instruction can be added to a packet, then a valid
21*9880d681SAndroid Build Coastguard Worker // transition exists from the corresponding state. Invalid transitions
22*9880d681SAndroid Build Coastguard Worker // indicate that the instruction cannot be added to the current packet.
23*9880d681SAndroid Build Coastguard Worker //
24*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "packets"
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/DFAPacketizer.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstr.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBundle.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/ScheduleDAGInstrs.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCInstrItineraries.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker using namespace llvm;
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker // --------------------------------------------------------------------
38*9880d681SAndroid Build Coastguard Worker // Definitions shared between DFAPacketizer.cpp and DFAPacketizerEmitter.cpp
39*9880d681SAndroid Build Coastguard Worker 
40*9880d681SAndroid Build Coastguard Worker namespace {
addDFAFuncUnits(DFAInput Inp,unsigned FuncUnits)41*9880d681SAndroid Build Coastguard Worker   DFAInput addDFAFuncUnits(DFAInput Inp, unsigned FuncUnits) {
42*9880d681SAndroid Build Coastguard Worker     return (Inp << DFA_MAX_RESOURCES) | FuncUnits;
43*9880d681SAndroid Build Coastguard Worker   }
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker   /// Return the DFAInput for an instruction class input vector.
46*9880d681SAndroid Build Coastguard Worker   /// This function is used in both DFAPacketizer.cpp and in
47*9880d681SAndroid Build Coastguard Worker   /// DFAPacketizerEmitter.cpp.
getDFAInsnInput(const std::vector<unsigned> & InsnClass)48*9880d681SAndroid Build Coastguard Worker   DFAInput getDFAInsnInput(const std::vector<unsigned> &InsnClass) {
49*9880d681SAndroid Build Coastguard Worker     DFAInput InsnInput = 0;
50*9880d681SAndroid Build Coastguard Worker     assert((InsnClass.size() <= DFA_MAX_RESTERMS) &&
51*9880d681SAndroid Build Coastguard Worker            "Exceeded maximum number of DFA terms");
52*9880d681SAndroid Build Coastguard Worker     for (auto U : InsnClass)
53*9880d681SAndroid Build Coastguard Worker       InsnInput = addDFAFuncUnits(InsnInput, U);
54*9880d681SAndroid Build Coastguard Worker     return InsnInput;
55*9880d681SAndroid Build Coastguard Worker   }
56*9880d681SAndroid Build Coastguard Worker }
57*9880d681SAndroid Build Coastguard Worker // --------------------------------------------------------------------
58*9880d681SAndroid Build Coastguard Worker 
DFAPacketizer(const InstrItineraryData * I,const DFAStateInput (* SIT)[2],const unsigned * SET)59*9880d681SAndroid Build Coastguard Worker DFAPacketizer::DFAPacketizer(const InstrItineraryData *I,
60*9880d681SAndroid Build Coastguard Worker                              const DFAStateInput (*SIT)[2],
61*9880d681SAndroid Build Coastguard Worker                              const unsigned *SET):
62*9880d681SAndroid Build Coastguard Worker   InstrItins(I), CurrentState(0), DFAStateInputTable(SIT),
63*9880d681SAndroid Build Coastguard Worker   DFAStateEntryTable(SET) {
64*9880d681SAndroid Build Coastguard Worker   // Make sure DFA types are large enough for the number of terms & resources.
65*9880d681SAndroid Build Coastguard Worker   static_assert((DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <=
66*9880d681SAndroid Build Coastguard Worker                     (8 * sizeof(DFAInput)),
67*9880d681SAndroid Build Coastguard Worker                 "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAInput");
68*9880d681SAndroid Build Coastguard Worker   static_assert(
69*9880d681SAndroid Build Coastguard Worker       (DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) <= (8 * sizeof(DFAStateInput)),
70*9880d681SAndroid Build Coastguard Worker       "(DFA_MAX_RESTERMS * DFA_MAX_RESOURCES) too big for DFAStateInput");
71*9880d681SAndroid Build Coastguard Worker }
72*9880d681SAndroid Build Coastguard Worker 
73*9880d681SAndroid Build Coastguard Worker 
74*9880d681SAndroid Build Coastguard Worker // Read the DFA transition table and update CachedTable.
75*9880d681SAndroid Build Coastguard Worker //
76*9880d681SAndroid Build Coastguard Worker // Format of the transition tables:
77*9880d681SAndroid Build Coastguard Worker // DFAStateInputTable[][2] = pairs of <Input, Transition> for all valid
78*9880d681SAndroid Build Coastguard Worker //                           transitions
79*9880d681SAndroid Build Coastguard Worker // DFAStateEntryTable[i] = Index of the first entry in DFAStateInputTable
80*9880d681SAndroid Build Coastguard Worker //                         for the ith state
81*9880d681SAndroid Build Coastguard Worker //
ReadTable(unsigned int state)82*9880d681SAndroid Build Coastguard Worker void DFAPacketizer::ReadTable(unsigned int state) {
83*9880d681SAndroid Build Coastguard Worker   unsigned ThisState = DFAStateEntryTable[state];
84*9880d681SAndroid Build Coastguard Worker   unsigned NextStateInTable = DFAStateEntryTable[state+1];
85*9880d681SAndroid Build Coastguard Worker   // Early exit in case CachedTable has already contains this
86*9880d681SAndroid Build Coastguard Worker   // state's transitions.
87*9880d681SAndroid Build Coastguard Worker   if (CachedTable.count(UnsignPair(state, DFAStateInputTable[ThisState][0])))
88*9880d681SAndroid Build Coastguard Worker     return;
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker   for (unsigned i = ThisState; i < NextStateInTable; i++)
91*9880d681SAndroid Build Coastguard Worker     CachedTable[UnsignPair(state, DFAStateInputTable[i][0])] =
92*9880d681SAndroid Build Coastguard Worker       DFAStateInputTable[i][1];
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker 
96*9880d681SAndroid Build Coastguard Worker // Return the DFAInput for an instruction class.
getInsnInput(unsigned InsnClass)97*9880d681SAndroid Build Coastguard Worker DFAInput DFAPacketizer::getInsnInput(unsigned InsnClass) {
98*9880d681SAndroid Build Coastguard Worker   // Note: this logic must match that in DFAPacketizerDefs.h for input vectors.
99*9880d681SAndroid Build Coastguard Worker   DFAInput InsnInput = 0;
100*9880d681SAndroid Build Coastguard Worker   unsigned i = 0;
101*9880d681SAndroid Build Coastguard Worker   (void)i;
102*9880d681SAndroid Build Coastguard Worker   for (const InstrStage *IS = InstrItins->beginStage(InsnClass),
103*9880d681SAndroid Build Coastguard Worker        *IE = InstrItins->endStage(InsnClass); IS != IE; ++IS) {
104*9880d681SAndroid Build Coastguard Worker     InsnInput = addDFAFuncUnits(InsnInput, IS->getUnits());
105*9880d681SAndroid Build Coastguard Worker     assert((i++ < DFA_MAX_RESTERMS) && "Exceeded maximum number of DFA inputs");
106*9880d681SAndroid Build Coastguard Worker   }
107*9880d681SAndroid Build Coastguard Worker   return InsnInput;
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker 
110*9880d681SAndroid Build Coastguard Worker 
111*9880d681SAndroid Build Coastguard Worker // Return the DFAInput for an instruction class input vector.
getInsnInput(const std::vector<unsigned> & InsnClass)112*9880d681SAndroid Build Coastguard Worker DFAInput DFAPacketizer::getInsnInput(const std::vector<unsigned> &InsnClass) {
113*9880d681SAndroid Build Coastguard Worker   return getDFAInsnInput(InsnClass);
114*9880d681SAndroid Build Coastguard Worker }
115*9880d681SAndroid Build Coastguard Worker 
116*9880d681SAndroid Build Coastguard Worker 
117*9880d681SAndroid Build Coastguard Worker // Check if the resources occupied by a MCInstrDesc are available in the
118*9880d681SAndroid Build Coastguard Worker // current state.
canReserveResources(const llvm::MCInstrDesc * MID)119*9880d681SAndroid Build Coastguard Worker bool DFAPacketizer::canReserveResources(const llvm::MCInstrDesc *MID) {
120*9880d681SAndroid Build Coastguard Worker   unsigned InsnClass = MID->getSchedClass();
121*9880d681SAndroid Build Coastguard Worker   DFAInput InsnInput = getInsnInput(InsnClass);
122*9880d681SAndroid Build Coastguard Worker   UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
123*9880d681SAndroid Build Coastguard Worker   ReadTable(CurrentState);
124*9880d681SAndroid Build Coastguard Worker   return CachedTable.count(StateTrans) != 0;
125*9880d681SAndroid Build Coastguard Worker }
126*9880d681SAndroid Build Coastguard Worker 
127*9880d681SAndroid Build Coastguard Worker 
128*9880d681SAndroid Build Coastguard Worker // Reserve the resources occupied by a MCInstrDesc and change the current
129*9880d681SAndroid Build Coastguard Worker // state to reflect that change.
reserveResources(const llvm::MCInstrDesc * MID)130*9880d681SAndroid Build Coastguard Worker void DFAPacketizer::reserveResources(const llvm::MCInstrDesc *MID) {
131*9880d681SAndroid Build Coastguard Worker   unsigned InsnClass = MID->getSchedClass();
132*9880d681SAndroid Build Coastguard Worker   DFAInput InsnInput = getInsnInput(InsnClass);
133*9880d681SAndroid Build Coastguard Worker   UnsignPair StateTrans = UnsignPair(CurrentState, InsnInput);
134*9880d681SAndroid Build Coastguard Worker   ReadTable(CurrentState);
135*9880d681SAndroid Build Coastguard Worker   assert(CachedTable.count(StateTrans) != 0);
136*9880d681SAndroid Build Coastguard Worker   CurrentState = CachedTable[StateTrans];
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker 
139*9880d681SAndroid Build Coastguard Worker 
140*9880d681SAndroid Build Coastguard Worker // Check if the resources occupied by a machine instruction are available
141*9880d681SAndroid Build Coastguard Worker // in the current state.
canReserveResources(llvm::MachineInstr & MI)142*9880d681SAndroid Build Coastguard Worker bool DFAPacketizer::canReserveResources(llvm::MachineInstr &MI) {
143*9880d681SAndroid Build Coastguard Worker   const llvm::MCInstrDesc &MID = MI.getDesc();
144*9880d681SAndroid Build Coastguard Worker   return canReserveResources(&MID);
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker 
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker // Reserve the resources occupied by a machine instruction and change the
149*9880d681SAndroid Build Coastguard Worker // current state to reflect that change.
reserveResources(llvm::MachineInstr & MI)150*9880d681SAndroid Build Coastguard Worker void DFAPacketizer::reserveResources(llvm::MachineInstr &MI) {
151*9880d681SAndroid Build Coastguard Worker   const llvm::MCInstrDesc &MID = MI.getDesc();
152*9880d681SAndroid Build Coastguard Worker   reserveResources(&MID);
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker 
155*9880d681SAndroid Build Coastguard Worker 
156*9880d681SAndroid Build Coastguard Worker namespace llvm {
157*9880d681SAndroid Build Coastguard Worker // This class extends ScheduleDAGInstrs and overrides the schedule method
158*9880d681SAndroid Build Coastguard Worker // to build the dependence graph.
159*9880d681SAndroid Build Coastguard Worker class DefaultVLIWScheduler : public ScheduleDAGInstrs {
160*9880d681SAndroid Build Coastguard Worker private:
161*9880d681SAndroid Build Coastguard Worker   AliasAnalysis *AA;
162*9880d681SAndroid Build Coastguard Worker   /// Ordered list of DAG postprocessing steps.
163*9880d681SAndroid Build Coastguard Worker   std::vector<std::unique_ptr<ScheduleDAGMutation>> Mutations;
164*9880d681SAndroid Build Coastguard Worker public:
165*9880d681SAndroid Build Coastguard Worker   DefaultVLIWScheduler(MachineFunction &MF, MachineLoopInfo &MLI,
166*9880d681SAndroid Build Coastguard Worker                        AliasAnalysis *AA);
167*9880d681SAndroid Build Coastguard Worker   // Actual scheduling work.
168*9880d681SAndroid Build Coastguard Worker   void schedule() override;
169*9880d681SAndroid Build Coastguard Worker 
170*9880d681SAndroid Build Coastguard Worker   /// DefaultVLIWScheduler takes ownership of the Mutation object.
addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation)171*9880d681SAndroid Build Coastguard Worker   void addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation) {
172*9880d681SAndroid Build Coastguard Worker     Mutations.push_back(std::move(Mutation));
173*9880d681SAndroid Build Coastguard Worker   }
174*9880d681SAndroid Build Coastguard Worker protected:
175*9880d681SAndroid Build Coastguard Worker   void postprocessDAG();
176*9880d681SAndroid Build Coastguard Worker };
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
179*9880d681SAndroid Build Coastguard Worker 
DefaultVLIWScheduler(MachineFunction & MF,MachineLoopInfo & MLI,AliasAnalysis * AA)180*9880d681SAndroid Build Coastguard Worker DefaultVLIWScheduler::DefaultVLIWScheduler(MachineFunction &MF,
181*9880d681SAndroid Build Coastguard Worker                                            MachineLoopInfo &MLI,
182*9880d681SAndroid Build Coastguard Worker                                            AliasAnalysis *AA)
183*9880d681SAndroid Build Coastguard Worker     : ScheduleDAGInstrs(MF, &MLI), AA(AA) {
184*9880d681SAndroid Build Coastguard Worker   CanHandleTerminators = true;
185*9880d681SAndroid Build Coastguard Worker }
186*9880d681SAndroid Build Coastguard Worker 
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker /// Apply each ScheduleDAGMutation step in order.
postprocessDAG()189*9880d681SAndroid Build Coastguard Worker void DefaultVLIWScheduler::postprocessDAG() {
190*9880d681SAndroid Build Coastguard Worker   for (auto &M : Mutations)
191*9880d681SAndroid Build Coastguard Worker     M->apply(this);
192*9880d681SAndroid Build Coastguard Worker }
193*9880d681SAndroid Build Coastguard Worker 
194*9880d681SAndroid Build Coastguard Worker 
schedule()195*9880d681SAndroid Build Coastguard Worker void DefaultVLIWScheduler::schedule() {
196*9880d681SAndroid Build Coastguard Worker   // Build the scheduling graph.
197*9880d681SAndroid Build Coastguard Worker   buildSchedGraph(AA);
198*9880d681SAndroid Build Coastguard Worker   postprocessDAG();
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker 
VLIWPacketizerList(MachineFunction & mf,MachineLoopInfo & mli,AliasAnalysis * aa)202*9880d681SAndroid Build Coastguard Worker VLIWPacketizerList::VLIWPacketizerList(MachineFunction &mf,
203*9880d681SAndroid Build Coastguard Worker                                        MachineLoopInfo &mli, AliasAnalysis *aa)
204*9880d681SAndroid Build Coastguard Worker     : MF(mf), TII(mf.getSubtarget().getInstrInfo()), AA(aa) {
205*9880d681SAndroid Build Coastguard Worker   ResourceTracker = TII->CreateTargetScheduleState(MF.getSubtarget());
206*9880d681SAndroid Build Coastguard Worker   VLIWScheduler = new DefaultVLIWScheduler(MF, mli, AA);
207*9880d681SAndroid Build Coastguard Worker }
208*9880d681SAndroid Build Coastguard Worker 
209*9880d681SAndroid Build Coastguard Worker 
~VLIWPacketizerList()210*9880d681SAndroid Build Coastguard Worker VLIWPacketizerList::~VLIWPacketizerList() {
211*9880d681SAndroid Build Coastguard Worker   if (VLIWScheduler)
212*9880d681SAndroid Build Coastguard Worker     delete VLIWScheduler;
213*9880d681SAndroid Build Coastguard Worker   if (ResourceTracker)
214*9880d681SAndroid Build Coastguard Worker     delete ResourceTracker;
215*9880d681SAndroid Build Coastguard Worker }
216*9880d681SAndroid Build Coastguard Worker 
217*9880d681SAndroid Build Coastguard Worker 
218*9880d681SAndroid Build Coastguard Worker // End the current packet, bundle packet instructions and reset DFA state.
endPacket(MachineBasicBlock * MBB,MachineBasicBlock::iterator MI)219*9880d681SAndroid Build Coastguard Worker void VLIWPacketizerList::endPacket(MachineBasicBlock *MBB,
220*9880d681SAndroid Build Coastguard Worker                                    MachineBasicBlock::iterator MI) {
221*9880d681SAndroid Build Coastguard Worker   if (CurrentPacketMIs.size() > 1) {
222*9880d681SAndroid Build Coastguard Worker     MachineInstr &MIFirst = *CurrentPacketMIs.front();
223*9880d681SAndroid Build Coastguard Worker     finalizeBundle(*MBB, MIFirst.getIterator(), MI.getInstrIterator());
224*9880d681SAndroid Build Coastguard Worker   }
225*9880d681SAndroid Build Coastguard Worker   CurrentPacketMIs.clear();
226*9880d681SAndroid Build Coastguard Worker   ResourceTracker->clearResources();
227*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "End packet\n");
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker 
230*9880d681SAndroid Build Coastguard Worker 
231*9880d681SAndroid Build Coastguard Worker // Bundle machine instructions into packets.
PacketizeMIs(MachineBasicBlock * MBB,MachineBasicBlock::iterator BeginItr,MachineBasicBlock::iterator EndItr)232*9880d681SAndroid Build Coastguard Worker void VLIWPacketizerList::PacketizeMIs(MachineBasicBlock *MBB,
233*9880d681SAndroid Build Coastguard Worker                                       MachineBasicBlock::iterator BeginItr,
234*9880d681SAndroid Build Coastguard Worker                                       MachineBasicBlock::iterator EndItr) {
235*9880d681SAndroid Build Coastguard Worker   assert(VLIWScheduler && "VLIW Scheduler is not initialized!");
236*9880d681SAndroid Build Coastguard Worker   VLIWScheduler->startBlock(MBB);
237*9880d681SAndroid Build Coastguard Worker   VLIWScheduler->enterRegion(MBB, BeginItr, EndItr,
238*9880d681SAndroid Build Coastguard Worker                              std::distance(BeginItr, EndItr));
239*9880d681SAndroid Build Coastguard Worker   VLIWScheduler->schedule();
240*9880d681SAndroid Build Coastguard Worker 
241*9880d681SAndroid Build Coastguard Worker   DEBUG({
242*9880d681SAndroid Build Coastguard Worker     dbgs() << "Scheduling DAG of the packetize region\n";
243*9880d681SAndroid Build Coastguard Worker     for (SUnit &SU : VLIWScheduler->SUnits)
244*9880d681SAndroid Build Coastguard Worker       SU.dumpAll(VLIWScheduler);
245*9880d681SAndroid Build Coastguard Worker   });
246*9880d681SAndroid Build Coastguard Worker 
247*9880d681SAndroid Build Coastguard Worker   // Generate MI -> SU map.
248*9880d681SAndroid Build Coastguard Worker   MIToSUnit.clear();
249*9880d681SAndroid Build Coastguard Worker   for (SUnit &SU : VLIWScheduler->SUnits)
250*9880d681SAndroid Build Coastguard Worker     MIToSUnit[SU.getInstr()] = &SU;
251*9880d681SAndroid Build Coastguard Worker 
252*9880d681SAndroid Build Coastguard Worker   // The main packetizer loop.
253*9880d681SAndroid Build Coastguard Worker   for (; BeginItr != EndItr; ++BeginItr) {
254*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI = *BeginItr;
255*9880d681SAndroid Build Coastguard Worker     initPacketizerState();
256*9880d681SAndroid Build Coastguard Worker 
257*9880d681SAndroid Build Coastguard Worker     // End the current packet if needed.
258*9880d681SAndroid Build Coastguard Worker     if (isSoloInstruction(MI)) {
259*9880d681SAndroid Build Coastguard Worker       endPacket(MBB, MI);
260*9880d681SAndroid Build Coastguard Worker       continue;
261*9880d681SAndroid Build Coastguard Worker     }
262*9880d681SAndroid Build Coastguard Worker 
263*9880d681SAndroid Build Coastguard Worker     // Ignore pseudo instructions.
264*9880d681SAndroid Build Coastguard Worker     if (ignorePseudoInstruction(MI, MBB))
265*9880d681SAndroid Build Coastguard Worker       continue;
266*9880d681SAndroid Build Coastguard Worker 
267*9880d681SAndroid Build Coastguard Worker     SUnit *SUI = MIToSUnit[&MI];
268*9880d681SAndroid Build Coastguard Worker     assert(SUI && "Missing SUnit Info!");
269*9880d681SAndroid Build Coastguard Worker 
270*9880d681SAndroid Build Coastguard Worker     // Ask DFA if machine resource is available for MI.
271*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "Checking resources for adding MI to packet " << MI);
272*9880d681SAndroid Build Coastguard Worker 
273*9880d681SAndroid Build Coastguard Worker     bool ResourceAvail = ResourceTracker->canReserveResources(MI);
274*9880d681SAndroid Build Coastguard Worker     DEBUG({
275*9880d681SAndroid Build Coastguard Worker       if (ResourceAvail)
276*9880d681SAndroid Build Coastguard Worker         dbgs() << "  Resources are available for adding MI to packet\n";
277*9880d681SAndroid Build Coastguard Worker       else
278*9880d681SAndroid Build Coastguard Worker         dbgs() << "  Resources NOT available\n";
279*9880d681SAndroid Build Coastguard Worker     });
280*9880d681SAndroid Build Coastguard Worker     if (ResourceAvail && shouldAddToPacket(MI)) {
281*9880d681SAndroid Build Coastguard Worker       // Dependency check for MI with instructions in CurrentPacketMIs.
282*9880d681SAndroid Build Coastguard Worker       for (auto MJ : CurrentPacketMIs) {
283*9880d681SAndroid Build Coastguard Worker         SUnit *SUJ = MIToSUnit[MJ];
284*9880d681SAndroid Build Coastguard Worker         assert(SUJ && "Missing SUnit Info!");
285*9880d681SAndroid Build Coastguard Worker 
286*9880d681SAndroid Build Coastguard Worker         DEBUG(dbgs() << "  Checking against MJ " << *MJ);
287*9880d681SAndroid Build Coastguard Worker         // Is it legal to packetize SUI and SUJ together.
288*9880d681SAndroid Build Coastguard Worker         if (!isLegalToPacketizeTogether(SUI, SUJ)) {
289*9880d681SAndroid Build Coastguard Worker           DEBUG(dbgs() << "  Not legal to add MI, try to prune\n");
290*9880d681SAndroid Build Coastguard Worker           // Allow packetization if dependency can be pruned.
291*9880d681SAndroid Build Coastguard Worker           if (!isLegalToPruneDependencies(SUI, SUJ)) {
292*9880d681SAndroid Build Coastguard Worker             // End the packet if dependency cannot be pruned.
293*9880d681SAndroid Build Coastguard Worker             DEBUG(dbgs() << "  Could not prune dependencies for adding MI\n");
294*9880d681SAndroid Build Coastguard Worker             endPacket(MBB, MI);
295*9880d681SAndroid Build Coastguard Worker             break;
296*9880d681SAndroid Build Coastguard Worker           }
297*9880d681SAndroid Build Coastguard Worker           DEBUG(dbgs() << "  Pruned dependence for adding MI\n");
298*9880d681SAndroid Build Coastguard Worker         }
299*9880d681SAndroid Build Coastguard Worker       }
300*9880d681SAndroid Build Coastguard Worker     } else {
301*9880d681SAndroid Build Coastguard Worker       DEBUG(if (ResourceAvail)
302*9880d681SAndroid Build Coastguard Worker         dbgs() << "Resources are available, but instruction should not be "
303*9880d681SAndroid Build Coastguard Worker                   "added to packet\n  " << MI);
304*9880d681SAndroid Build Coastguard Worker       // End the packet if resource is not available, or if the instruction
305*9880d681SAndroid Build Coastguard Worker       // shoud not be added to the current packet.
306*9880d681SAndroid Build Coastguard Worker       endPacket(MBB, MI);
307*9880d681SAndroid Build Coastguard Worker     }
308*9880d681SAndroid Build Coastguard Worker 
309*9880d681SAndroid Build Coastguard Worker     // Add MI to the current packet.
310*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "* Adding MI to packet " << MI << '\n');
311*9880d681SAndroid Build Coastguard Worker     BeginItr = addToPacket(MI);
312*9880d681SAndroid Build Coastguard Worker   } // For all instructions in the packetization range.
313*9880d681SAndroid Build Coastguard Worker 
314*9880d681SAndroid Build Coastguard Worker   // End any packet left behind.
315*9880d681SAndroid Build Coastguard Worker   endPacket(MBB, EndItr);
316*9880d681SAndroid Build Coastguard Worker   VLIWScheduler->exitRegion();
317*9880d681SAndroid Build Coastguard Worker   VLIWScheduler->finishBlock();
318*9880d681SAndroid Build Coastguard Worker }
319*9880d681SAndroid Build Coastguard Worker 
320*9880d681SAndroid Build Coastguard Worker 
321*9880d681SAndroid Build Coastguard Worker // Add a DAG mutation object to the ordered list.
addMutation(std::unique_ptr<ScheduleDAGMutation> Mutation)322*9880d681SAndroid Build Coastguard Worker void VLIWPacketizerList::addMutation(
323*9880d681SAndroid Build Coastguard Worker       std::unique_ptr<ScheduleDAGMutation> Mutation) {
324*9880d681SAndroid Build Coastguard Worker   VLIWScheduler->addMutation(std::move(Mutation));
325*9880d681SAndroid Build Coastguard Worker }
326