Пример #1
0
void CodeGenRegBank::inferMatchingSuperRegClass(CodeGenRegisterClass *RC,
                                                unsigned FirstSubRegRC) {
  SmallVector<std::pair<const CodeGenRegister*,
                        const CodeGenRegister*>, 16> SSPairs;

  // Iterate in SubRegIndex numerical order to visit synthetic indices last.
  for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
    CodeGenSubRegIndex *SubIdx = SubRegIndices[sri];
    // Skip indexes that aren't fully supported by RC's registers. This was
    // computed by inferSubClassWithSubReg() above which should have been
    // called first.
    if (RC->getSubClassWithSubReg(SubIdx) != RC)
      continue;

    // Build list of (Super, Sub) pairs for this SubIdx.
    SSPairs.clear();
    for (CodeGenRegister::Set::const_iterator RI = RC->getMembers().begin(),
         RE = RC->getMembers().end(); RI != RE; ++RI) {
      const CodeGenRegister *Super = *RI;
      const CodeGenRegister *Sub = Super->getSubRegs().find(SubIdx)->second;
      assert(Sub && "Missing sub-register");
      SSPairs.push_back(std::make_pair(Super, Sub));
    }

    // Iterate over sub-register class candidates.  Ignore classes created by
    // this loop. They will never be useful.
    for (unsigned rci = FirstSubRegRC, rce = RegClasses.size(); rci != rce;
         ++rci) {
      CodeGenRegisterClass *SubRC = RegClasses[rci];
      // Compute the subset of RC that maps into SubRC.
      CodeGenRegister::Set SubSet;
      for (unsigned i = 0, e = SSPairs.size(); i != e; ++i)
        if (SubRC->contains(SSPairs[i].second))
          SubSet.insert(SSPairs[i].first);
      if (SubSet.empty())
        continue;
      // RC injects completely into SubRC.
      if (SubSet.size() == SSPairs.size()) {
        SubRC->addSuperRegClass(SubIdx, RC);
        continue;
      }
      // Only a subset of RC maps into SubRC. Make sure it is represented by a
      // class.
      getOrCreateSubClass(RC, &SubSet, RC->getName() +
                          "_with_" + SubIdx->getName() +
                          "_in_" + SubRC->getName());
    }
  }
}
Пример #2
0
//
// runTargetDesc - Output the target register and register file descriptions.
//
void
RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
                                   CodeGenRegBank &RegBank){
  EmitSourceFileHeader("Target Register and Register Classes Information", OS);

  OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n";
  OS << "#undef GET_REGINFO_TARGET_DESC\n";

  OS << "namespace llvm {\n\n";

  // Get access to MCRegisterClass data.
  OS << "extern const MCRegisterClass " << Target.getName()
     << "MCRegisterClasses[];\n";

  // Start out by emitting each of the register classes.
  ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();
  ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();

  // Collect all registers belonging to any allocatable class.
  std::set<Record*> AllocatableRegs;

  // Collect allocatable registers.
  for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
    const CodeGenRegisterClass &RC = *RegisterClasses[rc];
    ArrayRef<Record*> Order = RC.getOrder();

    if (RC.Allocatable)
      AllocatableRegs.insert(Order.begin(), Order.end());
  }

  // Build a shared array of value types.
  SequenceToOffsetTable<std::vector<MVT::SimpleValueType> > VTSeqs;
  for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc)
    VTSeqs.add(RegisterClasses[rc]->VTs);
  VTSeqs.layout();
  OS << "\nstatic const MVT::SimpleValueType VTLists[] = {\n";
  VTSeqs.emit(OS, printSimpleValueType, "MVT::Other");
  OS << "};\n";

  // Emit SubRegIndex names, skipping 0
  OS << "\nstatic const char *const SubRegIndexTable[] = { \"";
  for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
    OS << SubRegIndices[i]->getName();
    if (i+1 != e)
      OS << "\", \"";
  }
  OS << "\" };\n\n";

  // Emit names of the anonymous subreg indices.
  unsigned NamedIndices = RegBank.getNumNamedIndices();
  if (SubRegIndices.size() > NamedIndices) {
    OS << "  enum {";
    for (unsigned i = NamedIndices, e = SubRegIndices.size(); i != e; ++i) {
      OS << "\n    " << SubRegIndices[i]->getName() << " = " << i+1;
      if (i+1 != e)
        OS << ',';
    }
    OS << "\n  };\n\n";
  }
  OS << "\n";

  // Now that all of the structs have been emitted, emit the instances.
  if (!RegisterClasses.empty()) {
    OS << "\nstatic const TargetRegisterClass *const "
       << "NullRegClasses[] = { NULL };\n\n";

    // Emit register class bit mask tables. The first bit mask emitted for a
    // register class, RC, is the set of sub-classes, including RC itself.
    //
    // If RC has super-registers, also create a list of subreg indices and bit
    // masks, (Idx, Mask). The bit mask has a bit for every superreg regclass,
    // SuperRC, that satisfies:
    //
    //   For all SuperReg in SuperRC: SuperReg:Idx in RC
    //
    // The 0-terminated list of subreg indices starts at:
    //
    //   RC->getSuperRegIndices() = SuperRegIdxSeqs + ...
    //
    // The corresponding bitmasks follow the sub-class mask in memory. Each
    // mask has RCMaskWords uint32_t entries.
    //
    // Every bit mask present in the list has at least one bit set.

    // Compress the sub-reg index lists.
    typedef std::vector<const CodeGenSubRegIndex*> IdxList;
    SmallVector<IdxList, 8> SuperRegIdxLists(RegisterClasses.size());
    SequenceToOffsetTable<IdxList> SuperRegIdxSeqs;
    BitVector MaskBV(RegisterClasses.size());

    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
      const CodeGenRegisterClass &RC = *RegisterClasses[rc];
      OS << "static const uint32_t " << RC.getName() << "SubClassMask[] = {\n  ";
      printBitVectorAsHex(OS, RC.getSubClasses(), 32);

      // Emit super-reg class masks for any relevant SubRegIndices that can
      // project into RC.
      IdxList &SRIList = SuperRegIdxLists[rc];
      for (unsigned sri = 0, sre = SubRegIndices.size(); sri != sre; ++sri) {
        CodeGenSubRegIndex *Idx = SubRegIndices[sri];
        MaskBV.reset();
        RC.getSuperRegClasses(Idx, MaskBV);
        if (MaskBV.none())
          continue;
        SRIList.push_back(Idx);
        OS << "\n  ";
        printBitVectorAsHex(OS, MaskBV, 32);
        OS << "// " << Idx->getName();
      }
      SuperRegIdxSeqs.add(SRIList);
      OS << "\n};\n\n";
    }

    OS << "static const uint16_t SuperRegIdxSeqs[] = {\n";
    SuperRegIdxSeqs.layout();
    SuperRegIdxSeqs.emit(OS, printSubRegIndex);
    OS << "};\n\n";

    // Emit NULL terminated super-class lists.
    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
      const CodeGenRegisterClass &RC = *RegisterClasses[rc];
      ArrayRef<CodeGenRegisterClass*> Supers = RC.getSuperClasses();

      // Skip classes without supers.  We can reuse NullRegClasses.
      if (Supers.empty())
        continue;

      OS << "static const TargetRegisterClass *const "
         << RC.getName() << "Superclasses[] = {\n";
      for (unsigned i = 0; i != Supers.size(); ++i)
        OS << "  &" << Supers[i]->getQualifiedName() << "RegClass,\n";
      OS << "  NULL\n};\n\n";
    }

    // Emit methods.
    for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
      const CodeGenRegisterClass &RC = *RegisterClasses[i];
      if (!RC.AltOrderSelect.empty()) {
        OS << "\nstatic inline unsigned " << RC.getName()
           << "AltOrderSelect(const MachineFunction &MF) {"
           << RC.AltOrderSelect << "}\n\n"
           << "static ArrayRef<uint16_t> " << RC.getName()
           << "GetRawAllocationOrder(const MachineFunction &MF) {\n";
        for (unsigned oi = 1 , oe = RC.getNumOrders(); oi != oe; ++oi) {
          ArrayRef<Record*> Elems = RC.getOrder(oi);
          if (!Elems.empty()) {
            OS << "  static const uint16_t AltOrder" << oi << "[] = {";
            for (unsigned elem = 0; elem != Elems.size(); ++elem)
              OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]);
            OS << " };\n";
          }
        }
        OS << "  const MCRegisterClass &MCR = " << Target.getName()
           << "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];\n"
           << "  const ArrayRef<uint16_t> Order[] = {\n"
           << "    makeArrayRef(MCR.begin(), MCR.getNumRegs()";
        for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
          if (RC.getOrder(oi).empty())
            OS << "),\n    ArrayRef<uint16_t>(";
          else
            OS << "),\n    makeArrayRef(AltOrder" << oi;
        OS << ")\n  };\n  const unsigned Select = " << RC.getName()
           << "AltOrderSelect(MF);\n  assert(Select < " << RC.getNumOrders()
           << ");\n  return Order[Select];\n}\n";
        }
    }

    // Now emit the actual value-initialized register class instances.
    OS << "namespace " << RegisterClasses[0]->Namespace
       << " {   // Register class instances\n";

    for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
      const CodeGenRegisterClass &RC = *RegisterClasses[i];
      OS << "  extern const TargetRegisterClass "
         << RegisterClasses[i]->getName() << "RegClass = {\n    "
         << '&' << Target.getName() << "MCRegisterClasses[" << RC.getName()
         << "RegClassID],\n    "
         << "VTLists + " << VTSeqs.get(RC.VTs) << ",\n    "
         << RC.getName() << "SubClassMask,\n    SuperRegIdxSeqs + "
         << SuperRegIdxSeqs.get(SuperRegIdxLists[i]) << ",\n    ";
      if (RC.getSuperClasses().empty())
        OS << "NullRegClasses,\n    ";
      else
        OS << RC.getName() << "Superclasses,\n    ";
      if (RC.AltOrderSelect.empty())
        OS << "0\n";
      else
        OS << RC.getName() << "GetRawAllocationOrder\n";
      OS << "  };\n\n";
    }

    OS << "}\n";
  }

  OS << "\nnamespace {\n";
  OS << "  const TargetRegisterClass* const RegisterClasses[] = {\n";
  for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i)
    OS << "    &" << RegisterClasses[i]->getQualifiedName()
       << "RegClass,\n";
  OS << "  };\n";
  OS << "}\n";       // End of anonymous namespace...

  // Emit extra information about registers.
  const std::string &TargetName = Target.getName();
  OS << "\nstatic const TargetRegisterInfoDesc "
     << TargetName << "RegInfoDesc[] = { // Extra Descriptors\n";
  OS << "  { 0, 0 },\n";

  const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
  for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
    const CodeGenRegister &Reg = *Regs[i];
    OS << "  { ";
    OS << Reg.CostPerUse << ", "
       << int(AllocatableRegs.count(Reg.TheDef)) << " },\n";
  }
  OS << "};\n";      // End of register descriptors...


  std::string ClassName = Target.getName() + "GenRegisterInfo";

  // Emit composeSubRegIndices
  if (!SubRegIndices.empty()) {
    OS << "unsigned " << ClassName
      << "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n"
      << "  switch (IdxA) {\n"
      << "  default:\n    return IdxB;\n";
    for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
      bool Open = false;
      for (unsigned j = 0; j != e; ++j) {
        if (CodeGenSubRegIndex *Comp =
            SubRegIndices[i]->compose(SubRegIndices[j])) {
          if (!Open) {
            OS << "  case " << SubRegIndices[i]->getQualifiedName()
              << ": switch(IdxB) {\n    default: return IdxB;\n";
            Open = true;
          }
          OS << "    case " << SubRegIndices[j]->getQualifiedName()
            << ": return " << Comp->getQualifiedName() << ";\n";
        }
      }
      if (Open)
        OS << "    }\n";
    }
    OS << "  }\n}\n\n";
  }

  // Emit getSubClassWithSubReg.
  if (!SubRegIndices.empty()) {
    OS << "const TargetRegisterClass *" << ClassName
       << "::getSubClassWithSubReg(const TargetRegisterClass *RC, unsigned Idx)"
       << " const {\n";
    // 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) {
        CodeGenSubRegIndex *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}\n\n";
  }

  EmitRegUnitPressure(OS, RegBank, ClassName);

  // Emit the constructor of the class...
  OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
  OS << "extern const uint16_t " << TargetName << "RegLists[];\n";
  if (SubRegIndices.size() != 0)
    OS << "extern const uint16_t *get" << TargetName
       << "SubRegTable();\n";
  OS << "extern const uint16_t " << TargetName << "RegEncodingTable[];\n";

  EmitRegMappingTables(OS, Regs, true);

  OS << ClassName << "::\n" << ClassName
     << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
     << "  : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
     << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
     << "             SubRegIndexTable) {\n"
     << "  InitMCRegisterInfo(" << TargetName << "RegDesc, "
     << Regs.size()+1 << ", RA,\n                     " << TargetName
     << "MCRegisterClasses, " << RegisterClasses.size() << ",\n"
     << "                     " << TargetName << "RegLists,\n"
     << "                     ";
  if (SubRegIndices.size() != 0)
    OS << "get" << TargetName << "SubRegTable(), "
       << SubRegIndices.size() << ",\n";
  else
    OS << "NULL, 0,\n";

  OS << "                     " << TargetName << "RegEncodingTable);\n\n";

  EmitRegMapping(OS, Regs, true);

  OS << "}\n\n";


  // Emit CalleeSavedRegs information.
  std::vector<Record*> CSRSets =
    Records.getAllDerivedDefinitions("CalleeSavedRegs");
  for (unsigned i = 0, e = CSRSets.size(); i != e; ++i) {
    Record *CSRSet = CSRSets[i];
    const SetTheory::RecVec *Regs = RegBank.getSets().expand(CSRSet);
    assert(Regs && "Cannot expand CalleeSavedRegs instance");

    // Emit the *_SaveList list of callee-saved registers.
    OS << "static const uint16_t " << CSRSet->getName()
       << "_SaveList[] = { ";
    for (unsigned r = 0, re = Regs->size(); r != re; ++r)
      OS << getQualifiedName((*Regs)[r]) << ", ";
    OS << "0 };\n";

    // Emit the *_RegMask bit mask of call-preserved registers.
    OS << "static const uint32_t " << CSRSet->getName()
       << "_RegMask[] = { ";
    printBitVectorAsHex(OS, RegBank.computeCoveredRegisters(*Regs), 32);
    OS << "};\n";
  }
  OS << "\n\n";

  OS << "} // End llvm namespace \n";
  OS << "#endif // GET_REGINFO_TARGET_DESC\n\n";
}
Пример #3
0
//
// runTargetDesc - Output the target register and register file descriptions.
//
void
RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
                                   CodeGenRegBank &RegBank) {
    EmitSourceFileHeader("Target Register and Register Classes Information", OS);

    OS << "\n#ifdef GET_REGINFO_TARGET_DESC\n";
    OS << "#undef GET_REGINFO_TARGET_DESC\n";

    OS << "namespace llvm {\n\n";

    // Get access to MCRegisterClass data.
    OS << "extern const MCRegisterClass " << Target.getName()
       << "MCRegisterClasses[];\n";

    // Start out by emitting each of the register classes.
    ArrayRef<CodeGenRegisterClass*> RegisterClasses = RegBank.getRegClasses();

    // Collect all registers belonging to any allocatable class.
    std::set<Record*> AllocatableRegs;

    // Collect allocatable registers.
    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
        const CodeGenRegisterClass &RC = *RegisterClasses[rc];
        ArrayRef<Record*> Order = RC.getOrder();

        if (RC.Allocatable)
            AllocatableRegs.insert(Order.begin(), Order.end());
    }

    OS << "namespace {     // Register classes...\n";

    // Emit the ValueType arrays for each RegisterClass
    for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
        const CodeGenRegisterClass &RC = *RegisterClasses[rc];

        // Give the register class a legal C name if it's anonymous.
        std::string Name = RC.getName() + "VTs";

        // Emit the register list now.
        OS << "  // " << Name
           << " Register Class Value Types...\n"
           << "  const MVT::SimpleValueType " << Name
           << "[] = {\n    ";
        for (unsigned i = 0, e = RC.VTs.size(); i != e; ++i)
            OS << getEnumName(RC.VTs[i]) << ", ";
        OS << "MVT::Other\n  };\n\n";
    }
    OS << "}  // end anonymous namespace\n\n";

    // Now that all of the structs have been emitted, emit the instances.
    if (!RegisterClasses.empty()) {
        std::map<unsigned, std::set<unsigned> > SuperRegClassMap;

        OS << "\nstatic const TargetRegisterClass *const "
           << "NullRegClasses[] = { NULL };\n\n";

        unsigned NumSubRegIndices = RegBank.getSubRegIndices().size();

        if (NumSubRegIndices) {
            // Compute the super-register classes for each RegisterClass
            for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
                const CodeGenRegisterClass &RC = *RegisterClasses[rc];
                for (DenseMap<Record*,Record*>::const_iterator
                        i = RC.SubRegClasses.begin(),
                        e = RC.SubRegClasses.end(); i != e; ++i) {
                    // Find the register class number of i->second for SuperRegClassMap.
                    const CodeGenRegisterClass *RC2 = RegBank.getRegClass(i->second);
                    assert(RC2 && "Invalid register class in SubRegClasses");
                    SuperRegClassMap[RC2->EnumValue].insert(rc);
                }
            }

            // Emit the super-register classes for each RegisterClass
            for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
                const CodeGenRegisterClass &RC = *RegisterClasses[rc];

                // Give the register class a legal C name if it's anonymous.
                std::string Name = RC.getName();

                OS << "// " << Name
                   << " Super-register Classes...\n"
                   << "static const TargetRegisterClass *const "
                   << Name << "SuperRegClasses[] = {\n  ";

                bool Empty = true;
                std::map<unsigned, std::set<unsigned> >::iterator I =
                    SuperRegClassMap.find(rc);
                if (I != SuperRegClassMap.end()) {
                    for (std::set<unsigned>::iterator II = I->second.begin(),
                            EE = I->second.end(); II != EE; ++II) {
                        const CodeGenRegisterClass &RC2 = *RegisterClasses[*II];
                        if (!Empty)
                            OS << ", ";
                        OS << "&" << RC2.getQualifiedName() << "RegClass";
                        Empty = false;
                    }
                }

                OS << (!Empty ? ", " : "") << "NULL";
                OS << "\n};\n\n";
            }
        }

        // Emit the sub-classes array for each RegisterClass
        for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
            const CodeGenRegisterClass &RC = *RegisterClasses[rc];

            // Give the register class a legal C name if it's anonymous.
            std::string Name = RC.getName();

            OS << "static const uint32_t " << Name << "SubclassMask[] = {\n  ";
            printBitVectorAsHex(OS, RC.getSubClasses(), 32);
            OS << "\n};\n\n";
        }

        // Emit NULL terminated super-class lists.
        for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) {
            const CodeGenRegisterClass &RC = *RegisterClasses[rc];
            ArrayRef<CodeGenRegisterClass*> Supers = RC.getSuperClasses();

            // Skip classes without supers.  We can reuse NullRegClasses.
            if (Supers.empty())
                continue;

            OS << "static const TargetRegisterClass *const "
               << RC.getName() << "Superclasses[] = {\n";
            for (unsigned i = 0; i != Supers.size(); ++i)
                OS << "  &" << Supers[i]->getQualifiedName() << "RegClass,\n";
            OS << "  NULL\n};\n\n";
        }

        // Emit methods.
        for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
            const CodeGenRegisterClass &RC = *RegisterClasses[i];
            if (!RC.AltOrderSelect.empty()) {
                OS << "\nstatic inline unsigned " << RC.getName()
                   << "AltOrderSelect(const MachineFunction &MF) {"
                   << RC.AltOrderSelect << "}\n\n"
                   << "static ArrayRef<uint16_t> " << RC.getName()
                   << "GetRawAllocationOrder(const MachineFunction &MF) {\n";
                for (unsigned oi = 1 , oe = RC.getNumOrders(); oi != oe; ++oi) {
                    ArrayRef<Record*> Elems = RC.getOrder(oi);
                    if (!Elems.empty()) {
                        OS << "  static const uint16_t AltOrder" << oi << "[] = {";
                        for (unsigned elem = 0; elem != Elems.size(); ++elem)
                            OS << (elem ? ", " : " ") << getQualifiedName(Elems[elem]);
                        OS << " };\n";
                    }
                }
                OS << "  const MCRegisterClass &MCR = " << Target.getName()
                   << "MCRegisterClasses[" << RC.getQualifiedName() + "RegClassID];\n"
                   << "  const ArrayRef<uint16_t> Order[] = {\n"
                   << "    makeArrayRef(MCR.begin(), MCR.getNumRegs()";
                for (unsigned oi = 1, oe = RC.getNumOrders(); oi != oe; ++oi)
                    if (RC.getOrder(oi).empty())
                        OS << "),\n    ArrayRef<uint16_t>(";
                    else
                        OS << "),\n    makeArrayRef(AltOrder" << oi;
                OS << ")\n  };\n  const unsigned Select = " << RC.getName()
                   << "AltOrderSelect(MF);\n  assert(Select < " << RC.getNumOrders()
                   << ");\n  return Order[Select];\n}\n";
            }
        }

        // Now emit the actual value-initialized register class instances.
        OS << "namespace " << RegisterClasses[0]->Namespace
           << " {   // Register class instances\n";

        for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i) {
            const CodeGenRegisterClass &RC = *RegisterClasses[i];
            OS << "  extern const TargetRegisterClass "
               << RegisterClasses[i]->getName() << "RegClass = {\n    "
               << '&' << Target.getName() << "MCRegisterClasses[" << RC.getName()
               << "RegClassID],\n    "
               << RC.getName() << "VTs,\n    "
               << RC.getName() << "SubclassMask,\n    ";
            if (RC.getSuperClasses().empty())
                OS << "NullRegClasses,\n    ";
            else
                OS << RC.getName() << "Superclasses,\n    ";
            OS << (NumSubRegIndices ? RC.getName() + "Super" : std::string("Null"))
               << "RegClasses,\n    ";
            if (RC.AltOrderSelect.empty())
                OS << "0\n";
            else
                OS << RC.getName() << "GetRawAllocationOrder\n";
            OS << "  };\n\n";
        }

        OS << "}\n";
    }

    OS << "\nnamespace {\n";
    OS << "  const TargetRegisterClass* const RegisterClasses[] = {\n";
    for (unsigned i = 0, e = RegisterClasses.size(); i != e; ++i)
        OS << "    &" << RegisterClasses[i]->getQualifiedName()
           << "RegClass,\n";
    OS << "  };\n";
    OS << "}\n";       // End of anonymous namespace...

    // Emit extra information about registers.
    const std::string &TargetName = Target.getName();
    OS << "\n  static const TargetRegisterInfoDesc "
       << TargetName << "RegInfoDesc[] = "
       << "{ // Extra Descriptors\n";
    OS << "    { 0, 0 },\n";

    const std::vector<CodeGenRegister*> &Regs = RegBank.getRegisters();
    for (unsigned i = 0, e = Regs.size(); i != e; ++i) {
        const CodeGenRegister &Reg = *Regs[i];
        OS << "    { ";
        OS << Reg.CostPerUse << ", "
           << int(AllocatableRegs.count(Reg.TheDef)) << " },\n";
    }
    OS << "  };\n";      // End of register descriptors...


    // Calculate the mapping of subregister+index pairs to physical registers.
    // This will also create further anonymous indices.
    unsigned NamedIndices = RegBank.getNumNamedIndices();

    // Emit SubRegIndex names, skipping 0
    ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
    OS << "\n  static const char *const " << TargetName
       << "SubRegIndexTable[] = { \"";
    for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
        OS << SubRegIndices[i]->getName();
        if (i+1 != e)
            OS << "\", \"";
    }
    OS << "\" };\n\n";

    // Emit names of the anonymous subreg indices.
    if (SubRegIndices.size() > NamedIndices) {
        OS << "  enum {";
        for (unsigned i = NamedIndices, e = SubRegIndices.size(); i != e; ++i) {
            OS << "\n    " << SubRegIndices[i]->getName() << " = " << i+1;
            if (i+1 != e)
                OS << ',';
        }
        OS << "\n  };\n\n";
    }
    OS << "\n";

    std::string ClassName = Target.getName() + "GenRegisterInfo";

    // Emit composeSubRegIndices
    OS << "unsigned " << ClassName
       << "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n"
       << "  switch (IdxA) {\n"
       << "  default:\n    return IdxB;\n";
    for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
        bool Open = false;
        for (unsigned j = 0; j != e; ++j) {
            if (CodeGenSubRegIndex *Comp =
                        SubRegIndices[i]->compose(SubRegIndices[j])) {
                if (!Open) {
                    OS << "  case " << SubRegIndices[i]->getQualifiedName()
                       << ": switch(IdxB) {\n    default: return IdxB;\n";
                    Open = true;
                }
                OS << "    case " << SubRegIndices[j]->getQualifiedName()
                   << ": return " << Comp->getQualifiedName() << ";\n";
            }
        }
        if (Open)
            OS << "    }\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) {
                CodeGenSubRegIndex *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 getMatchingSuperRegClass.
    OS << "const TargetRegisterClass *" << ClassName
       << "::getMatchingSuperRegClass(const TargetRegisterClass *A,"
       " const TargetRegisterClass *B, unsigned Idx) const {\n";
    if (SubRegIndices.empty()) {
        OS << "  llvm_unreachable(\"Target has no sub-registers\");\n";
    } else {
        // We need to find the largest sub-class of A such that every register has
        // an Idx sub-register in B.  Map (B, Idx) to a bit-vector of
        // super-register classes that map into B. Then compute the largest common
        // sub-class with A by taking advantage of the register class ordering,
        // like getCommonSubClass().

        // Bitvector table is NumRCs x NumSubIndexes x BVWords, where BVWords is
        // the number of 32-bit words required to represent all register classes.
        const unsigned BVWords = (RegisterClasses.size()+31)/32;
        BitVector BV(RegisterClasses.size());

        OS << "  static const uint32_t Table[" << RegisterClasses.size()
           << "][" << SubRegIndices.size() << "][" << BVWords << "] = {\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) {
                CodeGenSubRegIndex *Idx = SubRegIndices[sri];
                BV.reset();
                RC.getSuperRegClasses(Idx, BV);
                OS << "      { ";
                printBitVectorAsHex(OS, BV, 32);
                OS << "},\t// " << Idx->getName() << '\n';
            }
            OS << "    },\n";
        }
        OS << "  };\n  assert(A && B && \"Missing regclass\");\n"
           << "  --Idx;\n"
           << "  assert(Idx < " << SubRegIndices.size() << " && \"Bad subreg\");\n"
           << "  const uint32_t *TV = Table[B->getID()][Idx];\n"
           << "  const uint32_t *SC = A->getSubClassMask();\n"
           << "  for (unsigned i = 0; i != " << BVWords << "; ++i)\n"
           << "    if (unsigned Common = TV[i] & SC[i])\n"
           << "      return getRegClass(32*i + CountTrailingZeros_32(Common));\n"
           << "  return 0;\n";
    }
    OS << "}\n\n";

    // Emit the constructor of the class...
    OS << "extern const MCRegisterDesc " << TargetName << "RegDesc[];\n";
    OS << "extern const uint16_t " << TargetName << "RegOverlaps[];\n";
    OS << "extern const uint16_t " << TargetName << "SubRegsSet[];\n";
    OS << "extern const uint16_t " << TargetName << "SuperRegsSet[];\n";
    if (SubRegIndices.size() != 0)
        OS << "extern const uint16_t *get" << TargetName
           << "SubRegTable();\n";

    OS << ClassName << "::\n" << ClassName
       << "(unsigned RA, unsigned DwarfFlavour, unsigned EHFlavour)\n"
       << "  : TargetRegisterInfo(" << TargetName << "RegInfoDesc"
       << ", RegisterClasses, RegisterClasses+" << RegisterClasses.size() <<",\n"
       << "             " << TargetName << "SubRegIndexTable) {\n"
       << "  InitMCRegisterInfo(" << TargetName << "RegDesc, "
       << 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);

    OS << "}\n\n";


    // Emit CalleeSavedRegs information.
    std::vector<Record*> CSRSets =
        Records.getAllDerivedDefinitions("CalleeSavedRegs");
    for (unsigned i = 0, e = CSRSets.size(); i != e; ++i) {
        Record *CSRSet = CSRSets[i];
        const SetTheory::RecVec *Regs = RegBank.getSets().expand(CSRSet);
        assert(Regs && "Cannot expand CalleeSavedRegs instance");

        // Emit the *_SaveList list of callee-saved registers.
        OS << "static const uint16_t " << CSRSet->getName()
           << "_SaveList[] = { ";
        for (unsigned r = 0, re = Regs->size(); r != re; ++r)
            OS << getQualifiedName((*Regs)[r]) << ", ";
        OS << "0 };\n";

        // Emit the *_RegMask bit mask of call-preserved registers.
        OS << "static const uint32_t " << CSRSet->getName()
           << "_RegMask[] = { ";
        printBitVectorAsHex(OS, RegBank.computeCoveredRegisters(*Regs), 32);
        OS << "};\n";
    }
    OS << "\n\n";

    OS << "} // End llvm namespace \n";
    OS << "#endif // GET_REGINFO_TARGET_DESC\n\n";
}
Пример #4
0
const CodeGenRegister::SubRegMap &
CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
  // Only compute this map once.
  if (SubRegsComplete)
    return SubRegs;
  SubRegsComplete = true;

  std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
  std::vector<Record*> IdxList = TheDef->getValueAsListOfDefs("SubRegIndices");
  if (SubList.size() != IdxList.size())
    throw TGError(TheDef->getLoc(), "Register " + getName() +
                  " SubRegIndices doesn't match SubRegs");

  // First insert the direct subregs and make sure they are fully indexed.
  SmallVector<CodeGenSubRegIndex*, 8> Indices;
  for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
    CodeGenRegister *SR = RegBank.getReg(SubList[i]);
    CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxList[i]);
    Indices.push_back(Idx);
    if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
      throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
                    " appears twice in Register " + getName());
  }

  // Keep track of inherited subregs and how they can be reached.
  SmallPtrSet<CodeGenRegister*, 8> Orphans;

  // Clone inherited subregs and place duplicate entries in Orphans.
  // Here the order is important - earlier subregs take precedence.
  for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
    CodeGenRegister *SR = RegBank.getReg(SubList[i]);
    const SubRegMap &Map = SR->getSubRegs(RegBank);

    // Add this as a super-register of SR now all sub-registers are in the list.
    // This creates a topological ordering, the exact order depends on the
    // order getSubRegs is called on all registers.
    SR->SuperRegs.push_back(this);

    for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
         ++SI) {
      if (!SubRegs.insert(*SI).second)
        Orphans.insert(SI->second);

      // Noop sub-register indexes are possible, so avoid duplicates.
      if (SI->second != SR)
        SI->second->SuperRegs.push_back(this);
    }
  }

  // Expand any composed subreg indices.
  // If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a
  // qsub_1 subreg, add a dsub_2 subreg.  Keep growing Indices and process
  // expanded subreg indices recursively.
  for (unsigned i = 0; i != Indices.size(); ++i) {
    CodeGenSubRegIndex *Idx = Indices[i];
    const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites();
    CodeGenRegister *SR = SubRegs[Idx];
    const SubRegMap &Map = SR->getSubRegs(RegBank);

    // Look at the possible compositions of Idx.
    // They may not all be supported by SR.
    for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(),
           E = Comps.end(); I != E; ++I) {
      SubRegMap::const_iterator SRI = Map.find(I->first);
      if (SRI == Map.end())
        continue; // Idx + I->first doesn't exist in SR.
      // Add I->second as a name for the subreg SRI->second, assuming it is
      // orphaned, and the name isn't already used for something else.
      if (SubRegs.count(I->second) || !Orphans.erase(SRI->second))
        continue;
      // We found a new name for the orphaned sub-register.
      SubRegs.insert(std::make_pair(I->second, SRI->second));
      Indices.push_back(I->second);
    }
  }

  // Process the composites.
  ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
  for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
    DagInit *Pat = dynamic_cast<DagInit*>(Comps->getElement(i));
    if (!Pat)
      throw TGError(TheDef->getLoc(), "Invalid dag '" +
                    Comps->getElement(i)->getAsString() +
                    "' in CompositeIndices");
    DefInit *BaseIdxInit = dynamic_cast<DefInit*>(Pat->getOperator());
    if (!BaseIdxInit || !BaseIdxInit->getDef()->isSubClassOf("SubRegIndex"))
      throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
                    Pat->getAsString());
    CodeGenSubRegIndex *BaseIdx = RegBank.getSubRegIdx(BaseIdxInit->getDef());

    // Resolve list of subreg indices into R2.
    CodeGenRegister *R2 = this;
    for (DagInit::const_arg_iterator di = Pat->arg_begin(),
         de = Pat->arg_end(); di != de; ++di) {
      DefInit *IdxInit = dynamic_cast<DefInit*>(*di);
      if (!IdxInit || !IdxInit->getDef()->isSubClassOf("SubRegIndex"))
        throw TGError(TheDef->getLoc(), "Invalid SubClassIndex in " +
                      Pat->getAsString());
      CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxInit->getDef());
      const SubRegMap &R2Subs = R2->getSubRegs(RegBank);
      SubRegMap::const_iterator ni = R2Subs.find(Idx);
      if (ni == R2Subs.end())
        throw TGError(TheDef->getLoc(), "Composite " + Pat->getAsString() +
                      " refers to bad index in " + R2->getName());
      R2 = ni->second;
    }

    // Insert composite index. Allow overriding inherited indices etc.
    SubRegs[BaseIdx] = R2;

    // R2 is no longer an orphan.
    Orphans.erase(R2);
  }

  // Now Orphans contains the inherited subregisters without a direct index.
  // Create inferred indexes for all missing entries.
  // Work backwards in the Indices vector in order to compose subregs bottom-up.
  // Consider this subreg sequence:
  //
  //   qsub_1 -> dsub_0 -> ssub_0
  //
  // The qsub_1 -> dsub_0 composition becomes dsub_2, so the ssub_0 register
  // can be reached in two different ways:
  //
  //   qsub_1 -> ssub_0
  //   dsub_2 -> ssub_0
  //
  // We pick the latter composition because another register may have [dsub_0,
  // dsub_1, dsub_2] subregs without neccessarily having a qsub_1 subreg.  The
  // dsub_2 -> ssub_0 composition can be shared.
  while (!Indices.empty() && !Orphans.empty()) {
    CodeGenSubRegIndex *Idx = Indices.pop_back_val();
    CodeGenRegister *SR = SubRegs[Idx];
    const SubRegMap &Map = SR->getSubRegs(RegBank);
    for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
         ++SI)
      if (Orphans.erase(SI->second))
        SubRegs[RegBank.getCompositeSubRegIndex(Idx, SI->first)] = SI->second;
  }

  // Initialize RegUnitList. A register with no subregisters creates its own
  // unit. Otherwise, it inherits all its subregister's units. Because
  // getSubRegs is called recursively, this processes the register hierarchy in
  // postorder.
  //
  // TODO: We currently assume all register units correspond to a named "leaf"
  // register. We should also unify register units for ad-hoc register
  // aliases. This can be done by iteratively merging units for aliasing
  // registers using a worklist.
  assert(RegUnits.empty() && "Should only initialize RegUnits once");
  if (SubRegs.empty()) {
    RegUnits.push_back(RegBank.newRegUnit());
  }
  else {
    for (SubRegMap::const_iterator I = SubRegs.begin(), E = SubRegs.end();
         I != E; ++I) {
      // Strangely a register may have itself as a subreg (self-cycle) e.g. XMM.
      CodeGenRegister *SR = I->second;
      if (SR == this) {
        if (RegUnits.empty())
          RegUnits.push_back(RegBank.newRegUnit());
        continue;
      }
      // Merge the subregister's units into this register's RegUnits.
      mergeRegUnits(RegUnits, SR->RegUnits);
    }
  }
  return SubRegs;
}