void RegisterInfoEmitter:: EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, const std::string &ClassName) { unsigned NumRCs = RegBank.getRegClasses().size(); unsigned NumSets = RegBank.getNumRegPressureSets(); OS << "/// Get the weight in units of pressure for this register class.\n" << "const RegClassWeight &" << ClassName << "::\n" << "getRegClassWeight(const TargetRegisterClass *RC) const {\n" << " static const RegClassWeight RCWeightTable[] = {\n"; for (unsigned i = 0, e = NumRCs; i != e; ++i) { const CodeGenRegisterClass &RC = *RegBank.getRegClasses()[i]; const CodeGenRegister::Set &Regs = RC.getMembers(); if (Regs.empty()) OS << " {0, 0"; else { std::vector<unsigned> RegUnits; RC.buildRegUnitSet(RegUnits); OS << " {" << (*Regs.begin())->getWeight(RegBank) << ", " << RegBank.getRegUnitSetWeight(RegUnits); } OS << "}, \t// " << RC.getName() << "\n"; } OS << " {0, 0} };\n" << " return RCWeightTable[RC->getID()];\n" << "}\n\n"; OS << "\n" << "// Get the number of dimensions of register pressure.\n" << "unsigned " << ClassName << "::getNumRegPressureSets() const {\n" << " return " << NumSets << ";\n}\n\n"; OS << "// Get the name of this register unit pressure set.\n" << "const char *" << ClassName << "::\n" << "getRegPressureSetName(unsigned Idx) const {\n" << " static const char *PressureNameTable[] = {\n"; for (unsigned i = 0; i < NumSets; ++i ) { OS << " \"" << RegBank.getRegPressureSet(i).Name << "\",\n"; } OS << " 0 };\n" << " return PressureNameTable[Idx];\n" << "}\n\n"; OS << "// Get the register unit pressure limit for this dimension.\n" << "// This limit must be adjusted dynamically for reserved registers.\n" << "unsigned " << ClassName << "::\n" << "getRegPressureSetLimit(unsigned Idx) const {\n" << " static const unsigned PressureLimitTable[] = {\n"; for (unsigned i = 0; i < NumSets; ++i ) { const RegUnitSet &RegUnits = RegBank.getRegPressureSet(i); OS << " " << RegBank.getRegUnitSetWeight(RegUnits.Units) << ", \t// " << i << ": " << RegUnits.Name << "\n"; } OS << " 0 };\n" << " return PressureLimitTable[Idx];\n" << "}\n\n"; OS << "/// Get the dimensions of register pressure " << "impacted by this register class.\n" << "/// Returns a -1 terminated array of pressure set IDs\n" << "const int* " << ClassName << "::\n" << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n" << " static const int RCSetsTable[] = {\n "; std::vector<unsigned> RCSetStarts(NumRCs); for (unsigned i = 0, StartIdx = 0, e = NumRCs; i != e; ++i) { RCSetStarts[i] = StartIdx; ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i); for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(), PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) { OS << *PSetI << ", "; ++StartIdx; } OS << "-1, \t// " << RegBank.getRegClasses()[i]->getName() << "\n "; ++StartIdx; } OS << "-1 };\n"; OS << " static const unsigned RCSetStartTable[] = {\n "; for (unsigned i = 0, e = NumRCs; i != e; ++i) { OS << RCSetStarts[i] << ","; } OS << "0 };\n" << " unsigned SetListStart = RCSetStartTable[RC->getID()];\n" << " return &RCSetsTable[SetListStart];\n" << "}\n\n"; }
void RegisterInfoEmitter:: EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank, const std::string &ClassName) { unsigned NumRCs = RegBank.getRegClasses().size(); unsigned NumSets = RegBank.getNumRegPressureSets(); OS << "/// Get the weight in units of pressure for this register class.\n" << "const RegClassWeight &" << ClassName << "::\n" << "getRegClassWeight(const TargetRegisterClass *RC) const {\n" << " static const RegClassWeight RCWeightTable[] = {\n"; for (unsigned i = 0, e = NumRCs; i != e; ++i) { const CodeGenRegisterClass &RC = *RegBank.getRegClasses()[i]; const CodeGenRegister::Set &Regs = RC.getMembers(); if (Regs.empty()) OS << " {0, 0"; else { std::vector<unsigned> RegUnits; RC.buildRegUnitSet(RegUnits); OS << " {" << (*Regs.begin())->getWeight(RegBank) << ", " << RegBank.getRegUnitSetWeight(RegUnits); } OS << "}, \t// " << RC.getName() << "\n"; } OS << " {0, 0} };\n" << " return RCWeightTable[RC->getID()];\n" << "}\n\n"; // Reasonable targets (not ARMv7) have unit weight for all units, so don't // bother generating a table. bool RegUnitsHaveUnitWeight = true; for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits(); UnitIdx < UnitEnd; ++UnitIdx) { if (RegBank.getRegUnit(UnitIdx).Weight > 1) RegUnitsHaveUnitWeight = false; } OS << "/// Get the weight in units of pressure for this register unit.\n" << "unsigned " << ClassName << "::\n" << "getRegUnitWeight(unsigned RegUnit) const {\n" << " assert(RegUnit < " << RegBank.getNumNativeRegUnits() << " && \"invalid register unit\");\n"; if (!RegUnitsHaveUnitWeight) { OS << " static const uint8_t RUWeightTable[] = {\n "; for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits(); UnitIdx < UnitEnd; ++UnitIdx) { const RegUnit &RU = RegBank.getRegUnit(UnitIdx); assert(RU.Weight < 256 && "RegUnit too heavy"); OS << RU.Weight << ", "; } OS << "0 };\n" << " return RUWeightTable[RegUnit];\n"; } else { OS << " // All register units have unit weight.\n" << " return 1;\n"; } OS << "}\n\n"; OS << "\n" << "// Get the number of dimensions of register pressure.\n" << "unsigned " << ClassName << "::getNumRegPressureSets() const {\n" << " return " << NumSets << ";\n}\n\n"; OS << "// Get the name of this register unit pressure set.\n" << "const char *" << ClassName << "::\n" << "getRegPressureSetName(unsigned Idx) const {\n" << " static const char *PressureNameTable[] = {\n"; for (unsigned i = 0; i < NumSets; ++i ) { OS << " \"" << RegBank.getRegPressureSet(i).Name << "\",\n"; } OS << " 0 };\n" << " return PressureNameTable[Idx];\n" << "}\n\n"; OS << "// Get the register unit pressure limit for this dimension.\n" << "// This limit must be adjusted dynamically for reserved registers.\n" << "unsigned " << ClassName << "::\n" << "getRegPressureSetLimit(unsigned Idx) const {\n" << " static const unsigned PressureLimitTable[] = {\n"; for (unsigned i = 0; i < NumSets; ++i ) { const RegUnitSet &RegUnits = RegBank.getRegPressureSet(i); OS << " " << RegBank.getRegUnitSetWeight(RegUnits.Units) << ", \t// " << i << ": " << RegUnits.Name << "\n"; } OS << " 0 };\n" << " return PressureLimitTable[Idx];\n" << "}\n\n"; // This table may be larger than NumRCs if some register units needed a list // of unit sets that did not correspond to a register class. unsigned NumRCUnitSets = RegBank.getNumRegClassPressureSetLists(); OS << "/// Table of pressure sets per register class or unit.\n" << "static const int RCSetsTable[] = {\n "; std::vector<unsigned> RCSetStarts(NumRCUnitSets); for (unsigned i = 0, StartIdx = 0, e = NumRCUnitSets; i != e; ++i) { RCSetStarts[i] = StartIdx; ArrayRef<unsigned> PSetIDs = RegBank.getRCPressureSetIDs(i); for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(), PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) { OS << *PSetI << ", "; ++StartIdx; } OS << "-1, \t// #" << RCSetStarts[i] << " "; if (i < NumRCs) OS << RegBank.getRegClasses()[i]->getName(); else { OS << "inferred"; for (ArrayRef<unsigned>::iterator PSetI = PSetIDs.begin(), PSetE = PSetIDs.end(); PSetI != PSetE; ++PSetI) { OS << "~" << RegBank.getRegPressureSet(*PSetI).Name; } } OS << "\n "; ++StartIdx; } OS << "-1 };\n\n"; OS << "/// Get the dimensions of register pressure impacted by this " << "register class.\n" << "/// Returns a -1 terminated array of pressure set IDs\n" << "const int* " << ClassName << "::\n" << "getRegClassPressureSets(const TargetRegisterClass *RC) const {\n"; OS << " static const unsigned RCSetStartTable[] = {\n "; for (unsigned i = 0, e = NumRCs; i != e; ++i) { OS << RCSetStarts[i] << ","; } OS << "0 };\n" << " unsigned SetListStart = RCSetStartTable[RC->getID()];\n" << " return &RCSetsTable[SetListStart];\n" << "}\n\n"; OS << "/// Get the dimensions of register pressure impacted by this " << "register unit.\n" << "/// Returns a -1 terminated array of pressure set IDs\n" << "const int* " << ClassName << "::\n" << "getRegUnitPressureSets(unsigned RegUnit) const {\n" << " assert(RegUnit < " << RegBank.getNumNativeRegUnits() << " && \"invalid register unit\");\n"; OS << " static const unsigned RUSetStartTable[] = {\n "; for (unsigned UnitIdx = 0, UnitEnd = RegBank.getNumNativeRegUnits(); UnitIdx < UnitEnd; ++UnitIdx) { OS << RCSetStarts[RegBank.getRegUnit(UnitIdx).RegClassUnitSetsIdx] << ","; } OS << "0 };\n" << " unsigned SetListStart = RUSetStartTable[RegUnit];\n" << " return &RCSetsTable[SetListStart];\n" << "}\n\n"; }