aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-18 00:16:39 +0000
committerJakob Stoklund Olesen <stoklund@2pi.dk>2012-01-18 00:16:39 +0000
commit31867660cb81ea2b1d1a6ffa7d09c91acb754a8b (patch)
tree3ccbfded75387b943b2877f7f5975da12d98a84b
parent7434c9a053789c04d73bb58df41ad6fdf6a84e6a (diff)
downloadexternal_llvm-31867660cb81ea2b1d1a6ffa7d09c91acb754a8b.zip
external_llvm-31867660cb81ea2b1d1a6ffa7d09c91acb754a8b.tar.gz
external_llvm-31867660cb81ea2b1d1a6ffa7d09c91acb754a8b.tar.bz2
Add a CoveredBySubRegs property to Register descriptions.
When set, this bit indicates that a register is completely defined by the value of its sub-registers. Use the CoveredBySubRegs property to infer which super-registers are call-preserved given a list of callee-saved registers. For example, the ARM registers D8-D15 are callee-saved. This now automatically implies that Q4-Q7 are call-preserved. Conversely, Win64 callees save XMM6-XMM15, but the corresponding YMM6-YMM15 registers are not call-preserved because they are not fully defined by their sub-registers. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148363 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/Target/Target.td6
-rw-r--r--lib/Target/ARM/ARMRegisterInfo.td2
-rw-r--r--lib/Target/Hexagon/HexagonRegisterInfo.td2
-rw-r--r--lib/Target/Mips/MipsRegisterInfo.td1
-rw-r--r--lib/Target/Sparc/SparcRegisterInfo.td1
-rw-r--r--lib/Target/X86/X86RegisterInfo.td2
-rw-r--r--utils/TableGen/CodeGenRegisters.cpp52
-rw-r--r--utils/TableGen/CodeGenRegisters.h1
8 files changed, 53 insertions, 14 deletions
diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td
index be08b9c..f9f30a8 100644
--- a/include/llvm/Target/Target.td
+++ b/include/llvm/Target/Target.td
@@ -86,6 +86,12 @@ class Register<string n, list<string> 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 f341d51..3dedcf6 100644
--- a/lib/Target/ARM/ARMRegisterInfo.td
+++ b/lib/Target/ARM/ARMRegisterInfo.td
@@ -16,6 +16,8 @@ class ARMReg<bits<4> num, string n, list<Register> subregs = []> : Register<n> {
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<bits<6> num, string n> : Register<n> {
diff --git a/lib/Target/Hexagon/HexagonRegisterInfo.td b/lib/Target/Hexagon/HexagonRegisterInfo.td
index c05f844..d74a683 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 76ee2e6..15a6adc 100644
--- a/lib/Target/Mips/MipsRegisterInfo.td
+++ b/lib/Target/Mips/MipsRegisterInfo.td
@@ -50,6 +50,7 @@ class AFPR<bits<5> num, string n, list<Register> subregs>
: MipsRegWithSubRegs<n, subregs> {
let Num = num;
let SubRegIndices = [sub_fpeven, sub_fpodd];
+ let CoveredBySubRegs = 1;
}
class AFPR64<bits<5> num, string n, list<Register> subregs>
diff --git a/lib/Target/Sparc/SparcRegisterInfo.td b/lib/Target/Sparc/SparcRegisterInfo.td
index cf92829..7f3c9b4 100644
--- a/lib/Target/Sparc/SparcRegisterInfo.td
+++ b/lib/Target/Sparc/SparcRegisterInfo.td
@@ -39,6 +39,7 @@ class Rd<bits<5> num, string n, list<Register> subregs> : SparcReg<n> {
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 9a7db36..5263a49 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 89358c8..7cd27a7 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<Record*> 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 6153fe5..0551055 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<Record*, CodeGenRegister*, LessRecord> SubRegMap;