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:
parent
1ace5adf9a
commit
96b93cde64
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user