// 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
// 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>;
}
//===----------------------------------------------------------------------===//
}
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]>;
}
// 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]>;
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 {
(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)>;
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 {
}
; 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
%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
}
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
; 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
//===----------------------------------------------------------------------===//
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");
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 {
HasDisjunctSubRegs(false),
SubRegsComplete(false),
SuperRegsComplete(false),
- TopoSig(~0u)
-{}
+ TopoSig(~0u) {
+ Artificial = R->getValueAsBit("isArtificial");
+}
void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) {
std::vector<Record*> SRIs = TheDef->getValueAsListOfDefs("SubRegIndices");
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());
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);
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.
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) {
}
// Populate a unique sorted list of units from a register set.
-void CodeGenRegisterClass::buildRegUnitSet(
+void CodeGenRegisterClass::buildRegUnitSet(const CodeGenRegBank &RegBank,
std::vector<unsigned> &RegUnits) const {
std::vector<unsigned> 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));
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();
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.
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;
}
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);
}
// 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.
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<RegUnitSet>::const_iterator SetI =
// Recompute the sorted list of units in this class.
std::vector<unsigned> RCRegUnits;
- RC.buildRegUnitSet(RCRegUnits);
+ RC.buildRegUnitSet(*this, RCRegUnits);
// Don't increase pressure for unallocatable regclasses.
if (RCRegUnits.empty())
// 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)
// 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())
// 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);
// 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);
unsigned CostPerUse;
bool CoveredBySubRegs;
bool HasDisjunctSubRegs;
+ bool Artificial;
// Map SubRegIndex -> Register.
typedef std::map<CodeGenSubRegIndex *, CodeGenRegister *, deref<llvm::less>>
/// 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.
const BitVector &getTopoSigs() const { return TopoSigs; }
// Populate a unique sorted list of units from a register set.
- void buildRegUnitSet(std::vector<unsigned> &RegUnits) const;
+ void buildRegUnitSet(const CodeGenRegBank &RegBank,
+ std::vector<unsigned> &RegUnits) const;
CodeGenRegisterClass(CodeGenRegBank&, Record *R);
// 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;
}
// 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;
}
<< " 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<unsigned> RegUnits;
- RC.buildRegUnitSet(RegUnits);
+ RC.buildRegUnitSet(RegBank, RegUnits);
OS << " {" << (*Regs.begin())->getWeight(RegBank)
<< ", " << RegBank.getRegUnitSetWeight(RegUnits);
}