Keep track of register masks in LiveIntervalAnalysis.

Build an ordered vector of register mask operands (i.e., calls) when
computing live intervals. Provide a checkRegMaskInterference() function
that computes a bit mask of usable registers for a live range.

This is a quick way of determining of a live range crosses any calls,
and restricting it to the callee saved registers if it does.
Previously, we had to discover call clobbers for each candidate register
independently.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150077 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen
2012-02-08 17:33:45 +00:00
parent 90a468c424
commit 3fd3a840c5
2 changed files with 105 additions and 0 deletions

View File

@ -88,6 +88,8 @@ void LiveIntervals::releaseMemory() {
delete I->second;
r2iMap_.clear();
RegMaskSlots.clear();
RegMaskBits.clear();
// Release VNInfo memory regions, VNInfo objects don't need to be dtor'd.
VNInfoAllocator.Reset();
@ -558,10 +560,20 @@ void LiveIntervals::computeIntervals() {
DEBUG(dbgs() << MIIndex << "\t" << *MI);
if (MI->isDebugValue())
continue;
assert(indexes_->getInstructionFromIndex(MIIndex) == MI &&
"Lost SlotIndex synchronization");
// Handle defs.
for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
MachineOperand &MO = MI->getOperand(i);
// Collect register masks.
if (MO.isRegMask()) {
RegMaskSlots.push_back(MIIndex.getRegSlot());
RegMaskBits.push_back(MO.getRegMask());
continue;
}
if (!MO.isReg() || !MO.getReg())
continue;
@ -1111,3 +1123,53 @@ LiveRange LiveIntervals::addLiveRangeToEndOfBlock(unsigned reg,
return LR;
}
//===----------------------------------------------------------------------===//
// Register mask functions
//===----------------------------------------------------------------------===//
bool LiveIntervals::checkRegMaskInterference(LiveInterval &LI,
BitVector &UsableRegs) {
if (LI.empty())
return false;
// We are going to enumerate all the register mask slots contained in LI.
// Start with a binary search of RegMaskSlots to find a starting point.
LiveInterval::iterator LiveI = LI.begin(), LiveE = LI.end();
ArrayRef<SlotIndex> Slots = getRegMaskSlots();
ArrayRef<SlotIndex>::iterator SlotI =
std::lower_bound(Slots.begin(), Slots.end(), LiveI->start);
ArrayRef<SlotIndex>::iterator SlotE = Slots.end();
// No slots in range, LI begins after the last call.
if (SlotI == SlotE)
return false;
bool Found = false;
for (;;) {
assert(*SlotI >= LiveI->start);
// Loop over all slots overlapping this segment.
while (*SlotI < LiveI->end) {
// *SlotI overlaps LI. Collect mask bits.
if (!Found) {
// This is the first overlap. Initialize UsableRegs to all ones.
UsableRegs.clear();
UsableRegs.resize(tri_->getNumRegs(), true);
Found = true;
}
// Remove usable registers clobbered by this mask.
UsableRegs.clearBitsNotInMask(RegMaskBits[SlotI-Slots.begin()]);
if (++SlotI == SlotE)
return Found;
}
// *SlotI is beyond the current LI segment.
LiveI = LI.advanceTo(LiveI, *SlotI);
if (LiveI == LiveE)
return Found;
// Advance SlotI until it overlaps.
while (*SlotI < LiveI->start)
if (++SlotI == SlotE)
return Found;
}
}