diff options
author | Lang Hames <lhames@gmail.com> | 2012-02-14 18:51:53 +0000 |
---|---|---|
committer | Lang Hames <lhames@gmail.com> | 2012-02-14 18:51:53 +0000 |
commit | 342c64c90418a97ec26303c27d1829edd994d9a9 (patch) | |
tree | df714cd91e524367f07fd2661312f1369d8127dc | |
parent | 8b7c3d0ee42938a9e6ca37239cc327bd9f4c0cd0 (diff) |
Tighten physical register invariants: Allocatable physical registers can
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
-rw-r--r-- | include/llvm/CodeGen/LiveIntervalAnalysis.h | 9 | ||||
-rw-r--r-- | lib/CodeGen/LiveIntervalAnalysis.cpp | 52 | ||||
-rw-r--r-- | test/CodeGen/ARM/2010-05-18-PostIndexBug.ll | 2 |
3 files changed, 53 insertions, 10 deletions
diff --git a/include/llvm/CodeGen/LiveIntervalAnalysis.h b/include/llvm/CodeGen/LiveIntervalAnalysis.h index 693d66b7de..c18c479ce8 100644 --- a/include/llvm/CodeGen/LiveIntervalAnalysis.h +++ b/include/llvm/CodeGen/LiveIntervalAnalysis.h @@ -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. diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index 72f4eb7d64..1bd49a1a5f 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -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); diff --git a/test/CodeGen/ARM/2010-05-18-PostIndexBug.ll b/test/CodeGen/ARM/2010-05-18-PostIndexBug.ll index df9dbca313..0ae7f84f3e 100644 --- a/test/CodeGen/ARM/2010-05-18-PostIndexBug.ll +++ b/test/CodeGen/ARM/2010-05-18-PostIndexBug.ll @@ -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 |