Example #1
0
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";
}