Index: llvm/trunk/include/llvm/Target/Target.td =================================================================== --- llvm/trunk/include/llvm/Target/Target.td +++ llvm/trunk/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: llvm/trunk/lib/Target/X86/X86RegisterInfo.td =================================================================== --- llvm/trunk/lib/Target/X86/X86RegisterInfo.td +++ llvm/trunk/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: llvm/trunk/test/CodeGen/X86/dynamic-regmask.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/dynamic-regmask.ll +++ llvm/trunk/test/CodeGen/X86/dynamic-regmask.ll @@ -11,7 +11,7 @@ ret i32 %b2 } ; CHECK: name: caller -; CHECK: CALL64pcrel32 @callee, CustomRegMask($bh,$bl,$bp,$bpl,$bx,$ebp,$ebx,$esp,$rbp,$rbx,$rsp,$sp,$spl,$r10,$r11,$r12,$r13,$r14,$r15,$xmm8,$xmm9,$xmm10,$xmm11,$xmm12,$xmm13,$xmm14,$xmm15,$r10b,$r11b,$r12b,$r13b,$r14b,$r15b,$r10d,$r11d,$r12d,$r13d,$r14d,$r15d,$r10w,$r11w,$r12w,$r13w,$r14w,$r15w) +; CHECK: CALL64pcrel32 @callee, CustomRegMask($bh,$bl,$bp,$bpl,$bx,$ebp,$ebx,$esp,$hbp,$hbx,$hsp,$rbp,$rbx,$rsp,$sp,$spl,$r10,$r11,$r12,$r13,$r14,$r15,$xmm8,$xmm9,$xmm10,$xmm11,$xmm12,$xmm13,$xmm14,$xmm15,$r10b,$r11b,$r12b,$r13b,$r14b,$r15b,$r10d,$r11d,$r12d,$r13d,$r14d,$r15d,$r10w,$r11w,$r12w,$r13w,$r14w,$r15w), implicit $rsp, implicit $ssp, implicit $eax, implicit $ecx, implicit $edx, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax ; CHECK: RET 0, $eax define x86_regcallcc {i32, i32, i32} @test_callee(i32 %a0, i32 %b0, i32 %c0, i32 %d0, i32 %e0) nounwind { Index: llvm/trunk/test/CodeGen/X86/ipra-inline-asm.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/ipra-inline-asm.ll +++ llvm/trunk/test/CodeGen/X86/ipra-inline-asm.ll @@ -11,7 +11,7 @@ } ; Verifies that inline assembly is correctly handled by giving a list of clobbered registers -; CHECK: foo Clobbered Registers: $ah $al $ax $ch $cl $cx $di $dil $eax $ecx $edi $rax $rcx $rdi +; CHECK: foo Clobbered Registers: $ah $al $ax $ch $cl $cx $di $dil $eax $ecx $edi $hax $hcx $hdi $rax $rcx $rdi define void @foo() #0 { call void asm sideeffect "", "~{eax},~{ecx},~{edi}"() #0 ret void Index: llvm/trunk/test/CodeGen/X86/ipra-reg-alias.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/ipra-reg-alias.ll +++ llvm/trunk/test/CodeGen/X86/ipra-reg-alias.ll @@ -6,7 +6,7 @@ %inc2 = mul i8 %inc, 5 ; Here only CL is clobbred so CH should not be clobbred, but CX, ECX and RCX ; should be clobbered. -; CHECK: main Clobbered Registers: $ah $al $ax $cl $cx $eax $ecx $eflags $rax $rcx +; CHECK: main Clobbered Registers: $ah $al $ax $cl $cx $eax $ecx $eflags $hax $rax $rcx ret i8 %inc2 } Index: llvm/trunk/test/CodeGen/X86/ipra-reg-usage.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/ipra-reg-usage.ll +++ llvm/trunk/test/CodeGen/X86/ipra-reg-usage.ll @@ -3,7 +3,7 @@ target triple = "x86_64-unknown-unknown" declare void @bar1() define preserve_allcc void @foo()#0 { -; CHECK: foo Clobbered Registers: $cs $ds $eflags $eip $eiz $es $fpsw $fs $gs $ip $rip $riz $ss $ssp $bnd0 $bnd1 $bnd2 $bnd3 $cr0 $cr1 $cr2 $cr3 $cr4 $cr5 $cr6 $cr7 $cr8 $cr9 $cr10 $cr11 $cr12 $cr13 $cr14 $cr15 $dr0 $dr1 $dr2 $dr3 $dr4 $dr5 $dr6 $dr7 $dr8 $dr9 $dr10 $dr11 $dr12 $dr13 $dr14 $dr15 $fp0 $fp1 $fp2 $fp3 $fp4 $fp5 $fp6 $fp7 $k0 $k1 $k2 $k3 $k4 $k5 $k6 $k7 $mm0 $mm1 $mm2 $mm3 $mm4 $mm5 $mm6 $mm7 $r11 $st0 $st1 $st2 $st3 $st4 $st5 $st6 $st7 $xmm16 $xmm17 $xmm18 $xmm19 $xmm20 $xmm21 $xmm22 $xmm23 $xmm24 $xmm25 $xmm26 $xmm27 $xmm28 $xmm29 $xmm30 $xmm31 $ymm0 $ymm1 $ymm2 $ymm3 $ymm4 $ymm5 $ymm6 $ymm7 $ymm8 $ymm9 $ymm10 $ymm11 $ymm12 $ymm13 $ymm14 $ymm15 $ymm16 $ymm17 $ymm18 $ymm19 $ymm20 $ymm21 $ymm22 $ymm23 $ymm24 $ymm25 $ymm26 $ymm27 $ymm28 $ymm29 $ymm30 $ymm31 $zmm0 $zmm1 $zmm2 $zmm3 $zmm4 $zmm5 $zmm6 $zmm7 $zmm8 $zmm9 $zmm10 $zmm11 $zmm12 $zmm13 $zmm14 $zmm15 $zmm16 $zmm17 $zmm18 $zmm19 $zmm20 $zmm21 $zmm22 $zmm23 $zmm24 $zmm25 $zmm26 $zmm27 $zmm28 $zmm29 $zmm30 $zmm31 $r11b $r11d $r11w +; CHECK: foo Clobbered Registers: $cs $ds $eflags $eip $eiz $es $fpsw $fs $gs $hip $ip $rip $riz $ss $ssp $bnd0 $bnd1 $bnd2 $bnd3 $cr0 $cr1 $cr2 $cr3 $cr4 $cr5 $cr6 $cr7 $cr8 $cr9 $cr10 $cr11 $cr12 $cr13 $cr14 $cr15 $dr0 $dr1 $dr2 $dr3 $dr4 $dr5 $dr6 $dr7 $dr8 $dr9 $dr10 $dr11 $dr12 $dr13 $dr14 $dr15 $fp0 $fp1 $fp2 $fp3 $fp4 $fp5 $fp6 $fp7 $k0 $k1 $k2 $k3 $k4 $k5 $k6 $k7 $mm0 $mm1 $mm2 $mm3 $mm4 $mm5 $mm6 $mm7 $r11 $st0 $st1 $st2 $st3 $st4 $st5 $st6 $st7 $xmm16 $xmm17 $xmm18 $xmm19 $xmm20 $xmm21 $xmm22 $xmm23 $xmm24 $xmm25 $xmm26 $xmm27 $xmm28 $xmm29 $xmm30 $xmm31 $ymm0 $ymm1 $ymm2 $ymm3 $ymm4 $ymm5 $ymm6 $ymm7 $ymm8 $ymm9 $ymm10 $ymm11 $ymm12 $ymm13 $ymm14 $ymm15 $ymm16 $ymm17 $ymm18 $ymm19 $ymm20 $ymm21 $ymm22 $ymm23 $ymm24 $ymm25 $ymm26 $ymm27 $ymm28 $ymm29 $ymm30 $ymm31 $zmm0 $zmm1 $zmm2 $zmm3 $zmm4 $zmm5 $zmm6 $zmm7 $zmm8 $zmm9 $zmm10 $zmm11 $zmm12 $zmm13 $zmm14 $zmm15 $zmm16 $zmm17 $zmm18 $zmm19 $zmm20 $zmm21 $zmm22 $zmm23 $zmm24 $zmm25 $zmm26 $zmm27 $zmm28 $zmm29 $zmm30 $zmm31 $r11b $r11d $r11w call void @bar1() call void @bar2() ret void Index: llvm/trunk/test/CodeGen/X86/tail-call-conditional.mir =================================================================== --- llvm/trunk/test/CodeGen/X86/tail-call-conditional.mir +++ llvm/trunk/test/CodeGen/X86/tail-call-conditional.mir @@ -48,7 +48,7 @@ ; CHECK-NEXT: $rdi = COPY $rsi ; CHECK-NEXT: $rsi = COPY $rax ; CHECK-NEXT: CMP64ri8 $rax, 9, implicit-def $eflags - ; CHECK-NEXT: TCRETURNdi64cc @f1, 0, 3, csr_64, implicit $rsp, implicit $eflags, implicit $ssp, implicit $rsp, implicit $rdi, implicit $rsi, implicit $rax, implicit-def $rax, implicit $sil, implicit-def $sil, implicit $si, implicit-def $si, implicit $esi, implicit-def $esi, implicit $rsi, implicit-def $rsi, implicit $dil, implicit-def $dil, implicit $di, implicit-def $di, implicit $edi, implicit-def $edi, implicit $rdi, implicit-def $rdi, implicit $ah, implicit-def $ah, implicit $al, implicit-def $al, implicit $ax, implicit-def $ax, implicit $eax, implicit-def $eax + ; CHECK-NEXT: TCRETURNdi64cc @f1, 0, 3, csr_64, implicit $rsp, implicit $eflags, implicit $ssp, implicit $rsp, implicit $rdi, implicit $rsi, implicit $rax, implicit-def $rax, implicit $hsi, implicit-def $hsi, implicit $sil, implicit-def $sil, implicit $si, implicit-def $si, implicit $esi, implicit-def $esi, implicit $rsi, implicit-def $rsi, implicit $hdi, implicit-def $hdi, implicit $dil, implicit-def $dil, implicit $di, implicit-def $di, implicit $edi, implicit-def $edi, implicit $rdi, implicit-def $rdi, implicit $hax, implicit-def $hax, implicit $ah, implicit-def $ah, implicit $al, implicit-def $al, implicit $ax, implicit-def $ax, implicit $eax, implicit-def $eax bb.1: successors: %bb.2, %bb.3 Index: llvm/trunk/utils/TableGen/CodeGenRegisters.h =================================================================== --- llvm/trunk/utils/TableGen/CodeGenRegisters.h +++ llvm/trunk/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 |= R1->Artificial; return RegUnits.size() - 1; } Index: llvm/trunk/utils/TableGen/CodeGenRegisters.cpp =================================================================== --- llvm/trunk/utils/TableGen/CodeGenRegisters.cpp +++ llvm/trunk/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)); @@ -1131,6 +1144,18 @@ for (auto &Reg : Registers) Reg.computeSuperRegs(*this); + // For each pair of Reg:SR, if both are non-artificial, mark the + // corresponding sub-register index as non-artificial. + for (auto &Reg : Registers) { + if (Reg.Artificial) + continue; + for (auto P : Reg.getSubRegs()) { + const CodeGenRegister *SR = P.second; + if (!SR->Artificial) + P.first->Artificial = false; + } + } + // Native register units are associated with a leaf register. They've all been // discovered now. NumNativeRegUnits = RegUnits.size(); @@ -1141,9 +1166,11 @@ 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 +1581,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 +1666,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 +1801,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 +1809,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 +1912,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 +2099,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 +2115,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 +2218,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: llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/RegisterInfoEmitter.cpp +++ llvm/trunk/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); }