From 3b30bca16f7ab002bcd5058b3f3a044a267541e0 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Wed, 20 Jun 2012 22:32:05 +0000 Subject: 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 --- lib/CodeGen/RegAllocPBQP.cpp | 64 +++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 33 deletions(-) (limited to 'lib/CodeGen/RegAllocPBQP.cpp') 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 PBQPBuilder::build(MachineFunction *mf, const RegSet &vregs) { typedef std::vector LIVector; - ArrayRef regMaskSlots = lis->getRegMaskSlots(); + LiveIntervals *LIS = const_cast(lis); MachineRegisterInfo *mri = &mf->getRegInfo(); const TargetRegisterInfo *tri = mf->getTarget().getRegisterInfo(); @@ -206,7 +206,7 @@ std::auto_ptr 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 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 VRAllowed; @@ -227,9 +231,28 @@ std::auto_ptr PBQPBuilder::build(MachineFunction *mf, ArrayRef 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 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 PBQPBuilder::build(MachineFunction *mf, overlappingPRegs.insert(preg); } - // Record any overlaps with regmask operands. - BitVector regMaskOverlaps(tri->getNumRegs()); - for (ArrayRef::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) { -- cgit v1.2.3