Fix a typo.
[oota-llvm.git] / lib / CodeGen / StackColoring.cpp
index 16b715a7962ac976a94d7d43047a68f325a48ef1..832d4d1ca5d3f2758bbe096917dd6e74114c902e 100644 (file)
@@ -59,12 +59,19 @@ using namespace llvm;
 
 static cl::opt<bool>
 DisableColoring("no-stack-coloring",
-               cl::init(true), cl::Hidden,
-               cl::desc("Suppress stack coloring"));
+        cl::init(false), cl::Hidden,
+        cl::desc("Disable stack coloring"));
 
-STATISTIC(NumMarkerSeen,  "Number of life markers found.");
+static cl::opt<bool>
+CheckEscapedAllocas("stack-coloring-check-escaped",
+        cl::init(true), cl::Hidden,
+        cl::desc("Look for allocas which escaped the lifetime region"));
+
+STATISTIC(NumMarkerSeen,  "Number of lifetime markers found.");
 STATISTIC(StackSpaceSaved, "Number of bytes saved due to merging slots.");
 STATISTIC(StackSlotMerged, "Number of stack slot merged.");
+STATISTIC(EscapedAllocas,
+          "Number of allocas that escaped the lifetime region");
 
 //===----------------------------------------------------------------------===//
 //                           StackColoring Pass
@@ -104,7 +111,7 @@ class StackColoring : public MachineFunctionPass {
   /// VNInfo is used for the construction of LiveIntervals.
   VNInfo::Allocator VNInfoAllocator;
   /// SlotIndex analysis object.
-  SlotIndexesIndexes;
+  SlotIndexes *Indexes;
 
   /// The list of lifetime markers found. These markers are to be removed
   /// once the coloring is done.
@@ -251,8 +258,8 @@ unsigned StackColoring::collectMarkers(unsigned NumSlot) {
 
       const Value *Allocation = MFI->getObjectAllocation(Slot);
       if (Allocation) {
-        DEBUG(dbgs()<<"Found lifetime marker for allocation: "<<
-              Allocation->getName()<<"\n");
+        DEBUG(dbgs()<<"Found a lifetime marker for slot #"<<Slot<<
+              " with allocation: "<< Allocation->getName()<<"\n");
       }
 
       if (IsStart) {
@@ -530,10 +537,14 @@ void StackColoring::remapInstructions(DenseMap<int, int> &SlotRemap) {
         // inside the expected live range. If the instruction is not inside
         // the calculated range then it means that the alloca usage moved
         // outside of the lifetime markers.
+        // NOTE: Alloca address calculations which happen outside the lifetime
+        // zone are are okay, despite the fact that we don't have a good way
+        // for validating all of the usages of the calculation.
 #ifndef NDEBUG
-        if (!I->isDebugValue()) {
+        bool TouchesMemory = I->mayLoad() || I->mayStore();
+        if (!I->isDebugValue() && TouchesMemory) {
           SlotIndex Index = Indexes->getInstructionIndex(I);
-          LiveIntervalInterval = Intervals[FromSlot];
+          LiveInterval *Interval = Intervals[FromSlot];
           assert(Interval->find(Index) != Interval->end() &&
                "Found instruction usage outside of live range.");
         }
@@ -561,6 +572,15 @@ void StackColoring::removeInvalidSlotRanges() {
           I->getOpcode() == TargetOpcode::LIFETIME_END || I->isDebugValue())
         continue;
 
+      // Some intervals are suspicious! In some cases we find address
+      // calculations outside of the lifetime zone, but not actual memory
+      // read or write. Memory accesses outside of the lifetime zone are a clear
+      // violation, but address calculations are okay. This can happen when
+      // GEPs are hoisted outside of the lifetime zone.
+      // So, in here we only check instructions which can read or write memory.
+      if (!I->mayLoad() && !I->mayStore())
+        continue;
+
       // Check all of the machine operands.
       for (unsigned i = 0 ; i <  I->getNumOperands(); ++i) {
         MachineOperand &MO = I->getOperand(i);
@@ -583,6 +603,7 @@ void StackColoring::removeInvalidSlotRanges() {
         if (Interval->find(Index) == Interval->end()) {
           Intervals[Slot]->clear();
           DEBUG(dbgs()<<"Invalidating range #"<<Slot<<"\n");
+          EscapedAllocas++;
         }
       }
     }
@@ -643,7 +664,7 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
   DEBUG(dbgs()<<"Total Stack size: "<<TotalSize<<" bytes\n\n");
 
   // Don't continue because there are not enough lifetime markers, or the
-  // stack or too small, or we are told not to optimize the slots.
+  // stack is too small, or we are told not to optimize the slots.
   if (NumMarkers < 2 || TotalSize < 16 || DisableColoring) {
     DEBUG(dbgs()<<"Will not try to merge slots.\n");
     return removeAllMarkers();
@@ -662,7 +683,10 @@ bool StackColoring::runOnMachineFunction(MachineFunction &Func) {
   // Propagate the liveness information.
   calculateLiveIntervals(NumSlots);
 
-  removeInvalidSlotRanges();
+  // Search for allocas which are used outside of the declared lifetime
+  // markers.
+  if (CheckEscapedAllocas)
+    removeInvalidSlotRanges();
 
   // Maps old slots to new slots.
   DenseMap<int, int> SlotRemap;