summaryrefslogtreecommitdiff
path: root/lib/CodeGen/RegAllocPBQP.cpp
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-06-20 22:32:05 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-06-20 22:32:05 +0000
commit3b30bca16f7ab002bcd5058b3f3a044a267541e0 (patch)
treeef88a2417e1272a2998706c7823e0a780b12b44f /lib/CodeGen/RegAllocPBQP.cpp
parentb9598e41bc5187cfe8fb6345a90be27e6967958f (diff)
downloadllvm-3b30bca16f7ab002bcd5058b3f3a044a267541e0.tar.gz
llvm-3b30bca16f7ab002bcd5058b3f3a044a267541e0.tar.bz2
llvm-3b30bca16f7ab002bcd5058b3f3a044a267541e0.tar.xz
Teach PBQPBuilder::build() about regunit interference.
Filter out physreg candidates with regunit interferrence. Also compute regmask interference more efficiently. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158864 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/RegAllocPBQP.cpp')
-rw-r--r--lib/CodeGen/RegAllocPBQP.cpp64
1 files changed, 31 insertions, 33 deletions
diff --git a/lib/CodeGen/RegAllocPBQP.cpp b/lib/CodeGen/RegAllocPBQP.cpp
index dde6fba529..a3fe6faba3 100644
--- a/lib/CodeGen/RegAllocPBQP.cpp
+++ b/lib/CodeGen/RegAllocPBQP.cpp
@@ -196,7 +196,7 @@ std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
const RegSet &vregs) {
typedef std::vector<const LiveInterval*> LIVector;
- ArrayRef<SlotIndex> regMaskSlots = lis->getRegMaskSlots();
+ LiveIntervals *LIS = const_cast<LiveIntervals*>(lis);
MachineRegisterInfo *mri = &mf->getRegInfo();
const TargetRegisterInfo *tri = mf->getTarget().getRegisterInfo();
@@ -206,7 +206,7 @@ std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
// Collect the set of preg intervals, record that they're used in the MF.
for (unsigned Reg = 1, e = tri->getNumRegs(); Reg != e; ++Reg) {
- if (!lis->hasInterval(Reg))
+ if (mri->def_empty(Reg))
continue;
pregs.insert(Reg);
mri->setPhysRegUsed(Reg);
@@ -219,7 +219,11 @@ std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
vregItr != vregEnd; ++vregItr) {
unsigned vreg = *vregItr;
const TargetRegisterClass *trc = mri->getRegClass(vreg);
- const LiveInterval *vregLI = &lis->getInterval(vreg);
+ LiveInterval *vregLI = &LIS->getInterval(vreg);
+
+ // Record any overlaps with regmask operands.
+ BitVector regMaskOverlaps(tri->getNumRegs());
+ LIS->checkRegMaskInterference(*vregLI, regMaskOverlaps);
// Compute an initial allowed set for the current vreg.
typedef std::vector<unsigned> VRAllowed;
@@ -227,9 +231,28 @@ std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
ArrayRef<uint16_t> rawOrder = trc->getRawAllocationOrder(*mf);
for (unsigned i = 0; i != rawOrder.size(); ++i) {
unsigned preg = rawOrder[i];
- if (!reservedRegs.test(preg)) {
- vrAllowed.push_back(preg);
+ if (reservedRegs.test(preg))
+ continue;
+
+ // vregLI crosses a regmask operand that clobbers preg.
+ if (!regMaskOverlaps.empty() && !regMaskOverlaps.test(preg))
+ continue;
+
+ // vregLI overlaps fixed regunit interference.
+ if (LIS->trackingRegUnits()) {
+ bool Interference = false;
+ for (MCRegUnitIterator Units(preg, tri); Units.isValid(); ++Units) {
+ if (vregLI->overlaps(LIS->getRegUnit(*Units))) {
+ Interference = true;
+ break;
+ }
+ }
+ if (Interference)
+ continue;
}
+
+ // preg is usable for this virtual register.
+ vrAllowed.push_back(preg);
}
RegSet overlappingPRegs;
@@ -239,7 +262,9 @@ std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
pregEnd = pregs.end();
pregItr != pregEnd; ++pregItr) {
unsigned preg = *pregItr;
- const LiveInterval *pregLI = &lis->getInterval(preg);
+ if (!LIS->hasInterval(preg))
+ continue;
+ const LiveInterval *pregLI = &LIS->getInterval(preg);
if (pregLI->empty()) {
continue;
@@ -249,33 +274,6 @@ std::auto_ptr<PBQPRAProblem> PBQPBuilder::build(MachineFunction *mf,
overlappingPRegs.insert(preg);
}
- // Record any overlaps with regmask operands.
- BitVector regMaskOverlaps(tri->getNumRegs());
- for (ArrayRef<SlotIndex>::iterator rmItr = regMaskSlots.begin(),
- rmEnd = regMaskSlots.end();
- rmItr != rmEnd; ++rmItr) {
- SlotIndex rmIdx = *rmItr;
- if (vregLI->liveAt(rmIdx)) {
- MachineInstr *rmMI = lis->getInstructionFromIndex(rmIdx);
- const uint32_t* regMask = 0;
- for (MachineInstr::mop_iterator mopItr = rmMI->operands_begin(),
- mopEnd = rmMI->operands_end();
- mopItr != mopEnd; ++mopItr) {
- if (mopItr->isRegMask()) {
- regMask = mopItr->getRegMask();
- break;
- }
- }
- assert(regMask != 0 && "Couldn't find register mask.");
- regMaskOverlaps.setBitsNotInMask(regMask);
- }
- }
-
- for (unsigned preg = 0; preg < tri->getNumRegs(); ++preg) {
- if (regMaskOverlaps.test(preg))
- overlappingPRegs.insert(preg);
- }
-
for (RegSet::const_iterator pregItr = overlappingPRegs.begin(),
pregEnd = overlappingPRegs.end();
pregItr != pregEnd; ++pregItr) {