// // Synthesize missing register class intersections. // // Make sure that sub-classes of RC exists such that getCommonSubClass(RC, X) // returns a maximal register class for all X. // void CodeGenRegBank::inferCommonSubClass(CodeGenRegisterClass *RC) { for (unsigned rci = 0, rce = RegClasses.size(); rci != rce; ++rci) { CodeGenRegisterClass *RC1 = RC; CodeGenRegisterClass *RC2 = RegClasses[rci]; if (RC1 == RC2) continue; // Compute the set intersection of RC1 and RC2. const CodeGenRegister::Set &Memb1 = RC1->getMembers(); const CodeGenRegister::Set &Memb2 = RC2->getMembers(); CodeGenRegister::Set Intersection; std::set_intersection(Memb1.begin(), Memb1.end(), Memb2.begin(), Memb2.end(), std::inserter(Intersection, Intersection.begin()), CodeGenRegister::Less()); // Skip disjoint class pairs. if (Intersection.empty()) continue; // If RC1 and RC2 have different spill sizes or alignments, use the // larger size for sub-classing. If they are equal, prefer RC1. if (RC2->SpillSize > RC1->SpillSize || (RC2->SpillSize == RC1->SpillSize && RC2->SpillAlignment > RC1->SpillAlignment)) std::swap(RC1, RC2); getOrCreateSubClass(RC1, &Intersection, RC1->getName() + "_and_" + RC2->getName()); } }
void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC, unsigned FirstSubRegRC) { SmallVector<std::pair<const CodeGenRegister*, const CodeGenRegister*>, 16> SSPairs; // Iterate in SubRegIndex numerical order to visit synthetic indices last. for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) { Record *SubIdx = SubRegIndices[sri]; // 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) continue; // Build list of (Super, Sub) pairs for this SubIdx. SSPairs.clear(); 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; assert(Sub && "Missing sub-register"); SSPairs.push_back(std::make_pair(Super, Sub)); } // 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]; // 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)) SubSet.insert(SSPairs[i].first); if (SubSet.empty()) continue; // RC injects completely into SubRC. if (SubSet.size() == SSPairs.size()) { 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()); } } }