LiveIntervalAnalysis: Adapt handleMove() to subregister ranges.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223881 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Matthias Braun 2014-12-10 01:12:20 +00:00
parent e59399c28c
commit dc08729288

View File

@ -32,6 +32,7 @@
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h"
@ -838,9 +839,17 @@ public:
continue; continue;
if (TargetRegisterInfo::isVirtualRegister(Reg)) { if (TargetRegisterInfo::isVirtualRegister(Reg)) {
LiveInterval &LI = LIS.getInterval(Reg); LiveInterval &LI = LIS.getInterval(Reg);
// TODO: handle subranges instead of dropping them if (LI.hasSubRanges()) {
LI.clearSubRanges(); unsigned SubReg = MO->getSubReg();
updateRange(LI, Reg); unsigned LaneMask = TRI.getSubRegIndexLaneMask(SubReg);
for (LiveInterval::subrange_iterator S = LI.subrange_begin(),
SE = LI.subrange_end(); S != SE; ++S) {
if ((S->LaneMask & LaneMask) == 0)
continue;
updateRange(*S, Reg, S->LaneMask);
}
}
updateRange(LI, Reg, 0);
continue; continue;
} }
@ -848,7 +857,7 @@ public:
// precomputed live range. // precomputed live range.
for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units) for (MCRegUnitIterator Units(Reg, &TRI); Units.isValid(); ++Units)
if (LiveRange *LR = getRegUnitLI(*Units)) if (LiveRange *LR = getRegUnitLI(*Units))
updateRange(*LR, *Units); updateRange(*LR, *Units, 0);
} }
if (hasRegMask) if (hasRegMask)
updateRegMaskSlots(); updateRegMaskSlots();
@ -857,21 +866,24 @@ public:
private: private:
/// Update a single live range, assuming an instruction has been moved from /// Update a single live range, assuming an instruction has been moved from
/// OldIdx to NewIdx. /// OldIdx to NewIdx.
void updateRange(LiveRange &LR, unsigned Reg) { void updateRange(LiveRange &LR, unsigned Reg, unsigned LaneMask) {
if (!Updated.insert(&LR).second) if (!Updated.insert(&LR).second)
return; return;
DEBUG({ DEBUG({
dbgs() << " "; dbgs() << " ";
if (TargetRegisterInfo::isVirtualRegister(Reg)) if (TargetRegisterInfo::isVirtualRegister(Reg)) {
dbgs() << PrintReg(Reg); dbgs() << PrintReg(Reg);
else if (LaneMask != 0)
dbgs() << format(" L%04X", LaneMask);
} else {
dbgs() << PrintRegUnit(Reg, &TRI); dbgs() << PrintRegUnit(Reg, &TRI);
}
dbgs() << ":\t" << LR << '\n'; dbgs() << ":\t" << LR << '\n';
}); });
if (SlotIndex::isEarlierInstr(OldIdx, NewIdx)) if (SlotIndex::isEarlierInstr(OldIdx, NewIdx))
handleMoveDown(LR); handleMoveDown(LR);
else else
handleMoveUp(LR, Reg); handleMoveUp(LR, Reg, LaneMask);
DEBUG(dbgs() << " -->\t" << LR << '\n'); DEBUG(dbgs() << " -->\t" << LR << '\n');
LR.verify(); LR.verify();
} }
@ -984,7 +996,7 @@ private:
/// Hoist kill to NewIdx, then scan for last kill between NewIdx and /// Hoist kill to NewIdx, then scan for last kill between NewIdx and
/// OldIdx. /// OldIdx.
/// ///
void handleMoveUp(LiveRange &LR, unsigned Reg) { void handleMoveUp(LiveRange &LR, unsigned Reg, unsigned LaneMask) {
// First look for a kill at OldIdx. // First look for a kill at OldIdx.
LiveRange::iterator I = LR.find(OldIdx.getBaseIndex()); LiveRange::iterator I = LR.find(OldIdx.getBaseIndex());
LiveRange::iterator E = LR.end(); LiveRange::iterator E = LR.end();
@ -1005,7 +1017,7 @@ private:
if (I == E || !SlotIndex::isSameInstr(I->start, OldIdx)) { if (I == E || !SlotIndex::isSameInstr(I->start, OldIdx)) {
// No def, search for the new kill. // No def, search for the new kill.
// This can never be an early clobber kill since there is no def. // This can never be an early clobber kill since there is no def.
std::prev(I)->end = findLastUseBefore(Reg).getRegSlot(); std::prev(I)->end = findLastUseBefore(Reg, LaneMask).getRegSlot();
return; return;
} }
} }
@ -1061,15 +1073,17 @@ private:
} }
// Return the last use of reg between NewIdx and OldIdx. // Return the last use of reg between NewIdx and OldIdx.
SlotIndex findLastUseBefore(unsigned Reg) { SlotIndex findLastUseBefore(unsigned Reg, unsigned LaneMask) {
if (TargetRegisterInfo::isVirtualRegister(Reg)) { if (TargetRegisterInfo::isVirtualRegister(Reg)) {
SlotIndex LastUse = NewIdx; SlotIndex LastUse = NewIdx;
for (MachineRegisterInfo::use_instr_nodbg_iterator for (MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
UI = MRI.use_instr_nodbg_begin(Reg), unsigned SubReg = MO.getSubReg();
UE = MRI.use_instr_nodbg_end(); if (SubReg != 0 && LaneMask != 0
UI != UE; ++UI) { && (TRI.getSubRegIndexLaneMask(SubReg) & LaneMask) == 0)
const MachineInstr* MI = &*UI; continue;
const MachineInstr *MI = MO.getParent();
SlotIndex InstSlot = LIS.getSlotIndexes()->getInstructionIndex(MI); SlotIndex InstSlot = LIS.getSlotIndexes()->getInstructionIndex(MI);
if (InstSlot > LastUse && InstSlot < OldIdx) if (InstSlot > LastUse && InstSlot < OldIdx)
LastUse = InstSlot; LastUse = InstSlot;