Tighten physical register invariants: Allocatable physical registers can
authorLang Hames <lhames@gmail.com>
Tue, 14 Feb 2012 18:51:53 +0000 (18:51 +0000)
committerLang Hames <lhames@gmail.com>
Tue, 14 Feb 2012 18:51:53 +0000 (18:51 +0000)
only be live in to a block if it is the function entry point or a landing pad.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150494 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/LiveIntervalAnalysis.h
lib/CodeGen/LiveIntervalAnalysis.cpp
test/CodeGen/ARM/2010-05-18-PostIndexBug.ll

index 693d66b7de27c03a11a9429eb8363965a1f9da70..c18c479ce8d2137479c520b6774bc37c7c74a36b 100644 (file)
@@ -63,6 +63,9 @@ namespace llvm {
     /// allocatableRegs_ - A bit vector of allocatable registers.
     BitVector allocatableRegs_;
 
+    /// reservedRegs_ - A bit vector of reserved registers.
+    BitVector reservedRegs_;
+
     /// RegMaskSlots - Sorted list of instructions with register mask operands.
     /// Always use the 'r' slot, RegMasks are normal clobbers, not early
     /// clobbers.
@@ -128,6 +131,12 @@ namespace llvm {
       return allocatableRegs_.test(reg);
     }
 
+    /// isReserved - is the physical register reg reserved in the current
+    /// function
+    bool isReserved(unsigned reg) const {
+      return reservedRegs_.test(reg);
+    }
+
     /// getScaledIntervalSize - get the size of an interval in "units,"
     /// where every function is composed of one thousand units.  This
     /// measure scales properly with empty index slots in the function.
index 72f4eb7d646e373bc73a19dcc072f15799a76508..1bd49a1a5f9b080cee6af1cb1e85f94bf8ad3325 100644 (file)
@@ -94,6 +94,7 @@ bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
   lv_ = &getAnalysis<LiveVariables>();
   indexes_ = &getAnalysis<SlotIndexes>();
   allocatableRegs_ = tri_->getAllocatableSet(fn);
+  reservedRegs_ = tri_->getReservedRegs(fn);
 
   computeIntervals();
 
@@ -347,13 +348,24 @@ void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
   DEBUG(dbgs() << '\n');
 }
 
+#ifndef NDEBUG
+static bool isRegLiveOutOf(const MachineBasicBlock *MBB, unsigned Reg) {
+  for (MachineBasicBlock::const_succ_iterator SI = MBB->succ_begin(),
+                                              SE = MBB->succ_end();
+       SI != SE; ++SI) {
+    const MachineBasicBlock* succ = *SI;
+    if (succ->isLiveIn(Reg))
+      return true;
+  }
+  return false;
+}
+#endif
+
 void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
                                               MachineBasicBlock::iterator mi,
                                               SlotIndex MIIdx,
                                               MachineOperand& MO,
                                               LiveInterval &interval) {
-  // A physical register cannot be live across basic block, so its
-  // lifetime must end somewhere in its defining basic block.
   DEBUG(dbgs() << "\t\tregister: " << PrintReg(interval.reg, tri_));
 
   SlotIndex baseIndex = MIIdx;
@@ -407,12 +419,19 @@ void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
     baseIndex = baseIndex.getNextIndex();
   }
 
-  // The only case we should have a dead physreg here without a killing or
-  // instruction where we know it's dead is if it is live-in to the function
-  // and never used. Another possible case is the implicit use of the
-  // physical register has been deleted by two-address pass.
-  end = start.getDeadSlot();
+  // If we get here the register *should* be live out.
+  assert(!isAllocatable(interval.reg) && "Physregs shouldn't be live out!");
 
+  // FIXME: We need saner rules for reserved regs.
+  if (isReserved(interval.reg)) {
+    assert(!isRegLiveOutOf(MBB, interval.reg) && "Reserved reg live-out?");
+    end = start.getDeadSlot();
+  } else {
+    // Unreserved, unallocable registers like EFLAGS can be live across basic
+    // block boundaries.
+    assert(isRegLiveOutOf(MBB, interval.reg) && "Unreserved reg not live-out?");
+    end = getMBBEndIdx(MBB);
+  }
 exit:
   assert(start < end && "did not find end of interval?");
 
@@ -442,6 +461,12 @@ void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
 void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
                                          SlotIndex MIIdx,
                                          LiveInterval &interval) {
+  assert(TargetRegisterInfo::isPhysicalRegister(interval.reg) &&
+         "Only physical registers can be live in.");
+  assert((!isAllocatable(interval.reg) || MBB->getParent()->begin() ||
+          MBB->isLandingPad()) &&
+          "Allocatable live-ins only valid for entry blocks and landing pads.");
+
   DEBUG(dbgs() << "\t\tlivein register: " << PrintReg(interval.reg, tri_));
 
   // Look for kills, if it reaches a def before it's killed, then it shouldn't
@@ -491,8 +516,17 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
 
   // Live-in register might not be used at all.
   if (!SeenDefUse) {
-    DEBUG(dbgs() << " live through");
-    end = getMBBEndIdx(MBB);
+    if (isAllocatable(interval.reg) || isReserved(interval.reg)) {
+      // This must be an entry block or landing pad - we asserted so on entry
+      // to the function. For these blocks the interval is dead on entry.
+      DEBUG(dbgs() << " dead");
+      end = start.getDeadSlot();
+    } else {
+      assert(isRegLiveOutOf(MBB, interval.reg) &&
+             "Live in reg untouched in block should be be live through.");
+      DEBUG(dbgs() << " live through");
+      end = getMBBEndIdx(MBB);
+    }
   }
 
   SlotIndex defIdx = getMBBStartIdx(MBB);
index df9dbca313f2d9fad9ddd75edcf7b8e7f84b269a..0ae7f84f3ef344ba86102076d53dd5506036f60e 100644 (file)
@@ -11,7 +11,7 @@ entry:
 
 ; THUMB:     t:
 ; THUMB-NOT: str r0, [r1], r0
-; THUMB:     str r2, [r1]
+; THUMB:     str r1, [r0]
   %0 = getelementptr inbounds %struct.foo* %this, i32 0, i32 1 ; <i64*> [#uses=1]
   store i32 0, i32* inttoptr (i32 8 to i32*), align 8
   br i1 undef, label %bb.nph96, label %bb3