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