diff options
author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-01-18 00:16:39 +0000 |
---|---|---|
committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2012-01-18 00:16:39 +0000 |
commit | 31867660cb81ea2b1d1a6ffa7d09c91acb754a8b (patch) | |
tree | 3ccbfded75387b943b2877f7f5975da12d98a84b /utils | |
parent | 7434c9a053789c04d73bb58df41ad6fdf6a84e6a (diff) | |
download | external_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
Diffstat (limited to 'utils')
-rw-r--r-- | utils/TableGen/CodeGenRegisters.cpp | 52 | ||||
-rw-r--r-- | utils/TableGen/CodeGenRegisters.h | 1 |
2 files changed, 41 insertions, 12 deletions
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; |