aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLang Hames <lhames@gmail.com>2012-02-14 18:51:53 +0000
committerLang Hames <lhames@gmail.com>2012-02-14 18:51:53 +0000
commit342c64c90418a97ec26303c27d1829edd994d9a9 (patch)
treedf714cd91e524367f07fd2661312f1369d8127dc
parent8b7c3d0ee42938a9e6ca37239cc327bd9f4c0cd0 (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.h9
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp52
-rw-r--r--test/CodeGen/ARM/2010-05-18-PostIndexBug.ll2
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