diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index be08b9c9bec..f9f30a8bb70 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -86,6 +86,12 @@ class Register altNames = []> { // This is used by the x86-64 and ARM Thumb targets where some registers // require larger instruction encodings. int CostPerUse = 0; + + // CoveredBySubRegs - When this bit is set, the value of this register is + // completely determined by the value of its sub-registers. For example, the + // x86 register AX is covered by its sub-registers AL and AH, but EAX is not + // covered by its sub-register AX. + bit CoveredBySubRegs = 0; } // RegisterWithSubRegs - This can be used to define instances of Register which diff --git a/lib/Target/ARM/ARMRegisterInfo.td b/lib/Target/ARM/ARMRegisterInfo.td index f341d516499..3dedcf6ccee 100644 --- a/lib/Target/ARM/ARMRegisterInfo.td +++ b/lib/Target/ARM/ARMRegisterInfo.td @@ -16,6 +16,8 @@ class ARMReg num, string n, list subregs = []> : Register { field bits<4> Num; let Namespace = "ARM"; let SubRegs = subregs; + // All bits of ARM registers with sub-registers are covered by sub-registers. + let CoveredBySubRegs = 1; } class ARMFReg num, string n> : Register { diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.td b/lib/Target/Hexagon/HexagonRegisterInfo.td index c05f844556a..d74a6832856 100644 --- a/lib/Target/Hexagon/HexagonRegisterInfo.td +++ b/lib/Target/Hexagon/HexagonRegisterInfo.td @@ -94,7 +94,7 @@ let Namespace = "Hexagon" in { def GP : Ri<31, "r31">, DwarfRegNum<[33]>; // Aliases of the R* registers used to hold 64-bit int values (doubles). - let SubRegIndices = [subreg_loreg, subreg_hireg] in { + let SubRegIndices = [subreg_loreg, subreg_hireg], CoveredBySubRegs = 1 in { def D0 : Rd< 0, "r1:0", [R0, R1]>, DwarfRegNum<[32]>; def D1 : Rd< 2, "r3:2", [R2, R3]>, DwarfRegNum<[34]>; def D2 : Rd< 4, "r5:4", [R4, R5]>, DwarfRegNum<[36]>; diff --git a/lib/Target/Mips/MipsRegisterInfo.td b/lib/Target/Mips/MipsRegisterInfo.td index 76ee2e6ed71..15a6adc102b 100644 --- a/lib/Target/Mips/MipsRegisterInfo.td +++ b/lib/Target/Mips/MipsRegisterInfo.td @@ -50,6 +50,7 @@ class AFPR num, string n, list subregs> : MipsRegWithSubRegs { let Num = num; let SubRegIndices = [sub_fpeven, sub_fpodd]; + let CoveredBySubRegs = 1; } class AFPR64 num, string n, list subregs> diff --git a/lib/Target/Sparc/SparcRegisterInfo.td b/lib/Target/Sparc/SparcRegisterInfo.td index cf928293c16..7f3c9b47e8c 100644 --- a/lib/Target/Sparc/SparcRegisterInfo.td +++ b/lib/Target/Sparc/SparcRegisterInfo.td @@ -39,6 +39,7 @@ class Rd num, string n, list subregs> : SparcReg { let Num = num; let SubRegs = subregs; let SubRegIndices = [sub_even, sub_odd]; + let CoveredBySubRegs = 1; } // Control Registers diff --git a/lib/Target/X86/X86RegisterInfo.td b/lib/Target/X86/X86RegisterInfo.td index 9a7db36e087..5263a4934cb 100644 --- a/lib/Target/X86/X86RegisterInfo.td +++ b/lib/Target/X86/X86RegisterInfo.td @@ -70,7 +70,7 @@ let Namespace = "X86" in { def BH : Register<"bh">; // 16-bit registers - let SubRegIndices = [sub_8bit, sub_8bit_hi] in { + let SubRegIndices = [sub_8bit, sub_8bit_hi], CoveredBySubRegs = 1 in { def AX : RegisterWithSubRegs<"ax", [AL,AH]>; def DX : RegisterWithSubRegs<"dx", [DL,DH]>; def CX : RegisterWithSubRegs<"cx", [CL,CH]>; diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 89358c8d2fc..7cd27a7d740 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -29,6 +29,7 @@ CodeGenRegister::CodeGenRegister(Record *R, unsigned Enum) : TheDef(R), EnumValue(Enum), CostPerUse(R->getValueAsInt("CostPerUse")), + CoveredBySubRegs(R->getValueAsBit("CoveredBySubRegs")), SubRegsComplete(false) {} @@ -215,33 +216,40 @@ struct TupleExpander : SetTheory::Expander { for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) { RecordVal RV = Proto->getValues()[i]; - if (RV.getName() == "NAME") + // Skip existing fields, like NAME. + if (NewReg->getValue(RV.getNameInit())) continue; + StringRef Field = RV.getName(); + // Replace the sub-register list with Tuple. - if (RV.getName() == "SubRegs") + if (Field == "SubRegs") RV.setValue(ListInit::get(Tuple, RegisterRecTy)); // Provide a blank AsmName. MC hacks are required anyway. - if (RV.getName() == "AsmName") + if (Field == "AsmName") RV.setValue(BlankName); // CostPerUse is aggregated from all Tuple members. - if (RV.getName() == "CostPerUse") + if (Field == "CostPerUse") RV.setValue(IntInit::get(CostPerUse)); + // Composite registers are always covered by sub-registers. + if (Field == "CoveredBySubRegs") + RV.setValue(BitInit::get(true)); + // Copy fields from the RegisterTuples def. - if (RV.getName() == "SubRegIndices" || - RV.getName() == "CompositeIndices") { - NewReg->addValue(*Def->getValue(RV.getName())); + if (Field == "SubRegIndices" || + Field == "CompositeIndices") { + NewReg->addValue(*Def->getValue(Field)); continue; } // Some fields get their default uninitialized value. - if (RV.getName() == "DwarfNumbers" || - RV.getName() == "DwarfAlias" || - RV.getName() == "Aliases") { - if (const RecordVal *DefRV = RegisterCl->getValue(RV.getName())) + if (Field == "DwarfNumbers" || + Field == "DwarfAlias" || + Field == "Aliases") { + if (const RecordVal *DefRV = RegisterCl->getValue(Field)) NewReg->addValue(*DefRV); continue; } @@ -1006,7 +1014,27 @@ BitVector CodeGenRegBank::computeCoveredRegisters(ArrayRef Regs) { } // Second, find all super-registers that are completely covered by the set. - // FIXME: Implement CoveredBySubRegs bit. + for (unsigned i = 0; i != Set.size(); ++i) { + const CodeGenRegister::SuperRegList &SR = Set[i]->getSuperRegs(); + for (unsigned j = 0, e = SR.size(); j != e; ++j) { + CodeGenRegister *Super = SR[j]; + if (!Super->CoveredBySubRegs || Set.count(Super)) + continue; + // This new super-register is covered by its sub-registers. + bool AllSubsInSet = true; + const CodeGenRegister::SubRegMap &SRM = Super->getSubRegs(); + for (CodeGenRegister::SubRegMap::const_iterator I = SRM.begin(), + E = SRM.end(); I != E; ++I) + if (!Set.count(I->second)) { + AllSubsInSet = false; + break; + } + // All sub-registers in Set, add Super as well. + // We will visit Super later to recheck its super-registers. + if (AllSubsInSet) + Set.insert(Super); + } + } // Convert to BitVector. BitVector BV(Registers.size() + 1); diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 6153fe51793..05510558069 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -36,6 +36,7 @@ namespace llvm { Record *TheDef; unsigned EnumValue; unsigned CostPerUse; + bool CoveredBySubRegs; // Map SubRegIndex -> Register. typedef std::map SubRegMap;