[llvm] [NFC][TableGen] Minor code cleanup in CodeGenRegister (PR #137994)
Rahul Joshi via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 30 10:08:25 PDT 2025
https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/137994
- Use range for loops.
>From 90908ec01da7bf1ceb8fc6da10cf84e98722b853 Mon Sep 17 00:00:00 2001
From: Rahul Joshi <rjoshi at nvidia.com>
Date: Wed, 30 Apr 2025 08:15:01 -0700
Subject: [PATCH] [NFC][TableGen] Minor code cleanup in CodeGenRegister
- Use range for loops.
---
llvm/include/llvm/TableGen/Record.h | 22 +-
.../TableGen/Common/CodeGenRegisters.cpp | 218 +++++++++---------
llvm/utils/TableGen/Common/CodeGenRegisters.h | 4 +-
3 files changed, 117 insertions(+), 127 deletions(-)
diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h
index 0a10f6a74d009..1da72b48e66f1 100644
--- a/llvm/include/llvm/TableGen/Record.h
+++ b/llvm/include/llvm/TableGen/Record.h
@@ -632,10 +632,11 @@ class BitsInit final : public TypedInit,
const Init *resolveReferences(Resolver &R) const override;
- const Init *getBit(unsigned Bit) const override {
- assert(Bit < NumBits && "Bit index out of range!");
- return getTrailingObjects<const Init *>()[Bit];
+ ArrayRef<const Init *> getBits() const {
+ return ArrayRef(getTrailingObjects<const Init *>(), NumBits);
}
+
+ const Init *getBit(unsigned Bit) const override { return getBits()[Bit]; }
};
/// '7' - Represent an initialization by a literal integer value.
@@ -781,10 +782,15 @@ class ListInit final : public TypedInit,
void Profile(FoldingSetNodeID &ID) const;
+ ArrayRef<const Init *> getValues() const {
+ return ArrayRef(getTrailingObjects<const Init *>(), NumValues);
+ }
+
const Init *getElement(unsigned i) const {
assert(i < NumValues && "List element index out of range!");
- return getTrailingObjects<const Init *>()[i];
+ return getValues()[i];
}
+
const RecTy *getElementType() const {
return cast<ListRecTy>(getType())->getElementType();
}
@@ -804,12 +810,8 @@ class ListInit final : public TypedInit,
bool isConcrete() const override;
std::string getAsString() const override;
- ArrayRef<const Init *> getValues() const {
- return ArrayRef(getTrailingObjects<const Init *>(), NumValues);
- }
-
- const_iterator begin() const { return getTrailingObjects<const Init *>(); }
- const_iterator end () const { return begin() + NumValues; }
+ const_iterator begin() const { return getValues().begin(); }
+ const_iterator end() const { return getValues().end(); }
size_t size () const { return NumValues; }
bool empty() const { return NumValues == 0; }
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
index 10d84b5101c3a..4ca70242b3508 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.cpp
@@ -126,11 +126,11 @@ LaneBitmask CodeGenSubRegIndex::computeLaneMask() const {
void CodeGenSubRegIndex::setConcatenationOf(
ArrayRef<CodeGenSubRegIndex *> Parts) {
- if (ConcatenationOf.empty())
+ if (ConcatenationOf.empty()) {
ConcatenationOf.assign(Parts.begin(), Parts.end());
- else
- assert(std::equal(Parts.begin(), Parts.end(), ConcatenationOf.begin()) &&
- "parts consistent");
+ return;
+ }
+ assert(llvm::equal(Parts, ConcatenationOf) && "parts consistent");
}
void CodeGenSubRegIndex::computeConcatTransitiveClosure() {
@@ -178,9 +178,9 @@ void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) {
PrintFatalError(TheDef->getLoc(),
"SubRegs and SubRegIndices must have the same size");
- for (unsigned i = 0, e = SRIs.size(); i != e; ++i) {
- ExplicitSubRegIndices.push_back(RegBank.getSubRegIdx(SRIs[i]));
- ExplicitSubRegs.push_back(RegBank.getReg(SRs[i]));
+ for (const auto &[SRI, SR] : zip_equal(SRIs, SRs)) {
+ ExplicitSubRegIndices.push_back(RegBank.getSubRegIdx(SRI));
+ ExplicitSubRegs.push_back(RegBank.getReg(SR));
}
// Also compute leading super-registers. Each register has a list of
@@ -200,11 +200,6 @@ void CodeGenRegister::buildObjectGraph(CodeGenRegBank &RegBank) {
}
}
-StringRef CodeGenRegister::getName() const {
- assert(TheDef && "no def");
- return TheDef->getName();
-}
-
namespace {
// Iterate over all register units in a set of registers.
@@ -708,9 +703,7 @@ struct TupleExpander : SetTheory::Expander {
NewReg->addDirectSuperClass(Super, Loc);
// Copy Proto fields.
- for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) {
- RecordVal RV = Proto->getValues()[i];
-
+ for (RecordVal RV : Proto->getValues()) {
// Skip existing fields, like NAME.
if (NewReg->getValue(RV.getNameInit()))
continue;
@@ -773,8 +766,7 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
std::vector<const Record *> TypeList = R->getValueAsListOfDefs("RegTypes");
if (TypeList.empty())
PrintFatalError(R->getLoc(), "RegTypes list must not be empty!");
- for (unsigned i = 0, e = TypeList.size(); i != e; ++i) {
- const Record *Type = TypeList[i];
+ for (const Record *Type : TypeList) {
if (!Type->isSubClassOf("ValueType"))
PrintFatalError(R->getLoc(),
"RegTypes list member '" + Type->getName() +
@@ -789,9 +781,9 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
// 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]);
+ for (const Record *Element : *Elements) {
+ Orders[0].push_back(Element);
+ const CodeGenRegister *Reg = RegBank.getReg(Element);
Members.push_back(Reg);
Artificial &= Reg->Artificial;
if (!Reg->getSuperRegs().empty())
@@ -801,9 +793,9 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
// Alternative allocation orders may be subsets.
SetTheory::RecSet Order;
- for (unsigned i = 0, e = AltOrders->size(); i != e; ++i) {
- RegBank.getSets().evaluate(AltOrders->getElement(i), Order, R->getLoc());
- Orders[1 + i].append(Order.begin(), Order.end());
+ for (auto [Idx, AltOrderElem] : enumerate(AltOrders->getValues())) {
+ RegBank.getSets().evaluate(AltOrderElem, Order, R->getLoc());
+ Orders[1 + Idx].append(Order.begin(), Order.end());
// Verify that all altorder members are regclass members.
while (!Order.empty()) {
CodeGenRegister *Reg = RegBank.getReg(Order.back());
@@ -841,10 +833,8 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
GlobalPriority = R->getValueAsBit("GlobalPriority");
const BitsInit *TSF = R->getValueAsBitsInit("TSFlags");
- for (unsigned I = 0, E = TSF->getNumBits(); I != E; ++I) {
- const BitInit *Bit = cast<BitInit>(TSF->getBit(I));
- TSFlags |= uint8_t(Bit->getValue()) << I;
- }
+ for (auto [Idx, Bit] : enumerate(TSF->getBits()))
+ TSFlags |= uint8_t(cast<BitInit>(Bit)->getValue()) << Idx;
}
// Create an inferred register class that was missing from the .td files.
@@ -895,10 +885,10 @@ void CodeGenRegisterClass::inheritProperties(CodeGenRegBank &RegBank) {
// Copy all allocation orders, filter out foreign registers from the larger
// super-class.
Orders.resize(Super.Orders.size());
- for (unsigned i = 0, ie = Super.Orders.size(); i != ie; ++i)
- for (unsigned j = 0, je = Super.Orders[i].size(); j != je; ++j)
- if (contains(RegBank.getReg(Super.Orders[i][j])))
- Orders[i].push_back(Super.Orders[i][j]);
+ for (auto [Idx, Outer] : enumerate(Super.Orders))
+ for (const Record *Reg : Outer)
+ if (contains(RegBank.getReg(Reg)))
+ Orders[Idx].push_back(Reg);
}
bool CodeGenRegisterClass::hasType(const ValueTypeByHwMode &VT) const {
@@ -1248,13 +1238,13 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
llvm::sort(Regs, LessRecordRegister());
// Assign the enumeration values.
- for (unsigned i = 0, e = Regs.size(); i != e; ++i)
- getReg(Regs[i]);
+ for (const Record *Reg : Regs)
+ getReg(Reg);
} else {
llvm::sort(Regs, LessRecordRegister());
// Assign the enumeration values.
- for (unsigned i = 0, e = Regs.size(); i != e; ++i)
- getReg(Regs[i]);
+ for (const Record *Reg : Regs)
+ getReg(Reg);
// Expand tuples and number the new registers.
for (const Record *R : Records.getAllDerivedDefinitions("RegisterTuples")) {
@@ -1341,9 +1331,8 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
// Order register classes topologically and assign enum values.
RegClasses.sort(TopoOrderRC);
- unsigned i = 0;
- for (auto &RC : RegClasses)
- RC.EnumValue = i++;
+ for (auto [Idx, RC] : enumerate(RegClasses))
+ RC.EnumValue = Idx;
CodeGenRegisterClass::computeSubClasses(*this);
// Read in the register category definitions.
@@ -1449,9 +1438,9 @@ CodeGenSubRegIndex *CodeGenRegBank::getConcatSubRegIndex(
std::string Name = Parts.front()->getName();
const unsigned UnknownSize = (uint16_t)-1;
- for (unsigned i = 1, e = Parts.size(); i != e; ++i) {
+ for (const CodeGenSubRegIndex *Part : ArrayRef(Parts).drop_front()) {
Name += '_';
- Name += Parts[i]->getName();
+ Name += Part->getName();
}
Idx = createSubRegIndex(Name, Parts.front()->getNamespace());
@@ -1459,20 +1448,16 @@ CodeGenSubRegIndex *CodeGenRegBank::getConcatSubRegIndex(
unsigned NumModes = CGH.getNumModeIds();
for (unsigned M = 0; M < NumModes; ++M) {
- const CodeGenSubRegIndex *Part = Parts.front();
+ const CodeGenSubRegIndex *FirstPart = Parts.front();
// Determine whether all parts are contiguous.
bool IsContinuous = true;
- const SubRegRange &FirstPartRange = Part->Range.get(M);
+ const SubRegRange &FirstPartRange = FirstPart->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();
-
+ for (const CodeGenSubRegIndex *Part : ArrayRef(Parts).drop_front()) {
const SubRegRange &PartRange = Part->Range.get(M);
if (Size == UnknownSize || PartRange.Size == UnknownSize)
Size = UnknownSize;
@@ -1887,17 +1872,14 @@ static void computeUberSets(std::vector<UberRegSet> &UberSets,
}
// Recompute each UberSet weight after changing unit weights.
-static void computeUberWeights(std::vector<UberRegSet> &UberSets,
+static void computeUberWeights(MutableArrayRef<UberRegSet> UberSets,
CodeGenRegBank &RegBank) {
// Skip the first unallocatable set.
- for (std::vector<UberRegSet>::iterator I = std::next(UberSets.begin()),
- E = UberSets.end();
- I != E; ++I) {
-
+ for (UberRegSet &S : UberSets.drop_front()) {
// Initialize all unit weights in this set, and remember the max units/reg.
const CodeGenRegister *Reg = nullptr;
unsigned MaxWeight = 0, Weight = 0;
- for (RegUnitIterator UnitI(I->Regs); UnitI.isValid(); ++UnitI) {
+ for (RegUnitIterator UnitI(S.Regs); UnitI.isValid(); ++UnitI) {
if (Reg != UnitI.getReg()) {
if (Weight > MaxWeight)
MaxWeight = Weight;
@@ -1915,23 +1897,22 @@ static void computeUberWeights(std::vector<UberRegSet> &UberSets,
}
if (Weight > MaxWeight)
MaxWeight = Weight;
- if (I->Weight != MaxWeight) {
- LLVM_DEBUG(dbgs() << "UberSet " << I - UberSets.begin() << " Weight "
- << MaxWeight;
- for (auto &Unit
- : I->Regs) dbgs()
- << " " << Unit->getName();
- dbgs() << "\n");
+ if (S.Weight != MaxWeight) {
+ LLVM_DEBUG({
+ dbgs() << "UberSet " << &S - UberSets.begin() << " Weight "
+ << MaxWeight;
+ for (auto &Unit : S.Regs)
+ dbgs() << " " << Unit->getName();
+ dbgs() << '\n';
+ });
// Update the set weight.
- I->Weight = MaxWeight;
+ S.Weight = MaxWeight;
}
// Find singular determinants.
- for (const auto R : I->Regs) {
- if (R->getRegUnits().count() == 1 && R->getWeight(RegBank) == I->Weight) {
- I->SingularDeterminants |= R->getRegUnits();
- }
- }
+ for (const auto R : S.Regs)
+ if (R->getRegUnits().count() == 1 && R->getWeight(RegBank) == S.Weight)
+ S.SingularDeterminants |= R->getRegUnits();
}
}
@@ -2068,9 +2049,8 @@ void CodeGenRegBank::pruneUnitSets() {
// Form an equivalence class of UnitSets with no significant difference.
std::vector<unsigned> SuperSetIDs;
- for (unsigned SubIdx = 0, EndIdx = RegUnitSets.size(); SubIdx != EndIdx;
- ++SubIdx) {
- const RegUnitSet &SubSet = RegUnitSets[SubIdx];
+ unsigned EndIdx = RegUnitSets.size();
+ for (auto [SubIdx, SubSet] : enumerate(RegUnitSets)) {
unsigned SuperIdx = 0;
for (; SuperIdx != EndIdx; ++SuperIdx) {
if (SuperIdx == SubIdx)
@@ -2082,8 +2062,9 @@ void CodeGenRegBank::pruneUnitSets() {
(SubSet.Units.size() + 3 > SuperSet.Units.size()) &&
UnitWeight == RegUnits[SuperSet.Units[0]].Weight &&
UnitWeight == RegUnits[SuperSet.Units.back()].Weight) {
- LLVM_DEBUG(dbgs() << "UnitSet " << SubIdx << " subsumed by " << SuperIdx
- << "\n");
+ LLVM_DEBUG({
+ dbgs() << "UnitSet " << SubIdx << " subsumed by " << SuperIdx << '\n';
+ });
// We can pick any of the set names for the merged set. Go for the
// shortest one to avoid picking the name of one of the classes that are
// artificially created by tablegen. So "FPR128_lo" instead of
@@ -2099,8 +2080,7 @@ void CodeGenRegBank::pruneUnitSets() {
// Populate PrunedUnitSets with each equivalence class's superset.
std::vector<RegUnitSet> PrunedUnitSets;
PrunedUnitSets.reserve(SuperSetIDs.size());
- for (unsigned i = 0, e = SuperSetIDs.size(); i != e; ++i) {
- unsigned SuperIdx = SuperSetIDs[i];
+ for (unsigned SuperIdx : SuperSetIDs) {
PrunedUnitSets.emplace_back(RegUnitSets[SuperIdx].Name);
PrunedUnitSets.back().Units = std::move(RegUnitSets[SuperIdx].Units);
}
@@ -2135,28 +2115,33 @@ void CodeGenRegBank::computeRegUnitSets() {
if (RegUnitSets.empty())
PrintFatalError("RegUnitSets cannot be empty!");
- LLVM_DEBUG(dbgs() << "\nBefore pruning:\n"; for (unsigned USIdx = 0,
- USEnd = RegUnitSets.size();
- USIdx < USEnd; ++USIdx) {
- dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":";
- for (auto &U : RegUnitSets[USIdx].Units)
- printRegUnitName(U);
- dbgs() << "\n";
+ LLVM_DEBUG({
+ dbgs() << "\nBefore pruning:\n";
+ for (auto [USIdx, US] : enumerate(RegUnitSets)) {
+ dbgs() << "UnitSet " << USIdx << " " << US.Name << ":";
+ for (auto &U : US.Units)
+ printRegUnitName(U);
+ dbgs() << '\n';
+ }
});
// Iteratively prune unit sets.
pruneUnitSets();
- LLVM_DEBUG(dbgs() << "\nBefore union:\n"; for (unsigned USIdx = 0,
- USEnd = RegUnitSets.size();
- USIdx < USEnd; ++USIdx) {
- dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":";
- for (auto &U : RegUnitSets[USIdx].Units)
- printRegUnitName(U);
- dbgs() << "\n";
- } dbgs() << "\nUnion sets:\n");
+ LLVM_DEBUG({
+ dbgs() << "\nBefore union:\n";
+ for (auto [USIdx, US] : enumerate(RegUnitSets)) {
+ dbgs() << "UnitSet " << USIdx << " " << US.Name << ":";
+ for (auto &U : US.Units)
+ printRegUnitName(U);
+ dbgs() << '\n';
+ }
+ dbgs() << "\nUnion sets:\n";
+ });
// Iterate over all unit sets, including new ones added by this loop.
+ // FIXME: Since `EndIdx` is computed just once during loop initialization,
+ // does this really iterate over new unit sets added by this loop?
unsigned NumRegUnitSubSets = RegUnitSets.size();
for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) {
// In theory, this is combinatorial. In practice, it needs to be bounded
@@ -2185,11 +2170,13 @@ void CodeGenRegBank::computeRegUnitSets() {
// Find an existing RegUnitSet, or add the union to the unique sets.
if (findRegUnitSet(RegUnitSets, RUSet) == RegUnitSets.end()) {
- LLVM_DEBUG(dbgs() << "UnitSet " << RegUnitSets.size() << " "
- << RUSet.Name << ":";
- for (auto &U
- : RUSet.Units) printRegUnitName(U);
- dbgs() << "\n";);
+ LLVM_DEBUG({
+ dbgs() << "UnitSet " << RegUnitSets.size() << " " << RUSet.Name
+ << ":";
+ for (auto &U : RUSet.Units)
+ printRegUnitName(U);
+ dbgs() << '\n';
+ });
RegUnitSets.push_back(std::move(RUSet));
}
}
@@ -2198,14 +2185,15 @@ void CodeGenRegBank::computeRegUnitSets() {
// Iteratively prune unit sets after inferring supersets.
pruneUnitSets();
- LLVM_DEBUG(
- dbgs() << "\n"; for (unsigned USIdx = 0, USEnd = RegUnitSets.size();
- USIdx < USEnd; ++USIdx) {
- dbgs() << "UnitSet " << USIdx << " " << RegUnitSets[USIdx].Name << ":";
- for (auto &U : RegUnitSets[USIdx].Units)
- printRegUnitName(U);
- dbgs() << "\n";
- });
+ LLVM_DEBUG({
+ dbgs() << '\n';
+ for (auto [USIdx, US] : enumerate(RegUnitSets)) {
+ dbgs() << "UnitSet " << USIdx << " " << US.Name << ":";
+ for (auto &U : US.Units)
+ printRegUnitName(U);
+ dbgs() << '\n';
+ }
+ });
// For each register class, list the UnitSets that are supersets.
RegClassUnitSets.resize(RegClasses.size());
@@ -2221,20 +2209,21 @@ void CodeGenRegBank::computeRegUnitSets() {
if (RCRegUnits.empty())
continue;
- LLVM_DEBUG(dbgs() << "RC " << RC.getName() << " Units:\n";
- for (auto U
- : RCRegUnits) printRegUnitName(U);
- dbgs() << "\n UnitSetIDs:");
+ LLVM_DEBUG({
+ dbgs() << "RC " << RC.getName() << " Units:\n";
+ for (auto U : RCRegUnits)
+ printRegUnitName(U);
+ dbgs() << "\n UnitSetIDs:";
+ });
// Find all supersets.
- for (unsigned USIdx = 0, USEnd = RegUnitSets.size(); USIdx != USEnd;
- ++USIdx) {
- if (isRegUnitSubSet(RCRegUnits, RegUnitSets[USIdx].Units)) {
+ for (const auto &[USIdx, Set] : enumerate(RegUnitSets)) {
+ if (isRegUnitSubSet(RCRegUnits, Set.Units)) {
LLVM_DEBUG(dbgs() << " " << USIdx);
RegClassUnitSets[RC.EnumValue].push_back(USIdx);
}
}
- LLVM_DEBUG(dbgs() << "\n");
+ LLVM_DEBUG(dbgs() << '\n');
assert(
(!RegClassUnitSets[RC.EnumValue].empty() || !RC.GeneratePressureSet) &&
"missing unit set for regclass");
@@ -2247,10 +2236,10 @@ void CodeGenRegBank::computeRegUnitSets() {
for (unsigned UnitIdx = 0, UnitEnd = NumNativeRegUnits; UnitIdx < UnitEnd;
++UnitIdx) {
std::vector<unsigned> RUSets;
- for (unsigned i = 0, e = RegUnitSets.size(); i != e; ++i) {
- if (is_contained(RegUnitSets[i].Units, UnitIdx))
- RUSets.push_back(i);
- }
+ for (auto [Idx, S] : enumerate(RegUnitSets))
+ if (is_contained(S.Units, UnitIdx))
+ RUSets.push_back(Idx);
+
unsigned RCUnitSetsIdx = 0;
for (unsigned e = RegClassUnitSets.size(); RCUnitSetsIdx != e;
++RCUnitSetsIdx) {
@@ -2341,9 +2330,8 @@ void CodeGenRegBank::computeDerivedInfo() {
return getRegPressureSet(ID1).Units.size() <
getRegPressureSet(ID2).Units.size();
});
- for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx) {
+ for (unsigned Idx = 0, EndIdx = RegUnitSets.size(); Idx != EndIdx; ++Idx)
RegUnitSets[RegUnitSetOrder[Idx]].Order = Idx;
- }
}
//
diff --git a/llvm/utils/TableGen/Common/CodeGenRegisters.h b/llvm/utils/TableGen/Common/CodeGenRegisters.h
index f9a7904709830..4acfdb6e19d03 100644
--- a/llvm/utils/TableGen/Common/CodeGenRegisters.h
+++ b/llvm/utils/TableGen/Common/CodeGenRegisters.h
@@ -185,7 +185,7 @@ class CodeGenRegister {
CodeGenRegister(const Record *R, unsigned Enum);
- StringRef getName() const;
+ StringRef getName() const { return TheDef->getName(); }
// Extract more information from TheDef. This is used to build an object
// graph after all CodeGenRegister objects have been created.
@@ -734,7 +734,7 @@ class CodeGenRegBank {
// Find or create a sub-register index representing the concatenation of
// non-overlapping sibling indices.
CodeGenSubRegIndex *
- getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8> &,
+ getConcatSubRegIndex(const SmallVector<CodeGenSubRegIndex *, 8> &Parts,
const CodeGenHwModes &CGH);
const std::deque<CodeGenRegister> &getRegisters() const { return Registers; }
More information about the llvm-commits
mailing list