Add sub-registers sets.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36278 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2007-04-20 21:13:46 +00:00
parent a92d62c15f
commit 3cafbf7e5f
2 changed files with 77 additions and 7 deletions

View File

@ -41,9 +41,14 @@ class Register<string n> {
// Aliases - A list of registers that this register overlaps with. A read or
// modification of this register can potentially read or modify the aliased
// registers.
//
list<Register> Aliases = [];
// SubRegs - A list of registers that are parts of this register. Note these
// are "immediate" sub-registers and the registers within the list do not
// themselves overlap. e.g. For X86, EAX's SubRegs list contains only [AX],
// not [AX, AH, AL].
list<Register> SubRegs = [];
// DwarfNumber - Number used internally by gcc/gdb to identify the register.
// These values can be determined by locating the <target>.h file in the
// directory llvmgcc/gcc/config/<target>/ and looking for REGISTER_NAMES. The
@ -52,6 +57,16 @@ class Register<string n> {
int DwarfNumber = -1;
}
// RegisterWithSubRegs - This can be used to define instances of Register which
// need to specify sub-registers.
// List "subregs" specifies which registers are sub-registers to this one. This
// is used to populate the SubRegs and AliasSet fields of TargetRegisterDesc.
// This allows the code generator to be careful not to put two values with
// overlapping live ranges into registers which alias.
class RegisterWithSubRegs<string n, list<Register> subregs> : Register<n> {
let SubRegs = subregs;
}
// RegisterGroup - This can be used to define instances of Register which
// need to specify aliases.
// List "aliases" specifies which registers are aliased to this one. This

View File

@ -107,6 +107,27 @@ bool isSubRegisterClass(const CodeGenRegisterClass &RC,
return true;
}
static void addSubReg(Record *R, Record *S,
std::map<Record*, std::set<Record*> > &SubRegs,
std::map<Record*, std::set<Record*> > &Aliases,
RegisterInfoEmitter &RIE) {
if (R == S) {
cerr << "Error: recursive sub-register relationship between"
<< " register " << RIE.getQualifiedName(R)
<< " and its sub-registers?\n";
abort();
}
if (!SubRegs[R].insert(S).second)
return;
Aliases[R].insert(S);
Aliases[S].insert(R);
if (SubRegs.count(S))
for (std::set<Record*>::iterator I = SubRegs[S].begin(),
E = SubRegs[S].end(); I != E; ++I)
addSubReg(R, *I, SubRegs, Aliases, RIE);
}
// RegisterInfoEmitter::run - Main register file description emitter.
//
void RegisterInfoEmitter::run(std::ostream &OS) {
@ -273,7 +294,8 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
<< "RegClass,\n";
OS << " };\n";
// Emit register class aliases...
// Emit register sub-registers / aliases...
std::map<Record*, std::set<Record*> > RegisterSubRegs;
std::map<Record*, std::set<Record*> > RegisterAliases;
const std::vector<CodeGenRegister> &Regs = Target.getRegisters();
@ -298,6 +320,20 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
}
}
for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
Record *R = Regs[i].TheDef;
std::vector<Record*> LI = Regs[i].TheDef->getValueAsListOfDefs("SubRegs");
// Process sub-register set and add aliases information.
for (unsigned j = 0, e = LI.size(); j != e; ++j) {
Record *SubReg = LI[j];
if (RegisterSubRegs[R].count(SubReg))
cerr << "Warning: register " << getQualifiedName(SubReg)
<< " specified as a sub-register of " << getQualifiedName(R)
<< " multiple times!\n";
addSubReg(R, SubReg, RegisterSubRegs, RegisterAliases, *this);
}
}
if (!RegisterAliases.empty())
OS << "\n\n // Register Alias Sets...\n";
@ -314,12 +350,27 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
OS << "0 };\n";
}
if (!RegisterSubRegs.empty())
OS << "\n\n // Register Sub-registers Sets...\n";
// Emit the empty sub-registers list
OS << " const unsigned Empty_SubRegsSet[] = { 0 };\n";
// Loop over all of the registers which have sub-registers, emitting the
// sub-registers list to memory.
for (std::map<Record*, std::set<Record*> >::iterator
I = RegisterSubRegs.begin(), E = RegisterSubRegs.end(); I != E; ++I) {
OS << " const unsigned " << I->first->getName() << "_SubRegsSet[] = { ";
for (std::set<Record*>::iterator ASI = I->second.begin(),
E = I->second.end(); ASI != E; ++ASI)
OS << getQualifiedName(*ASI) << ", ";
OS << "0 };\n";
}
OS<<"\n const TargetRegisterDesc RegisterDescriptors[] = { // Descriptors\n";
OS << " { \"NOREG\",\t0 },\n";
OS << " { \"NOREG\",\t0,\t0 },\n";
// Now that register alias sets have been emitted, emit the register
// descriptors now.
// Now that register alias and sub-registers sets have been emitted, emit the
// register descriptors now.
const std::vector<CodeGenRegister> &Registers = Target.getRegisters();
for (unsigned i = 0, e = Registers.size(); i != e; ++i) {
const CodeGenRegister &Reg = Registers[i];
@ -330,9 +381,13 @@ void RegisterInfoEmitter::run(std::ostream &OS) {
OS << Reg.getName();
OS << "\",\t";
if (RegisterAliases.count(Reg.TheDef))
OS << Reg.getName() << "_AliasSet },\n";
OS << Reg.getName() << "_AliasSet,\t";
else
OS << "Empty_AliasSet },\n";
OS << "Empty_AliasSet,\t";
if (RegisterSubRegs.count(Reg.TheDef))
OS << Reg.getName() << "_SubRegsSet },\n";
else
OS << "Empty_SubRegsSet },\n";
}
OS << " };\n"; // End of register descriptors...
OS << "}\n\n"; // End of anonymous namespace...