Index: include/llvm/Target/Target.td =================================================================== --- include/llvm/Target/Target.td +++ include/llvm/Target/Target.td @@ -175,6 +175,8 @@ // HWEncoding - The target specific hardware encoding for this register. bits<16> HWEncoding = 0; + + bit isArtificial = 0; } // RegisterWithSubRegs - This can be used to define instances of Register which Index: lib/Target/X86/X86RegisterInfo.td =================================================================== --- lib/Target/X86/X86RegisterInfo.td +++ lib/Target/X86/X86RegisterInfo.td @@ -21,12 +21,13 @@ // Subregister indices. let Namespace = "X86" in { - def sub_8bit : SubRegIndex<8>; - def sub_8bit_hi : SubRegIndex<8, 8>; - def sub_16bit : SubRegIndex<16>; - def sub_32bit : SubRegIndex<32>; - def sub_xmm : SubRegIndex<128>; - def sub_ymm : SubRegIndex<256>; + def sub_8bit : SubRegIndex<8>; + def sub_8bit_hi : SubRegIndex<8, 8>; + def sub_16bit : SubRegIndex<16>; + def sub_16bit_hi : SubRegIndex<16, 16>; + def sub_32bit : SubRegIndex<32>; + def sub_xmm : SubRegIndex<128>; + def sub_ymm : SubRegIndex<256>; } //===----------------------------------------------------------------------===// @@ -88,6 +89,18 @@ } def IP : X86Reg<"ip", 0>; +let isArtificial = 1 in { + def HAX : X86Reg<"hax", -1>; + def HDX : X86Reg<"hdx", -3>; + def HCX : X86Reg<"hcx", -2>; + def HBX : X86Reg<"hbx", -4>; + def HSI : X86Reg<"hsi", -7>; + def HDI : X86Reg<"hdi", -8>; + def HBP : X86Reg<"hbp", -6>; + def HSP : X86Reg<"hsp", -5>; + def HIP : X86Reg<"hip", -1>; +} + // X86-64 only, requires REX. let SubRegIndices = [sub_8bit], CostPerUse = 1 in { def R8W : X86Reg<"r8w", 8, [R8B]>; @@ -101,19 +114,20 @@ } // 32-bit registers -let SubRegIndices = [sub_16bit] in { -def EAX : X86Reg<"eax", 0, [AX]>, DwarfRegNum<[-2, 0, 0]>; -def EDX : X86Reg<"edx", 2, [DX]>, DwarfRegNum<[-2, 2, 2]>; -def ECX : X86Reg<"ecx", 1, [CX]>, DwarfRegNum<[-2, 1, 1]>; -def EBX : X86Reg<"ebx", 3, [BX]>, DwarfRegNum<[-2, 3, 3]>; -def ESI : X86Reg<"esi", 6, [SI]>, DwarfRegNum<[-2, 6, 6]>; -def EDI : X86Reg<"edi", 7, [DI]>, DwarfRegNum<[-2, 7, 7]>; -def EBP : X86Reg<"ebp", 5, [BP]>, DwarfRegNum<[-2, 4, 5]>; -def ESP : X86Reg<"esp", 4, [SP]>, DwarfRegNum<[-2, 5, 4]>; -def EIP : X86Reg<"eip", 0, [IP]>, DwarfRegNum<[-2, 8, 8]>; +let SubRegIndices = [sub_16bit, sub_16bit_hi], CoveredBySubRegs = 1 in { +def EAX : X86Reg<"eax", 0, [AX, HAX]>, DwarfRegNum<[-2, 0, 0]>; +def EDX : X86Reg<"edx", 2, [DX, HDX]>, DwarfRegNum<[-2, 2, 2]>; +def ECX : X86Reg<"ecx", 1, [CX, HCX]>, DwarfRegNum<[-2, 1, 1]>; +def EBX : X86Reg<"ebx", 3, [BX, HBX]>, DwarfRegNum<[-2, 3, 3]>; +def ESI : X86Reg<"esi", 6, [SI, HSI]>, DwarfRegNum<[-2, 6, 6]>; +def EDI : X86Reg<"edi", 7, [DI, HDI]>, DwarfRegNum<[-2, 7, 7]>; +def EBP : X86Reg<"ebp", 5, [BP, HBP]>, DwarfRegNum<[-2, 4, 5]>; +def ESP : X86Reg<"esp", 4, [SP, HSP]>, DwarfRegNum<[-2, 5, 4]>; +def EIP : X86Reg<"eip", 0, [IP, HIP]>, DwarfRegNum<[-2, 8, 8]>; +} // X86-64 only, requires REX -let CostPerUse = 1 in { +let SubRegIndices = [sub_16bit], CostPerUse = 1 in { def R8D : X86Reg<"r8d", 8, [R8W]>; def R9D : X86Reg<"r9d", 9, [R9W]>; def R10D : X86Reg<"r10d", 10, [R10W]>; @@ -122,7 +136,7 @@ def R13D : X86Reg<"r13d", 13, [R13W]>; def R14D : X86Reg<"r14d", 14, [R14W]>; def R15D : X86Reg<"r15d", 15, [R15W]>; -}} +} // 64-bit registers, X86-64 only let SubRegIndices = [sub_32bit] in { @@ -341,6 +355,10 @@ (add AX, CX, DX, SI, DI, BX, BP, SP, R8W, R9W, R10W, R11W, R14W, R15W, R12W, R13W)>; +let isAllocatable = 0 in +def GRH16 : RegisterClass<"X86", [i16], 16, + (add HAX, HCX, HDX, HSI, HSI, HBX, HBP, HSP, HIP)>; + def GR32 : RegisterClass<"X86", [i32], 32, (add EAX, ECX, EDX, ESI, EDI, EBX, EBP, ESP, R8D, R9D, R10D, R11D, R14D, R15D, R12D, R13D)>; Index: utils/TableGen/CodeGenRegisters.h =================================================================== --- utils/TableGen/CodeGenRegisters.h +++ utils/TableGen/CodeGenRegisters.h @@ -80,6 +80,10 @@ // Are all super-registers containing this SubRegIndex covered by their // sub-registers? bool AllSuperRegsCovered; + // A subregister index is "artificial" if every subregister obtained + // from applying this index is artificial. Artificial subregister + // indexes are not used to create new register classes. + bool Artificial; CodeGenSubRegIndex(Record *R, unsigned Enum); CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum); @@ -150,6 +154,7 @@ unsigned CostPerUse; bool CoveredBySubRegs; bool HasDisjunctSubRegs; + bool Artificial; // Map SubRegIndex -> Register. typedef std::map> @@ -331,6 +336,8 @@ /// True if there are at least 2 subregisters which do not interfere. bool HasDisjunctSubRegs; bool CoveredBySubRegs; + /// A register class is artificial if all its members are artificial. + bool Artificial; // Return the Record that defined this class, or NULL if the class was // created by TableGen. @@ -427,7 +434,8 @@ const BitVector &getTopoSigs() const { return TopoSigs; } // Populate a unique sorted list of units from a register set. - void buildRegUnitSet(std::vector &RegUnits) const; + void buildRegUnitSet(const CodeGenRegBank &RegBank, + std::vector &RegUnits) const; CodeGenRegisterClass(CodeGenRegBank&, Record *R); @@ -475,8 +483,11 @@ // Index into RegClassUnitSets where we can find the list of UnitSets that // contain this unit. unsigned RegClassUnitSetsIdx; + // A register unit is artificial if at least one of its roots is + // artificial. + bool Artificial; - RegUnit() : Weight(0), RegClassUnitSetsIdx(0) { + RegUnit() : Weight(0), RegClassUnitSetsIdx(0), Artificial(false) { Roots[0] = Roots[1] = nullptr; } @@ -648,8 +659,12 @@ // registers. unsigned newRegUnit(CodeGenRegister *R0, CodeGenRegister *R1 = nullptr) { RegUnits.resize(RegUnits.size() + 1); - RegUnits.back().Roots[0] = R0; - RegUnits.back().Roots[1] = R1; + RegUnit &RU = RegUnits.back(); + RU.Roots[0] = R0; + RU.Roots[1] = R1; + RU.Artificial = R0->Artificial; + if (R1) + RU.Artificial = RU.Artificial || R1->Artificial; return RegUnits.size() - 1; } Index: utils/TableGen/CodeGenRegisters.cpp =================================================================== --- utils/TableGen/CodeGenRegisters.cpp +++ utils/TableGen/CodeGenRegisters.cpp @@ -52,7 +52,7 @@ //===----------------------------------------------------------------------===// CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum) - : TheDef(R), EnumValue(Enum), AllSuperRegsCovered(true) { + : TheDef(R), EnumValue(Enum), AllSuperRegsCovered(true), Artificial(true) { Name = R->getName(); if (R->getValue("Namespace")) Namespace = R->getValueAsString("Namespace"); @@ -63,7 +63,7 @@ CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum) : TheDef(nullptr), Name(N), Namespace(Nspace), Size(-1), Offset(-1), - EnumValue(Enum), AllSuperRegsCovered(true) { + EnumValue(Enum), AllSuperRegsCovered(true), Artificial(true) { } std::string CodeGenSubRegIndex::getQualifiedName() const { @@ -162,8 +162,9 @@ HasDisjunctSubRegs(false), SubRegsComplete(false), SuperRegsComplete(false), - TopoSig(~0u) -{} + TopoSig(~0u) { + Artificial = R->getValueAsBit("isArtificial"); +} void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) { std::vector SRIs = TheDef->getValueAsListOfDefs("SubRegIndices"); @@ -276,6 +277,8 @@ for (unsigned i = 0, e = ExplicitSubRegs.size(); i != e; ++i) { CodeGenRegister *SR = ExplicitSubRegs[i]; CodeGenSubRegIndex *Idx = ExplicitSubRegIndices[i]; + if (!SR->Artificial) + Idx->Artificial = false; if (!SubRegs.insert(std::make_pair(Idx, SR)).second) PrintFatalError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() + " appears twice in Register " + getName()); @@ -736,10 +739,12 @@ Orders.resize(1 + AltOrders->size()); // Default allocation order always contains all registers. + Artificial = true; for (unsigned i = 0, e = Elements->size(); i != e; ++i) { Orders[0].push_back((*Elements)[i]); const CodeGenRegister *Reg = RegBank.getReg((*Elements)[i]); Members.push_back(Reg); + Artificial &= Reg->Artificial; TopoSigs.set(Reg->getTopoSig()); } sortAndUniqueRegisters(Members); @@ -798,8 +803,11 @@ CopyCost(0), Allocatable(true), AllocationPriority(0) { - for (const auto R : Members) + Artificial = true; + for (const auto R : Members) { TopoSigs.set(R->getTopoSig()); + Artificial &= R->Artificial; + } } // Compute inherited propertied for a synthesized register class. @@ -915,6 +923,8 @@ CodeGenRegisterClass &RC = *I; RC.SubClasses.resize(RegClasses.size()); RC.SubClasses.set(RC.EnumValue); + if (RC.Artificial) + continue; // Normally, all subclasses have IDs >= rci, unless RC is part of a clique. for (auto I2 = I.base(), E2 = RegClasses.end(); I2 != E2; ++I2) { @@ -1043,11 +1053,14 @@ } // Populate a unique sorted list of units from a register set. -void CodeGenRegisterClass::buildRegUnitSet( +void CodeGenRegisterClass::buildRegUnitSet(const CodeGenRegBank &RegBank, std::vector &RegUnits) const { std::vector TmpUnits; - for (RegUnitIterator UnitI(Members); UnitI.isValid(); ++UnitI) - TmpUnits.push_back(*UnitI); + for (RegUnitIterator UnitI(Members); UnitI.isValid(); ++UnitI) { + const RegUnit &RU = RegBank.getRegUnit(*UnitI); + if (!RU.Artificial) + TmpUnits.push_back(*UnitI); + } std::sort(TmpUnits.begin(), TmpUnits.end()); std::unique_copy(TmpUnits.begin(), TmpUnits.end(), std::back_inserter(RegUnits)); @@ -1135,15 +1148,18 @@ // discovered now. NumNativeRegUnits = RegUnits.size(); +dbgs() << "--- Register classes ---\n"; // Read in register class definitions. std::vector RCs = Records.getAllDerivedDefinitions("RegisterClass"); if (RCs.empty()) PrintFatalError("No 'RegisterClass' subclasses defined!"); // Allocate user-defined register classes. - for (auto *RC : RCs) { - RegClasses.emplace_back(*this, RC); - addToMaps(&RegClasses.back()); + for (auto *R : RCs) { + RegClasses.emplace_back(*this, R); + CodeGenRegisterClass &RC = RegClasses.back(); + if (!RC.Artificial) + addToMaps(&RC); } // Infer missing classes to create a full algebra. @@ -1554,12 +1570,14 @@ Reg = UnitI.getReg(); Weight = 0; } - unsigned UWeight = RegBank.getRegUnit(*UnitI).Weight; - if (!UWeight) { - UWeight = 1; - RegBank.increaseRegUnitWeight(*UnitI, UWeight); + if (!RegBank.getRegUnit(*UnitI).Artificial) { + unsigned UWeight = RegBank.getRegUnit(*UnitI).Weight; + if (!UWeight) { + UWeight = 1; + RegBank.increaseRegUnitWeight(*UnitI, UWeight); + } + Weight += UWeight; } - Weight += UWeight; } if (Weight > MaxWeight) MaxWeight = Weight; @@ -1637,7 +1655,8 @@ } else { // Adjust the existing single unit. - RegBank.increaseRegUnitWeight(AdjustUnit, UberSet->Weight - RegWeight); + if (!RegBank.getRegUnit(AdjustUnit).Artificial) + RegBank.increaseRegUnitWeight(AdjustUnit, UberSet->Weight - RegWeight); // The unit may be shared among sets and registers within this set. computeUberWeights(UberSets, RegBank); } @@ -1771,7 +1790,7 @@ // Compute a unique RegUnitSet for each RegClass. auto &RegClasses = getRegClasses(); for (auto &RC : RegClasses) { - if (!RC.Allocatable) + if (!RC.Allocatable || RC.Artificial) continue; // Speculatively grow the RegUnitSets to hold the new set. @@ -1779,7 +1798,7 @@ RegUnitSets.back().Name = RC.getName(); // Compute a sorted list of units in this class. - RC.buildRegUnitSet(RegUnitSets.back().Units); + RC.buildRegUnitSet(*this, RegUnitSets.back().Units); // Find an existing RegUnitSet. std::vector::const_iterator SetI = @@ -1882,7 +1901,7 @@ // Recompute the sorted list of units in this class. std::vector RCRegUnits; - RC.buildRegUnitSet(RCRegUnits); + RC.buildRegUnitSet(*this, RCRegUnits); // Don't increase pressure for unallocatable regclasses. if (RCRegUnits.empty()) @@ -2069,10 +2088,14 @@ // Compute the set of registers supporting each SubRegIndex. SubReg2SetMap SRSets; for (const auto R : RC->getMembers()) { + if (R->Artificial) + continue; const CodeGenRegister::SubRegMap &SRM = R->getSubRegs(); for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(), - E = SRM.end(); I != E; ++I) - SRSets[I->first].push_back(R); + E = SRM.end(); I != E; ++I) { + if (!I->first->Artificial) + SRSets[I->first].push_back(R); + } } for (auto I : SRSets) @@ -2081,6 +2104,8 @@ // Find matching classes for all SRSets entries. Iterate in SubRegIndex // numerical order to visit synthetic indices last. for (const auto &SubIdx : SubRegIndices) { + if (SubIdx.Artificial) + continue; SubReg2SetMap::const_iterator I = SRSets.find(&SubIdx); // Unsupported SubRegIndex. Skip it. if (I == SRSets.end()) @@ -2182,6 +2207,8 @@ // Watch out for iterator invalidation here. for (auto I = RegClasses.begin(), E = RegClasses.end(); I != E; ++I) { CodeGenRegisterClass *RC = &*I; + if (RC->Artificial) + continue; // Synthesize answers for getSubClassWithSubReg(). inferSubClassWithSubReg(RC); Index: utils/TableGen/RegisterInfoEmitter.cpp =================================================================== --- utils/TableGen/RegisterInfoEmitter.cpp +++ utils/TableGen/RegisterInfoEmitter.cpp @@ -203,11 +203,11 @@ << " static const RegClassWeight RCWeightTable[] = {\n"; for (const auto &RC : RegBank.getRegClasses()) { const CodeGenRegister::Vec &Regs = RC.getMembers(); - if (Regs.empty()) + if (Regs.empty() || RC.Artificial) OS << " {0, 0"; else { std::vector RegUnits; - RC.buildRegUnitSet(RegUnits); + RC.buildRegUnitSet(RegBank, RegUnits); OS << " {" << (*Regs.begin())->getWeight(RegBank) << ", " << RegBank.getRegUnitSetWeight(RegUnits); }