Change MachineBasicBlock's vector of MachineInstr pointers into an
[oota-llvm.git] / lib / Target / SparcV9 / InstrSched / InstrScheduling.cpp
index cf4f294155712ad59cb06577ffdf60457ade907f..f01196aefaae55467895be0f2439c1300c7034fe 100644 (file)
@@ -1,4 +1,11 @@
 //===- InstrScheduling.cpp - Generic Instruction Scheduling support -------===//
+// 
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// 
+//===----------------------------------------------------------------------===//
 //
 // This file implements the llvm/CodeGen/InstrScheduling.h interface, along with
 // generic support routines for instruction scheduling.
@@ -15,6 +22,8 @@
 #include "Support/CommandLine.h"
 #include <algorithm>
 
+namespace llvm {
+
 SchedDebugLevel_t SchedDebugLevel;
 
 static cl::opt<bool> EnableFillingDelaySlots("sched-fill-delay-slots",
@@ -104,10 +113,7 @@ public:
   
   inline bool operator!=(const _Self& x) const { return !operator==(x); }
   
-  inline _NodeType* operator*() const {
-    assert(cycleNum < S.groups.size());
-    return (*S.groups[cycleNum])[slotNum];
-  }
+  inline _NodeType* operator*() const;
   inline _NodeType* operator->() const { return operator*(); }
   
          _Self& operator++();                          // Preincrement
@@ -143,10 +149,10 @@ public: // iterators
   typedef ScheduleIterator<SchedGraphNode> iterator;
   typedef ScheduleIterator<const SchedGraphNode> const_iterator;
   
-        iterator begin();
-  const_iterator begin() const;
-        iterator end();
-  const_iterator end()   const;
+        iterator begin()       { return iterator::begin(*this); }
+  const_iterator begin() const { return const_iterator::begin(*this); }
+        iterator end()         { return iterator::end(*this); }
+  const_iterator end() const   { return const_iterator::end(*this); }
   
 public: // constructors and destructor
   /*ctor*/             InstrSchedule   (unsigned int _nslots,
@@ -194,11 +200,17 @@ public: // accessor functions to query chosen schedule
   }
   
 private:
-  friend class iterator;
-  friend class const_iterator;
+  friend class ScheduleIterator<SchedGraphNode>;
+  friend class ScheduleIterator<const SchedGraphNode>;
   /*ctor*/     InstrSchedule   ();     // Disable: DO NOT IMPLEMENT.
 };
 
+template<class NodeType>
+inline NodeType *ScheduleIterator<NodeType>::operator*() const {
+  assert(cycleNum < S.groups.size());
+  return (*S.groups[cycleNum])[slotNum];
+}
+
 
 /*ctor*/
 InstrSchedule::InstrSchedule(unsigned int _nslots, unsigned int _numNodes)
@@ -268,30 +280,6 @@ ScheduleIterator<_NodeType>::end(const InstrSchedule& _schedule)
   return _Self(_schedule, _schedule.groups.size(), 0);
 }
 
-InstrSchedule::iterator
-InstrSchedule::begin()
-{
-  return iterator::begin(*this);
-}
-
-InstrSchedule::const_iterator
-InstrSchedule::begin() const
-{
-  return const_iterator::begin(*this);
-}
-
-InstrSchedule::iterator
-InstrSchedule::end()
-{
-  return iterator::end(*this);
-}
-
-InstrSchedule::const_iterator
-InstrSchedule::end() const
-{
-  return const_iterator::end(  *this);
-}
-
 
 //----------------------------------------------------------------------
 // class DelaySlotInfo:
@@ -436,7 +424,7 @@ public:
     // Append the instruction to the vector of choices for current cycle.
     // Increment numInClass[c] for the sched class to which the instr belongs.
     choiceVec.push_back(node);
-    const InstrSchedClass& sc = schedInfo.getSchedClass(node->getOpCode());
+    const InstrSchedClass& sc = schedInfo.getSchedClass(node->getOpcode());
     assert(sc < numInClass.size());
     numInClass[sc]++;
   }
@@ -490,7 +478,7 @@ public:
       choicesForSlot[s].erase(node);
     
     // and decrement the instr count for the sched class to which it belongs
-    const InstrSchedClass& sc = schedInfo.getSchedClass(node->getOpCode());
+    const InstrSchedClass& sc = schedInfo.getSchedClass(node->getOpcode());
     assert(sc < numInClass.size());
     numInClass[sc]--;
   }
@@ -510,7 +498,7 @@ public:
     if (!createIfMissing) return 0;
 
     DelaySlotInfo *dinfo =
-      new DelaySlotInfo(bn, getInstrInfo().getNumDelaySlots(bn->getOpCode()));
+      new DelaySlotInfo(bn, getInstrInfo().getNumDelaySlots(bn->getOpcode()));
     return delaySlotInfoForBranches[bn] = dinfo;
   }
   
@@ -549,19 +537,19 @@ void
 SchedulingManager::updateEarliestStartTimes(const SchedGraphNode* node,
                                            cycles_t schedTime)
 {
-  if (schedInfo.numBubblesAfter(node->getOpCode()) > 0)
+  if (schedInfo.numBubblesAfter(node->getOpcode()) > 0)
     { // Update next earliest time before which *nothing* can issue.
       nextEarliestIssueTime = std::max(nextEarliestIssueTime,
-                 curTime + 1 + schedInfo.numBubblesAfter(node->getOpCode()));
+                 curTime + 1 + schedInfo.numBubblesAfter(node->getOpcode()));
     }
   
   const std::vector<MachineOpCode>&
-    conflictVec = schedInfo.getConflictList(node->getOpCode());
+    conflictVec = schedInfo.getConflictList(node->getOpcode());
   
   for (unsigned i=0; i < conflictVec.size(); i++)
     {
       MachineOpCode toOp = conflictVec[i];
-      cycles_t est=schedTime + schedInfo.getMinIssueGap(node->getOpCode(),toOp);
+      cycles_t est=schedTime + schedInfo.getMinIssueGap(node->getOpcode(),toOp);
       assert(toOp < (int) nextEarliestStartTime.size());
       if (nextEarliestStartTime[toOp] < est)
         nextEarliestStartTime[toOp] = est;
@@ -642,8 +630,8 @@ RecordSchedule(MachineBasicBlock &MBB, const SchedulingManager& S)
   // some NOPs from delay slots.  Also, PHIs are not included in the schedule.
   unsigned numInstr = 0;
   for (MachineBasicBlock::iterator I=MBB.begin(); I != MBB.end(); ++I)
-    if (! mii.isNop((*I)->getOpCode()) &&
-       ! mii.isDummyPhiInstr((*I)->getOpCode()))
+    if (! mii.isNop(I->getOpcode()) &&
+       ! mii.isDummyPhiInstr(I->getOpcode()))
       ++numInstr;
   assert(S.isched.getNumInstructions() >= numInstr &&
         "Lost some non-NOP instructions during scheduling!");
@@ -655,12 +643,12 @@ RecordSchedule(MachineBasicBlock &MBB, const SchedulingManager& S)
   // First find the dummy instructions at the start of the basic block
   MachineBasicBlock::iterator I = MBB.begin();
   for ( ; I != MBB.end(); ++I)
-    if (! mii.isDummyPhiInstr((*I)->getOpCode()))
+    if (! mii.isDummyPhiInstr(I->getOpcode()))
       break;
   
-  // Erase all except the dummy PHI instructions from MBB, and
+  // Remove all except the dummy PHI instructions from MBB, and
   // pre-allocate create space for the ones we will put back in.
-  MBB.erase(I, MBB.end());
+  while (I != MBB.end()) MBB.remove(I);
   
   InstrSchedule::const_iterator NIend = S.isched.end();
   for (InstrSchedule::const_iterator NI = S.isched.begin(); NI != NIend; ++NI)
@@ -738,7 +726,7 @@ FindSlotChoices(SchedulingManager& S,
     if (nextNode == NULL)
       break;                   // no more instructions for this cycle
       
-    if (S.getInstrInfo().getNumDelaySlots(nextNode->getOpCode()) > 0) {
+    if (S.getInstrInfo().getNumDelaySlots(nextNode->getOpcode()) > 0) {
       delaySlotInfo = S.getDelaySlotInfoForInstr(nextNode);
       if (delaySlotInfo != NULL) {
         if (indexForBreakingNode < S.nslots)
@@ -748,7 +736,7 @@ FindSlotChoices(SchedulingManager& S,
         else
           indexForDelayedInstr = S.getNumChoices();
       }
-    } else if (S.schedInfo.breaksIssueGroup(nextNode->getOpCode())) {
+    } else if (S.schedInfo.breaksIssueGroup(nextNode->getOpcode())) {
       if (indexForBreakingNode < S.nslots)
         // have a breaking instruction already so throw this one away
         nextNode = NULL;
@@ -759,7 +747,7 @@ FindSlotChoices(SchedulingManager& S,
     if (nextNode != NULL) {
       S.addChoice(nextNode);
       
-      if (S.schedInfo.isSingleIssue(nextNode->getOpCode())) {
+      if (S.schedInfo.isSingleIssue(nextNode->getOpcode())) {
         assert(S.getNumChoices() == 1 &&
                "Prioritizer returned invalid instr for this cycle!");
         break;
@@ -784,7 +772,7 @@ FindSlotChoices(SchedulingManager& S,
     // This is the common case, so handle it separately for efficiency.
       
     if (S.getNumChoices() == 1) {
-      MachineOpCode opCode = S.getChoice(0)->getOpCode();
+      MachineOpCode opCode = S.getChoice(0)->getOpcode();
       unsigned int s;
       for (s=startSlot; s < S.nslots; s++)
         if (S.schedInfo.instrCanUseSlot(opCode, s))
@@ -793,7 +781,7 @@ FindSlotChoices(SchedulingManager& S,
       S.addChoiceToSlot(s, S.getChoice(0));
     } else {
       for (unsigned i=0; i < S.getNumChoices(); i++) {
-        MachineOpCode opCode = S.getChoice(i)->getOpCode();
+        MachineOpCode opCode = S.getChoice(i)->getOpcode();
         for (unsigned int s=startSlot; s < S.nslots; s++)
           if (S.schedInfo.instrCanUseSlot(opCode, s))
             S.addChoiceToSlot(s, S.getChoice(i));
@@ -811,7 +799,7 @@ FindSlotChoices(SchedulingManager& S,
     assert(delaySlotInfo != NULL && "No delay slot info for instr?");
       
     const SchedGraphNode* delayedNode = S.getChoice(indexForDelayedInstr);
-    MachineOpCode delayOpCode = delayedNode->getOpCode();
+    MachineOpCode delayOpCode = delayedNode->getOpcode();
     unsigned ndelays= S.getInstrInfo().getNumDelaySlots(delayOpCode);
       
     unsigned delayedNodeSlot = S.nslots;
@@ -829,7 +817,7 @@ FindSlotChoices(SchedulingManager& S,
     for (unsigned i=0; i < S.getNumChoices() - 1; i++) {
       // Try to assign every other instruction to a lower numbered
       // slot than delayedNodeSlot.
-      MachineOpCode opCode =S.getChoice(i)->getOpCode();
+      MachineOpCode opCode =S.getChoice(i)->getOpcode();
       bool noSlotFound = true;
       unsigned int s;
       for (s=startSlot; s < delayedNodeSlot; s++)
@@ -879,7 +867,7 @@ FindSlotChoices(SchedulingManager& S,
          
     // Find the last possible slot for this instruction.
     for (int s = S.nslots-1; s >= (int) startSlot; s--)
-      if (S.schedInfo.instrCanUseSlot(breakingNode->getOpCode(), s)) {
+      if (S.schedInfo.instrCanUseSlot(breakingNode->getOpcode(), s)) {
         breakingSlot = s;
         break;
       }
@@ -892,7 +880,7 @@ FindSlotChoices(SchedulingManager& S,
     for (unsigned i=0;
          i < S.getNumChoices() && i < indexForBreakingNode; i++)
     {
-      MachineOpCode opCode =S.getChoice(i)->getOpCode();
+      MachineOpCode opCode =S.getChoice(i)->getOpcode();
          
       // If a higher priority instruction cannot be assigned to
       // any earlier slots, don't schedule the breaking instruction.
@@ -926,7 +914,7 @@ FindSlotChoices(SchedulingManager& S,
     // group, only assign them to slots lower than the breaking slot.
     // Otherwise, just ignore the instruction.
     for (unsigned i=indexForBreakingNode+1; i < S.getNumChoices(); i++) {
-      MachineOpCode opCode = S.getChoice(i)->getOpCode();
+      MachineOpCode opCode = S.getChoice(i)->getOpcode();
       for (unsigned int s=startSlot; s < nslotsToUse; s++)
         if (S.schedInfo.instrCanUseSlot(opCode, s))
           S.addChoiceToSlot(s, S.getChoice(i));
@@ -1038,11 +1026,11 @@ NodeCanFillDelaySlot(const SchedulingManager& S,
   assert(! node->isDummyNode());
   
   // don't put a branch in the delay slot of another branch
-  if (S.getInstrInfo().isBranch(node->getOpCode()))
+  if (S.getInstrInfo().isBranch(node->getOpcode()))
     return false;
   
   // don't put a single-issue instruction in the delay slot of a branch
-  if (S.schedInfo.isSingleIssue(node->getOpCode()))
+  if (S.schedInfo.isSingleIssue(node->getOpcode()))
     return false;
   
   // don't put a load-use dependence in the delay slot of a branch
@@ -1051,13 +1039,13 @@ NodeCanFillDelaySlot(const SchedulingManager& S,
   for (SchedGraphNode::const_iterator EI = node->beginInEdges();
        EI != node->endInEdges(); ++EI)
     if (! ((SchedGraphNode*)(*EI)->getSrc())->isDummyNode()
-       && mii.isLoad(((SchedGraphNode*)(*EI)->getSrc())->getOpCode())
+       && mii.isLoad(((SchedGraphNode*)(*EI)->getSrc())->getOpcode())
        && (*EI)->getDepType() == SchedGraphEdge::CtrlDep)
       return false;
   
   // for now, don't put an instruction that does not have operand
   // interlocks in the delay slot of a branch
-  if (! S.getInstrInfo().hasOperandInterlock(node->getOpCode()))
+  if (! S.getInstrInfo().hasOperandInterlock(node->getOpcode()))
     return false;
   
   // Finally, if the instruction precedes the branch, we make sure the
@@ -1114,7 +1102,7 @@ FindUsefulInstructionsForDelaySlots(SchedulingManager& S,
 {
   const TargetInstrInfo& mii = S.getInstrInfo();
   unsigned ndelays =
-    mii.getNumDelaySlots(brNode->getOpCode());
+    mii.getNumDelaySlots(brNode->getOpcode());
   
   if (ndelays == 0)
     return;
@@ -1129,10 +1117,10 @@ FindUsefulInstructionsForDelaySlots(SchedulingManager& S,
   for (sg_pred_iterator P = pred_begin(brNode);
        P != pred_end(brNode) && sdelayNodeVec.size() < ndelays; ++P)
     if (! (*P)->isDummyNode() &&
-       ! mii.isNop((*P)->getOpCode()) &&
+       ! mii.isNop((*P)->getOpcode()) &&
        NodeCanFillDelaySlot(S, *P, brNode, /*pred*/ true))
     {
-      if (mii.maxLatency((*P)->getOpCode()) > 1)
+      if (mii.maxLatency((*P)->getOpcode()) > 1)
         mdelayNodeVec.push_back(*P);
       else
         sdelayNodeVec.push_back(*P);
@@ -1145,12 +1133,12 @@ FindUsefulInstructionsForDelaySlots(SchedulingManager& S,
   // 
   while (sdelayNodeVec.size() < ndelays && mdelayNodeVec.size() > 0) {
     unsigned lmin =
-      mii.maxLatency(mdelayNodeVec[0]->getOpCode());
+      mii.maxLatency(mdelayNodeVec[0]->getOpcode());
     unsigned minIndex   = 0;
     for (unsigned i=1; i < mdelayNodeVec.size(); i++)
     {
       unsigned li = 
-        mii.maxLatency(mdelayNodeVec[i]->getOpCode());
+        mii.maxLatency(mdelayNodeVec[i]->getOpcode());
       if (lmin >= li)
       {
         lmin = li;
@@ -1178,7 +1166,7 @@ static void ReplaceNopsWithUsefulInstr(SchedulingManager& S,
   std::vector<SchedGraphNode*> nopNodeVec;   // this will hold unused NOPs
   const TargetInstrInfo& mii = S.getInstrInfo();
   const MachineInstr* brInstr = node->getMachineInstr();
-  unsigned ndelays= mii.getNumDelaySlots(brInstr->getOpCode());
+  unsigned ndelays= mii.getNumDelaySlots(brInstr->getOpcode());
   assert(ndelays > 0 && "Unnecessary call to replace NOPs");
   
   // Remove the NOPs currently in delay slots from the graph.
@@ -1187,25 +1175,25 @@ static void ReplaceNopsWithUsefulInstr(SchedulingManager& S,
   //  
   unsigned int firstDelaySlotIdx = node->getOrigIndexInBB() + 1;
   MachineBasicBlock& MBB = node->getMachineBasicBlock();
-  assert(MBB[firstDelaySlotIdx - 1] == brInstr &&
+  assert(&MBB[firstDelaySlotIdx - 1] == brInstr &&
          "Incorrect instr. index in basic block for brInstr");
   
   // First find all useful instructions already in the delay slots
   // and USE THEM.  We'll throw away the unused alternatives below
   // 
   for (unsigned i=firstDelaySlotIdx; i < firstDelaySlotIdx + ndelays; ++i)
-    if (! mii.isNop(MBB[i]->getOpCode()))
+    if (! mii.isNop(MBB[i].getOpcode()))
       sdelayNodeVec.insert(sdelayNodeVec.begin(),
-                           graph->getGraphNodeForInstr(MBB[i]));
+                           graph->getGraphNodeForInstr(&MBB[i]));
   
   // Then find the NOPs and keep only as many as are needed.
   // Put the rest in nopNodeVec to be deleted.
   for (unsigned i=firstDelaySlotIdx; i < firstDelaySlotIdx + ndelays; ++i)
-    if (mii.isNop(MBB[i]->getOpCode()))
+    if (mii.isNop(MBB[i].getOpcode()))
       if (sdelayNodeVec.size() < ndelays)
-        sdelayNodeVec.push_back(graph->getGraphNodeForInstr(MBB[i]));
+        sdelayNodeVec.push_back(graph->getGraphNodeForInstr(&MBB[i]));
       else {
-        nopNodeVec.push_back(graph->getGraphNodeForInstr(MBB[i]));
+        nopNodeVec.push_back(graph->getGraphNodeForInstr(&MBB[i]));
          
         //remove the MI from the Machine Code For Instruction
         const TerminatorInst *TI = MBB.getBasicBlock()->getTerminator();
@@ -1214,7 +1202,7 @@ static void ReplaceNopsWithUsefulInstr(SchedulingManager& S,
           
         for(MachineCodeForInstruction::iterator mciI=llvmMvec.begin(), 
               mciE=llvmMvec.end(); mciI!=mciE; ++mciI){
-          if (*mciI==MBB[i])
+          if (*mciI == &MBB[i])
             llvmMvec.erase(mciI);
         }
       }
@@ -1268,7 +1256,7 @@ ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB,
     // 
     unsigned first = 0;
     while (first < termMvec.size() &&
-           ! mii.isBranch(termMvec[first]->getOpCode()))
+           ! mii.isBranch(termMvec[first]->getOpcode()))
     {
       ++first;
     }
@@ -1294,10 +1282,10 @@ ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB,
   // 
   delayNodeVec.clear();
   for (unsigned i=0; i < MBB.size(); ++i)
-    if (MBB[i] != brInstr &&
-        mii.getNumDelaySlots(MBB[i]->getOpCode()) > 0)
+    if (&MBB[i] != brInstr &&
+        mii.getNumDelaySlots(MBB[i].getOpcode()) > 0)
     {
-      SchedGraphNode* node = graph->getGraphNodeForInstr(MBB[i]);
+      SchedGraphNode* node = graph->getGraphNodeForInstr(&MBB[i]);
       ReplaceNopsWithUsefulInstr(S, node, delayNodeVec, graph);
     }
 }
@@ -1333,10 +1321,10 @@ DelaySlotInfo::scheduleDelayedNode(SchedulingManager& S)
     for (unsigned i=0; i < delayNodeVec.size(); i++) {
       const SchedGraphNode* dnode = delayNodeVec[i];
       if ( ! S.isScheduled(dnode)
-           && S.schedInfo.instrCanUseSlot(dnode->getOpCode(), nextSlot)
-           && instrIsFeasible(S, dnode->getOpCode()))
+           && S.schedInfo.instrCanUseSlot(dnode->getOpcode(), nextSlot)
+           && instrIsFeasible(S, dnode->getOpcode()))
       {
-        assert(S.getInstrInfo().hasOperandInterlock(dnode->getOpCode())
+        assert(S.getInstrInfo().hasOperandInterlock(dnode->getOpcode())
                && "Instructions without interlocks not yet supported "
                "when filling branch delay slots");
         S.scheduleInstr(dnode, nextSlot, nextTime);
@@ -1508,3 +1496,6 @@ bool InstructionSchedulingWithSSA::runOnFunction(Function &F)
 FunctionPass *createInstructionSchedulingWithSSAPass(const TargetMachine &tgt) {
   return new InstructionSchedulingWithSSA(tgt);
 }
+
+} // End llvm namespace
+