Turns out AnalyzeBranch can modify the mbb being analyzed. This is a nasty
[oota-llvm.git] / lib / CodeGen / PostRASchedulerList.cpp
index 12d9efa87b4c0da46dd261845868845d3fadd5d1..94b6be19fbad35d1077d60fb1e834791c5697e18 100644 (file)
@@ -19,8 +19,8 @@
 //===----------------------------------------------------------------------===//
 
 #define DEBUG_TYPE "post-RA-sched"
+#include "ScheduleDAGInstrs.h"
 #include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/ScheduleDAGInstrs.h"
 #include "llvm/CodeGen/LatencyPriorityQueue.h"
 #include "llvm/CodeGen/SchedulerRegistry.h"
 #include "llvm/CodeGen/MachineDominators.h"
@@ -187,9 +187,19 @@ bool PostRAScheduler::runOnMachineFunction(MachineFunction &Fn) {
   // Loop over all of the basic blocks
   for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
        MBB != MBBe; ++MBB) {
+    // Schedule each sequence of instructions not interrupted by a label
+    // or anything else that effectively needs to shut down scheduling.
+    MachineBasicBlock::iterator Current = MBB->end(), Top = MBB->begin();
+    for (MachineBasicBlock::iterator I = Current; I != Top; ) {
+      MachineInstr *MI = --I;
+      if (MI->getDesc().isTerminator() || MI->isLabel()) {
+        Scheduler.Run(0, MBB, next(I), Current);
+        Scheduler.EmitSchedule();
+        Current = I;
+      }
+    }
 
-    Scheduler.Run(0, MBB);
-
+    Scheduler.Run(0, MBB, Top, Current);
     Scheduler.EmitSchedule();
   }
 
@@ -227,12 +237,11 @@ void SchedulePostRATDList::Schedule() {
 /// instruction of the specified TargetInstrDesc.
 static const TargetRegisterClass*
 getInstrOperandRegClass(const TargetRegisterInfo *TRI,
-                        const TargetInstrInfo *TII, const TargetInstrDesc &II,
-                        unsigned Op) {
+                         const TargetInstrDesc &II, unsigned Op) {
   if (Op >= II.getNumOperands())
     return NULL;
   if (II.OpInfo[Op].isLookupPtrRegClass())
-    return TII->getPointerRegClass();
+    return TRI->getPointerRegClass();
   return TRI->getRegClass(II.OpInfo[Op].RegClass);
 }
 
@@ -407,10 +416,10 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
   // instructions from the bottom up, tracking information about liveness
   // as we go to help determine which registers are available.
   bool Changed = false;
-  unsigned Count = BB->size() - 1;
-  for (MachineBasicBlock::reverse_iterator I = BB->rbegin(), E = BB->rend();
-       I != E; ++I, --Count) {
-    MachineInstr *MI = &*I;
+  unsigned Count = SUnits.size() - 1;
+  for (MachineBasicBlock::iterator I = End, E = Begin;
+       I != E; --Count) {
+    MachineInstr *MI = --I;
 
     // After regalloc, IMPLICIT_DEF instructions aren't safe to treat as
     // dependence-breaking. In the case of an INSERT_SUBREG, the IMPLICIT_DEF
@@ -442,7 +451,9 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
           AntiDepReg = Edge->getReg();
           assert(AntiDepReg != 0 && "Anti-dependence on reg0?");
           // Don't break anti-dependencies on non-allocatable registers.
-          if (AllocatableSet.test(AntiDepReg)) {
+          if (!AllocatableSet.test(AntiDepReg))
+            AntiDepReg = 0;
+          else {
             // If the SUnit has other dependencies on the SUnit that it
             // anti-depends on, don't bother breaking the anti-dependency
             // since those edges would prevent such units from being
@@ -478,7 +489,7 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
       unsigned Reg = MO.getReg();
       if (Reg == 0) continue;
       const TargetRegisterClass *NewRC =
-        getInstrOperandRegClass(TRI, TII, MI->getDesc(), i);
+        getInstrOperandRegClass(TRI, MI->getDesc(), i);
 
       // If this instruction has a use of AntiDepReg, breaking it
       // is invalid.
@@ -613,7 +624,7 @@ bool SchedulePostRATDList::BreakAntiDependencies() {
       if (!MO.isUse()) continue;
 
       const TargetRegisterClass *NewRC =
-        getInstrOperandRegClass(TRI, TII, MI->getDesc(), i);
+        getInstrOperandRegClass(TRI, MI->getDesc(), i);
 
       // For now, only allow the register to be changed if its register
       // class is consistent across all uses.