void RegisterBank::verify(const TargetRegisterInfo &TRI) const { assert(isValid() && "Invalid register bank"); assert(ContainedRegClasses.size() == TRI.getNumRegClasses() && "TRI does not match the initialization process?"); for (unsigned RCId = 0, End = TRI.getNumRegClasses(); RCId != End; ++RCId) { const TargetRegisterClass &RC = *TRI.getRegClass(RCId); if (!covers(RC)) continue; // Verify that the register bank covers all the sub classes of the // classes it covers. // Use a different (slow in that case) method than // RegisterBankInfo to find the subclasses of RC, to make sure // both agree on the covers. for (unsigned SubRCId = 0; SubRCId != End; ++SubRCId) { const TargetRegisterClass &SubRC = *TRI.getRegClass(RCId); if (!RC.hasSubClassEq(&SubRC)) continue; // Verify that the Size of the register bank is big enough to cover // all the register classes it covers. assert((getSize() >= SubRC.getSize() * 8) && "Size is not big enough for all the subclasses!"); assert(covers(SubRC) && "Not all subclasses are covered"); } } }
MachineRegisterInfo::MachineRegisterInfo(const TargetRegisterInfo &TRI) { VRegInfo.reserve(256); RegAllocHints.reserve(256); RegClass2VRegMap = new std::vector<unsigned>[TRI.getNumRegClasses()]; UsedPhysRegs.resize(TRI.getNumRegs()); // Create the physreg use/def lists. PhysRegUseDefLists = new MachineOperand*[TRI.getNumRegs()]; memset(PhysRegUseDefLists, 0, sizeof(MachineOperand*)*TRI.getNumRegs()); }
void RegisterBankInfo::addRegBankCoverage(unsigned ID, unsigned RCId, const TargetRegisterInfo &TRI, bool AddTypeMapping) { RegisterBank &RB = getRegBank(ID); unsigned NbOfRegClasses = TRI.getNumRegClasses(); DEBUG(dbgs() << "Add coverage for: " << RB << '\n'); // Check if RB is underconstruction. if (!RB.isValid()) RB.ContainedRegClasses.resize(NbOfRegClasses); else if (RB.covers(*TRI.getRegClass(RCId))) // If RB already covers this register class, there is nothing // to do. return; BitVector &Covered = RB.ContainedRegClasses; SmallVector<unsigned, 8> WorkList; WorkList.push_back(RCId); Covered.set(RCId); unsigned &MaxSize = RB.Size; do { unsigned RCId = WorkList.pop_back_val(); const TargetRegisterClass &CurRC = *TRI.getRegClass(RCId); DEBUG(dbgs() << "Examine: " << TRI.getRegClassName(&CurRC) << "(Size*8: " << (CurRC.getSize() * 8) << ")\n"); // Remember the biggest size in bits. MaxSize = std::max(MaxSize, CurRC.getSize() * 8); // If we have been asked to record the type supported by this // register bank, do it now. if (AddTypeMapping) for (MVT::SimpleValueType SVT : make_range(CurRC.vt_begin(), CurRC.vt_end())) recordRegBankForType(getRegBank(ID), SVT); // Walk through all sub register classes and push them into the worklist. bool First = true; for (BitMaskClassIterator It(CurRC.getSubClassMask(), TRI); It.isValid(); ++It) { unsigned SubRCId = It.getID(); if (!Covered.test(SubRCId)) { if (First) DEBUG(dbgs() << " Enqueue sub-class: "); DEBUG(dbgs() << TRI.getRegClassName(TRI.getRegClass(SubRCId)) << ", "); WorkList.push_back(SubRCId); // Remember that we saw the sub class. Covered.set(SubRCId); First = false; } } if (!First) DEBUG(dbgs() << '\n'); // Push also all the register classes that can be accessed via a // subreg index, i.e., its subreg-class (which is different than // its subclass). // // Note: It would probably be faster to go the other way around // and have this method add only super classes, since this // information is available in a more efficient way. However, it // feels less natural for the client of this APIs plus we will // TableGen the whole bitset at some point, so compile time for // the initialization is not very important. First = true; for (unsigned SubRCId = 0; SubRCId < NbOfRegClasses; ++SubRCId) { if (Covered.test(SubRCId)) continue; bool Pushed = false; const TargetRegisterClass *SubRC = TRI.getRegClass(SubRCId); for (SuperRegClassIterator SuperRCIt(SubRC, &TRI); SuperRCIt.isValid(); ++SuperRCIt) { if (Pushed) break; for (BitMaskClassIterator It(SuperRCIt.getMask(), TRI); It.isValid(); ++It) { unsigned SuperRCId = It.getID(); if (SuperRCId == RCId) { if (First) DEBUG(dbgs() << " Enqueue subreg-class: "); DEBUG(dbgs() << TRI.getRegClassName(SubRC) << ", "); WorkList.push_back(SubRCId); // Remember that we saw the sub class. Covered.set(SubRCId); Pushed = true; First = false; break; } } } } if (!First) DEBUG(dbgs() << '\n'); } while (!WorkList.empty()); }