Enable stack-coloring, in hope that the recent fixes will enable correct dragonegg...
[oota-llvm.git] / lib / CodeGen / StackColoring.cpp
index eb4ebb76f2989a5c83c2a14dcc3dd8822daf1961..0deb35ad7fbd98808fa41a957166f90e872ea1f9 100644 (file)
@@ -158,6 +158,14 @@ private:
   /// slots to use the joint slots.
   void remapInstructions(DenseMap<int, int> &SlotRemap);
 
+  /// The input program may contain intructions which are not inside lifetime
+  /// markers. This can happen due to a bug in the compiler or due to a bug in
+  /// user code (for example, returning a reference to a local variable).
+  /// This procedure checks all of the instructions in the function and
+  /// invalidates lifetime ranges which do not contain all of the instructions
+  /// which access that frame slot.
+  void removeInvalidSlotRanges();
+
   /// Map entries which point to other entries to their destination.
   ///   A->B->C becomes A->C.
    void expungeSlotMap(DenseMap<int, int> &SlotRemap, unsigned NumSlots);
@@ -220,7 +228,7 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
        FI != FE; ++FI) {
 
     // Assign a serial number to this basic block.
-    BasicBlocks[*FI] = BasicBlockNumbering.size();;
+    BasicBlocks[*FI] = BasicBlockNumbering.size();
     BasicBlockNumbering.push_back(*FI);
 
     BlockLiveness[*FI].Begin.resize(NumSlot);
@@ -523,10 +531,12 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
         // the calculated range then it means that the alloca usage moved
         // outside of the lifetime markers.
 #ifndef NDEBUG
-        SlotIndex Index = Indexes->getInstructionIndex(I);
-        LiveInterval* Interval = Intervals[FromSlot];
-        assert(Interval->find(Index) != Interval->end() &&
+        if (!I->isDebugValue()) {
+          SlotIndex Index = Indexes->getInstructionIndex(I);
+          LiveInterval* Interval = Intervals[FromSlot];
+          assert(Interval->find(Index) != Interval->end() &&
                "Found instruction usage outside of live range.");
+        }
 #endif
 
         // Fix the machine instructions.
@@ -541,6 +551,43 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
   DEBUG(dbgs()<<"Fixed "<<FixedInstr<<" machine instructions.\n");
 }
 
+void StackColoring::removeInvalidSlotRanges() {
+  MachineFunction::iterator BB, BBE;
+  MachineBasicBlock::iterator I, IE;
+  for (BB = MF->begin(), BBE = MF->end(); BB != BBE; ++BB)
+    for (I = BB->begin(), IE = BB->end(); I != IE; ++I) {
+
+      if (I->getOpcode() == TargetOpcode::LIFETIME_START ||
+          I->getOpcode() == TargetOpcode::LIFETIME_END || I->isDebugValue())
+        continue;
+
+      // Check all of the machine operands.
+      for (unsigned i = 0 ; i <  I->getNumOperands(); ++i) {
+        MachineOperand &MO = I->getOperand(i);
+
+        if (!MO.isFI())
+          continue;
+
+        int Slot = MO.getIndex();
+
+        if (Slot<0)
+          continue;
+
+        if (Intervals[Slot]->empty())
+          continue;
+
+        // Check that the used slot is inside the calculated lifetime range.
+        // If it is not, warn about it and invalidate the range.
+        LiveInterval *Interval = Intervals[Slot];
+        SlotIndex Index = Indexes->getInstructionIndex(I);
+        if (Interval->find(Index) == Interval->end()) {
+          Intervals[Slot]->clear();
+          DEBUG(dbgs()<<"Invalidating range #"<<Slot<<"\n");
+        }
+      }
+    }
+}
+
 void StackColoring::expungeSlotMap(DenseMap<int, int> &SlotRemap,
                                    unsigned NumSlots) {
   // Expunge slot remap map.
@@ -615,6 +662,8 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
   // Propagate the liveness information.
   calculateLiveIntervals(NumSlots);
 
+  removeInvalidSlotRanges();
+
   // Maps old slots to new slots.
   DenseMap<int, int> SlotRemap;
   unsigned RemovedSlots = 0;