From b3acdcc00c9dfb01663780e858e586cc5f04423f Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Thu, 1 Mar 2012 17:30:39 +0000 Subject: [PATCH 1/1] Move TargetRegisterInfo::getSubReg() to MCRegisterInfo. Allows us to de-virtualize the function and provides access to it in the instruction printer, which is useful for handling composite physical registers (e.g., ARM register lists). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@151815 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCRegisterInfo.h | 16 +++- include/llvm/Target/TargetRegisterInfo.h | 5 -- utils/TableGen/RegisterInfoEmitter.cpp | 107 ++++++++++++----------- 3 files changed, 71 insertions(+), 57 deletions(-) diff --git a/include/llvm/MC/MCRegisterInfo.h b/include/llvm/MC/MCRegisterInfo.h index b1f494277ce..2595e4fda08 100644 --- a/include/llvm/MC/MCRegisterInfo.h +++ b/include/llvm/MC/MCRegisterInfo.h @@ -136,6 +136,9 @@ private: const unsigned *Overlaps; // Pointer to the overlaps array const unsigned *SubRegs; // Pointer to the subregs array const unsigned *SuperRegs; // Pointer to the superregs array + const unsigned short *SubRegIndices; // Pointer to the subreg lookup + // array. + unsigned NumSubRegIndices; // Number of subreg indices. DenseMap L2DwarfRegs; // LLVM to Dwarf regs mapping DenseMap EHL2DwarfRegs; // LLVM to Dwarf regs mapping EH DenseMap Dwarf2LRegs; // Dwarf to LLVM regs mapping @@ -148,7 +151,9 @@ public: void InitMCRegisterInfo(const MCRegisterDesc *D, unsigned NR, unsigned RA, const MCRegisterClass *C, unsigned NC, const unsigned *O, const unsigned *Sub, - const unsigned *Super) { + const unsigned *Super, + const unsigned short *SubIndices, + unsigned NumIndices) { Desc = D; NumRegs = NR; RAReg = RA; @@ -157,6 +162,8 @@ public: SubRegs = Sub; SuperRegs = Super; NumClasses = NC; + SubRegIndices = SubIndices; + NumSubRegIndices = NumIndices; } /// mapLLVMRegToDwarfReg - Used to initialize LLVM register to Dwarf @@ -234,6 +241,13 @@ public: return SubRegs + get(RegNo).SubRegs; } + /// getSubReg - Returns the physical register number of sub-register "Index" + /// for physical register RegNo. Return zero if the sub-register does not + /// exist. + unsigned getSubReg(unsigned Reg, unsigned Idx) const { + return *(SubRegIndices + (Reg - 1) * NumSubRegIndices + Idx - 1); + } + /// getSuperRegisters - Return the list of registers that are super-registers /// of the specified register, or a null list of there are none. The list /// returned is zero terminated and sorted according to super-sub register diff --git a/include/llvm/Target/TargetRegisterInfo.h b/include/llvm/Target/TargetRegisterInfo.h index 9f18fc1e4dc..57553c68783 100644 --- a/include/llvm/Target/TargetRegisterInfo.h +++ b/include/llvm/Target/TargetRegisterInfo.h @@ -383,11 +383,6 @@ public: /// used by register scavenger to determine what registers are free. virtual BitVector getReservedRegs(const MachineFunction &MF) const = 0; - /// getSubReg - Returns the physical register number of sub-register "Index" - /// for physical register RegNo. Return zero if the sub-register does not - /// exist. - virtual unsigned getSubReg(unsigned RegNo, unsigned Index) const = 0; - /// getSubRegIndex - For a given register pair, return the sub-register index /// if the second register is a sub-register of the first. Return zero /// otherwise. diff --git a/utils/TableGen/RegisterInfoEmitter.cpp b/utils/TableGen/RegisterInfoEmitter.cpp index 7171e50dc35..5ccfad8b403 100644 --- a/utils/TableGen/RegisterInfoEmitter.cpp +++ b/utils/TableGen/RegisterInfoEmitter.cpp @@ -411,6 +411,38 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "};\n\n"; + // Emit the data table for getSubReg(). + ArrayRef SubRegIndices = RegBank.getSubRegIndices(); + if (SubRegIndices.size()) { + OS << "const unsigned short " << TargetName << "SubRegTable[][" + << SubRegIndices.size() << "] = {\n"; + for (unsigned i = 0, e = Regs.size(); i != e; ++i) { + const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs(); + OS << " /* " << Regs[i]->TheDef->getName() << " */\n"; + if (SRM.empty()) { + OS << " {0},\n"; + continue; + } + OS << " {"; + for (unsigned j = 0, je = SubRegIndices.size(); j != je; ++j) { + // FIXME: We really should keep this to 80 columns... + CodeGenRegister::SubRegMap::const_iterator SubReg = + SRM.find(SubRegIndices[j]); + if (SubReg != SRM.end()) + OS << getQualifiedName(SubReg->second->TheDef); + else + OS << "0"; + if (j != je - 1) + OS << ", "; + } + OS << "}" << (i != e ? "," : "") << "\n"; + } + OS << "};\n\n"; + OS << "const unsigned short *get" << TargetName + << "SubRegTable() {\n return (const unsigned short *)" << TargetName + << "SubRegTable;\n}\n\n"; + } + // MCRegisterInfo initialization routine. OS << "static inline void Init" << TargetName << "MCRegisterInfo(MCRegisterInfo *RI, unsigned RA, " @@ -418,13 +450,17 @@ RegisterInfoEmitter::runMCDesc(raw_ostream &OS, CodeGenTarget &Target, OS << " RI->InitMCRegisterInfo(" << TargetName << "RegDesc, " << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " << RegisterClasses.size() << ", " << TargetName << "RegOverlaps, " - << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet);\n\n"; + << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet, "; + if (SubRegIndices.size() != 0) + OS << "(unsigned short*)" << TargetName << "SubRegTable, " + << SubRegIndices.size() << ");\n\n"; + else + OS << "NULL, 0);\n\n"; EmitRegMapping(OS, Regs, false); OS << "}\n\n"; - OS << "} // End llvm namespace \n"; OS << "#endif // GET_REGINFO_MC_DESC\n\n"; } @@ -450,7 +486,6 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target, << "(unsigned RA, unsigned D = 0, unsigned E = 0);\n" << " virtual bool needsStackRealignment(const MachineFunction &) const\n" << " { return false; }\n" - << " unsigned getSubReg(unsigned RegNo, unsigned Index) const;\n" << " unsigned getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const;\n" << " unsigned composeSubRegIndices(unsigned, unsigned) const;\n" << " const TargetRegisterClass *" @@ -731,52 +766,12 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, std::string ClassName = Target.getName() + "GenRegisterInfo"; - // Emit the data table for getSubReg(). - if (SubRegIndices.size()) { - OS << "static const unsigned short " << TargetName << "SubRegTable[][" - << SubRegIndices.size() << "] = {\n"; - for (unsigned i = 0, e = Regs.size(); i != e; ++i) { - const CodeGenRegister::SubRegMap &SRM = Regs[i]->getSubRegs(); - OS << " /* " << Regs[i]->TheDef->getName() << " */\n"; - if (SRM.empty()) { - OS << " {0},\n"; - continue; - } - OS << " {"; - for (unsigned j = 0, je = SubRegIndices.size(); j != je; ++j) { - // FIXME: We really should keep this to 80 columns... - CodeGenRegister::SubRegMap::const_iterator SubReg = - SRM.find(SubRegIndices[j]); - if (SubReg != SRM.end()) - OS << getQualifiedName(SubReg->second->TheDef); - else - OS << "0"; - if (j != je - 1) - OS << ", "; - } - OS << "}" << (i != e ? "," : "") << "\n"; - } - OS << "};\n\n"; - } - - // Emit the subregister + index mapping function based on the information - // calculated above. - OS << "unsigned " << ClassName - << "::getSubReg(unsigned RegNo, unsigned Index) const {\n" - << " assert(RegNo > 0 && Index > 0 && \"invalid subreg query!\");\n"; - if (SubRegIndices.size()) - OS << " return " << TargetName << "SubRegTable[RegNo - 1][Index - 1];\n" - << "}\n\n"; - else - OS << " return 0;\n}\n\n"; - OS << "unsigned " << ClassName << "::getSubRegIndex(unsigned RegNo, unsigned SubRegNo) const {\n"; if (SubRegIndices.size()) { - OS << " for (unsigned I = 0; I != array_lengthof(" - << TargetName << "SubRegTable[0]); ++I)\n" - << " if (" << TargetName << "SubRegTable[RegNo - 1][I] == SubRegNo)\n" - << " return I + 1;\n"; + OS << " for (unsigned I = 1; I <= " << SubRegIndices.size() << "; ++I)\n" + << " if (getSubReg(RegNo, I) == SubRegNo)\n" + << " return I;\n"; } OS << " return 0;\n"; OS << "}\n\n"; @@ -893,16 +888,26 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, OS << "extern const unsigned " << TargetName << "RegOverlaps[];\n"; OS << "extern const unsigned " << TargetName << "SubRegsSet[];\n"; OS << "extern const unsigned " << TargetName << "SuperRegsSet[];\n"; + if (SubRegIndices.size() != 0) + OS << "extern const unsigned short *get" << TargetName + << "SubRegTable();\n"; - OS << ClassName << "::" << ClassName + OS << ClassName << "::\n" << ClassName << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n" << " : TargetRegisterInfo(" << TargetName << "RegInfoDesc" << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n" - << " " << TargetName << "SubRegIndexTable) {\n" + << " " << TargetName << "SubRegIndexTable) {\n" << " InitMCRegisterInfo(" << TargetName << "RegDesc, " - << Regs.size()+1 << ", RA, " << TargetName << "MCRegisterClasses, " - << RegisterClasses.size() << ", " << TargetName << "RegOverlaps, " - << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet);\n\n"; + << Regs.size()+1 << ", RA,\n " << TargetName + << "MCRegisterClasses, " << RegisterClasses.size() << ",\n" + << " " << TargetName << "RegOverlaps, " + << TargetName << "SubRegsSet, " << TargetName << "SuperRegsSet,\n" + << " "; + if (SubRegIndices.size() != 0) + OS << "get" << TargetName << "SubRegTable(), " + << SubRegIndices.size() << ");\n\n"; + else + OS << "NULL, 0);\n\n"; EmitRegMapping(OS, Regs, true); -- 2.34.1