Stack Coloring: Add support for multiple regions of the same slot, within a single...
authorNadav Rotem <nrotem@apple.com>
Mon, 10 Sep 2012 12:39:35 +0000 (12:39 +0000)
committerNadav Rotem <nrotem@apple.com>
Mon, 10 Sep 2012 12:39:35 +0000 (12:39 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163507 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/StackColoring.cpp
test/CodeGen/X86/StackColoring.ll

index b0cbda827ce1c426c71412da057284317b4bb3a8..027096b81050bb4c4b8a2b32862c983d86561e19 100644 (file)
@@ -351,40 +351,50 @@ void StackColoring::calculateLiveIntervals(unsigned NumSlots) {
     Finishes.clear();
     Finishes.resize(NumSlots);
 
-    BitVector Alive = BlockLiveness[MBB].LiveIn;
-    Alive |= BlockLiveness[MBB].LiveOut;
-
-    if (Alive.any()) {
-      for (int pos = Alive.find_first(); pos != -1;
-           pos = Alive.find_next(pos)) {
-        Starts[pos] = Indexes->getMBBStartIdx(MBB);
-        Finishes[pos] = Indexes->getMBBEndIdx(MBB);
-      }
-    }
-
+    // Create the interval for the basic blocks with lifetime markers in them.
     for (SmallVector<MachineInstr*, 8>::iterator it = Markers.begin(),
          e = Markers.end(); it != e; ++it) {
       MachineInstr *MI = *it;
+      if (MI->getParent() != MBB)
+        continue;
+
       assert((MI->getOpcode() == TargetOpcode::LIFETIME_START ||
               MI->getOpcode() == TargetOpcode::LIFETIME_END) &&
              "Invalid Lifetime marker");
 
-      if (MI->getParent() == MBB) {
-        bool IsStart = MI->getOpcode() == TargetOpcode::LIFETIME_START;
-        MachineOperand &Mo = MI->getOperand(0);
-        int Slot = Mo.getIndex();
-        assert(Slot >= 0 && "Invalid slot");
-        if (IsStart) {
-          Starts[Slot] = Indexes->getInstructionIndex(MI);
-        } else {
-          Finishes[Slot] = Indexes->getInstructionIndex(MI);
-        }
+      bool IsStart = MI->getOpcode() == TargetOpcode::LIFETIME_START;
+      MachineOperand &Mo = MI->getOperand(0);
+      int Slot = Mo.getIndex();
+      assert(Slot >= 0 && "Invalid slot");
+
+      SlotIndex ThisIndex = Indexes->getInstructionIndex(MI);
+
+      if (IsStart) {
+        if (!Starts[Slot].isValid() || Starts[Slot] > ThisIndex)
+          Starts[Slot] = ThisIndex;
+      } else {
+        if (!Finishes[Slot].isValid() || Finishes[Slot] < ThisIndex)
+          Finishes[Slot] = ThisIndex;
+      }
+    }
+
+    // Create the interval of the blocks that we previously found to be 'alive'.
+    BitVector Alive = BlockLiveness[MBB].LiveIn;
+    Alive |= BlockLiveness[MBB].LiveOut;
+
+    if (Alive.any()) {
+      for (int pos = Alive.find_first(); pos != -1;
+           pos = Alive.find_next(pos)) {
+        if (!Starts[pos].isValid())
+          Starts[pos] = Indexes->getMBBStartIdx(MBB);
+        if (!Finishes[pos].isValid())
+          Finishes[pos] = Indexes->getMBBEndIdx(MBB);
       }
     }
 
     for (unsigned i = 0; i < NumSlots; ++i) {
-      assert(!!Starts[i] == !!Finishes[i] && "Unmatched range");
-      if (Starts[i] == Finishes[i])
+      assert(Starts[i].isValid() == Finishes[i].isValid() && "Unmatched range");
+      if (!Starts[i].isValid())
         continue;
 
       assert(Starts[i] && Finishes[i] && "Invalid interval");
index 42235a03e3a900c8effbd1b477f06e89dd11e77f..6ef3b3cd023223d4da6b71ca9fe38e1612658d7c 100644 (file)
@@ -297,6 +297,34 @@ bb3:
   ret i32 0
 }
 
+
+;YESCOLOR: multi_region_bb
+;NOCOLOR: multi_region_bb
+define void @multi_region_bb() nounwind ssp {
+entry:
+  %A.i1 = alloca [100 x i32], align 4
+  %B.i2 = alloca [100 x i32], align 4
+  %A.i = alloca [100 x i32], align 4
+  %B.i = alloca [100 x i32], align 4
+  %0 = bitcast [100 x i32]* %A.i to i8*
+  call void @llvm.lifetime.start(i64 -1, i8* %0) nounwind ; <---- start #1
+  %1 = bitcast [100 x i32]* %B.i to i8*
+  call void @llvm.lifetime.start(i64 -1, i8* %1) nounwind
+  call void @bar([100 x i32]* %A.i, [100 x i32]* %B.i) nounwind
+  call void @llvm.lifetime.end(i64 -1, i8* %0) nounwind
+  call void @llvm.lifetime.end(i64 -1, i8* %1) nounwind
+  %2 = bitcast [100 x i32]* %A.i1 to i8*
+  call void @llvm.lifetime.start(i64 -1, i8* %2) nounwind
+  %3 = bitcast [100 x i32]* %B.i2 to i8*
+  call void @llvm.lifetime.start(i64 -1, i8* %3) nounwind
+  call void @llvm.lifetime.start(i64 -1, i8* %0) nounwind  ; <---- start #2
+  call void @bar([100 x i32]* %A.i1, [100 x i32]* %B.i2) nounwind
+  call void @llvm.lifetime.end(i64 -1, i8* %2) nounwind
+  call void @llvm.lifetime.end(i64 -1, i8* %0) nounwind
+  call void @llvm.lifetime.end(i64 -1, i8* %3) nounwind
+  ret void
+}
+
 declare void @bar([100 x i32]* , [100 x i32]*) nounwind
 
 declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind