forked from OSchip/llvm-project
[X86] Add phony registers for high halves of regs with low halves
Registers E[A-D]X, E[SD]I, E[BS]P, and EIP have 16-bit subregisters that cover the low halves of these registers. This change adds artificial subregisters for the high halves in order to differentiate (in terms of register units) between the 32- and the low 16-bit registers. This patch contains parts that aim to preserve the calculated register pressure. This is in order to preserve the current codegen (minimize the impact of this patch). The approach of having artificial subregisters could be used to fix PR23423, but the pressure calculation would need to be changed. Differential Revision: https://reviews.llvm.org/D43353 llvm-svn: 328016
This commit is contained in:
parent
ce998adf0a
commit
eb0c510ecd
|
@ -175,6 +175,8 @@ class Register<string n, list<string> altNames = []> {
|
|||
|
||||
// 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
|
||||
|
|
|
@ -21,12 +21,13 @@ class X86Reg<string n, bits<16> Enc, list<Register> subregs = []> : Register<n>
|
|||
|
||||
// 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 SP : X86Reg<"sp", 4, [SPL]>;
|
|||
}
|
||||
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 @@ def R15W : X86Reg<"r15w", 15, [R15B]>;
|
|||
}
|
||||
|
||||
// 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 R12D : X86Reg<"r12d", 12, [R12W]>;
|
|||
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 @@ def GR16 : RegisterClass<"X86", [i16], 16,
|
|||
(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)>;
|
||||
|
|
|
@ -11,7 +11,7 @@ define i32 @caller(i32 %a0) nounwind {
|
|||
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 {
|
||||
|
|
|
@ -11,7 +11,7 @@ define void @bar() #0 {
|
|||
}
|
||||
|
||||
; 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
|
||||
|
|
|
@ -6,7 +6,7 @@ define i8 @main(i8 %X) {
|
|||
%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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -48,7 +48,7 @@ body: |
|
|||
; 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
|
||||
|
|
|
@ -52,7 +52,7 @@ using namespace llvm;
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
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(Record *R, unsigned Enum)
|
|||
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 @@ CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum)
|
|||
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");
|
||||
|
@ -276,6 +277,8 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) {
|
|||
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 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R)
|
|||
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 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
|
|||
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 @@ void CodeGenRegisterClass::computeSubClasses(CodeGenRegBank &RegBank) {
|
|||
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 @@ void CodeGenRegisterClass::getSuperRegClasses(const CodeGenSubRegIndex *SubIdx,
|
|||
}
|
||||
|
||||
// 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));
|
||||
|
@ -1131,6 +1144,18 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records,
|
|||
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 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records,
|
|||
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 @@ static void computeUberWeights(std::vector<UberRegSet> &UberSets,
|
|||
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 @@ static bool normalizeWeight(CodeGenRegister *Reg,
|
|||
}
|
||||
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 @@ void CodeGenRegBank::computeRegUnitSets() {
|
|||
// 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 @@ void CodeGenRegBank::computeRegUnitSets() {
|
|||
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 =
|
||||
|
@ -1882,7 +1912,7 @@ void CodeGenRegBank::computeRegUnitSets() {
|
|||
|
||||
// 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())
|
||||
|
@ -2069,10 +2099,14 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
|
|||
// 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 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
|
|||
// 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 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
|
|||
// 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);
|
||||
|
|
|
@ -80,6 +80,10 @@ namespace llvm {
|
|||
// 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 @@ namespace llvm {
|
|||
unsigned CostPerUse;
|
||||
bool CoveredBySubRegs;
|
||||
bool HasDisjunctSubRegs;
|
||||
bool Artificial;
|
||||
|
||||
// Map SubRegIndex -> Register.
|
||||
typedef std::map<CodeGenSubRegIndex *, CodeGenRegister *, deref<llvm::less>>
|
||||
|
@ -331,6 +336,8 @@ namespace llvm {
|
|||
/// 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 @@ namespace llvm {
|
|||
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);
|
||||
|
||||
|
@ -475,8 +483,11 @@ namespace llvm {
|
|||
// 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 @@ namespace llvm {
|
|||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -203,11 +203,11 @@ EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
|
|||
<< " 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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue