summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2018-03-20 18:46:55 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2018-03-20 18:46:55 +0000
commiteb0c510ecde667cd911682cc1e855f73f341d134 (patch)
treec0c18f6a1f6298abf5e99a494d10088e49fada75
parentce998adf0a8f678b8121e3ce5bb6e46cd3a36d36 (diff)
downloadbcm5719-llvm-eb0c510ecde667cd911682cc1e855f73f341d134.tar.gz
bcm5719-llvm-eb0c510ecde667cd911682cc1e855f73f341d134.zip
[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
-rw-r--r--llvm/include/llvm/Target/Target.td2
-rw-r--r--llvm/lib/Target/X86/X86RegisterInfo.td54
-rw-r--r--llvm/test/CodeGen/X86/dynamic-regmask.ll2
-rw-r--r--llvm/test/CodeGen/X86/ipra-inline-asm.ll2
-rw-r--r--llvm/test/CodeGen/X86/ipra-reg-alias.ll2
-rw-r--r--llvm/test/CodeGen/X86/ipra-reg-usage.ll2
-rw-r--r--llvm/test/CodeGen/X86/tail-call-conditional.mir2
-rw-r--r--llvm/utils/TableGen/CodeGenRegisters.cpp82
-rw-r--r--llvm/utils/TableGen/CodeGenRegisters.h23
-rw-r--r--llvm/utils/TableGen/RegisterInfoEmitter.cpp4
10 files changed, 124 insertions, 51 deletions
diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td
index 1bdef8ca673..0a09e9b1835 100644
--- a/llvm/include/llvm/Target/Target.td
+++ b/llvm/include/llvm/Target/Target.td
@@ -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
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td
index ca508255c36..d53bf6565e5 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.td
+++ b/llvm/lib/Target/X86/X86RegisterInfo.td
@@ -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)>;
diff --git a/llvm/test/CodeGen/X86/dynamic-regmask.ll b/llvm/test/CodeGen/X86/dynamic-regmask.ll
index 01a87eaa7c2..b84fe816fc7 100644
--- a/llvm/test/CodeGen/X86/dynamic-regmask.ll
+++ b/llvm/test/CodeGen/X86/dynamic-regmask.ll
@@ -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 {
diff --git a/llvm/test/CodeGen/X86/ipra-inline-asm.ll b/llvm/test/CodeGen/X86/ipra-inline-asm.ll
index dc9cbfa1078..4e67a974fe3 100644
--- a/llvm/test/CodeGen/X86/ipra-inline-asm.ll
+++ b/llvm/test/CodeGen/X86/ipra-inline-asm.ll
@@ -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
diff --git a/llvm/test/CodeGen/X86/ipra-reg-alias.ll b/llvm/test/CodeGen/X86/ipra-reg-alias.ll
index 86bba7c06c3..92bf1d17610 100644
--- a/llvm/test/CodeGen/X86/ipra-reg-alias.ll
+++ b/llvm/test/CodeGen/X86/ipra-reg-alias.ll
@@ -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
}
diff --git a/llvm/test/CodeGen/X86/ipra-reg-usage.ll b/llvm/test/CodeGen/X86/ipra-reg-usage.ll
index 4930526b8f4..bdda7ba6d8f 100644
--- a/llvm/test/CodeGen/X86/ipra-reg-usage.ll
+++ b/llvm/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
diff --git a/llvm/test/CodeGen/X86/tail-call-conditional.mir b/llvm/test/CodeGen/X86/tail-call-conditional.mir
index 329c4cb3589..396fbf3bac8 100644
--- a/llvm/test/CodeGen/X86/tail-call-conditional.mir
+++ b/llvm/test/CodeGen/X86/tail-call-conditional.mir
@@ -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
diff --git a/llvm/utils/TableGen/CodeGenRegisters.cpp b/llvm/utils/TableGen/CodeGenRegisters.cpp
index a6b0a4beb8e..586d5cfffc1 100644
--- a/llvm/utils/TableGen/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/CodeGenRegisters.cpp
@@ -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);
diff --git a/llvm/utils/TableGen/CodeGenRegisters.h b/llvm/utils/TableGen/CodeGenRegisters.h
index f2f1e6971af..c4811401de4 100644
--- a/llvm/utils/TableGen/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/CodeGenRegisters.h
@@ -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;
}
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 7eef2337c14..9e6be26a5c1 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -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);
}
OpenPOWER on IntegriCloud