Mark all calls as "could throw", when exceptions are enabled. Emit necessary LP info...
[oota-llvm.git] / lib / CodeGen / SelectionDAG / ScheduleDAGSimple.cpp
index 2b8a754a061cf56023eac239acf4dcd0c4fde7c6..c6187f1109f9c950dc3610c721e6d06e87190709 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "sched"
-#include "llvm/CodeGen/MachinePassRegistry.h"
+#include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/ScheduleDAG.h"
+#include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/Target/TargetData.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetInstrInfo.h"
 #include "llvm/Support/Debug.h"
-#include "llvm/Support/Visibility.h"
+#include "llvm/Support/Compiler.h"
 #include <algorithm>
-#include <iostream>
 using namespace llvm;
 
-
 namespace {
 
 static RegisterScheduler
@@ -277,7 +277,7 @@ public:
 /// ResourceTally - Manages the use of resources over time intervals.  Each
 /// item (slot) in the tally vector represents the resources used at a given
 /// moment.  A bit set to 1 indicates that a resource is in use, otherwise
-/// available.  An assumption is made that the tally is large enough to schedule 
+/// available.  An assumption is made that the tally is large enough to schedule
 /// all current instructions (asserts otherwise.)
 ///
 template<class T>
@@ -288,9 +288,9 @@ private:
                                         // Tally iterator 
   
   /// SlotsAvailable - Returns true if all units are available.
-       ///
+  ///
   bool SlotsAvailable(Iter Begin, unsigned N, unsigned ResourceSet,
-                                              unsigned &Resource) {
+                      unsigned &Resource) {
     assert(N && "Must check availability with N != 0");
     // Determine end of interval
     Iter End = Begin + N;
@@ -318,23 +318,23 @@ private:
     Resource = 0;
     return false;
   }
-       
-       /// RetrySlot - Finds a good candidate slot to retry search.
+  
+  /// RetrySlot - Finds a good candidate slot to retry search.
   Iter RetrySlot(Iter Begin, unsigned N, unsigned ResourceSet) {
     assert(N && "Must check availability with N != 0");
     // Determine end of interval
     Iter End = Begin + N;
     assert(End <= Tally.end() && "Tally is not large enough for schedule");
-               
-               while (Begin != End--) {
-                       // Clear units in use
-                       ResourceSet &= ~*End;
-                       // If no units left then we should go no further 
-                       if (!ResourceSet) return End + 1;
-               }
-               // Made it all the way through
-               return Begin;
-       }
+    
+    while (Begin != End--) {
+      // Clear units in use
+      ResourceSet &= ~*End;
+      // If no units left then we should go no further 
+      if (!ResourceSet) return End + 1;
+    }
+    // Made it all the way through
+    return Begin;
+  }
   
   /// FindAndReserveStages - Return true if the stages can be completed. If
   /// so mark as busy.
@@ -377,7 +377,7 @@ private:
       // Try at cursor, if successful return position.
       if (FindAndReserveStages(Cursor, StageBegin, StageEnd)) return Cursor;
       // Locate a better position
-                       Cursor = RetrySlot(Cursor + 1, StageBegin->Cycles, StageBegin->Units);
+      Cursor = RetrySlot(Cursor + 1, StageBegin->Cycles, StageBegin->Units);
     }
   }
   
@@ -391,13 +391,13 @@ public:
   // FindAndReserve - Locate an ideal slot for the specified stages and mark
   // as busy.
   unsigned FindAndReserve(unsigned Slot, InstrStage *StageBegin,
-                                         InstrStage *StageEnd) {
-               // Where to begin 
-               Iter Begin = Tally.begin() + Slot;
-               // Find a free slot
-               Iter Where = FindSlots(Begin, StageBegin, StageEnd);
-               // Distance is slot number
-               unsigned Final = Where - Tally.begin();
+                          InstrStage *StageEnd) {
+    // Where to begin 
+    Iter Begin = Tally.begin() + Slot;
+    // Find a free slot
+    Iter Where = FindSlots(Begin, StageBegin, StageEnd);
+    // Distance is slot number
+    unsigned Final = Where - Tally.begin();
     return Final;
   }
 
@@ -474,6 +474,7 @@ private:
   /// print - Print ordering to specified output stream.
   ///
   void print(std::ostream &O) const;
+  void print(std::ostream *O) const { if (O) print(*O); }
   
   void dump(const char *tag) const;
   
@@ -486,6 +487,7 @@ private:
   /// printNI - Print node info.
   ///
   void printNI(std::ostream &O, NodeInfo *NI) const;
+  void printNI(std::ostream *O, NodeInfo *NI) const { if (O) printNI(*O, NI); }
   
   /// printChanges - Hilight changes in order caused by scheduling.
   ///
@@ -503,7 +505,6 @@ enum {
   RSLoadStore = 0x0C000000,  // Two load store units
   RSBranch    = 0x02000000   // One branch unit
 };
-static InstrStage CallStage  = { CallLatency, RSBranch };
 static InstrStage LoadStage  = { 5, RSLoadStore };
 static InstrStage StoreStage = { 2, RSLoadStore };
 static InstrStage IntStage   = { 2, RSInteger };
@@ -658,18 +659,30 @@ void ScheduleDAGSimple::print(std::ostream &O) const {
 }
 
 void ScheduleDAGSimple::dump(const char *tag) const {
-  std::cerr << tag; dump();
+  cerr << tag; dump();
 }
 
 void ScheduleDAGSimple::dump() const {
-  print(std::cerr);
+  print(cerr);
 }
 
 
 /// EmitAll - Emit all nodes in schedule sorted order.
 ///
 void ScheduleDAGSimple::EmitAll() {
-  std::map<SDNode*, unsigned> VRBaseMap;
+  // If this is the first basic block in the function, and if it has live ins
+  // that need to be copied into vregs, emit the copies into the top of the
+  // block before emitting the code for the block.
+  MachineFunction &MF = DAG.getMachineFunction();
+  if (&MF.front() == BB && MF.livein_begin() != MF.livein_end()) {
+    for (MachineFunction::livein_iterator LI = MF.livein_begin(),
+         E = MF.livein_end(); LI != E; ++LI)
+      if (LI->second)
+        MRI->copyRegToReg(*MF.begin(), MF.begin()->end(), LI->second,
+                          LI->first, RegMap->getRegClass(LI->second));
+  }
+  
+  DenseMap<SDNode*, unsigned> VRBaseMap;
   
   // For each node in the ordering
   for (unsigned i = 0, N = Ordering.size(); i < N; i++) {
@@ -728,25 +741,25 @@ void ScheduleDAGSimple::printChanges(unsigned Index) const {
   }
   
   if (i < N) {
-    std::cerr << Index << ". New Ordering\n";
+    cerr << Index << ". New Ordering\n";
     
     for (i = 0; i < N; i++) {
       NodeInfo *NI = Ordering[i];
-      std::cerr << "  " << NI->Preorder << ". ";
-      printNI(std::cerr, NI);
-      std::cerr << "\n";
+      cerr << "  " << NI->Preorder << ". ";
+      printNI(cerr, NI);
+      cerr << "\n";
       if (NI->isGroupDominator()) {
         NodeGroup *Group = NI->Group;
         for (NIIterator NII = Group->group_begin(), E = Group->group_end();
              NII != E; NII++) {
-          std::cerr << "          ";
-          printNI(std::cerr, *NII);
-          std::cerr << "\n";
+          cerr << "          ";
+          printNI(cerr, *NII);
+          cerr << "\n";
         }
       }
     }
   } else {
-    std::cerr << Index << ". No Changes\n";
+    cerr << Index << ". No Changes\n";
   }
 #endif
 }