1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 05:01:59 +01:00

LiveRegMatrix: Respect subregister liveness when allocating registers.

llvm-svn: 223891
This commit is contained in:
Matthias Braun 2014-12-10 01:13:01 +00:00
parent 1ace5adf9a
commit 96b93cde64

View File

@ -19,6 +19,7 @@
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Format.h"
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
@ -71,16 +72,45 @@ void LiveRegMatrix::releaseMemory() {
}
}
template<typename Callable>
bool foreachUnit(const TargetRegisterInfo *TRI, LiveInterval &VRegInterval,
unsigned PhysReg, Callable Func) {
if (VRegInterval.hasSubRanges()) {
for (MCRegUnitMaskIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
unsigned Unit = (*Units).first;
unsigned Mask = (*Units).second;
for (LiveInterval::subrange_iterator S = VRegInterval.subrange_begin(),
SE = VRegInterval.subrange_end(); S != SE; ++S) {
if (S->LaneMask & Mask) {
if (Func(Unit, *S))
return true;
break;
}
}
}
} else {
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
if (Func(*Units, VRegInterval))
return true;
}
}
return false;
}
void LiveRegMatrix::assign(LiveInterval &VirtReg, unsigned PhysReg) {
DEBUG(dbgs() << "assigning " << PrintReg(VirtReg.reg, TRI)
<< " to " << PrintReg(PhysReg, TRI) << ':');
assert(!VRM->hasPhys(VirtReg.reg) && "Duplicate VirtReg assignment");
VRM->assignVirt2Phys(VirtReg.reg, PhysReg);
MRI->setPhysRegUsed(PhysReg);
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
DEBUG(dbgs() << ' ' << PrintRegUnit(*Units, TRI));
Matrix[*Units].unify(VirtReg);
}
foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit,
const LiveRange &Range) {
DEBUG(dbgs() << ' ' << PrintRegUnit(Unit, TRI) << ' ' << Range);
Matrix[Unit].unify(VirtReg, Range);
return false;
});
++NumAssigned;
DEBUG(dbgs() << '\n');
}
@ -90,10 +120,14 @@ void LiveRegMatrix::unassign(LiveInterval &VirtReg) {
DEBUG(dbgs() << "unassigning " << PrintReg(VirtReg.reg, TRI)
<< " from " << PrintReg(PhysReg, TRI) << ':');
VRM->clearVirt(VirtReg.reg);
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
DEBUG(dbgs() << ' ' << PrintRegUnit(*Units, TRI));
Matrix[*Units].extract(VirtReg);
}
foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit,
const LiveRange &Range) {
DEBUG(dbgs() << ' ' << PrintRegUnit(Unit, TRI));
Matrix[Unit].extract(VirtReg, Range);
return false;
});
++NumUnassigned;
DEBUG(dbgs() << '\n');
}
@ -121,12 +155,13 @@ bool LiveRegMatrix::checkRegUnitInterference(LiveInterval &VirtReg,
if (VirtReg.empty())
return false;
CoalescerPair CP(VirtReg.reg, PhysReg, *TRI);
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
const LiveRange &UnitRange = LIS->getRegUnit(*Units);
if (VirtReg.overlaps(UnitRange, CP, *LIS->getSlotIndexes()))
return true;
}
return false;
bool Result = foreachUnit(TRI, VirtReg, PhysReg, [&](unsigned Unit,
const LiveRange &Range) {
const LiveRange &UnitRange = LIS->getRegUnit(Unit);
return Range.overlaps(UnitRange, CP, *LIS->getSlotIndexes());
});
return Result;
}
LiveIntervalUnion::Query &LiveRegMatrix::query(LiveInterval &VirtReg,