diff options
Diffstat (limited to 'utils/TableGen/CodeGenRegisters.cpp')
| -rw-r--r-- | utils/TableGen/CodeGenRegisters.cpp | 474 |
1 files changed, 291 insertions, 183 deletions
diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 8099f134fd0ed..bef8a4b8fa12a 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -82,7 +82,7 @@ void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) { } } -unsigned CodeGenSubRegIndex::computeLaneMask() { +unsigned CodeGenSubRegIndex::computeLaneMask() const { // Already computed? if (LaneMask) return LaneMask; @@ -92,8 +92,8 @@ unsigned CodeGenSubRegIndex::computeLaneMask() { // The lane mask is simply the union of all sub-indices. unsigned M = 0; - for (CompMap::iterator I = Composed.begin(), E = Composed.end(); I != E; ++I) - M |= I->second->computeLaneMask(); + for (const auto &C : Composed) + M |= C.second->computeLaneMask(); assert(M && "Missing lane mask, sub-register cycle?"); LaneMask = M; return LaneMask; @@ -146,6 +146,7 @@ void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) { } const std::string &CodeGenRegister::getName() const { + assert(TheDef && "no def"); return TheDef->getName(); } @@ -661,7 +662,8 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) : TheDef(R), Name(R->getName()), TopoSigs(RegBank.getNumTopoSigs()), - EnumValue(-1) { + EnumValue(-1), + LaneMask(0) { // Rename anonymous register classes. if (R->getName().size() > 9 && R->getName()[9] == '.') { static unsigned AnonCounter = 0; @@ -810,34 +812,34 @@ static bool testSubClass(const CodeGenRegisterClass *A, /// Register classes with the same registers, spill size, and alignment form a /// clique. They will be ordered alphabetically. /// -static int TopoOrderRC(CodeGenRegisterClass *const *PA, - CodeGenRegisterClass *const *PB) { - const CodeGenRegisterClass *A = *PA; - const CodeGenRegisterClass *B = *PB; +static bool TopoOrderRC(const CodeGenRegisterClass &PA, + const CodeGenRegisterClass &PB) { + auto *A = &PA; + auto *B = &PB; if (A == B) return 0; // Order by ascending spill size. if (A->SpillSize < B->SpillSize) - return -1; + return true; if (A->SpillSize > B->SpillSize) - return 1; + return false; // Order by ascending spill alignment. if (A->SpillAlignment < B->SpillAlignment) - return -1; + return true; if (A->SpillAlignment > B->SpillAlignment) - return 1; + return false; // Order by descending set size. Note that the classes' allocation order may // not have been computed yet. The Members set is always vaild. if (A->getMembers().size() > B->getMembers().size()) - return -1; + return true; if (A->getMembers().size() < B->getMembers().size()) - return 1; + return false; // Finally order by name as a tie breaker. - return StringRef(A->getName()).compare(B->getName()); + return StringRef(A->getName()) < B->getName(); } std::string CodeGenRegisterClass::getQualifiedName() const { @@ -850,60 +852,60 @@ std::string CodeGenRegisterClass::getQualifiedName() const { // Compute sub-classes of all register classes. // Assume the classes are ordered topologically. void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) { - ArrayRef<CodeGenRegisterClass*> RegClasses = RegBank.getRegClasses(); + auto &RegClasses = RegBank.getRegClasses(); // Visit backwards so sub-classes are seen first. - for (unsigned rci = RegClasses.size(); rci; --rci) { - CodeGenRegisterClass &RC = *RegClasses[rci - 1]; + for (auto I = RegClasses.rbegin(), E = RegClasses.rend(); I != E; ++I) { + CodeGenRegisterClass &RC = *I; RC.SubClasses.resize(RegClasses.size()); RC.SubClasses.set(RC.EnumValue); // Normally, all subclasses have IDs >= rci, unless RC is part of a clique. - for (unsigned s = rci; s != RegClasses.size(); ++s) { - if (RC.SubClasses.test(s)) + for (auto I2 = I.base(), E2 = RegClasses.end(); I2 != E2; ++I2) { + CodeGenRegisterClass &SubRC = *I2; + if (RC.SubClasses.test(SubRC.EnumValue)) continue; - CodeGenRegisterClass *SubRC = RegClasses[s]; - if (!testSubClass(&RC, SubRC)) + if (!testSubClass(&RC, &SubRC)) continue; // SubRC is a sub-class. Grap all its sub-classes so we won't have to // check them again. - RC.SubClasses |= SubRC->SubClasses; + RC.SubClasses |= SubRC.SubClasses; } // Sweep up missed clique members. They will be immediately preceding RC. - for (unsigned s = rci - 1; s && testSubClass(&RC, RegClasses[s - 1]); --s) - RC.SubClasses.set(s - 1); + for (auto I2 = std::next(I); I2 != E && testSubClass(&RC, &*I2); ++I2) + RC.SubClasses.set(I2->EnumValue); } // Compute the SuperClasses lists from the SubClasses vectors. - for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { - const BitVector &SC = RegClasses[rci]->getSubClasses(); - for (int s = SC.find_first(); s >= 0; s = SC.find_next(s)) { - if (unsigned(s) == rci) + for (auto &RC : RegClasses) { + const BitVector &SC = RC.getSubClasses(); + auto I = RegClasses.begin(); + for (int s = 0, next_s = SC.find_first(); next_s != -1; + next_s = SC.find_next(s)) { + std::advance(I, next_s - s); + s = next_s; + if (&*I == &RC) continue; - RegClasses[s]->SuperClasses.push_back(RegClasses[rci]); + I->SuperClasses.push_back(&RC); } } // With the class hierarchy in place, let synthesized register classes inherit // properties from their closest super-class. The iteration order here can // propagate properties down multiple levels. - for (unsigned rci = 0; rci != RegClasses.size(); ++rci) - if (!RegClasses[rci]->getDef()) - RegClasses[rci]->inheritProperties(RegBank); + for (auto &RC : RegClasses) + if (!RC.getDef()) + RC.inheritProperties(RegBank); } -void -CodeGenRegisterClass::getSuperRegClasses(CodeGenSubRegIndex *SubIdx, - BitVector &Out) const { - DenseMap<CodeGenSubRegIndex*, - SmallPtrSet<CodeGenRegisterClass*, 8> >::const_iterator - FindI = SuperRegClasses.find(SubIdx); +void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx, + BitVector &Out) const { + auto FindI = SuperRegClasses.find(SubIdx); if (FindI == SuperRegClasses.end()) return; - for (SmallPtrSet<CodeGenRegisterClass*, 8>::const_iterator I = - FindI->second.begin(), E = FindI->second.end(); I != E; ++I) - Out.set((*I)->EnumValue); + for (CodeGenRegisterClass *RC : FindI->second) + Out.set(RC->EnumValue); } // Populate a unique sorted list of units from a register set. @@ -934,13 +936,12 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) { for (unsigned i = 0, e = SRIs.size(); i != e; ++i) getSubRegIdx(SRIs[i]); // Build composite maps from ComposedOf fields. - for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) - SubRegIndices[i]->updateComponents(*this); + for (auto &Idx : SubRegIndices) + Idx.updateComponents(*this); // Read in the register definitions. std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register"); std::sort(Regs.begin(), Regs.end(), LessRecordRegister()); - Registers.reserve(Regs.size()); // Assign the enumeration values. for (unsigned i = 0, e = Regs.size(); i != e; ++i) getReg(Regs[i]); @@ -949,42 +950,41 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) { std::vector<Record*> Tups = Records.getAllDerivedDefinitions("RegisterTuples"); - std::vector<Record*> TupRegsCopy; - for (unsigned i = 0, e = Tups.size(); i != e; ++i) { - const std::vector<Record*> *TupRegs = Sets.expand(Tups[i]); - TupRegsCopy.reserve(TupRegs->size()); - TupRegsCopy.assign(TupRegs->begin(), TupRegs->end()); - std::sort(TupRegsCopy.begin(), TupRegsCopy.end(), LessRecordRegister()); - for (unsigned j = 0, je = TupRegsCopy.size(); j != je; ++j) - getReg((TupRegsCopy)[j]); - TupRegsCopy.clear(); + for (Record *R : Tups) { + std::vector<Record *> TupRegs = *Sets.expand(R); + std::sort(TupRegs.begin(), TupRegs.end(), LessRecordRegister()); + for (Record *RC : TupRegs) + getReg(RC); } // Now all the registers are known. Build the object graph of explicit // register-register references. - for (unsigned i = 0, e = Registers.size(); i != e; ++i) - Registers[i]->buildObjectGraph(*this); + for (auto &Reg : Registers) + Reg.buildObjectGraph(*this); // Compute register name map. - for (unsigned i = 0, e = Registers.size(); i != e; ++i) - RegistersByName.GetOrCreateValue( - Registers[i]->TheDef->getValueAsString("AsmName"), - Registers[i]); + for (auto &Reg : Registers) + // FIXME: This could just be RegistersByName[name] = register, except that + // causes some failures in MIPS - perhaps they have duplicate register name + // entries? (or maybe there's a reason for it - I don't know much about this + // code, just drive-by refactoring) + RegistersByName.insert( + std::make_pair(Reg.TheDef->getValueAsString("AsmName"), &Reg)); // Precompute all sub-register maps. // This will create Composite entries for all inferred sub-register indices. - for (unsigned i = 0, e = Registers.size(); i != e; ++i) - Registers[i]->computeSubRegs(*this); + for (auto &Reg : Registers) + Reg.computeSubRegs(*this); // Infer even more sub-registers by combining leading super-registers. - for (unsigned i = 0, e = Registers.size(); i != e; ++i) - if (Registers[i]->CoveredBySubRegs) - Registers[i]->computeSecondarySubRegs(*this); + for (auto &Reg : Registers) + if (Reg.CoveredBySubRegs) + Reg.computeSecondarySubRegs(*this); // After the sub-register graph is complete, compute the topologically // ordered SuperRegs list. - for (unsigned i = 0, e = Registers.size(); i != e; ++i) - Registers[i]->computeSuperRegs(*this); + for (auto &Reg : Registers) + Reg.computeSuperRegs(*this); // Native register units are associated with a leaf register. They've all been // discovered now. @@ -996,35 +996,35 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) { PrintFatalError("No 'RegisterClass' subclasses defined!"); // Allocate user-defined register classes. - RegClasses.reserve(RCs.size()); - for (unsigned i = 0, e = RCs.size(); i != e; ++i) - addToMaps(new CodeGenRegisterClass(*this, RCs[i])); + for (auto *RC : RCs) { + RegClasses.push_back(CodeGenRegisterClass(*this, RC)); + addToMaps(&RegClasses.back()); + } // Infer missing classes to create a full algebra. computeInferredRegisterClasses(); // Order register classes topologically and assign enum values. - array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC); - for (unsigned i = 0, e = RegClasses.size(); i != e; ++i) - RegClasses[i]->EnumValue = i; + RegClasses.sort(TopoOrderRC); + unsigned i = 0; + for (auto &RC : RegClasses) + RC.EnumValue = i++; CodeGenRegisterClass::computeSubClasses(*this); } // Create a synthetic CodeGenSubRegIndex without a corresponding Record. CodeGenSubRegIndex* CodeGenRegBank::createSubRegIndex(StringRef Name, StringRef Namespace) { - CodeGenSubRegIndex *Idx = new CodeGenSubRegIndex(Name, Namespace, - SubRegIndices.size() + 1); - SubRegIndices.push_back(Idx); - return Idx; + SubRegIndices.emplace_back(Name, Namespace, SubRegIndices.size() + 1); + return &SubRegIndices.back(); } CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(Record *Def) { CodeGenSubRegIndex *&Idx = Def2SubRegIdx[Def]; if (Idx) return Idx; - Idx = new CodeGenSubRegIndex(Def, SubRegIndices.size() + 1); - SubRegIndices.push_back(Idx); + SubRegIndices.emplace_back(Def, SubRegIndices.size() + 1); + Idx = &SubRegIndices.back(); return Idx; } @@ -1032,14 +1032,12 @@ CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { CodeGenRegister *&Reg = Def2Reg[Def]; if (Reg) return Reg; - Reg = new CodeGenRegister(Def, Registers.size() + 1); - Registers.push_back(Reg); + Registers.emplace_back(Def, Registers.size() + 1); + Reg = &Registers.back(); return Reg; } void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) { - RegClasses.push_back(RC); - if (Record *Def = RC->getDef()) Def2RC.insert(std::make_pair(Def, RC)); @@ -1061,9 +1059,9 @@ CodeGenRegBank::getOrCreateSubClass(const CodeGenRegisterClass *RC, return FoundI->second; // Sub-class doesn't exist, create a new one. - CodeGenRegisterClass *NewRC = new CodeGenRegisterClass(*this, Name, K); - addToMaps(NewRC); - return NewRC; + RegClasses.push_back(CodeGenRegisterClass(*this, Name, K)); + addToMaps(&RegClasses.back()); + return &RegClasses.back(); } CodeGenRegisterClass *CodeGenRegBank::getRegClass(Record *Def) { @@ -1124,21 +1122,19 @@ void CodeGenRegBank::computeComposites() { // and many registers will share TopoSigs on regular architectures. BitVector TopoSigs(getNumTopoSigs()); - for (unsigned i = 0, e = Registers.size(); i != e; ++i) { - CodeGenRegister *Reg1 = Registers[i]; - + for (const auto &Reg1 : Registers) { // Skip identical subreg structures already processed. - if (TopoSigs.test(Reg1->getTopoSig())) + if (TopoSigs.test(Reg1.getTopoSig())) continue; - TopoSigs.set(Reg1->getTopoSig()); + TopoSigs.set(Reg1.getTopoSig()); - const CodeGenRegister::SubRegMap &SRM1 = Reg1->getSubRegs(); + const CodeGenRegister::SubRegMap &SRM1 = Reg1.getSubRegs(); for (CodeGenRegister::SubRegMap::const_iterator i1 = SRM1.begin(), e1 = SRM1.end(); i1 != e1; ++i1) { CodeGenSubRegIndex *Idx1 = i1->first; CodeGenRegister *Reg2 = i1->second; // Ignore identity compositions. - if (Reg1 == Reg2) + if (&Reg1 == Reg2) continue; const CodeGenRegister::SubRegMap &SRM2 = Reg2->getSubRegs(); // Try composing Idx1 with another SubRegIndex. @@ -1150,7 +1146,7 @@ void CodeGenRegBank::computeComposites() { if (Reg2 == Reg3) continue; // OK Reg1:IdxPair == Reg3. Find the index with Reg:Idx == Reg3. - CodeGenSubRegIndex *Idx3 = Reg1->getSubRegIndex(Reg3); + CodeGenSubRegIndex *Idx3 = Reg1.getSubRegIndex(Reg3); assert(Idx3 && "Sub-register doesn't have an index"); // Conflicting composition? Emit a warning but allow it. @@ -1171,15 +1167,14 @@ void CodeGenRegBank::computeComposites() { // // Conservatively share a lane mask bit if two sub-register indices overlap in // some registers, but not in others. That shouldn't happen a lot. -void CodeGenRegBank::computeSubRegIndexLaneMasks() { +void CodeGenRegBank::computeSubRegLaneMasks() { // First assign individual bits to all the leaf indices. unsigned Bit = 0; // Determine mask of lanes that cover their registers. CoveringLanes = ~0u; - for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { - CodeGenSubRegIndex *Idx = SubRegIndices[i]; - if (Idx->getComposites().empty()) { - Idx->LaneMask = 1u << Bit; + for (auto &Idx : SubRegIndices) { + if (Idx.getComposites().empty()) { + Idx.LaneMask = 1u << Bit; // Share bit 31 in the unlikely case there are more than 32 leafs. // // Sharing bits is harmless; it allows graceful degradation in targets @@ -1194,7 +1189,71 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() { // is no longer covering its registers. CoveringLanes &= ~(1u << Bit); } else { - Idx->LaneMask = 0; + Idx.LaneMask = 0; + } + } + + // Compute transformation sequences for composeSubRegIndexLaneMask. The idea + // here is that for each possible target subregister we look at the leafs + // in the subregister graph that compose for this target and create + // transformation sequences for the lanemasks. Each step in the sequence + // consists of a bitmask and a bitrotate operation. As the rotation amounts + // are usually the same for many subregisters we can easily combine the steps + // by combining the masks. + for (const auto &Idx : SubRegIndices) { + const auto &Composites = Idx.getComposites(); + auto &LaneTransforms = Idx.CompositionLaneMaskTransform; + // Go through all leaf subregisters and find the ones that compose with Idx. + // These make out all possible valid bits in the lane mask we want to + // transform. Looking only at the leafs ensure that only a single bit in + // the mask is set. + unsigned NextBit = 0; + for (auto &Idx2 : SubRegIndices) { + // Skip non-leaf subregisters. + if (!Idx2.getComposites().empty()) + continue; + // Replicate the behaviour from the lane mask generation loop above. + unsigned SrcBit = NextBit; + unsigned SrcMask = 1u << SrcBit; + if (NextBit < 31) + ++NextBit; + assert(Idx2.LaneMask == SrcMask); + + // Get the composed subregister if there is any. + auto C = Composites.find(&Idx2); + if (C == Composites.end()) + continue; + const CodeGenSubRegIndex *Composite = C->second; + // The Composed subreg should be a leaf subreg too + assert(Composite->getComposites().empty()); + + // Create Mask+Rotate operation and merge with existing ops if possible. + unsigned DstBit = Log2_32(Composite->LaneMask); + int Shift = DstBit - SrcBit; + uint8_t RotateLeft = Shift >= 0 ? (uint8_t)Shift : 32+Shift; + for (auto &I : LaneTransforms) { + if (I.RotateLeft == RotateLeft) { + I.Mask |= SrcMask; + SrcMask = 0; + } + } + if (SrcMask != 0) { + MaskRolPair MaskRol = { SrcMask, RotateLeft }; + LaneTransforms.push_back(MaskRol); + } + } + // Optimize if the transformation consists of one step only: Set mask to + // 0xffffffff (including some irrelevant invalid bits) so that it should + // merge with more entries later while compressing the table. + if (LaneTransforms.size() == 1) + LaneTransforms[0].Mask = ~0u; + + // Further compression optimization: For invalid compositions resulting + // in a sequence with 0 entries we can just pick any other. Choose + // Mask 0xffffffff with Rotation 0. + if (LaneTransforms.size() == 0) { + MaskRolPair P = { ~0u, 0 }; + LaneTransforms.push_back(P); } } @@ -1202,13 +1261,24 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() { // by the sub-register graph? This doesn't occur in any known targets. // Inherit lanes from composites. - for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { - unsigned Mask = SubRegIndices[i]->computeLaneMask(); + for (const auto &Idx : SubRegIndices) { + unsigned Mask = Idx.computeLaneMask(); // If some super-registers without CoveredBySubRegs use this index, we can // no longer assume that the lanes are covering their registers. - if (!SubRegIndices[i]->AllSuperRegsCovered) + if (!Idx.AllSuperRegsCovered) CoveringLanes &= ~Mask; } + + // Compute lane mask combinations for register classes. + for (auto &RegClass : RegClasses) { + unsigned LaneMask = 0; + for (const auto &SubRegIndex : SubRegIndices) { + if (RegClass.getSubClassWithSubReg(&SubRegIndex) != &RegClass) + continue; + LaneMask |= SubRegIndex.LaneMask; + } + RegClass.LaneMask = LaneMask; + } } namespace { @@ -1245,22 +1315,20 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets, std::vector<UberRegSet*> &RegSets, CodeGenRegBank &RegBank) { - const std::vector<CodeGenRegister*> &Registers = RegBank.getRegisters(); + const auto &Registers = RegBank.getRegisters(); // The Register EnumValue is one greater than its index into Registers. - assert(Registers.size() == Registers[Registers.size()-1]->EnumValue && + assert(Registers.size() == Registers.back().EnumValue && "register enum value mismatch"); // For simplicitly make the SetID the same as EnumValue. IntEqClasses UberSetIDs(Registers.size()+1); std::set<unsigned> AllocatableRegs; - for (unsigned i = 0, e = RegBank.getRegClasses().size(); i != e; ++i) { - - CodeGenRegisterClass *RegClass = RegBank.getRegClasses()[i]; - if (!RegClass->Allocatable) + for (auto &RegClass : RegBank.getRegClasses()) { + if (!RegClass.Allocatable) continue; - const CodeGenRegister::Set &Regs = RegClass->getMembers(); + const CodeGenRegister::Set &Regs = RegClass.getMembers(); if (Regs.empty()) continue; @@ -1275,8 +1343,8 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets, } } // Combine non-allocatable regs. - for (unsigned i = 0, e = Registers.size(); i != e; ++i) { - unsigned RegNum = Registers[i]->EnumValue; + for (const auto &Reg : Registers) { + unsigned RegNum = Reg.EnumValue; if (AllocatableRegs.count(RegNum)) continue; @@ -1290,17 +1358,17 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets, // Insert Registers into the UberSets formed by union-find. // Do not resize after this. UberSets.resize(UberSetIDs.getNumClasses()); - for (unsigned i = 0, e = Registers.size(); i != e; ++i) { - const CodeGenRegister *Reg = Registers[i]; - unsigned USetID = UberSetIDs[Reg->EnumValue]; + unsigned i = 0; + for (const CodeGenRegister &Reg : Registers) { + unsigned USetID = UberSetIDs[Reg.EnumValue]; if (!USetID) USetID = ZeroID; else if (USetID == ZeroID) USetID = 0; UberRegSet *USet = &UberSets[USetID]; - USet->Regs.insert(Reg); - RegSets[i] = USet; + USet->Regs.insert(&Reg); + RegSets[i++] = USet; } } @@ -1333,11 +1401,8 @@ static void computeUberWeights(std::vector<UberRegSet> &UberSets, if (I->Weight != MaxWeight) { DEBUG( dbgs() << "UberSet " << I - UberSets.begin() << " Weight " << MaxWeight; - for (CodeGenRegister::Set::iterator - UnitI = I->Regs.begin(), UnitE = I->Regs.end(); - UnitI != UnitE; ++UnitI) { - dbgs() << " " << (*UnitI)->getName(); - } + for (auto &Unit : I->Regs) + dbgs() << " " << Unit->getName(); dbgs() << "\n"); // Update the set weight. I->Weight = MaxWeight; @@ -1438,11 +1503,11 @@ void CodeGenRegBank::computeRegUnitWeights() { for (bool Changed = true; Changed; ++NumIters) { assert(NumIters <= NumNativeRegUnits && "Runaway register unit weights"); Changed = false; - for (unsigned i = 0, e = Registers.size(); i != e; ++i) { + for (auto &Reg : Registers) { CodeGenRegister::RegUnitList NormalUnits; std::set<unsigned> NormalRegs; - Changed |= normalizeWeight(Registers[i], UberSets, RegSets, - NormalRegs, NormalUnits, *this); + Changed |= normalizeWeight(&Reg, UberSets, RegSets, NormalRegs, + NormalUnits, *this); } } } @@ -1533,18 +1598,17 @@ void CodeGenRegBank::computeRegUnitSets() { assert(RegUnitSets.empty() && "dirty RegUnitSets"); // Compute a unique RegUnitSet for each RegClass. - const ArrayRef<CodeGenRegisterClass*> &RegClasses = getRegClasses(); - unsigned NumRegClasses = RegClasses.size(); - for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) { - if (!RegClasses[RCIdx]->Allocatable) + auto &RegClasses = getRegClasses(); + for (auto &RC : RegClasses) { + if (!RC.Allocatable) continue; // Speculatively grow the RegUnitSets to hold the new set. RegUnitSets.resize(RegUnitSets.size() + 1); - RegUnitSets.back().Name = RegClasses[RCIdx]->getName(); + RegUnitSets.back().Name = RC.getName(); // Compute a sorted list of units in this class. - RegClasses[RCIdx]->buildRegUnitSet(RegUnitSets.back().Units); + RC.buildRegUnitSet(RegUnitSets.back().Units); // Find an existing RegUnitSet. std::vector<RegUnitSet>::const_iterator SetI = @@ -1558,9 +1622,8 @@ void CodeGenRegBank::computeRegUnitSets() { USIdx < USEnd; ++USIdx) { dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":"; - ArrayRef<unsigned> Units = RegUnitSets[USIdx].Units; - for (unsigned i = 0, e = Units.size(); i < e; ++i) - dbgs() << " " << RegUnits[Units[i]].Roots[0]->getName(); + for (auto &U : RegUnitSets[USIdx].Units) + dbgs() << " " << RegUnits[U].Roots[0]->getName(); dbgs() << "\n"; }); @@ -1572,9 +1635,8 @@ void CodeGenRegBank::computeRegUnitSets() { USIdx < USEnd; ++USIdx) { dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":"; - ArrayRef<unsigned> Units = RegUnitSets[USIdx].Units; - for (unsigned i = 0, e = Units.size(); i < e; ++i) - dbgs() << " " << RegUnits[Units[i]].Roots[0]->getName(); + for (auto &U : RegUnitSets[USIdx].Units) + dbgs() << " " << RegUnits[U].Roots[0]->getName(); dbgs() << "\n"; } dbgs() << "\nUnion sets:\n"); @@ -1619,9 +1681,8 @@ void CodeGenRegBank::computeRegUnitSets() { else { DEBUG(dbgs() << "UnitSet " << RegUnitSets.size()-1 << " " << RegUnitSets.back().Name << ":"; - ArrayRef<unsigned> Units = RegUnitSets.back().Units; - for (unsigned i = 0, e = Units.size(); i < e; ++i) - dbgs() << " " << RegUnits[Units[i]].Roots[0]->getName(); + for (auto &U : RegUnitSets.back().Units) + dbgs() << " " << RegUnits[U].Roots[0]->getName(); dbgs() << "\n";); } } @@ -1635,29 +1696,30 @@ void CodeGenRegBank::computeRegUnitSets() { USIdx < USEnd; ++USIdx) { dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":"; - ArrayRef<unsigned> Units = RegUnitSets[USIdx].Units; - for (unsigned i = 0, e = Units.size(); i < e; ++i) - dbgs() << " " << RegUnits[Units[i]].Roots[0]->getName(); + for (auto &U : RegUnitSets[USIdx].Units) + dbgs() << " " << RegUnits[U].Roots[0]->getName(); dbgs() << "\n"; }); // For each register class, list the UnitSets that are supersets. - RegClassUnitSets.resize(NumRegClasses); - for (unsigned RCIdx = 0, RCEnd = NumRegClasses; RCIdx != RCEnd; ++RCIdx) { - if (!RegClasses[RCIdx]->Allocatable) + RegClassUnitSets.resize(RegClasses.size()); + int RCIdx = -1; + for (auto &RC : RegClasses) { + ++RCIdx; + if (!RC.Allocatable) continue; // Recompute the sorted list of units in this class. std::vector<unsigned> RCRegUnits; - RegClasses[RCIdx]->buildRegUnitSet(RCRegUnits); + RC.buildRegUnitSet(RCRegUnits); // Don't increase pressure for unallocatable regclasses. if (RCRegUnits.empty()) continue; - DEBUG(dbgs() << "RC " << RegClasses[RCIdx]->getName() << " Units: \n"; - for (unsigned i = 0, e = RCRegUnits.size(); i < e; ++i) - dbgs() << RegUnits[RCRegUnits[i]].getRoots()[0]->getName() << " "; + DEBUG(dbgs() << "RC " << RC.getName() << " Units: \n"; + for (auto &U : RCRegUnits) + dbgs() << RegUnits[U].getRoots()[0]->getName() << " "; dbgs() << "\n UnitSetIDs:"); // Find all supersets. @@ -1702,9 +1764,44 @@ void CodeGenRegBank::computeRegUnitSets() { } } +void CodeGenRegBank::computeRegUnitLaneMasks() { + for (auto &Register : Registers) { + // Create an initial lane mask for all register units. + const auto &RegUnits = Register.getRegUnits(); + CodeGenRegister::RegUnitLaneMaskList RegUnitLaneMasks(RegUnits.size(), 0); + // Iterate through SubRegisters. + typedef CodeGenRegister::SubRegMap SubRegMap; + const SubRegMap &SubRegs = Register.getSubRegs(); + for (SubRegMap::const_iterator S = SubRegs.begin(), + SE = SubRegs.end(); S != SE; ++S) { + CodeGenRegister *SubReg = S->second; + // Ignore non-leaf subregisters, their lane masks are fully covered by + // the leaf subregisters anyway. + if (SubReg->getSubRegs().size() != 0) + continue; + CodeGenSubRegIndex *SubRegIndex = S->first; + const CodeGenRegister *SubRegister = S->second; + unsigned LaneMask = SubRegIndex->LaneMask; + // Distribute LaneMask to Register Units touched. + for (const auto &SUI : SubRegister->getRegUnits()) { + bool Found = false; + for (size_t u = 0, ue = RegUnits.size(); u < ue; ++u) { + if (SUI == RegUnits[u]) { + RegUnitLaneMasks[u] |= LaneMask; + assert(!Found); + Found = true; + } + } + assert(Found); + } + } + Register.setRegUnitLaneMasks(RegUnitLaneMasks); + } +} + void CodeGenRegBank::computeDerivedInfo() { computeComposites(); - computeSubRegIndexLaneMasks(); + computeSubRegLaneMasks(); // Compute a weight for each register unit created during getSubRegs. // This may create adopted register units (with unit # >= NumNativeRegUnits). @@ -1714,6 +1811,8 @@ void CodeGenRegBank::computeDerivedInfo() { // supersets for the union of overlapping sets. computeRegUnitSets(); + computeRegUnitLaneMasks(); + // Get the weight of each set. for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) RegUnitSets[Idx].Weight = getRegUnitSetWeight(RegUnitSets[Idx].Units); @@ -1740,9 +1839,13 @@ void CodeGenRegBank::computeDerivedInfo() { // returns a maximal register class for all X. // void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) { - for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) { + assert(!RegClasses.empty()); + // Stash the iterator to the last element so that this loop doesn't visit + // elements added by the getOrCreateSubClass call within it. + for (auto I = RegClasses.begin(), E = std::prev(RegClasses.end()); + I != std::next(E); ++I) { CodeGenRegisterClass *RC1 = RC; - CodeGenRegisterClass *RC2 = RegClasses[rci]; + CodeGenRegisterClass *RC2 = &*I; if (RC1 == RC2) continue; @@ -1779,7 +1882,7 @@ void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) { // void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) { // Map SubRegIndex to set of registers in RC supporting that SubRegIndex. - typedef std::map<CodeGenSubRegIndex*, CodeGenRegister::Set, + typedef std::map<const CodeGenSubRegIndex *, CodeGenRegister::Set, CodeGenSubRegIndex::Less> SubReg2SetMap; // Compute the set of registers supporting each SubRegIndex. @@ -1794,22 +1897,21 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) { // Find matching classes for all SRSets entries. Iterate in SubRegIndex // numerical order to visit synthetic indices last. - for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) { - CodeGenSubRegIndex *SubIdx = SubRegIndices[sri]; - SubReg2SetMap::const_iterator I = SRSets.find(SubIdx); + for (const auto &SubIdx : SubRegIndices) { + SubReg2SetMap::const_iterator I = SRSets.find(&SubIdx); // Unsupported SubRegIndex. Skip it. if (I == SRSets.end()) continue; // In most cases, all RC registers support the SubRegIndex. if (I->second.size() == RC->getMembers().size()) { - RC->setSubClassWithSubReg(SubIdx, RC); + RC->setSubClassWithSubReg(&SubIdx, RC); continue; } // This is a real subset. See if we have a matching class. CodeGenRegisterClass *SubRC = getOrCreateSubClass(RC, &I->second, RC->getName() + "_with_" + I->first->getName()); - RC->setSubClassWithSubReg(SubIdx, SubRC); + RC->setSubClassWithSubReg(&SubIdx, SubRC); } } @@ -1821,18 +1923,17 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) { // void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC, - unsigned FirstSubRegRC) { + std::list<CodeGenRegisterClass>::iterator FirstSubRegRC) { SmallVector<std::pair<const CodeGenRegister*, const CodeGenRegister*>, 16> SSPairs; BitVector TopoSigs(getNumTopoSigs()); // Iterate in SubRegIndex numerical order to visit synthetic indices last. - for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) { - CodeGenSubRegIndex *SubIdx = SubRegIndices[sri]; + for (auto &SubIdx : SubRegIndices) { // Skip indexes that aren't fully supported by RC's registers. This was // computed by inferSubClassWithSubReg() above which should have been // called first. - if (RC->getSubClassWithSubReg(SubIdx) != RC) + if (RC->getSubClassWithSubReg(&SubIdx) != RC) continue; // Build list of (Super, Sub) pairs for this SubIdx. @@ -1841,7 +1942,7 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC, for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(), RE = RC->getMembers().end(); RI != RE; ++RI) { const CodeGenRegister *Super = *RI; - const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second; + const CodeGenRegister *Sub = Super->getSubRegs().find(&SubIdx)->second; assert(Sub && "Missing sub-register"); SSPairs.push_back(std::make_pair(Super, Sub)); TopoSigs.set(Sub->getTopoSig()); @@ -1849,29 +1950,32 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC, // Iterate over sub-register class candidates. Ignore classes created by // this loop. They will never be useful. - for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce; - ++rci) { - CodeGenRegisterClass *SubRC = RegClasses[rci]; + // Store an iterator to the last element (not end) so that this loop doesn't + // visit newly inserted elements. + assert(!RegClasses.empty()); + for (auto I = FirstSubRegRC, E = std::prev(RegClasses.end()); + I != std::next(E); ++I) { + CodeGenRegisterClass &SubRC = *I; // Topological shortcut: SubRC members have the wrong shape. - if (!TopoSigs.anyCommon(SubRC->getTopoSigs())) + if (!TopoSigs.anyCommon(SubRC.getTopoSigs())) continue; // Compute the subset of RC that maps into SubRC. CodeGenRegister::Set SubSet; for (unsigned i = 0, e = SSPairs.size(); i != e; ++i) - if (SubRC->contains(SSPairs[i].second)) + if (SubRC.contains(SSPairs[i].second)) SubSet.insert(SSPairs[i].first); if (SubSet.empty()) continue; // RC injects completely into SubRC. if (SubSet.size() == SSPairs.size()) { - SubRC->addSuperRegClass(SubIdx, RC); + SubRC.addSuperRegClass(&SubIdx, RC); continue; } // Only a subset of RC maps into SubRC. Make sure it is represented by a // class. - getOrCreateSubClass(RC, &SubSet, RC->getName() + - "_with_" + SubIdx->getName() + - "_in_" + SubRC->getName()); + getOrCreateSubClass(RC, &SubSet, RC->getName() + "_with_" + + SubIdx.getName() + "_in_" + + SubRC.getName()); } } } @@ -1881,14 +1985,19 @@ void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC, // Infer missing register classes. // void CodeGenRegBank::computeInferredRegisterClasses() { + assert(!RegClasses.empty()); // When this function is called, the register classes have not been sorted // and assigned EnumValues yet. That means getSubClasses(), // getSuperClasses(), and hasSubClass() functions are defunct. - unsigned FirstNewRC = RegClasses.size(); + + // Use one-before-the-end so it doesn't move forward when new elements are + // added. + auto FirstNewRC = std::prev(RegClasses.end()); // Visit all register classes, including the ones being added by the loop. - for (unsigned rci = 0; rci != RegClasses.size(); ++rci) { - CodeGenRegisterClass *RC = RegClasses[rci]; + // Watch out for iterator invalidation here. + for (auto I = RegClasses.begin(), E = RegClasses.end(); I != E; ++I) { + CodeGenRegisterClass *RC = &*I; // Synthesize answers for getSubClassWithSubReg(). inferSubClassWithSubReg(RC); @@ -1905,10 +2014,11 @@ void CodeGenRegBank::computeInferredRegisterClasses() { // after inferMatchingSuperRegClass was called. At this point, // inferMatchingSuperRegClass has checked SuperRC = [0..rci] with SubRC = // [0..FirstNewRC). We need to cover SubRC = [FirstNewRC..rci]. - if (rci + 1 == FirstNewRC) { - unsigned NextNewRC = RegClasses.size(); - for (unsigned rci2 = 0; rci2 != FirstNewRC; ++rci2) - inferMatchingSuperRegClass(RegClasses[rci2], FirstNewRC); + if (I == FirstNewRC) { + auto NextNewRC = std::prev(RegClasses.end()); + for (auto I2 = RegClasses.begin(), E2 = std::next(FirstNewRC); I2 != E2; + ++I2) + inferMatchingSuperRegClass(&*I2, E2); FirstNewRC = NextNewRC; } } @@ -1922,10 +2032,8 @@ void CodeGenRegBank::computeInferredRegisterClasses() { const CodeGenRegisterClass* CodeGenRegBank::getRegClassForRegister(Record *R) { const CodeGenRegister *Reg = getReg(R); - ArrayRef<CodeGenRegisterClass*> RCs = getRegClasses(); const CodeGenRegisterClass *FoundRC = nullptr; - for (unsigned i = 0, e = RCs.size(); i != e; ++i) { - const CodeGenRegisterClass &RC = *RCs[i]; + for (const auto &RC : getRegClasses()) { if (!RC.contains(Reg)) continue; |
