f01196aefaae55467895be0f2439c1300c7034fe
[oota-llvm.git] / lib / Target / SparcV9 / InstrSched / InstrScheduling.cpp
1 //===- InstrScheduling.cpp - Generic Instruction Scheduling support -------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the llvm/CodeGen/InstrScheduling.h interface, along with
11 // generic support routines for instruction scheduling.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "SchedPriorities.h"
16 #include "llvm/CodeGen/MachineInstr.h"
17 #include "llvm/CodeGen/MachineCodeForInstruction.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/CodeGen/FunctionLiveVarInfo.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "llvm/BasicBlock.h"
22 #include "Support/CommandLine.h"
23 #include <algorithm>
24
25 namespace llvm {
26
27 SchedDebugLevel_t SchedDebugLevel;
28
29 static cl::opt<bool> EnableFillingDelaySlots("sched-fill-delay-slots",
30               cl::desc("Fill branch delay slots during local scheduling"));
31
32 static cl::opt<SchedDebugLevel_t, true>
33 SDL_opt("dsched", cl::Hidden, cl::location(SchedDebugLevel),
34         cl::desc("enable instruction scheduling debugging information"),
35         cl::values(
36  clEnumValN(Sched_NoDebugInfo,      "n", "disable debug output"),
37  clEnumValN(Sched_PrintMachineCode, "y", "print machine code after scheduling"),
38  clEnumValN(Sched_PrintSchedTrace,  "t", "print trace of scheduling actions"),
39  clEnumValN(Sched_PrintSchedGraphs, "g", "print scheduling graphs"),
40                    0));
41
42
43 //************************* Internal Data Types *****************************/
44
45 class InstrSchedule;
46 class SchedulingManager;
47
48
49 //----------------------------------------------------------------------
50 // class InstrGroup:
51 // 
52 // Represents a group of instructions scheduled to be issued
53 // in a single cycle.
54 //----------------------------------------------------------------------
55
56 class InstrGroup {
57   InstrGroup(const InstrGroup&);       // DO NOT IMPLEMENT
58   void operator=(const InstrGroup&);   // DO NOT IMPLEMENT
59   
60 public:
61   inline const SchedGraphNode* operator[](unsigned int slotNum) const {
62     assert(slotNum  < group.size());
63     return group[slotNum];
64   }
65   
66 private:
67   friend class InstrSchedule;
68   
69   inline void   addInstr(const SchedGraphNode* node, unsigned int slotNum) {
70     assert(slotNum < group.size());
71     group[slotNum] = node;
72   }
73   
74   /*ctor*/      InstrGroup(unsigned int nslots)
75     : group(nslots, NULL) {}
76   
77   /*ctor*/      InstrGroup();           // disable: DO NOT IMPLEMENT
78   
79 private:
80   std::vector<const SchedGraphNode*> group;
81 };
82
83
84 //----------------------------------------------------------------------
85 // class ScheduleIterator:
86 // 
87 // Iterates over the machine instructions in the for a single basic block.
88 // The schedule is represented by an InstrSchedule object.
89 //----------------------------------------------------------------------
90
91 template<class _NodeType>
92 class ScheduleIterator : public forward_iterator<_NodeType, ptrdiff_t> {
93 private:
94   unsigned cycleNum;
95   unsigned slotNum;
96   const InstrSchedule& S;
97 public:
98   typedef ScheduleIterator<_NodeType> _Self;
99   
100   /*ctor*/ inline ScheduleIterator(const InstrSchedule& _schedule,
101                                    unsigned _cycleNum,
102                                    unsigned _slotNum)
103     : cycleNum(_cycleNum), slotNum(_slotNum), S(_schedule) {
104     skipToNextInstr(); 
105   }
106   
107   /*ctor*/ inline ScheduleIterator(const _Self& x)
108     : cycleNum(x.cycleNum), slotNum(x.slotNum), S(x.S) {}
109   
110   inline bool operator==(const _Self& x) const {
111     return (slotNum == x.slotNum && cycleNum== x.cycleNum && &S==&x.S);
112   }
113   
114   inline bool operator!=(const _Self& x) const { return !operator==(x); }
115   
116   inline _NodeType* operator*() const;
117   inline _NodeType* operator->() const { return operator*(); }
118   
119          _Self& operator++();                           // Preincrement
120   inline _Self operator++(int) {                        // Postincrement
121     _Self tmp(*this); ++*this; return tmp; 
122   }
123   
124   static _Self begin(const InstrSchedule& _schedule);
125   static _Self end(  const InstrSchedule& _schedule);
126   
127 private:
128   inline _Self& operator=(const _Self& x); // DISABLE -- DO NOT IMPLEMENT
129   void  skipToNextInstr();
130 };
131
132
133 //----------------------------------------------------------------------
134 // class InstrSchedule:
135 // 
136 // Represents the schedule of machine instructions for a single basic block.
137 //----------------------------------------------------------------------
138
139 class InstrSchedule {
140   const unsigned int nslots;
141   unsigned int numInstr;
142   std::vector<InstrGroup*> groups;              // indexed by cycle number
143   std::vector<cycles_t> startTime;              // indexed by node id
144
145   InstrSchedule(InstrSchedule&);   // DO NOT IMPLEMENT
146   void operator=(InstrSchedule&);  // DO NOT IMPLEMENT
147   
148 public: // iterators
149   typedef ScheduleIterator<SchedGraphNode> iterator;
150   typedef ScheduleIterator<const SchedGraphNode> const_iterator;
151   
152         iterator begin()       { return iterator::begin(*this); }
153   const_iterator begin() const { return const_iterator::begin(*this); }
154         iterator end()         { return iterator::end(*this); }
155   const_iterator end() const   { return const_iterator::end(*this); }
156   
157 public: // constructors and destructor
158   /*ctor*/              InstrSchedule   (unsigned int _nslots,
159                                          unsigned int _numNodes);
160   /*dtor*/              ~InstrSchedule  ();
161   
162 public: // accessor functions to query chosen schedule
163   const SchedGraphNode* getInstr        (unsigned int slotNum,
164                                          cycles_t c) const {
165     const InstrGroup* igroup = this->getIGroup(c);
166     return (igroup == NULL)? NULL : (*igroup)[slotNum];
167   }
168   
169   inline InstrGroup*    getIGroup       (cycles_t c) {
170     if ((unsigned)c >= groups.size())
171       groups.resize(c+1);
172     if (groups[c] == NULL)
173       groups[c] = new InstrGroup(nslots);
174     return groups[c];
175   }
176   
177   inline const InstrGroup* getIGroup    (cycles_t c) const {
178     assert((unsigned)c < groups.size());
179     return groups[c];
180   }
181   
182   inline cycles_t       getStartTime    (unsigned int nodeId) const {
183     assert(nodeId < startTime.size());
184     return startTime[nodeId];
185   }
186   
187   unsigned int          getNumInstructions() const {
188     return numInstr;
189   }
190   
191   inline void           scheduleInstr   (const SchedGraphNode* node,
192                                          unsigned int slotNum,
193                                          cycles_t cycle) {
194     InstrGroup* igroup = this->getIGroup(cycle);
195     assert((*igroup)[slotNum] == NULL &&  "Slot already filled?");
196     igroup->addInstr(node, slotNum);
197     assert(node->getNodeId() < startTime.size());
198     startTime[node->getNodeId()] = cycle;
199     ++numInstr;
200   }
201   
202 private:
203   friend class ScheduleIterator<SchedGraphNode>;
204   friend class ScheduleIterator<const SchedGraphNode>;
205   /*ctor*/      InstrSchedule   ();     // Disable: DO NOT IMPLEMENT.
206 };
207
208 template<class NodeType>
209 inline NodeType *ScheduleIterator<NodeType>::operator*() const {
210   assert(cycleNum < S.groups.size());
211   return (*S.groups[cycleNum])[slotNum];
212 }
213
214
215 /*ctor*/
216 InstrSchedule::InstrSchedule(unsigned int _nslots, unsigned int _numNodes)
217   : nslots(_nslots),
218     numInstr(0),
219     groups(2 * _numNodes / _nslots),            // 2 x lower-bound for #cycles
220     startTime(_numNodes, (cycles_t) -1)         // set all to -1
221 {
222 }
223
224
225 /*dtor*/
226 InstrSchedule::~InstrSchedule()
227 {
228   for (unsigned c=0, NC=groups.size(); c < NC; c++)
229     if (groups[c] != NULL)
230       delete groups[c];                 // delete InstrGroup objects
231 }
232
233
234 template<class _NodeType>
235 inline 
236 void
237 ScheduleIterator<_NodeType>::skipToNextInstr()
238 {
239   while(cycleNum < S.groups.size() && S.groups[cycleNum] == NULL)
240     ++cycleNum;                 // skip cycles with no instructions
241   
242   while (cycleNum < S.groups.size() &&
243          (*S.groups[cycleNum])[slotNum] == NULL)
244   {
245     ++slotNum;
246     if (slotNum == S.nslots) {
247       ++cycleNum;
248       slotNum = 0;
249       while(cycleNum < S.groups.size() && S.groups[cycleNum] == NULL)
250         ++cycleNum;                     // skip cycles with no instructions
251     }
252   }
253 }
254
255 template<class _NodeType>
256 inline 
257 ScheduleIterator<_NodeType>&
258 ScheduleIterator<_NodeType>::operator++()       // Preincrement
259 {
260   ++slotNum;
261   if (slotNum == S.nslots) {
262     ++cycleNum;
263     slotNum = 0;
264   }
265   skipToNextInstr(); 
266   return *this;
267 }
268
269 template<class _NodeType>
270 ScheduleIterator<_NodeType>
271 ScheduleIterator<_NodeType>::begin(const InstrSchedule& _schedule)
272 {
273   return _Self(_schedule, 0, 0);
274 }
275
276 template<class _NodeType>
277 ScheduleIterator<_NodeType>
278 ScheduleIterator<_NodeType>::end(const InstrSchedule& _schedule)
279 {
280   return _Self(_schedule, _schedule.groups.size(), 0);
281 }
282
283
284 //----------------------------------------------------------------------
285 // class DelaySlotInfo:
286 // 
287 // Record information about delay slots for a single branch instruction.
288 // Delay slots are simply indexed by slot number 1 ... numDelaySlots
289 //----------------------------------------------------------------------
290
291 class DelaySlotInfo {
292   const SchedGraphNode* brNode;
293   unsigned ndelays;
294   std::vector<const SchedGraphNode*> delayNodeVec;
295   cycles_t delayedNodeCycle;
296   unsigned delayedNodeSlotNum;
297   
298   DelaySlotInfo(const DelaySlotInfo &);  // DO NOT IMPLEMENT
299   void operator=(const DelaySlotInfo&);  // DO NOT IMPLEMENT
300 public:
301   /*ctor*/      DelaySlotInfo           (const SchedGraphNode* _brNode,
302                                          unsigned _ndelays)
303     : brNode(_brNode), ndelays(_ndelays),
304       delayedNodeCycle(0), delayedNodeSlotNum(0) {}
305   
306   inline unsigned getNumDelays  () {
307     return ndelays;
308   }
309   
310   inline const std::vector<const SchedGraphNode*>& getDelayNodeVec() {
311     return delayNodeVec;
312   }
313   
314   inline void   addDelayNode            (const SchedGraphNode* node) {
315     delayNodeVec.push_back(node);
316     assert(delayNodeVec.size() <= ndelays && "Too many delay slot instrs!");
317   }
318   
319   inline void   recordChosenSlot        (cycles_t cycle, unsigned slotNum) {
320     delayedNodeCycle = cycle;
321     delayedNodeSlotNum = slotNum;
322   }
323   
324   unsigned      scheduleDelayedNode     (SchedulingManager& S);
325 };
326
327
328 //----------------------------------------------------------------------
329 // class SchedulingManager:
330 // 
331 // Represents the schedule of machine instructions for a single basic block.
332 //----------------------------------------------------------------------
333
334 class SchedulingManager {
335   SchedulingManager(SchedulingManager &);    // DO NOT IMPLEMENT
336   void operator=(const SchedulingManager &); // DO NOT IMPLEMENT
337 public: // publicly accessible data members
338   const unsigned nslots;
339   const TargetSchedInfo& schedInfo;
340   SchedPriorities& schedPrio;
341   InstrSchedule isched;
342   
343 private:
344   unsigned totalInstrCount;
345   cycles_t curTime;
346   cycles_t nextEarliestIssueTime;               // next cycle we can issue
347   // indexed by slot#
348   std::vector<hash_set<const SchedGraphNode*> > choicesForSlot;
349   std::vector<const SchedGraphNode*> choiceVec; // indexed by node ptr
350   std::vector<int> numInClass;                  // indexed by sched class
351   std::vector<cycles_t> nextEarliestStartTime;  // indexed by opCode
352   hash_map<const SchedGraphNode*, DelaySlotInfo*> delaySlotInfoForBranches;
353                                                 // indexed by branch node ptr 
354   
355 public:
356   SchedulingManager(const TargetMachine& _target, const SchedGraph* graph,
357                     SchedPriorities& schedPrio);
358   ~SchedulingManager() {
359     for (hash_map<const SchedGraphNode*,
360            DelaySlotInfo*>::iterator I = delaySlotInfoForBranches.begin(),
361            E = delaySlotInfoForBranches.end(); I != E; ++I)
362       delete I->second;
363   }
364   
365   //----------------------------------------------------------------------
366   // Simplify access to the machine instruction info
367   //----------------------------------------------------------------------
368   
369   inline const TargetInstrInfo& getInstrInfo    () const {
370     return schedInfo.getInstrInfo();
371   }
372   
373   //----------------------------------------------------------------------
374   // Interface for checking and updating the current time
375   //----------------------------------------------------------------------
376   
377   inline cycles_t       getTime                 () const {
378     return curTime;
379   }
380   
381   inline cycles_t       getEarliestIssueTime() const {
382     return nextEarliestIssueTime;
383   }
384   
385   inline cycles_t       getEarliestStartTimeForOp(MachineOpCode opCode) const {
386     assert(opCode < (int) nextEarliestStartTime.size());
387     return nextEarliestStartTime[opCode];
388   }
389   
390   // Update current time to specified cycle
391   inline void   updateTime              (cycles_t c) {
392     curTime = c;
393     schedPrio.updateTime(c);
394   }
395   
396   //----------------------------------------------------------------------
397   // Functions to manage the choices for the current cycle including:
398   // -- a vector of choices by priority (choiceVec)
399   // -- vectors of the choices for each instruction slot (choicesForSlot[])
400   // -- number of choices in each sched class, used to check issue conflicts
401   //    between choices for a single cycle
402   //----------------------------------------------------------------------
403   
404   inline unsigned int getNumChoices     () const {
405     return choiceVec.size();
406   }
407   
408   inline unsigned getNumChoicesInClass  (const InstrSchedClass& sc) const {
409     assert(sc < numInClass.size() && "Invalid op code or sched class!");
410     return numInClass[sc];
411   }
412   
413   inline const SchedGraphNode* getChoice(unsigned int i) const {
414     // assert(i < choiceVec.size());    don't check here.
415     return choiceVec[i];
416   }
417   
418   inline hash_set<const SchedGraphNode*>& getChoicesForSlot(unsigned slotNum) {
419     assert(slotNum < nslots);
420     return choicesForSlot[slotNum];
421   }
422   
423   inline void   addChoice               (const SchedGraphNode* node) {
424     // Append the instruction to the vector of choices for current cycle.
425     // Increment numInClass[c] for the sched class to which the instr belongs.
426     choiceVec.push_back(node);
427     const InstrSchedClass& sc = schedInfo.getSchedClass(node->getOpcode());
428     assert(sc < numInClass.size());
429     numInClass[sc]++;
430   }
431   
432   inline void   addChoiceToSlot         (unsigned int slotNum,
433                                          const SchedGraphNode* node) {
434     // Add the instruction to the choice set for the specified slot
435     assert(slotNum < nslots);
436     choicesForSlot[slotNum].insert(node);
437   }
438   
439   inline void   resetChoices            () {
440     choiceVec.clear();
441     for (unsigned int s=0; s < nslots; s++)
442       choicesForSlot[s].clear();
443     for (unsigned int c=0; c < numInClass.size(); c++)
444       numInClass[c] = 0;
445   }
446   
447   //----------------------------------------------------------------------
448   // Code to query and manage the partial instruction schedule so far
449   //----------------------------------------------------------------------
450   
451   inline unsigned int   getNumScheduled () const {
452     return isched.getNumInstructions();
453   }
454   
455   inline unsigned int   getNumUnscheduled() const {
456     return totalInstrCount - isched.getNumInstructions();
457   }
458   
459   inline bool           isScheduled     (const SchedGraphNode* node) const {
460     return (isched.getStartTime(node->getNodeId()) >= 0);
461   }
462   
463   inline void   scheduleInstr           (const SchedGraphNode* node,
464                                          unsigned int slotNum,
465                                          cycles_t cycle)
466   {
467     assert(! isScheduled(node) && "Instruction already scheduled?");
468     
469     // add the instruction to the schedule
470     isched.scheduleInstr(node, slotNum, cycle);
471     
472     // update the earliest start times of all nodes that conflict with `node'
473     // and the next-earliest time anything can issue if `node' causes bubbles
474     updateEarliestStartTimes(node, cycle);
475     
476     // remove the instruction from the choice sets for all slots
477     for (unsigned s=0; s < nslots; s++)
478       choicesForSlot[s].erase(node);
479     
480     // and decrement the instr count for the sched class to which it belongs
481     const InstrSchedClass& sc = schedInfo.getSchedClass(node->getOpcode());
482     assert(sc < numInClass.size());
483     numInClass[sc]--;
484   }
485
486   //----------------------------------------------------------------------
487   // Create and retrieve delay slot info for delayed instructions
488   //----------------------------------------------------------------------
489   
490   inline DelaySlotInfo* getDelaySlotInfoForInstr(const SchedGraphNode* bn,
491                                                  bool createIfMissing=false)
492   {
493     hash_map<const SchedGraphNode*, DelaySlotInfo*>::const_iterator
494       I = delaySlotInfoForBranches.find(bn);
495     if (I != delaySlotInfoForBranches.end())
496       return I->second;
497
498     if (!createIfMissing) return 0;
499
500     DelaySlotInfo *dinfo =
501       new DelaySlotInfo(bn, getInstrInfo().getNumDelaySlots(bn->getOpcode()));
502     return delaySlotInfoForBranches[bn] = dinfo;
503   }
504   
505 private:
506   SchedulingManager();     // DISABLED: DO NOT IMPLEMENT
507   void updateEarliestStartTimes(const SchedGraphNode* node, cycles_t schedTime);
508 };
509
510
511 /*ctor*/
512 SchedulingManager::SchedulingManager(const TargetMachine& target,
513                                      const SchedGraph* graph,
514                                      SchedPriorities& _schedPrio)
515   : nslots(target.getSchedInfo().getMaxNumIssueTotal()),
516     schedInfo(target.getSchedInfo()),
517     schedPrio(_schedPrio),
518     isched(nslots, graph->getNumNodes()),
519     totalInstrCount(graph->getNumNodes() - 2),
520     nextEarliestIssueTime(0),
521     choicesForSlot(nslots),
522     numInClass(target.getSchedInfo().getNumSchedClasses(), 0),  // set all to 0
523     nextEarliestStartTime(target.getInstrInfo().getNumRealOpCodes(),
524                           (cycles_t) 0)                         // set all to 0
525 {
526   updateTime(0);
527   
528   // Note that an upper bound on #choices for each slot is = nslots since
529   // we use this vector to hold a feasible set of instructions, and more
530   // would be infeasible. Reserve that much memory since it is probably small.
531   for (unsigned int i=0; i < nslots; i++)
532     choicesForSlot[i].resize(nslots);
533 }
534
535
536 void
537 SchedulingManager::updateEarliestStartTimes(const SchedGraphNode* node,
538                                             cycles_t schedTime)
539 {
540   if (schedInfo.numBubblesAfter(node->getOpcode()) > 0)
541     { // Update next earliest time before which *nothing* can issue.
542       nextEarliestIssueTime = std::max(nextEarliestIssueTime,
543                   curTime + 1 + schedInfo.numBubblesAfter(node->getOpcode()));
544     }
545   
546   const std::vector<MachineOpCode>&
547     conflictVec = schedInfo.getConflictList(node->getOpcode());
548   
549   for (unsigned i=0; i < conflictVec.size(); i++)
550     {
551       MachineOpCode toOp = conflictVec[i];
552       cycles_t est=schedTime + schedInfo.getMinIssueGap(node->getOpcode(),toOp);
553       assert(toOp < (int) nextEarliestStartTime.size());
554       if (nextEarliestStartTime[toOp] < est)
555         nextEarliestStartTime[toOp] = est;
556     }
557 }
558
559 //************************* Internal Functions *****************************/
560
561
562 static void
563 AssignInstructionsToSlots(class SchedulingManager& S, unsigned maxIssue)
564 {
565   // find the slot to start from, in the current cycle
566   unsigned int startSlot = 0;
567   cycles_t curTime = S.getTime();
568   
569   assert(maxIssue > 0 && maxIssue <= S.nslots - startSlot);
570   
571   // If only one instruction can be issued, do so.
572   if (maxIssue == 1)
573     for (unsigned s=startSlot; s < S.nslots; s++)
574       if (S.getChoicesForSlot(s).size() > 0) {
575         // found the one instruction
576         S.scheduleInstr(*S.getChoicesForSlot(s).begin(), s, curTime);
577         return;
578       }
579   
580   // Otherwise, choose from the choices for each slot
581   // 
582   InstrGroup* igroup = S.isched.getIGroup(S.getTime());
583   assert(igroup != NULL && "Group creation failed?");
584   
585   // Find a slot that has only a single choice, and take it.
586   // If all slots have 0 or multiple choices, pick the first slot with
587   // choices and use its last instruction (just to avoid shifting the vector).
588   unsigned numIssued;
589   for (numIssued = 0; numIssued < maxIssue; numIssued++) {
590     int chosenSlot = -1;
591     for (unsigned s=startSlot; s < S.nslots; s++)
592       if ((*igroup)[s] == NULL && S.getChoicesForSlot(s).size() == 1) {
593         chosenSlot = (int) s;
594         break;
595       }
596       
597     if (chosenSlot == -1)
598       for (unsigned s=startSlot; s < S.nslots; s++)
599         if ((*igroup)[s] == NULL && S.getChoicesForSlot(s).size() > 0) {
600           chosenSlot = (int) s;
601           break;
602         }
603       
604     if (chosenSlot != -1) {
605       // Insert the chosen instr in the chosen slot and
606       // erase it from all slots.
607       const SchedGraphNode* node= *S.getChoicesForSlot(chosenSlot).begin();
608       S.scheduleInstr(node, chosenSlot, curTime);
609     }
610   }
611   
612   assert(numIssued > 0 && "Should not happen when maxIssue > 0!");
613 }
614
615
616 // 
617 // For now, just assume we are scheduling within a single basic block.
618 // Get the machine instruction vector for the basic block and clear it,
619 // then append instructions in scheduled order.
620 // Also, re-insert the dummy PHI instructions that were at the beginning
621 // of the basic block, since they are not part of the schedule.
622 //   
623 static void
624 RecordSchedule(MachineBasicBlock &MBB, const SchedulingManager& S)
625 {
626   const TargetInstrInfo& mii = S.schedInfo.getInstrInfo();
627   
628 #ifndef NDEBUG
629   // Lets make sure we didn't lose any instructions, except possibly
630   // some NOPs from delay slots.  Also, PHIs are not included in the schedule.
631   unsigned numInstr = 0;
632   for (MachineBasicBlock::iterator I=MBB.begin(); I != MBB.end(); ++I)
633     if (! mii.isNop(I->getOpcode()) &&
634         ! mii.isDummyPhiInstr(I->getOpcode()))
635       ++numInstr;
636   assert(S.isched.getNumInstructions() >= numInstr &&
637          "Lost some non-NOP instructions during scheduling!");
638 #endif
639   
640   if (S.isched.getNumInstructions() == 0)
641     return;                             // empty basic block!
642   
643   // First find the dummy instructions at the start of the basic block
644   MachineBasicBlock::iterator I = MBB.begin();
645   for ( ; I != MBB.end(); ++I)
646     if (! mii.isDummyPhiInstr(I->getOpcode()))
647       break;
648   
649   // Remove all except the dummy PHI instructions from MBB, and
650   // pre-allocate create space for the ones we will put back in.
651   while (I != MBB.end()) MBB.remove(I);
652   
653   InstrSchedule::const_iterator NIend = S.isched.end();
654   for (InstrSchedule::const_iterator NI = S.isched.begin(); NI != NIend; ++NI)
655     MBB.push_back(const_cast<MachineInstr*>((*NI)->getMachineInstr()));
656 }
657
658
659
660 static void
661 MarkSuccessorsReady(SchedulingManager& S, const SchedGraphNode* node)
662 {
663   // Check if any successors are now ready that were not already marked
664   // ready before, and that have not yet been scheduled.
665   // 
666   for (sg_succ_const_iterator SI = succ_begin(node); SI !=succ_end(node); ++SI)
667     if (! (*SI)->isDummyNode()
668         && ! S.isScheduled(*SI)
669         && ! S.schedPrio.nodeIsReady(*SI))
670     {
671       // successor not scheduled and not marked ready; check *its* preds.
672         
673       bool succIsReady = true;
674       for (sg_pred_const_iterator P=pred_begin(*SI); P != pred_end(*SI); ++P)
675         if (! (*P)->isDummyNode() && ! S.isScheduled(*P)) {
676           succIsReady = false;
677           break;
678         }
679         
680       if (succIsReady)  // add the successor to the ready list
681         S.schedPrio.insertReady(*SI);
682     }
683 }
684
685
686 // Choose up to `nslots' FEASIBLE instructions and assign each
687 // instruction to all possible slots that do not violate feasibility.
688 // FEASIBLE means it should be guaranteed that the set
689 // of chosen instructions can be issued in a single group.
690 // 
691 // Return value:
692 //      maxIssue : total number of feasible instructions
693 //      S.choicesForSlot[i=0..nslots] : set of instructions feasible in slot i
694 // 
695 static unsigned
696 FindSlotChoices(SchedulingManager& S,
697                 DelaySlotInfo*& getDelaySlotInfo)
698 {
699   // initialize result vectors to empty
700   S.resetChoices();
701   
702   // find the slot to start from, in the current cycle
703   unsigned int startSlot = 0;
704   InstrGroup* igroup = S.isched.getIGroup(S.getTime());
705   for (int s = S.nslots - 1; s >= 0; s--)
706     if ((*igroup)[s] != NULL) {
707       startSlot = s+1;
708       break;
709     }
710   
711   // Make sure we pick at most one instruction that would break the group.
712   // Also, if we do pick one, remember which it was.
713   unsigned int indexForBreakingNode = S.nslots;
714   unsigned int indexForDelayedInstr = S.nslots;
715   DelaySlotInfo* delaySlotInfo = NULL;
716
717   getDelaySlotInfo = NULL;
718   
719   // Choose instructions in order of priority.
720   // Add choices to the choice vector in the SchedulingManager class as
721   // we choose them so that subsequent choices will be correctly tested
722   // for feasibility, w.r.t. higher priority choices for the same cycle.
723   // 
724   while (S.getNumChoices() < S.nslots - startSlot) {
725     const SchedGraphNode* nextNode=S.schedPrio.getNextHighest(S,S.getTime());
726     if (nextNode == NULL)
727       break;                    // no more instructions for this cycle
728       
729     if (S.getInstrInfo().getNumDelaySlots(nextNode->getOpcode()) > 0) {
730       delaySlotInfo = S.getDelaySlotInfoForInstr(nextNode);
731       if (delaySlotInfo != NULL) {
732         if (indexForBreakingNode < S.nslots)
733           // cannot issue a delayed instr in the same cycle as one
734           // that breaks the issue group or as another delayed instr
735           nextNode = NULL;
736         else
737           indexForDelayedInstr = S.getNumChoices();
738       }
739     } else if (S.schedInfo.breaksIssueGroup(nextNode->getOpcode())) {
740       if (indexForBreakingNode < S.nslots)
741         // have a breaking instruction already so throw this one away
742         nextNode = NULL;
743       else
744         indexForBreakingNode = S.getNumChoices();
745     }
746       
747     if (nextNode != NULL) {
748       S.addChoice(nextNode);
749       
750       if (S.schedInfo.isSingleIssue(nextNode->getOpcode())) {
751         assert(S.getNumChoices() == 1 &&
752                "Prioritizer returned invalid instr for this cycle!");
753         break;
754       }
755     }
756           
757     if (indexForDelayedInstr < S.nslots)
758       break;                    // leave the rest for delay slots
759   }
760   
761   assert(S.getNumChoices() <= S.nslots);
762   assert(! (indexForDelayedInstr < S.nslots &&
763             indexForBreakingNode < S.nslots) && "Cannot have both in a cycle");
764   
765   // Assign each chosen instruction to all possible slots for that instr.
766   // But if only one instruction was chosen, put it only in the first
767   // feasible slot; no more analysis will be needed.
768   // 
769   if (indexForDelayedInstr >= S.nslots && 
770       indexForBreakingNode >= S.nslots)
771   { // No instructions that break the issue group or that have delay slots.
772     // This is the common case, so handle it separately for efficiency.
773       
774     if (S.getNumChoices() == 1) {
775       MachineOpCode opCode = S.getChoice(0)->getOpcode();
776       unsigned int s;
777       for (s=startSlot; s < S.nslots; s++)
778         if (S.schedInfo.instrCanUseSlot(opCode, s))
779           break;
780       assert(s < S.nslots && "No feasible slot for this opCode?");
781       S.addChoiceToSlot(s, S.getChoice(0));
782     } else {
783       for (unsigned i=0; i < S.getNumChoices(); i++) {
784         MachineOpCode opCode = S.getChoice(i)->getOpcode();
785         for (unsigned int s=startSlot; s < S.nslots; s++)
786           if (S.schedInfo.instrCanUseSlot(opCode, s))
787             S.addChoiceToSlot(s, S.getChoice(i));
788       }
789     }
790   } else if (indexForDelayedInstr < S.nslots) {
791     // There is an instruction that needs delay slots.
792     // Try to assign that instruction to a higher slot than any other
793     // instructions in the group, so that its delay slots can go
794     // right after it.
795     //  
796
797     assert(indexForDelayedInstr == S.getNumChoices() - 1 &&
798            "Instruction with delay slots should be last choice!");
799     assert(delaySlotInfo != NULL && "No delay slot info for instr?");
800       
801     const SchedGraphNode* delayedNode = S.getChoice(indexForDelayedInstr);
802     MachineOpCode delayOpCode = delayedNode->getOpcode();
803     unsigned ndelays= S.getInstrInfo().getNumDelaySlots(delayOpCode);
804       
805     unsigned delayedNodeSlot = S.nslots;
806     int highestSlotUsed;
807       
808     // Find the last possible slot for the delayed instruction that leaves
809     // at least `d' slots vacant after it (d = #delay slots)
810     for (int s = S.nslots-ndelays-1; s >= (int) startSlot; s--)
811       if (S.schedInfo.instrCanUseSlot(delayOpCode, s)) {
812         delayedNodeSlot = s;
813         break;
814       }
815       
816     highestSlotUsed = -1;
817     for (unsigned i=0; i < S.getNumChoices() - 1; i++) {
818       // Try to assign every other instruction to a lower numbered
819       // slot than delayedNodeSlot.
820       MachineOpCode opCode =S.getChoice(i)->getOpcode();
821       bool noSlotFound = true;
822       unsigned int s;
823       for (s=startSlot; s < delayedNodeSlot; s++)
824         if (S.schedInfo.instrCanUseSlot(opCode, s)) {
825           S.addChoiceToSlot(s, S.getChoice(i));
826           noSlotFound = false;
827         }
828           
829       // No slot before `delayedNodeSlot' was found for this opCode
830       // Use a later slot, and allow some delay slots to fall in
831       // the next cycle.
832       if (noSlotFound)
833         for ( ; s < S.nslots; s++)
834           if (S.schedInfo.instrCanUseSlot(opCode, s)) {
835             S.addChoiceToSlot(s, S.getChoice(i));
836             break;
837           }
838           
839       assert(s < S.nslots && "No feasible slot for instruction?");
840           
841       highestSlotUsed = std::max(highestSlotUsed, (int) s);
842     }
843       
844     assert(highestSlotUsed <= (int) S.nslots-1 && "Invalid slot used?");
845       
846     // We will put the delayed node in the first slot after the
847     // highest slot used.  But we just mark that for now, and
848     // schedule it separately because we want to schedule the delay
849     // slots for the node at the same time.
850     cycles_t dcycle = S.getTime();
851     unsigned int dslot = highestSlotUsed + 1;
852     if (dslot == S.nslots) {
853       dslot = 0;
854       ++dcycle;
855     }
856     delaySlotInfo->recordChosenSlot(dcycle, dslot);
857     getDelaySlotInfo = delaySlotInfo;
858   } else {
859     // There is an instruction that breaks the issue group.
860     // For such an instruction, assign to the last possible slot in
861     // the current group, and then don't assign any other instructions
862     // to later slots.
863     assert(indexForBreakingNode < S.nslots);
864     const SchedGraphNode* breakingNode=S.getChoice(indexForBreakingNode);
865     unsigned breakingSlot = INT_MAX;
866     unsigned int nslotsToUse = S.nslots;
867           
868     // Find the last possible slot for this instruction.
869     for (int s = S.nslots-1; s >= (int) startSlot; s--)
870       if (S.schedInfo.instrCanUseSlot(breakingNode->getOpcode(), s)) {
871         breakingSlot = s;
872         break;
873       }
874     assert(breakingSlot < S.nslots &&
875            "No feasible slot for `breakingNode'?");
876       
877     // Higher priority instructions than the one that breaks the group:
878     // These can be assigned to all slots, but will be assigned only
879     // to earlier slots if possible.
880     for (unsigned i=0;
881          i < S.getNumChoices() && i < indexForBreakingNode; i++)
882     {
883       MachineOpCode opCode =S.getChoice(i)->getOpcode();
884           
885       // If a higher priority instruction cannot be assigned to
886       // any earlier slots, don't schedule the breaking instruction.
887       // 
888       bool foundLowerSlot = false;
889       nslotsToUse = S.nslots;       // May be modified in the loop
890       for (unsigned int s=startSlot; s < nslotsToUse; s++)
891         if (S.schedInfo.instrCanUseSlot(opCode, s)) {
892           if (breakingSlot < S.nslots && s < breakingSlot) {
893             foundLowerSlot = true;
894             nslotsToUse = breakingSlot; // RESETS LOOP UPPER BOUND!
895           }
896                     
897           S.addChoiceToSlot(s, S.getChoice(i));
898         }
899               
900       if (!foundLowerSlot)
901         breakingSlot = INT_MAX;         // disable breaking instr
902     }
903       
904     // Assign the breaking instruction (if any) to a single slot
905     // Otherwise, just ignore the instruction.  It will simply be
906     // scheduled in a later cycle.
907     if (breakingSlot < S.nslots) {
908       S.addChoiceToSlot(breakingSlot, breakingNode);
909       nslotsToUse = breakingSlot;
910     } else
911       nslotsToUse = S.nslots;
912           
913     // For lower priority instructions than the one that breaks the
914     // group, only assign them to slots lower than the breaking slot.
915     // Otherwise, just ignore the instruction.
916     for (unsigned i=indexForBreakingNode+1; i < S.getNumChoices(); i++) {
917       MachineOpCode opCode = S.getChoice(i)->getOpcode();
918       for (unsigned int s=startSlot; s < nslotsToUse; s++)
919         if (S.schedInfo.instrCanUseSlot(opCode, s))
920           S.addChoiceToSlot(s, S.getChoice(i));
921     }
922   } // endif (no delay slots and no breaking slots)
923   
924   return S.getNumChoices();
925 }
926
927
928 static unsigned
929 ChooseOneGroup(SchedulingManager& S)
930 {
931   assert(S.schedPrio.getNumReady() > 0
932          && "Don't get here without ready instructions.");
933   
934   cycles_t firstCycle = S.getTime();
935   DelaySlotInfo* getDelaySlotInfo = NULL;
936   
937   // Choose up to `nslots' feasible instructions and their possible slots.
938   unsigned numIssued = FindSlotChoices(S, getDelaySlotInfo);
939   
940   while (numIssued == 0) {
941     S.updateTime(S.getTime()+1);
942     numIssued = FindSlotChoices(S, getDelaySlotInfo);
943   }
944   
945   AssignInstructionsToSlots(S, numIssued);
946   
947   if (getDelaySlotInfo != NULL)
948     numIssued += getDelaySlotInfo->scheduleDelayedNode(S); 
949   
950   // Print trace of scheduled instructions before newly ready ones
951   if (SchedDebugLevel >= Sched_PrintSchedTrace) {
952     for (cycles_t c = firstCycle; c <= S.getTime(); c++) {
953       std::cerr << "    Cycle " << (long)c <<" : Scheduled instructions:\n";
954       const InstrGroup* igroup = S.isched.getIGroup(c);
955       for (unsigned int s=0; s < S.nslots; s++) {
956         std::cerr << "        ";
957         if ((*igroup)[s] != NULL)
958           std::cerr << * ((*igroup)[s])->getMachineInstr() << "\n";
959         else
960           std::cerr << "<none>\n";
961       }
962     }
963   }
964   
965   return numIssued;
966 }
967
968
969 static void
970 ForwardListSchedule(SchedulingManager& S)
971 {
972   unsigned N;
973   const SchedGraphNode* node;
974   
975   S.schedPrio.initialize();
976   
977   while ((N = S.schedPrio.getNumReady()) > 0) {
978     cycles_t nextCycle = S.getTime();
979       
980     // Choose one group of instructions for a cycle, plus any delay slot
981     // instructions (which may overflow into successive cycles).
982     // This will advance S.getTime() to the last cycle in which
983     // instructions are actually issued.
984     // 
985     unsigned numIssued = ChooseOneGroup(S);
986     assert(numIssued > 0 && "Deadlock in list scheduling algorithm?");
987       
988     // Notify the priority manager of scheduled instructions and mark
989     // any successors that may now be ready
990     // 
991     for (cycles_t c = nextCycle; c <= S.getTime(); c++) {
992       const InstrGroup* igroup = S.isched.getIGroup(c);
993       for (unsigned int s=0; s < S.nslots; s++)
994         if ((node = (*igroup)[s]) != NULL) {
995           S.schedPrio.issuedReadyNodeAt(S.getTime(), node);
996           MarkSuccessorsReady(S, node);
997         }
998     }
999       
1000     // Move to the next the next earliest cycle for which
1001     // an instruction can be issued, or the next earliest in which
1002     // one will be ready, or to the next cycle, whichever is latest.
1003     // 
1004     S.updateTime(std::max(S.getTime() + 1,
1005                           std::max(S.getEarliestIssueTime(),
1006                                    S.schedPrio.getEarliestReadyTime())));
1007   }
1008 }
1009
1010
1011 //---------------------------------------------------------------------
1012 // Code for filling delay slots for delayed terminator instructions
1013 // (e.g., BRANCH and RETURN).  Delay slots for non-terminator
1014 // instructions (e.g., CALL) are not handled here because they almost
1015 // always can be filled with instructions from the call sequence code
1016 // before a call.  That's preferable because we incur many tradeoffs here
1017 // when we cannot find single-cycle instructions that can be reordered.
1018 //----------------------------------------------------------------------
1019
1020 static bool
1021 NodeCanFillDelaySlot(const SchedulingManager& S,
1022                      const SchedGraphNode* node,
1023                      const SchedGraphNode* brNode,
1024                      bool nodeIsPredecessor)
1025 {
1026   assert(! node->isDummyNode());
1027   
1028   // don't put a branch in the delay slot of another branch
1029   if (S.getInstrInfo().isBranch(node->getOpcode()))
1030     return false;
1031   
1032   // don't put a single-issue instruction in the delay slot of a branch
1033   if (S.schedInfo.isSingleIssue(node->getOpcode()))
1034     return false;
1035   
1036   // don't put a load-use dependence in the delay slot of a branch
1037   const TargetInstrInfo& mii = S.getInstrInfo();
1038   
1039   for (SchedGraphNode::const_iterator EI = node->beginInEdges();
1040        EI != node->endInEdges(); ++EI)
1041     if (! ((SchedGraphNode*)(*EI)->getSrc())->isDummyNode()
1042         && mii.isLoad(((SchedGraphNode*)(*EI)->getSrc())->getOpcode())
1043         && (*EI)->getDepType() == SchedGraphEdge::CtrlDep)
1044       return false;
1045   
1046   // for now, don't put an instruction that does not have operand
1047   // interlocks in the delay slot of a branch
1048   if (! S.getInstrInfo().hasOperandInterlock(node->getOpcode()))
1049     return false;
1050   
1051   // Finally, if the instruction precedes the branch, we make sure the
1052   // instruction can be reordered relative to the branch.  We simply check
1053   // if the instr. has only 1 outgoing edge, viz., a CD edge to the branch.
1054   // 
1055   if (nodeIsPredecessor) {
1056     bool onlyCDEdgeToBranch = true;
1057     for (SchedGraphNode::const_iterator OEI = node->beginOutEdges();
1058          OEI != node->endOutEdges(); ++OEI)
1059       if (! ((SchedGraphNode*)(*OEI)->getSink())->isDummyNode()
1060           && ((*OEI)->getSink() != brNode
1061               || (*OEI)->getDepType() != SchedGraphEdge::CtrlDep))
1062       {
1063         onlyCDEdgeToBranch = false;
1064         break;
1065       }
1066       
1067     if (!onlyCDEdgeToBranch)
1068       return false;
1069   }
1070   
1071   return true;
1072 }
1073
1074
1075 static void
1076 MarkNodeForDelaySlot(SchedulingManager& S,
1077                      SchedGraph* graph,
1078                      SchedGraphNode* node,
1079                      const SchedGraphNode* brNode,
1080                      bool nodeIsPredecessor)
1081 {
1082   if (nodeIsPredecessor) {
1083     // If node is in the same basic block (i.e., precedes brNode),
1084     // remove it and all its incident edges from the graph.  Make sure we
1085     // add dummy edges for pred/succ nodes that become entry/exit nodes.
1086     graph->eraseIncidentEdges(node, /*addDummyEdges*/ true);
1087   } else { 
1088     // If the node was from a target block, add the node to the graph
1089     // and add a CD edge from brNode to node.
1090     assert(0 && "NOT IMPLEMENTED YET");
1091   }
1092   
1093   DelaySlotInfo* dinfo = S.getDelaySlotInfoForInstr(brNode, /*create*/ true);
1094   dinfo->addDelayNode(node);
1095 }
1096
1097
1098 void
1099 FindUsefulInstructionsForDelaySlots(SchedulingManager& S,
1100                                     SchedGraphNode* brNode,
1101                                     std::vector<SchedGraphNode*>& sdelayNodeVec)
1102 {
1103   const TargetInstrInfo& mii = S.getInstrInfo();
1104   unsigned ndelays =
1105     mii.getNumDelaySlots(brNode->getOpcode());
1106   
1107   if (ndelays == 0)
1108     return;
1109   
1110   sdelayNodeVec.reserve(ndelays);
1111   
1112   // Use a separate vector to hold the feasible multi-cycle nodes.
1113   // These will be used if not enough single-cycle nodes are found.
1114   // 
1115   std::vector<SchedGraphNode*> mdelayNodeVec;
1116   
1117   for (sg_pred_iterator P = pred_begin(brNode);
1118        P != pred_end(brNode) && sdelayNodeVec.size() < ndelays; ++P)
1119     if (! (*P)->isDummyNode() &&
1120         ! mii.isNop((*P)->getOpcode()) &&
1121         NodeCanFillDelaySlot(S, *P, brNode, /*pred*/ true))
1122     {
1123       if (mii.maxLatency((*P)->getOpcode()) > 1)
1124         mdelayNodeVec.push_back(*P);
1125       else
1126         sdelayNodeVec.push_back(*P);
1127     }
1128   
1129   // If not enough single-cycle instructions were found, select the
1130   // lowest-latency multi-cycle instructions and use them.
1131   // Note that this is the most efficient code when only 1 (or even 2)
1132   // values need to be selected.
1133   // 
1134   while (sdelayNodeVec.size() < ndelays && mdelayNodeVec.size() > 0) {
1135     unsigned lmin =
1136       mii.maxLatency(mdelayNodeVec[0]->getOpcode());
1137     unsigned minIndex   = 0;
1138     for (unsigned i=1; i < mdelayNodeVec.size(); i++)
1139     {
1140       unsigned li = 
1141         mii.maxLatency(mdelayNodeVec[i]->getOpcode());
1142       if (lmin >= li)
1143       {
1144         lmin = li;
1145         minIndex = i;
1146       }
1147     }
1148     sdelayNodeVec.push_back(mdelayNodeVec[minIndex]);
1149     if (sdelayNodeVec.size() < ndelays) // avoid the last erase!
1150       mdelayNodeVec.erase(mdelayNodeVec.begin() + minIndex);
1151   }
1152 }
1153
1154
1155 // Remove the NOPs currently in delay slots from the graph.
1156 // Mark instructions specified in sdelayNodeVec to replace them.
1157 // If not enough useful instructions were found, mark the NOPs to be used
1158 // for filling delay slots, otherwise, otherwise just discard them.
1159 // 
1160 static void ReplaceNopsWithUsefulInstr(SchedulingManager& S,
1161                                        SchedGraphNode* node,
1162                                        // FIXME: passing vector BY VALUE!!!
1163                                      std::vector<SchedGraphNode*> sdelayNodeVec,
1164                                        SchedGraph* graph)
1165 {
1166   std::vector<SchedGraphNode*> nopNodeVec;   // this will hold unused NOPs
1167   const TargetInstrInfo& mii = S.getInstrInfo();
1168   const MachineInstr* brInstr = node->getMachineInstr();
1169   unsigned ndelays= mii.getNumDelaySlots(brInstr->getOpcode());
1170   assert(ndelays > 0 && "Unnecessary call to replace NOPs");
1171   
1172   // Remove the NOPs currently in delay slots from the graph.
1173   // If not enough useful instructions were found, use the NOPs to
1174   // fill delay slots, otherwise, just discard them.
1175   //  
1176   unsigned int firstDelaySlotIdx = node->getOrigIndexInBB() + 1;
1177   MachineBasicBlock& MBB = node->getMachineBasicBlock();
1178   assert(&MBB[firstDelaySlotIdx - 1] == brInstr &&
1179          "Incorrect instr. index in basic block for brInstr");
1180   
1181   // First find all useful instructions already in the delay slots
1182   // and USE THEM.  We'll throw away the unused alternatives below
1183   // 
1184   for (unsigned i=firstDelaySlotIdx; i < firstDelaySlotIdx + ndelays; ++i)
1185     if (! mii.isNop(MBB[i].getOpcode()))
1186       sdelayNodeVec.insert(sdelayNodeVec.begin(),
1187                            graph->getGraphNodeForInstr(&MBB[i]));
1188   
1189   // Then find the NOPs and keep only as many as are needed.
1190   // Put the rest in nopNodeVec to be deleted.
1191   for (unsigned i=firstDelaySlotIdx; i < firstDelaySlotIdx + ndelays; ++i)
1192     if (mii.isNop(MBB[i].getOpcode()))
1193       if (sdelayNodeVec.size() < ndelays)
1194         sdelayNodeVec.push_back(graph->getGraphNodeForInstr(&MBB[i]));
1195       else {
1196         nopNodeVec.push_back(graph->getGraphNodeForInstr(&MBB[i]));
1197           
1198         //remove the MI from the Machine Code For Instruction
1199         const TerminatorInst *TI = MBB.getBasicBlock()->getTerminator();
1200         MachineCodeForInstruction& llvmMvec = 
1201           MachineCodeForInstruction::get((const Instruction *)TI);
1202           
1203         for(MachineCodeForInstruction::iterator mciI=llvmMvec.begin(), 
1204               mciE=llvmMvec.end(); mciI!=mciE; ++mciI){
1205           if (*mciI == &MBB[i])
1206             llvmMvec.erase(mciI);
1207         }
1208       }
1209
1210   assert(sdelayNodeVec.size() >= ndelays);
1211   
1212   // If some delay slots were already filled, throw away that many new choices
1213   if (sdelayNodeVec.size() > ndelays)
1214     sdelayNodeVec.resize(ndelays);
1215   
1216   // Mark the nodes chosen for delay slots.  This removes them from the graph.
1217   for (unsigned i=0; i < sdelayNodeVec.size(); i++)
1218     MarkNodeForDelaySlot(S, graph, sdelayNodeVec[i], node, true);
1219   
1220   // And remove the unused NOPs from the graph.
1221   for (unsigned i=0; i < nopNodeVec.size(); i++)
1222     graph->eraseIncidentEdges(nopNodeVec[i], /*addDummyEdges*/ true);
1223 }
1224
1225
1226 // For all delayed instructions, choose instructions to put in the delay
1227 // slots and pull those out of the graph.  Mark them for the delay slots
1228 // in the DelaySlotInfo object for that graph node.  If no useful work
1229 // is found for a delay slot, use the NOP that is currently in that slot.
1230 // 
1231 // We try to fill the delay slots with useful work for all instructions
1232 // EXCEPT CALLS AND RETURNS.
1233 // For CALLs and RETURNs, it is nearly always possible to use one of the
1234 // call sequence instrs and putting anything else in the delay slot could be
1235 // suboptimal.  Also, it complicates generating the calling sequence code in
1236 // regalloc.
1237 // 
1238 static void
1239 ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB,
1240                                 SchedGraph *graph)
1241 {
1242   const TargetInstrInfo& mii = S.getInstrInfo();
1243
1244   Instruction *termInstr = (Instruction*)MBB.getBasicBlock()->getTerminator();
1245   MachineCodeForInstruction &termMvec=MachineCodeForInstruction::get(termInstr);
1246   std::vector<SchedGraphNode*> delayNodeVec;
1247   const MachineInstr* brInstr = NULL;
1248   
1249   if (EnableFillingDelaySlots &&
1250       termInstr->getOpcode() != Instruction::Ret)
1251   {
1252     // To find instructions that need delay slots without searching the full
1253     // machine code, we assume that the only delayed instructions are CALLs
1254     // or instructions generated for the terminator inst.
1255     // Find the first branch instr in the sequence of machine instrs for term
1256     // 
1257     unsigned first = 0;
1258     while (first < termMvec.size() &&
1259            ! mii.isBranch(termMvec[first]->getOpcode()))
1260     {
1261       ++first;
1262     }
1263     assert(first < termMvec.size() &&
1264            "No branch instructions for BR?  Ok, but weird!  Delete assertion.");
1265       
1266     brInstr = (first < termMvec.size())? termMvec[first] : NULL;
1267       
1268     // Compute a vector of the nodes chosen for delay slots and then
1269     // mark delay slots to replace NOPs with these useful instructions.
1270     // 
1271     if (brInstr != NULL) {
1272       SchedGraphNode* brNode = graph->getGraphNodeForInstr(brInstr);
1273       FindUsefulInstructionsForDelaySlots(S, brNode, delayNodeVec);
1274       ReplaceNopsWithUsefulInstr(S, brNode, delayNodeVec, graph);
1275     }
1276   }
1277   
1278   // Also mark delay slots for other delayed instructions to hold NOPs. 
1279   // Simply passing in an empty delayNodeVec will have this effect.
1280   // If brInstr is not handled above (EnableFillingDelaySlots == false),
1281   // brInstr will be NULL so this will handle the branch instrs. as well.
1282   // 
1283   delayNodeVec.clear();
1284   for (unsigned i=0; i < MBB.size(); ++i)
1285     if (&MBB[i] != brInstr &&
1286         mii.getNumDelaySlots(MBB[i].getOpcode()) > 0)
1287     {
1288       SchedGraphNode* node = graph->getGraphNodeForInstr(&MBB[i]);
1289       ReplaceNopsWithUsefulInstr(S, node, delayNodeVec, graph);
1290     }
1291 }
1292
1293
1294 // 
1295 // Schedule the delayed branch and its delay slots
1296 // 
1297 unsigned
1298 DelaySlotInfo::scheduleDelayedNode(SchedulingManager& S)
1299 {
1300   assert(delayedNodeSlotNum < S.nslots && "Illegal slot for branch");
1301   assert(S.isched.getInstr(delayedNodeSlotNum, delayedNodeCycle) == NULL
1302          && "Slot for branch should be empty");
1303   
1304   unsigned int nextSlot = delayedNodeSlotNum;
1305   cycles_t nextTime = delayedNodeCycle;
1306   
1307   S.scheduleInstr(brNode, nextSlot, nextTime);
1308   
1309   for (unsigned d=0; d < ndelays; d++) {
1310     ++nextSlot;
1311     if (nextSlot == S.nslots) {
1312       nextSlot = 0;
1313       nextTime++;
1314     }
1315       
1316     // Find the first feasible instruction for this delay slot
1317     // Note that we only check for issue restrictions here.
1318     // We do *not* check for flow dependences but rely on pipeline
1319     // interlocks to resolve them.  Machines without interlocks
1320     // will require this code to be modified.
1321     for (unsigned i=0; i < delayNodeVec.size(); i++) {
1322       const SchedGraphNode* dnode = delayNodeVec[i];
1323       if ( ! S.isScheduled(dnode)
1324            && S.schedInfo.instrCanUseSlot(dnode->getOpcode(), nextSlot)
1325            && instrIsFeasible(S, dnode->getOpcode()))
1326       {
1327         assert(S.getInstrInfo().hasOperandInterlock(dnode->getOpcode())
1328                && "Instructions without interlocks not yet supported "
1329                "when filling branch delay slots");
1330         S.scheduleInstr(dnode, nextSlot, nextTime);
1331         break;
1332       }
1333     }
1334   }
1335   
1336   // Update current time if delay slots overflowed into later cycles.
1337   // Do this here because we know exactly which cycle is the last cycle
1338   // that contains delay slots.  The next loop doesn't compute that.
1339   if (nextTime > S.getTime())
1340     S.updateTime(nextTime);
1341   
1342   // Now put any remaining instructions in the unfilled delay slots.
1343   // This could lead to suboptimal performance but needed for correctness.
1344   nextSlot = delayedNodeSlotNum;
1345   nextTime = delayedNodeCycle;
1346   for (unsigned i=0; i < delayNodeVec.size(); i++)
1347     if (! S.isScheduled(delayNodeVec[i])) {
1348       do { // find the next empty slot
1349         ++nextSlot;
1350         if (nextSlot == S.nslots) {
1351           nextSlot = 0;
1352           nextTime++;
1353         }
1354       } while (S.isched.getInstr(nextSlot, nextTime) != NULL);
1355         
1356       S.scheduleInstr(delayNodeVec[i], nextSlot, nextTime);
1357       break;
1358     }
1359
1360   return 1 + ndelays;
1361 }
1362
1363
1364 // Check if the instruction would conflict with instructions already
1365 // chosen for the current cycle
1366 // 
1367 static inline bool
1368 ConflictsWithChoices(const SchedulingManager& S,
1369                      MachineOpCode opCode)
1370 {
1371   // Check if the instruction must issue by itself, and some feasible
1372   // choices have already been made for this cycle
1373   if (S.getNumChoices() > 0 && S.schedInfo.isSingleIssue(opCode))
1374     return true;
1375   
1376   // For each class that opCode belongs to, check if there are too many
1377   // instructions of that class.
1378   // 
1379   const InstrSchedClass sc = S.schedInfo.getSchedClass(opCode);
1380   return (S.getNumChoicesInClass(sc) == S.schedInfo.getMaxIssueForClass(sc));
1381 }
1382
1383
1384 //************************* External Functions *****************************/
1385
1386
1387 //---------------------------------------------------------------------------
1388 // Function: ViolatesMinimumGap
1389 // 
1390 // Purpose:
1391 //   Check minimum gap requirements relative to instructions scheduled in
1392 //   previous cycles.
1393 //   Note that we do not need to consider `nextEarliestIssueTime' here because
1394 //   that is also captured in the earliest start times for each opcode.
1395 //---------------------------------------------------------------------------
1396
1397 static inline bool
1398 ViolatesMinimumGap(const SchedulingManager& S,
1399                    MachineOpCode opCode,
1400                    const cycles_t inCycle)
1401 {
1402   return (inCycle < S.getEarliestStartTimeForOp(opCode));
1403 }
1404
1405
1406 //---------------------------------------------------------------------------
1407 // Function: instrIsFeasible
1408 // 
1409 // Purpose:
1410 //   Check if any issue restrictions would prevent the instruction from
1411 //   being issued in the current cycle
1412 //---------------------------------------------------------------------------
1413
1414 bool
1415 instrIsFeasible(const SchedulingManager& S,
1416                 MachineOpCode opCode)
1417 {
1418   // skip the instruction if it cannot be issued due to issue restrictions
1419   // caused by previously issued instructions
1420   if (ViolatesMinimumGap(S, opCode, S.getTime()))
1421     return false;
1422   
1423   // skip the instruction if it cannot be issued due to issue restrictions
1424   // caused by previously chosen instructions for the current cycle
1425   if (ConflictsWithChoices(S, opCode))
1426     return false;
1427   
1428   return true;
1429 }
1430
1431 //---------------------------------------------------------------------------
1432 // Function: ScheduleInstructionsWithSSA
1433 // 
1434 // Purpose:
1435 //   Entry point for instruction scheduling on SSA form.
1436 //   Schedules the machine instructions generated by instruction selection.
1437 //   Assumes that register allocation has not been done, i.e., operands
1438 //   are still in SSA form.
1439 //---------------------------------------------------------------------------
1440
1441 namespace {
1442   class InstructionSchedulingWithSSA : public FunctionPass {
1443     const TargetMachine &target;
1444   public:
1445     inline InstructionSchedulingWithSSA(const TargetMachine &T) : target(T) {}
1446
1447     const char *getPassName() const { return "Instruction Scheduling"; }
1448   
1449     // getAnalysisUsage - We use LiveVarInfo...
1450     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
1451       AU.addRequired<FunctionLiveVarInfo>();
1452       AU.setPreservesCFG();
1453     }
1454     
1455     bool runOnFunction(Function &F);
1456   };
1457 } // end anonymous namespace
1458
1459
1460 bool InstructionSchedulingWithSSA::runOnFunction(Function &F)
1461 {
1462   SchedGraphSet graphSet(&F, target);   
1463   
1464   if (SchedDebugLevel >= Sched_PrintSchedGraphs) {
1465       std::cerr << "\n*** SCHEDULING GRAPHS FOR INSTRUCTION SCHEDULING\n";
1466       graphSet.dump();
1467     }
1468   
1469   for (SchedGraphSet::const_iterator GI=graphSet.begin(), GE=graphSet.end();
1470        GI != GE; ++GI)
1471   {
1472     SchedGraph* graph = (*GI);
1473     MachineBasicBlock &MBB = graph->getBasicBlock();
1474       
1475     if (SchedDebugLevel >= Sched_PrintSchedTrace)
1476       std::cerr << "\n*** TRACE OF INSTRUCTION SCHEDULING OPERATIONS\n\n";
1477       
1478     // expensive!
1479     SchedPriorities schedPrio(&F, graph, getAnalysis<FunctionLiveVarInfo>());
1480     SchedulingManager S(target, graph, schedPrio);
1481           
1482     ChooseInstructionsForDelaySlots(S, MBB, graph); // modifies graph
1483     ForwardListSchedule(S);               // computes schedule in S
1484     RecordSchedule(MBB, S);                // records schedule in BB
1485   }
1486   
1487   if (SchedDebugLevel >= Sched_PrintMachineCode) {
1488     std::cerr << "\n*** Machine instructions after INSTRUCTION SCHEDULING\n";
1489     MachineFunction::get(&F).dump();
1490   }
1491   
1492   return false;
1493 }
1494
1495
1496 FunctionPass *createInstructionSchedulingWithSSAPass(const TargetMachine &tgt) {
1497   return new InstructionSchedulingWithSSA(tgt);
1498 }
1499
1500 } // End llvm namespace
1501