mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-15 23:31:37 +00:00
Add TRI::getSubClassWithSubReg(RC, Idx) function.
This function is used to constrain a register class to a sub-class that supports the given sub-register index. For example, getSubClassWithSubReg(GR32, sub_8bit) -> GR32_ABCD. The function will be used to compute register classes when emitting INSERT_SUBREG and EXTRACT_SUBREG nodes and for register class inflation of sub-register operations. The version provided by TableGen is usually adequate, but targets can override. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@141142 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2a85015313
commit
845d2c0c77
@ -429,6 +429,20 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getSubClassWithSubReg - Returns the largest legal sub-class of RC that
|
||||||
|
/// supports the sub-register index Idx.
|
||||||
|
/// If no such sub-class exists, return NULL.
|
||||||
|
/// If all registers in RC already have an Idx sub-register, return RC.
|
||||||
|
///
|
||||||
|
/// TableGen generates a version of this function that is good enough in most
|
||||||
|
/// cases. Targets can override if they have constraints that TableGen
|
||||||
|
/// doesn't understand. For example, the x86 sub_8bit sub-register index is
|
||||||
|
/// supported by the full GR32 register class in 64-bit mode, but only by the
|
||||||
|
/// GR32_ABCD regiister class in 32-bit mode.
|
||||||
|
///
|
||||||
|
virtual const TargetRegisterClass *
|
||||||
|
getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx) const =0;
|
||||||
|
|
||||||
/// composeSubRegIndices - Return the subregister index you get from composing
|
/// composeSubRegIndices - Return the subregister index you get from composing
|
||||||
/// two subregister indices.
|
/// two subregister indices.
|
||||||
///
|
///
|
||||||
|
@ -768,23 +768,31 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
|||||||
// Find matching classes for all SRSets entries. Iterate in SubRegIndex
|
// Find matching classes for all SRSets entries. Iterate in SubRegIndex
|
||||||
// numerical order to visit synthetic indices last.
|
// numerical order to visit synthetic indices last.
|
||||||
for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
|
for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
|
||||||
SubReg2SetMap::const_iterator I = SRSets.find(SubRegIndices[sri]);
|
Record *SubIdx = SubRegIndices[sri];
|
||||||
|
SubReg2SetMap::const_iterator I = SRSets.find(SubIdx);
|
||||||
// Unsupported SubRegIndex. Skip it.
|
// Unsupported SubRegIndex. Skip it.
|
||||||
if (I == SRSets.end())
|
if (I == SRSets.end())
|
||||||
continue;
|
continue;
|
||||||
// In most cases, all RC registers support the SubRegIndex. Skip those.
|
// In most cases, all RC registers support the SubRegIndex.
|
||||||
if (I->second.size() == RC.getMembers().size())
|
if (I->second.size() == RC.getMembers().size()) {
|
||||||
|
RC.setSubClassWithSubReg(SubIdx, &RC);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// This is a real subset. See if we have a matching class.
|
// This is a real subset. See if we have a matching class.
|
||||||
CodeGenRegisterClass::Key K(&I->second, RC.SpillSize, RC.SpillAlignment);
|
CodeGenRegisterClass::Key K(&I->second, RC.SpillSize, RC.SpillAlignment);
|
||||||
RCKeyMap::const_iterator FoundI = Key2RC.find(K);
|
RCKeyMap::const_iterator FoundI = Key2RC.find(K);
|
||||||
if (FoundI != Key2RC.end())
|
if (FoundI != Key2RC.end()) {
|
||||||
|
RC.setSubClassWithSubReg(SubIdx, FoundI->second);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Class doesn't exist.
|
// Class doesn't exist.
|
||||||
addToMaps(new CodeGenRegisterClass(RC.getName() + "_with_" +
|
CodeGenRegisterClass *NewRC =
|
||||||
I->first->getName(), K));
|
new CodeGenRegisterClass(RC.getName() + "_with_" +
|
||||||
|
I->first->getName(), K);
|
||||||
|
addToMaps(NewRC);
|
||||||
|
RC.setSubClassWithSubReg(SubIdx, NewRC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,6 +101,9 @@ namespace llvm {
|
|||||||
// super-class.
|
// super-class.
|
||||||
void inheritProperties(CodeGenRegBank&);
|
void inheritProperties(CodeGenRegBank&);
|
||||||
|
|
||||||
|
// Map SubRegIndex -> sub-class
|
||||||
|
DenseMap<Record*, CodeGenRegisterClass*> SubClassWithSubReg;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned EnumValue;
|
unsigned EnumValue;
|
||||||
std::string Namespace;
|
std::string Namespace;
|
||||||
@ -145,6 +148,16 @@ namespace llvm {
|
|||||||
return SubClasses.test(RC->EnumValue);
|
return SubClasses.test(RC->EnumValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getSubClassWithSubReg - Returns the largest sub-class where all
|
||||||
|
// registers have a SubIdx sub-register.
|
||||||
|
CodeGenRegisterClass *getSubClassWithSubReg(Record *SubIdx) const {
|
||||||
|
return SubClassWithSubReg.lookup(SubIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSubClassWithSubReg(Record *SubIdx, CodeGenRegisterClass *SubRC) {
|
||||||
|
SubClassWithSubReg[SubIdx] = SubRC;
|
||||||
|
}
|
||||||
|
|
||||||
// getSubClasses - Returns a constant BitVector of subclasses indexed by
|
// getSubClasses - Returns a constant BitVector of subclasses indexed by
|
||||||
// EnumValue.
|
// EnumValue.
|
||||||
// The SubClasses vector includs an entry for this class.
|
// The SubClasses vector includs an entry for this class.
|
||||||
|
@ -426,6 +426,8 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
<< " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
|
<< " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n"
|
||||||
<< " unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;\n"
|
<< " unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;\n"
|
||||||
<< " unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
|
<< " unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
|
||||||
|
<< " const TargetRegisterClass *"
|
||||||
|
"getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n"
|
||||||
<< "};\n\n";
|
<< "};\n\n";
|
||||||
|
|
||||||
const std::vector<Record*> &SubRegIndices = RegBank.getSubRegIndices();
|
const std::vector<Record*> &SubRegIndices = RegBank.getSubRegIndices();
|
||||||
@ -802,6 +804,44 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
|||||||
}
|
}
|
||||||
OS << " }\n}\n\n";
|
OS << " }\n}\n\n";
|
||||||
|
|
||||||
|
// Emit getSubClassWithSubReg.
|
||||||
|
OS << "const TargetRegisterClass *" << ClassName
|
||||||
|
<< "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"
|
||||||
|
" const {\n";
|
||||||
|
if (SubRegIndices.empty()) {
|
||||||
|
OS << " assert(Idx == 0 && \"Target has no sub-registers\");\n"
|
||||||
|
<< " return RC;\n";
|
||||||
|
} else {
|
||||||
|
// Use the smallest type that can hold a regclass ID with room for a
|
||||||
|
// sentinel.
|
||||||
|
if (RegisterClasses.size() < UINT8_MAX)
|
||||||
|
OS << " static const uint8_t Table[";
|
||||||
|
else if (RegisterClasses.size() < UINT16_MAX)
|
||||||
|
OS << " static const uint16_t Table[";
|
||||||
|
else
|
||||||
|
throw "Too many register classes.";
|
||||||
|
OS << RegisterClasses.size() << "][" << SubRegIndices.size() << "] = {\n";
|
||||||
|
for (unsigned rci = 0, rce = RegisterClasses.size(); rci != rce; ++rci) {
|
||||||
|
const CodeGenRegisterClass &RC = *RegisterClasses[rci];
|
||||||
|
OS << " {\t// " << RC.getName() << "\n";
|
||||||
|
for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
|
||||||
|
Record *Idx = SubRegIndices[sri];
|
||||||
|
if (CodeGenRegisterClass *SRC = RC.getSubClassWithSubReg(Idx))
|
||||||
|
OS << " " << SRC->EnumValue + 1 << ",\t// " << Idx->getName()
|
||||||
|
<< " -> " << SRC->getName() << "\n";
|
||||||
|
else
|
||||||
|
OS << " 0,\t// " << Idx->getName() << "\n";
|
||||||
|
}
|
||||||
|
OS << " },\n";
|
||||||
|
}
|
||||||
|
OS << " };\n assert(RC && \"Missing regclass\");\n"
|
||||||
|
<< " if (!Idx) return RC;\n --Idx;\n"
|
||||||
|
<< " assert(Idx < " << SubRegIndices.size() << " && \"Bad subreg\");\n"
|
||||||
|
<< " unsigned TV = Table[RC->getID()][Idx];\n"
|
||||||
|
<< " return TV ? getRegClass(TV - 1) : 0;\n";
|
||||||
|
}
|
||||||
|
OS << "}\n\n";
|
||||||
|
|
||||||
// Emit the constructor of the class...
|
// Emit the constructor of the class...
|
||||||
OS << "extern MCRegisterDesc " << TargetName << "RegDesc[];\n";
|
OS << "extern MCRegisterDesc " << TargetName << "RegDesc[];\n";
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user