[PATCH] Add a case to LiveIntervalAnalysis::HandleMoveUp

Vincent Lejeune vljn at ovi.com
Fri Feb 8 14:31:14 PST 2013


Some target like R600 may want to swap LiveRange order for a same register.
This happens for instance if several subregisters can be independantly written
to ; for instance in the case of R600, a 128 bits register is composed of 4 32
bits subregisters that have no write order restriction. To maximise VLIW bundle
size and thus increase parrallelism the R600 target may swap subreg definitions.
This patch allows LiveIntervals to support such changes.
---
 lib/CodeGen/LiveIntervalAnalysis.cpp | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index 4e75d89..dd849d3 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -1197,6 +1197,11 @@ private:
   ///    Hoist kill to NewIdx, then scan for last kill between NewIdx and
   ///    OldIdx.
   ///
+  /// 6. Live def at OldIdx AND several other values between NewIdx and OldIdx
+  ///    Extend the range that precedes OldIdx one and split the range that
+  ///    contains NewIdx.
+  ///    (Happens when reordering independant partial write to a register)
+  ///
   void handleMoveUp(LiveInterval &LI) {
     // First look for a kill at OldIdx.
     LiveInterval::iterator I = LI.find(OldIdx.getBaseIndex());
@@ -1245,6 +1250,21 @@ private:
       return;
     }
 
+    LiveInterval::iterator PredI = llvm::prior(I);
+    LiveInterval::iterator NewI2 = LI.find(NewIdx.getBaseIndex());
+    if (NewI2 != PredI && SlotIndex::isEarlierInstr(NewI2->start, NewIdx)) {
+      // Case 6
+      // First we extand range prior to I
+      PredI->end = I->end;
+      // We shrink range right before NewI2
+      SlotIndex NewI2End = NewI2->end;
+      NewI2->end = DefVNI->def;
+      // Now we slide [NewI2;I) down one position.
+      std::copy_backward(llvm::next(NewI2), I, llvm::next(I));
+      // Finally we insert a new range
+      *llvm::next(NewI2) = LiveRange(DefVNI->def, NewI2End, DefVNI);
+    }
+
     // There is no existing def at NewIdx. Hoist DefVNI.
     if (!I->end.isDead()) {
       // Leave the end point of a live def.
-- 
1.8.1.2




More information about the llvm-commits mailing list