From baf66ec061aa4da85d6bdfd1f9cd1030b9607fbb Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 27 Mar 2024 12:19:28 -0700 Subject: [PATCH] [Target][RISCV] Add HwMode support to subregister index size/offset. (#86368) This is needed to provide proper size and offset for the GPRPair subreg indices on RISC-V. The size of a GPR already uses HwMode. Previously we said the subreg indices have unknown size and offset, but this stops DwarfExpression::addMachineReg from being able to find the registers that make up the pair. I believe this fixes https://github.com/llvm/llvm-project/issues/85864 but need to verify. --- llvm/include/llvm/Target/Target.td | 17 ++++ llvm/lib/CodeGen/TargetRegisterInfo.cpp | 4 +- llvm/lib/Target/RISCV/RISCVRegisterInfo.td | 11 ++- llvm/test/TableGen/ConcatenatedSubregs.td | 9 ++- llvm/test/TableGen/HwModeSubRegs.td | 75 ++++++++++++++++++ .../TableGen/Common/CodeGenRegisters.cpp | 79 +++++++++++++------ llvm/utils/TableGen/Common/CodeGenRegisters.h | 43 +++++++--- llvm/utils/TableGen/Common/InfoByHwMode.cpp | 14 ++++ llvm/utils/TableGen/Common/InfoByHwMode.h | 21 ++++- llvm/utils/TableGen/RegisterInfoEmitter.cpp | 19 +++-- 10 files changed, 242 insertions(+), 50 deletions(-) create mode 100644 llvm/test/TableGen/HwModeSubRegs.td diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index cb1c0ed2513d..1f7dc6922f13 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -83,10 +83,27 @@ class RegInfoByHwMode Ms = [], list Ts = []> list Objects = Ts; } +class SubRegRange { + int Size = size; // Sub register size in bits. + int Offset = offset; // Offset of the first bit of the sub-reg index. +} + +class SubRegRangeByHwMode Ms = [], list Ts = []> + : HwModeSelect { + // The length of this list must be the same as the length of Ms. + list Objects = Ts; +} + // SubRegIndex - Use instances of SubRegIndex to identify subregisters. class SubRegIndex { string Namespace = ""; + // The size/offset information, parameterized by a HW mode. + // If the HwModes provided for SubRegRanges does not include the DefaultMode, + // the/ Size and Offset fields below will be used for the default. Otherwise, + // the Size and Offset fields are ignored. + SubRegRangeByHwMode SubRegRanges; + // Size - Size (in bits) of the sub-registers represented by this index. int Size = size; diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp index 4120c74c23b1..4e06393f4cc1 100644 --- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp +++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp @@ -595,13 +595,13 @@ bool TargetRegisterInfo::getCoveringSubRegIndexes( unsigned TargetRegisterInfo::getSubRegIdxSize(unsigned Idx) const { assert(Idx && Idx < getNumSubRegIndices() && "This is not a subregister index"); - return SubRegIdxRanges[Idx].Size; + return SubRegIdxRanges[HwMode * getNumSubRegIndices() + Idx].Size; } unsigned TargetRegisterInfo::getSubRegIdxOffset(unsigned Idx) const { assert(Idx && Idx < getNumSubRegIndices() && "This is not a subregister index"); - return SubRegIdxRanges[Idx].Offset; + return SubRegIdxRanges[HwMode * getNumSubRegIndices() + Idx].Offset; } Register diff --git a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td index 9da1f73681c6..90c4a7193ee3 100644 --- a/llvm/lib/Target/RISCV/RISCVRegisterInfo.td +++ b/llvm/lib/Target/RISCV/RISCVRegisterInfo.td @@ -64,9 +64,14 @@ def sub_vrm1_6 : ComposedSubRegIndex; def sub_vrm1_7 : ComposedSubRegIndex; // GPR sizes change with HwMode. -// FIXME: Support HwMode in SubRegIndex? -def sub_gpr_even : SubRegIndex<-1>; -def sub_gpr_odd : SubRegIndex<-1, -1>; +def sub_gpr_even : SubRegIndex<32> { + let SubRegRanges = SubRegRangeByHwMode<[RV32, RV64], + [SubRegRange<32>, SubRegRange<64>]>; +} +def sub_gpr_odd : SubRegIndex<32, 32> { + let SubRegRanges = SubRegRangeByHwMode<[RV32, RV64], + [SubRegRange<32, 32>, SubRegRange<64, 64>]>; +} } // Namespace = "RISCV" // Integer registers diff --git a/llvm/test/TableGen/ConcatenatedSubregs.td b/llvm/test/TableGen/ConcatenatedSubregs.td index 5b354c94dca5..ea4e7f01a2e2 100644 --- a/llvm/test/TableGen/ConcatenatedSubregs.td +++ b/llvm/test/TableGen/ConcatenatedSubregs.td @@ -90,16 +90,19 @@ def TestTarget : Target; // CHECK-LABEL: RegisterClass DRegs: // CHECK-LABEL: SubRegIndex ssub1: -// CHECK: Offset, Size: 16, 16 +// CHECK: Offset: { Default:16 } +// CHECK: Size: { Default:16 } // CHECK-LABEL: SubRegIndex sub0: // CHECK-LABEL: SubRegIndex sub1: // CHECK-LABEL: SubRegIndex sub2: // Check inferred indexes: // CHECK-LABEL: SubRegIndex ssub1_ssub2: -// CHECK: Offset, Size: 16, 65535 +// CHECK: Offset: { Default:16 } +// CHECK: Size: { Default:65535 } // CHECK-LABEL: SubRegIndex ssub3_ssub4: // CHECK-LABEL: SubRegIndex ssub0_ssub1_ssub2_ssub3: -// CHECK: Offset, Size: 65535, 65535 +// CHECK: Offset: { Default:65535 } +// CHECK: Size: { Default:65535 } // CHECK-LABEL: SubRegIndex ssub1_ssub2_ssub3_ssub4: // Check that all subregs are generated on some examples diff --git a/llvm/test/TableGen/HwModeSubRegs.td b/llvm/test/TableGen/HwModeSubRegs.td new file mode 100644 index 000000000000..2bf7a917979d --- /dev/null +++ b/llvm/test/TableGen/HwModeSubRegs.td @@ -0,0 +1,75 @@ +// RUN: llvm-tblgen -gen-register-info -register-info-debug -I %p/../../include %s -o /dev/null 2>&1 | FileCheck %s +include "llvm/Target/Target.td" + +def HasFeat : Predicate<"Subtarget->hasFeat()">; + +def TestMode : HwMode<"+feat1", [HasFeat]>; + +class MyReg + : Register { + let Namespace = "Test"; +} +class MyClass types, dag registers> + : RegisterClass<"Test", types, size, registers> { + let Size = size; +} + +def X0 : MyReg<"x0">; +def X1 : MyReg<"x1">; +def X2 : MyReg<"x2">; +def X3 : MyReg<"x3">; +def X4 : MyReg<"x4">; +def X5 : MyReg<"x5">; +def X6 : MyReg<"x6">; +def X7 : MyReg<"x7">; +def X8 : MyReg<"x8">; +def X9 : MyReg<"x9">; +def X10 : MyReg<"x10">; +def X11 : MyReg<"x11">; +def X12 : MyReg<"x12">; +def X13 : MyReg<"x13">; +def X14 : MyReg<"x14">; +def X15 : MyReg<"x15">; + +def ModeVT : ValueTypeByHwMode<[DefaultMode, TestMode], + [i32, i64]>; +let RegInfos = RegInfoByHwMode<[DefaultMode, TestMode], + [RegInfo<32,32,32>, RegInfo<64,64,64>]> in +def XRegs : MyClass<32, [ModeVT], (sequence "X%u", 0, 15)>; + +def sub_even : SubRegIndex<32> { + let SubRegRanges = SubRegRangeByHwMode<[DefaultMode, TestMode], + [SubRegRange<32>, SubRegRange<64>]>; +} +def sub_odd : SubRegIndex<32, 32> { + let SubRegRanges = SubRegRangeByHwMode<[DefaultMode, TestMode], + [SubRegRange<32, 32>, SubRegRange<64, 64>]>; +} + +def XPairs : RegisterTuples<[sub_even, sub_odd], + [(decimate (rotl XRegs, 0), 2), + (decimate (rotl XRegs, 1), 2)]>; + +let RegInfos = RegInfoByHwMode<[DefaultMode, TestMode], + [RegInfo<64,64,32>, RegInfo<128,128,64>]> in +def XPairsClass : MyClass<64, [untyped], (add XPairs)>; + +def TestTarget : Target; + +// CHECK-LABEL: RegisterClass XRegs: +// CHECK: SpillSize: { Default:32 TestMode:64 } +// CHECK: SpillAlignment: { Default:32 TestMode:64 } +// CHECK: Regs: X0 X1 X2 X3 X4 X5 X6 X7 X8 X9 X10 X11 X12 X13 X14 X15 + +// CHECK-LABEL: RegisterClass XPairsClass: +// CHECK: SpillSize: { Default:64 TestMode:128 } +// CHECK: SpillAlignment: { Default:32 TestMode:64 } +// CHECK: CoveredBySubRegs: 1 +// CHECK: Regs: X0_X1 X2_X3 X4_X5 X6_X7 X8_X9 X10_X11 X12_X13 X14_X15 + +// CHECK-LABEL: SubRegIndex sub_even: +// CHECK: Offset: { Default:0 TestMode:0 } +// CHECK: Size: { Default:32 TestMode:64 } +// CHECK-LABEL: SubRegIndex sub_odd: +// CHECK: Offset: { Default:32 TestMode:64 } +// CHECK: Size: { Default:32 TestMode:64 } diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp index e851d4c16bf7..624e8d5d54ba 100644 --- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp +++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp @@ -47,19 +47,24 @@ using namespace llvm; // CodeGenSubRegIndex //===----------------------------------------------------------------------===// -CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum) +CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum, + const CodeGenHwModes &CGH) : TheDef(R), EnumValue(Enum), AllSuperRegsCovered(true), Artificial(true) { Name = std::string(R->getName()); if (R->getValue("Namespace")) Namespace = std::string(R->getValueAsString("Namespace")); - Size = R->getValueAsInt("Size"); - Offset = R->getValueAsInt("Offset"); + + if (const RecordVal *RV = R->getValue("SubRegRanges")) + if (auto *DI = dyn_cast_or_null(RV->getValue())) + Range = SubRegRangeByHwMode(DI->getDef(), CGH); + if (!Range.hasDefault()) + Range.insertSubRegRangeForMode(DefaultMode, SubRegRange(R)); } CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum) : TheDef(nullptr), Name(std::string(N)), Namespace(std::string(Nspace)), - Size(-1), Offset(-1), EnumValue(Enum), AllSuperRegsCovered(true), + Range(SubRegRange(-1, -1)), EnumValue(Enum), AllSuperRegsCovered(true), Artificial(true) {} std::string CodeGenSubRegIndex::getQualifiedName() const { @@ -81,7 +86,7 @@ void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) { "ComposedOf must have exactly two entries"); CodeGenSubRegIndex *A = RegBank.getSubRegIdx(Comps[0]); CodeGenSubRegIndex *B = RegBank.getSubRegIdx(Comps[1]); - CodeGenSubRegIndex *X = A->addComposite(B, this); + CodeGenSubRegIndex *X = A->addComposite(B, this, RegBank.getHwModes()); if (X) PrintFatalError(TheDef->getLoc(), "Ambiguous ComposedOf entries"); } @@ -518,7 +523,8 @@ void CodeGenRegister::computeSecondarySubRegs(CodeGenRegBank &RegBank) { // Each part of Cand is a sub-register of this. Make the full Cand also // a sub-register with a concatenated sub-register index. - CodeGenSubRegIndex *Concat = RegBank.getConcatSubRegIndex(Parts); + CodeGenSubRegIndex *Concat = + RegBank.getConcatSubRegIndex(Parts, RegBank.getHwModes()); std::pair NewSubReg = std::pair(Concat, Cand); @@ -542,7 +548,7 @@ void CodeGenRegister::computeSecondarySubRegs(CodeGenRegBank &RegBank) { PrintFatalError(TheDef->getLoc(), "No SubRegIndex for " + SubReg.second->getName() + " in " + getName()); - NewIdx->addComposite(SubReg.first, SubIdx); + NewIdx->addComposite(SubReg.first, SubIdx, RegBank.getHwModes()); } } } @@ -1315,7 +1321,7 @@ CodeGenSubRegIndex *CodeGenRegBank::getSubRegIdx(Record *Def) { CodeGenSubRegIndex *&Idx = Def2SubRegIdx[Def]; if (Idx) return Idx; - SubRegIndices.emplace_back(Def, SubRegIndices.size() + 1); + SubRegIndices.emplace_back(Def, SubRegIndices.size() + 1, getHwModes()); Idx = &SubRegIndices.back(); return Idx; } @@ -1379,12 +1385,13 @@ CodeGenRegBank::getCompositeSubRegIndex(CodeGenSubRegIndex *A, // None exists, synthesize one. std::string Name = A->getName() + "_then_" + B->getName(); Comp = createSubRegIndex(Name, A->getNamespace()); - A->addComposite(B, Comp); + A->addComposite(B, Comp, getHwModes()); return Comp; } CodeGenSubRegIndex *CodeGenRegBank::getConcatSubRegIndex( - const SmallVector &Parts) { + const SmallVector &Parts, + const CodeGenHwModes &CGH) { assert(Parts.size() > 1 && "Need two parts to concatenate"); #ifndef NDEBUG for (CodeGenSubRegIndex *Idx : Parts) { @@ -1399,28 +1406,47 @@ CodeGenSubRegIndex *CodeGenRegBank::getConcatSubRegIndex( // None exists, synthesize one. std::string Name = Parts.front()->getName(); - // Determine whether all parts are contiguous. - bool IsContinuous = true; - unsigned Size = Parts.front()->Size; - unsigned LastOffset = Parts.front()->Offset; - unsigned LastSize = Parts.front()->Size; const unsigned UnknownSize = (uint16_t)-1; + for (unsigned i = 1, e = Parts.size(); i != e; ++i) { Name += '_'; Name += Parts[i]->getName(); - if (Size == UnknownSize || Parts[i]->Size == UnknownSize) - Size = UnknownSize; - else - Size += Parts[i]->Size; - if (LastSize == UnknownSize || Parts[i]->Offset != (LastOffset + LastSize)) - IsContinuous = false; - LastOffset = Parts[i]->Offset; - LastSize = Parts[i]->Size; } + Idx = createSubRegIndex(Name, Parts.front()->getNamespace()); - Idx->Size = Size; - Idx->Offset = IsContinuous ? Parts.front()->Offset : -1; Idx->ConcatenationOf.assign(Parts.begin(), Parts.end()); + + unsigned NumModes = CGH.getNumModeIds(); + for (unsigned M = 0; M < NumModes; ++M) { + const CodeGenSubRegIndex *Part = Parts.front(); + + // Determine whether all parts are contiguous. + bool IsContinuous = true; + const SubRegRange &FirstPartRange = Part->Range.get(M); + unsigned Size = FirstPartRange.Size; + unsigned LastOffset = FirstPartRange.Offset; + unsigned LastSize = FirstPartRange.Size; + + for (unsigned i = 1, e = Parts.size(); i != e; ++i) { + Part = Parts[i]; + Name += '_'; + Name += Part->getName(); + + const SubRegRange &PartRange = Part->Range.get(M); + if (Size == UnknownSize || PartRange.Size == UnknownSize) + Size = UnknownSize; + else + Size += PartRange.Size; + if (LastSize == UnknownSize || + PartRange.Offset != (LastOffset + LastSize)) + IsContinuous = false; + LastOffset = PartRange.Offset; + LastSize = PartRange.Size; + } + unsigned Offset = IsContinuous ? FirstPartRange.Offset : -1; + Idx->Range.get(M) = SubRegRange(Size, Offset); + } + return Idx; } @@ -1504,7 +1530,8 @@ void CodeGenRegBank::computeComposites() { assert(Idx3 && "Sub-register doesn't have an index"); // Conflicting composition? Emit a warning but allow it. - if (CodeGenSubRegIndex *Prev = Idx1->addComposite(Idx2, Idx3)) { + if (CodeGenSubRegIndex *Prev = + Idx1->addComposite(Idx2, Idx3, getHwModes())) { // If the composition was not user-defined, always emit a warning. if (!UserDefined.count({Idx1, Idx2}) || agree(compose(Idx1, Idx2), SubRegAction.at(Idx3))) diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h index c34f376ea99d..9058baea2b23 100644 --- a/llvm/utils/TableGen/Common/CodeGenRegisters.h +++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h @@ -68,8 +68,7 @@ class CodeGenSubRegIndex { std::string Namespace; public: - uint16_t Size; - uint16_t Offset; + SubRegRangeByHwMode Range; const unsigned EnumValue; mutable LaneBitmask LaneMask; mutable SmallVector CompositionLaneMaskTransform; @@ -86,7 +85,7 @@ public: // indexes are not used to create new register classes. bool Artificial; - CodeGenSubRegIndex(Record *R, unsigned Enum); + CodeGenSubRegIndex(Record *R, unsigned Enum, const CodeGenHwModes &CGH); CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum); CodeGenSubRegIndex(CodeGenSubRegIndex &) = delete; @@ -108,19 +107,42 @@ public: // Add a composite subreg index: this+A = B. // Return a conflicting composite, or NULL - CodeGenSubRegIndex *addComposite(CodeGenSubRegIndex *A, - CodeGenSubRegIndex *B) { + CodeGenSubRegIndex *addComposite(CodeGenSubRegIndex *A, CodeGenSubRegIndex *B, + const CodeGenHwModes &CGH) { assert(A && B); std::pair Ins = Composed.insert(std::pair(A, B)); + // Synthetic subreg indices that aren't contiguous (for instance ARM // register tuples) don't have a bit range, so it's OK to let // B->Offset == -1. For the other cases, accumulate the offset and set // the size here. Only do so if there is no offset yet though. - if ((Offset != (uint16_t)-1 && A->Offset != (uint16_t)-1) && - (B->Offset == (uint16_t)-1)) { - B->Offset = Offset + A->Offset; - B->Size = A->Size; + unsigned NumModes = CGH.getNumModeIds(); + // Skip default mode. + for (unsigned M = 0; M < NumModes; ++M) { + // Handle DefaultMode last. + if (M == DefaultMode) + continue; + SubRegRange &Range = this->Range.get(M); + SubRegRange &ARange = A->Range.get(M); + SubRegRange &BRange = B->Range.get(M); + + if (Range.Offset != (uint16_t)-1 && ARange.Offset != (uint16_t)-1 && + BRange.Offset == (uint16_t)-1) { + BRange.Offset = Range.Offset + ARange.Offset; + BRange.Size = ARange.Size; + } } + + // Now handle default. + SubRegRange &Range = this->Range.get(DefaultMode); + SubRegRange &ARange = A->Range.get(DefaultMode); + SubRegRange &BRange = B->Range.get(DefaultMode); + if (Range.Offset != (uint16_t)-1 && ARange.Offset != (uint16_t)-1 && + BRange.Offset == (uint16_t)-1) { + BRange.Offset = Range.Offset + ARange.Offset; + BRange.Size = ARange.Size; + } + return (Ins.second || Ins.first->second == B) ? nullptr : Ins.first->second; } @@ -681,7 +703,8 @@ public: // Find or create a sub-register index representing the concatenation of // non-overlapping sibling indices. CodeGenSubRegIndex * - getConcatSubRegIndex(const SmallVector &); + getConcatSubRegIndex(const SmallVector &, + const CodeGenHwModes &CGH); const std::deque &getRegisters() const { return Registers; } diff --git a/llvm/utils/TableGen/Common/InfoByHwMode.cpp b/llvm/utils/TableGen/Common/InfoByHwMode.cpp index 5496408bb0d3..cacf4ece6671 100644 --- a/llvm/utils/TableGen/Common/InfoByHwMode.cpp +++ b/llvm/utils/TableGen/Common/InfoByHwMode.cpp @@ -183,6 +183,20 @@ void RegSizeInfoByHwMode::writeToStream(raw_ostream &OS) const { OS << '}'; } +SubRegRange::SubRegRange(Record *R) { + Size = R->getValueAsInt("Size"); + Offset = R->getValueAsInt("Offset"); +} + +SubRegRangeByHwMode::SubRegRangeByHwMode(Record *R, const CodeGenHwModes &CGH) { + const HwModeSelect &MS = CGH.getHwModeSelect(R); + for (const HwModeSelect::PairType &P : MS.Items) { + auto I = Map.insert({P.first, SubRegRange(P.second)}); + assert(I.second && "Duplicate entry?"); + (void)I; + } +} + EncodingInfoByHwMode::EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH) { const HwModeSelect &MS = CGH.getHwModeSelect(R); diff --git a/llvm/utils/TableGen/Common/InfoByHwMode.h b/llvm/utils/TableGen/Common/InfoByHwMode.h index 1909913c50c6..dd0b9830d757 100644 --- a/llvm/utils/TableGen/Common/InfoByHwMode.h +++ b/llvm/utils/TableGen/Common/InfoByHwMode.h @@ -176,6 +176,8 @@ struct ValueTypeByHwMode : public InfoByHwMode { ValueTypeByHwMode getValueTypeByHwMode(Record *Rec, const CodeGenHwModes &CGH); +raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T); + struct RegSizeInfo { unsigned RegSize; unsigned SpillSize; @@ -213,10 +215,27 @@ struct RegSizeInfoByHwMode : public InfoByHwMode { } }; -raw_ostream &operator<<(raw_ostream &OS, const ValueTypeByHwMode &T); raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfo &T); raw_ostream &operator<<(raw_ostream &OS, const RegSizeInfoByHwMode &T); +struct SubRegRange { + uint16_t Size; + uint16_t Offset; + + SubRegRange(Record *R); + SubRegRange(uint16_t Size, uint16_t Offset) : Size(Size), Offset(Offset) {} +}; + +struct SubRegRangeByHwMode : public InfoByHwMode { + SubRegRangeByHwMode(Record *R, const CodeGenHwModes &CGH); + SubRegRangeByHwMode(SubRegRange Range) { Map.insert({DefaultMode, Range}); } + SubRegRangeByHwMode() = default; + + void insertSubRegRangeForMode(unsigned Mode, SubRegRange Info) { + Map.insert(std::pair(Mode, Info)); + } +}; + struct EncodingInfoByHwMode : public InfoByHwMode { EncodingInfoByHwMode(Record *R, const CodeGenHwModes &CGH); EncodingInfoByHwMode() = default; diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index a1259bff6ba8..ee8830edeedb 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -1245,10 +1245,13 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target, // Emit the table of sub-register index sizes. OS << "static const TargetRegisterInfo::SubRegCoveredBits " "SubRegIdxRangeTable[] = {\n"; - OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n"; - for (const auto &Idx : SubRegIndices) { - OS << " { " << Idx.Offset << ", " << Idx.Size << " },\t// " - << Idx.getName() << "\n"; + for (unsigned M = 0; M < NumModes; ++M) { + OS << " { " << (uint16_t)-1 << ", " << (uint16_t)-1 << " },\n"; + for (const auto &Idx : SubRegIndices) { + const SubRegRange &Range = Idx.Range.get(M); + OS << " { " << Range.Offset << ", " << Range.Size << " },\t// " + << Idx.getName() << "\n"; + } } OS << "};\n\n"; @@ -1864,7 +1867,13 @@ void RegisterInfoEmitter::debugDump(raw_ostream &OS) { OS << "SubRegIndex " << SRI.getName() << ":\n"; OS << "\tLaneMask: " << PrintLaneMask(SRI.LaneMask) << '\n'; OS << "\tAllSuperRegsCovered: " << SRI.AllSuperRegsCovered << '\n'; - OS << "\tOffset, Size: " << SRI.Offset << ", " << SRI.Size << '\n'; + OS << "\tOffset: {"; + for (unsigned M = 0; M != NumModes; ++M) + OS << ' ' << getModeName(M) << ':' << SRI.Range.get(M).Offset; + OS << " }\n\tSize: {"; + for (unsigned M = 0; M != NumModes; ++M) + OS << ' ' << getModeName(M) << ':' << SRI.Range.get(M).Size; + OS << " }\n"; } for (const CodeGenRegister &R : RegBank.getRegisters()) {