[llvm] c4484e8 - [CodeGen] De-type getMinimalPhysRegClass and related APIs (#197495)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 1 22:49:31 PDT 2026
Author: Cullen Rhodes
Date: 2026-06-02T06:49:26+01:00
New Revision: c4484e8422745ab8c1ada25a6bda5d69ef8da924
URL: https://github.com/llvm/llvm-project/commit/c4484e8422745ab8c1ada25a6bda5d69ef8da924
DIFF: https://github.com/llvm/llvm-project/commit/c4484e8422745ab8c1ada25a6bda5d69ef8da924.diff
LOG: [CodeGen] De-type getMinimalPhysRegClass and related APIs (#197495)
Follow-up #193438 to de-type getMinimalPhysRegClass so it can be replaced with
the precomputed getDefaultMinimalPhysRegClass. Type is also removed from
related APIs.
There's very few uses of getMinimalPhysRegClass with a non-default type
(MVT::Other) and none at all for getCommonMinimalPhysRegClass. Rather than
trying to also handle the type when precomputing at compile-time it seems
better to remove the type altogether and simplify the APIs. This also improves
compile-time for a number of targets and configurations:
CTMark geomean:
- stage1-O3: -0.23%
- stage1-ReleaseThinLTO: -0.19%
- stage1-ReleaseLTO-g: -0.15%
- stage1-aarch64-O3: -0.57%
- stage2-O3: -0.23%
- clang: -0.13%
https://llvm-compile-time-tracker.com/compare.php?from=eae0b6b2498305ee29dc85a405ede9ccdc10ce7d&to=08c052a2db407d2a21d468001fd2035d3720acf7&stat=instructions%3Au
Assisted-by: codex
Added:
Modified:
llvm/docs/ReleaseNotes.md
llvm/include/llvm/CodeGen/TargetRegisterInfo.h
llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
llvm/lib/CodeGen/MachineVerifier.cpp
llvm/lib/CodeGen/RegisterBankInfo.cpp
llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
llvm/lib/CodeGen/TargetRegisterInfo.cpp
llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
llvm/unittests/CodeGen/MFCommon.inc
llvm/utils/TableGen/RegisterInfoEmitter.cpp
Removed:
################################################################################
diff --git a/llvm/docs/ReleaseNotes.md b/llvm/docs/ReleaseNotes.md
index a222c5a146964..ef77fe1ba28a8 100644
--- a/llvm/docs/ReleaseNotes.md
+++ b/llvm/docs/ReleaseNotes.md
@@ -140,6 +140,10 @@ Makes programs 10x faster by doing Special New Thing.
Use the new ``remove_if`` member to erase matching elements in a single pass
instead of erasing while iterating.
+* ``TargetRegisterInfo::getMinimalPhysRegClass`` and related APIs have been
+ refactored and no longer take a type. This API is also now precomputed in
+ TableGen to improve compile-time.
+
### Changes to building LLVM
### Changes to TableGen
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 8148d11417128..7c3c56552b82c 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -353,33 +353,15 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
return I;
}
- /// Returns the Register Class of a physical register of the given type,
- /// picking the most sub register class of the right type that contains this
- /// physreg.
- const TargetRegisterClass *getMinimalPhysRegClass(MCRegister Reg,
- MVT VT = MVT::Other) const;
-
- /// Returns the common Register Class of two physical registers of the given
- /// type, picking the most sub register class of the right type that contains
- /// these two physregs.
- const TargetRegisterClass *
- getCommonMinimalPhysRegClass(MCRegister Reg1, MCRegister Reg2,
- MVT VT = MVT::Other) const;
-
- /// Returns the Register Class of a physical register of the given type,
- /// picking the most sub register class of the right type that contains this
- /// physreg. If there is no register class compatible with the given type,
- /// returns nullptr.
- const TargetRegisterClass *getMinimalPhysRegClassLLT(MCRegister Reg,
- LLT Ty = LLT()) const;
-
- /// Returns the common Register Class of two physical registers of the given
- /// type, picking the most sub register class of the right type that contains
- /// these two physregs. If there is no register class compatible with the
- /// given type, returns nullptr.
+ /// Returns the Register Class of a physical register, picking the smallest
+ /// register subclass that contains this physreg.
+ virtual const TargetRegisterClass *
+ getMinimalPhysRegClass(MCRegister Reg) const = 0;
+
+ /// Returns the common Register Class of two physical registers, picking the
+ /// smallest register subclass that contains these two physregs.
const TargetRegisterClass *
- getCommonMinimalPhysRegClassLLT(MCRegister Reg1, MCRegister Reg2,
- LLT Ty = LLT()) const;
+ getCommonMinimalPhysRegClass(MCRegister Reg1, MCRegister Reg2) const;
/// Return the maximal subclass of the given register class that is
/// allocatable or NULL.
@@ -829,13 +811,6 @@ class LLVM_ABI TargetRegisterInfo : public MCRegisterInfo {
return nullptr;
}
- /// Returns the target-defined minimal register class for an untyped physical
- /// register query or nullptr if the register is not in any register class.
- virtual const TargetRegisterClass *
- getDefaultMinimalPhysRegClass(MCRegister Reg) const {
- return nullptr;
- }
-
protected:
/// Overridden by TableGen in targets that have sub-registers.
virtual unsigned composeSubRegIndicesImpl(unsigned, unsigned) const {
diff --git a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
index 060582cec74d8..6be353bb8da63 100644
--- a/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ b/llvm/lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -606,8 +606,7 @@ bool AggressiveAntiDepBreaker::FindSuitableFreeRegisters(
// FIXME: Using getMinimalPhysRegClass is very conservative. We should
// check every use of the register and find the largest register class
// that can be used in all of them.
- const TargetRegisterClass *SuperRC =
- TRI->getMinimalPhysRegClass(SuperReg, MVT::Other);
+ const TargetRegisterClass *SuperRC = TRI->getMinimalPhysRegClass(SuperReg);
ArrayRef<MCPhysReg> Order = RegClassInfo.getOrder(SuperRC);
if (Order.empty()) {
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index af38525af6a6b..c611b837a86b4 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -99,6 +99,20 @@ namespace {
/// at one time.
static ManagedStatic<sys::SmartMutex<true>> ReportedErrorsLock;
+static bool hasPhysRegClassForType(const TargetRegisterInfo &TRI,
+ MCRegister Reg, LLT Ty) {
+ assert(Reg.isPhysical() && "reg must be a physical register");
+ assert(Ty.isValid() && "expected a valid type");
+
+ const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(Reg);
+ if (TRI.isTypeLegalForClass(*RC, Ty))
+ return true;
+
+ return llvm::any_of(TRI.regclasses(), [&](const TargetRegisterClass *RC) {
+ return RC->contains(Reg) && TRI.isTypeLegalForClass(*RC, Ty);
+ });
+}
+
struct MachineVerifier {
MachineVerifier(MachineFunctionAnalysisManager &MFAM, const char *b,
raw_ostream *OS, bool AbortOnError = true)
@@ -2420,18 +2434,14 @@ void MachineVerifier::visitMachineInstrBefore(const MachineInstr *MI) {
TypeSize SrcSize = TypeSize::getZero();
TypeSize DstSize = TypeSize::getZero();
if (SrcReg.isPhysical() && DstTy.isValid()) {
- const TargetRegisterClass *SrcRC =
- TRI->getMinimalPhysRegClassLLT(SrcReg, DstTy);
- if (!SrcRC)
+ if (!hasPhysRegClassForType(*TRI, SrcReg, DstTy))
SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
} else {
SrcSize = TRI->getRegSizeInBits(SrcReg, *MRI);
}
if (DstReg.isPhysical() && SrcTy.isValid()) {
- const TargetRegisterClass *DstRC =
- TRI->getMinimalPhysRegClassLLT(DstReg, SrcTy);
- if (!DstRC)
+ if (!hasPhysRegClassForType(*TRI, DstReg, SrcTy))
DstSize = TRI->getRegSizeInBits(DstReg, *MRI);
} else {
DstSize = TRI->getRegSizeInBits(DstReg, *MRI);
diff --git a/llvm/lib/CodeGen/RegisterBankInfo.cpp b/llvm/lib/CodeGen/RegisterBankInfo.cpp
index 1049aa979ce81..67ce8bff16465 100644
--- a/llvm/lib/CodeGen/RegisterBankInfo.cpp
+++ b/llvm/lib/CodeGen/RegisterBankInfo.cpp
@@ -104,7 +104,7 @@ RegisterBankInfo::getMinimalPhysRegClass(MCRegister Reg,
const TargetRegisterInfo &TRI) const {
const auto [RegRCIt, Inserted] = PhysRegMinimalRCs.try_emplace(Reg);
if (Inserted)
- RegRCIt->second = TRI.getMinimalPhysRegClassLLT(Reg, LLT());
+ RegRCIt->second = TRI.getMinimalPhysRegClass(Reg);
return RegRCIt->second;
}
diff --git a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index fe81d4b2351e0..8da255cda656d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -151,7 +151,7 @@ void InstrEmitter::EmitCopyFromReg(SDValue Op, bool IsClone, Register SrcReg,
}
const TargetRegisterClass *SrcRC = nullptr, *DstRC = nullptr;
- SrcRC = TRI->getMinimalPhysRegClass(SrcReg, VT);
+ SrcRC = TRI->getMinimalPhysRegClass(SrcReg);
// Figure out the register class to create for the destreg.
if (VRBase) {
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
index 9b76ebdb0f8fa..0f67cee757407 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGFast.cpp
@@ -404,29 +404,6 @@ void ScheduleDAGFast::InsertCopiesAndMoveSuccs(SUnit *SU, unsigned Reg,
++NumPRCopies;
}
-/// getPhysicalRegisterVT - Returns the ValueType of the physical register
-/// definition of the specified node.
-/// FIXME: Move to SelectionDAG?
-static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg,
- const TargetInstrInfo *TII) {
- unsigned NumRes;
- if (N->getOpcode() == ISD::CopyFromReg) {
- // CopyFromReg has: "chain, Val, glue" so operand 1 gives the type.
- NumRes = 1;
- } else {
- const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
- assert(!MCID.implicit_defs().empty() &&
- "Physical reg def must be in implicit def list!");
- NumRes = MCID.getNumDefs();
- for (MCPhysReg ImpDef : MCID.implicit_defs()) {
- if (Reg == ImpDef)
- break;
- ++NumRes;
- }
- }
- return N->getSimpleValueType(NumRes);
-}
-
/// CheckForLiveRegDef - Return true and update live register vector if the
/// specified register def of the specified SUnit clobbers any "live" registers.
static bool CheckForLiveRegDef(SUnit *SU, MCRegister Reg,
@@ -572,9 +549,7 @@ void ScheduleDAGFast::ListScheduleBottomUp() {
assert(LRegs.size() == 1 && "Can't handle this yet!");
unsigned Reg = LRegs[0];
SUnit *LRDef = LiveRegDefs[Reg];
- MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII);
- const TargetRegisterClass *RC =
- TRI->getMinimalPhysRegClass(Reg, VT);
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC);
// If cross copy register class is the same as RC, then it must be
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
index bc747d250afae..fffe5b8a83501 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
@@ -1268,29 +1268,6 @@ void ScheduleDAGRRList::InsertCopiesAndMoveSuccs(SUnit *SU, unsigned Reg,
++NumPRCopies;
}
-/// getPhysicalRegisterVT - Returns the ValueType of the physical register
-/// definition of the specified node.
-/// FIXME: Move to SelectionDAG?
-static MVT getPhysicalRegisterVT(SDNode *N, unsigned Reg,
- const TargetInstrInfo *TII) {
- unsigned NumRes;
- if (N->getOpcode() == ISD::CopyFromReg) {
- // CopyFromReg has: "chain, Val, glue" so operand 1 gives the type.
- NumRes = 1;
- } else {
- const MCInstrDesc &MCID = TII->get(N->getMachineOpcode());
- assert(!MCID.implicit_defs().empty() &&
- "Physical reg def must be in implicit def list!");
- NumRes = MCID.getNumDefs();
- for (MCPhysReg ImpDef : MCID.implicit_defs()) {
- if (Reg == ImpDef)
- break;
- ++NumRes;
- }
- }
- return N->getSimpleValueType(NumRes);
-}
-
/// CheckForLiveRegDef - Return true and update live register vector if the
/// specified register def of the specified SUnit clobbers any "live" registers.
static void CheckForLiveRegDef(SUnit *SU, MCRegister Reg, SUnit **LiveRegDefs,
@@ -1561,9 +1538,7 @@ SUnit *ScheduleDAGRRList::PickNodeToScheduleBottomUp() {
assert(LRegs.size() == 1 && "Can't handle this yet!");
unsigned Reg = LRegs[0];
SUnit *LRDef = LiveRegDefs[Reg];
- MVT VT = getPhysicalRegisterVT(LRDef->getNode(), Reg, TII);
- const TargetRegisterClass *RC =
- TRI->getMinimalPhysRegClass(Reg, VT);
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
const TargetRegisterClass *DestRC = TRI->getCrossCopyRegClass(RC);
// If cross copy register class is the same as RC, then it must be possible
diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index 1b28e3a9dc3a3..58101f415ce51 100644
--- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -130,8 +130,7 @@ static void CheckForPhysRegDependency(SDNode *Def, SDNode *User, unsigned Op,
}
if (PhysReg) {
- const TargetRegisterClass *RC =
- TRI->getMinimalPhysRegClass(Reg, Def->getSimpleValueType(ResNo));
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(Reg);
Cost = RC->expensiveOrImpossibleToCopy() ? -1 : RC->getCopyCost();
}
}
diff --git a/llvm/lib/CodeGen/TargetRegisterInfo.cpp b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
index 98cf65d465f63..b97e3afd9da1e 100644
--- a/llvm/lib/CodeGen/TargetRegisterInfo.cpp
+++ b/llvm/lib/CodeGen/TargetRegisterInfo.cpp
@@ -204,86 +204,27 @@ TargetRegisterInfo::getAllocatableClass(const TargetRegisterClass *RC) const {
return nullptr;
}
-template <typename TypeT>
-static const TargetRegisterClass *
-getMinimalPhysRegClass(const TargetRegisterInfo *TRI, MCRegister Reg,
- TypeT Ty) {
- static_assert(std::is_same_v<TypeT, MVT> || std::is_same_v<TypeT, LLT>);
- assert(Reg.isPhysical() && "reg must be a physical register");
-
- bool IsDefault = [&]() {
- if constexpr (std::is_same_v<TypeT, MVT>)
- return Ty == MVT::Other;
- else
- return !Ty.isValid();
- }();
-
- if (IsDefault) {
- if (const TargetRegisterClass *RC = TRI->getDefaultMinimalPhysRegClass(Reg))
- return RC;
- }
-
- // Pick the most sub register class of the right type that contains
- // this physreg.
- const TargetRegisterClass *BestRC = nullptr;
- for (const TargetRegisterClass *RC : TRI->regclasses()) {
- if ((IsDefault || TRI->isTypeLegalForClass(*RC, Ty)) && RC->contains(Reg) &&
- (!BestRC || BestRC->hasSubClass(RC)))
- BestRC = RC;
- }
-
- if constexpr (std::is_same_v<TypeT, MVT>)
- assert(BestRC && "Couldn't find the register class");
- return BestRC;
-}
-
-template <typename TypeT>
static const TargetRegisterClass *
getCommonMinimalPhysRegClass(const TargetRegisterInfo *TRI, MCRegister Reg1,
- MCRegister Reg2, TypeT Ty) {
- static_assert(std::is_same_v<TypeT, MVT> || std::is_same_v<TypeT, LLT>);
+ MCRegister Reg2) {
assert(Reg1.isPhysical() && Reg2.isPhysical() &&
"Reg1/Reg2 must be a physical register");
- bool IsDefault = [&]() {
- if constexpr (std::is_same_v<TypeT, MVT>)
- return Ty == MVT::Other;
- else
- return !Ty.isValid();
- }();
-
- // Pick the most sub register class of the right type that contains
- // this physreg.
+ // Pick the most specific register class that contains both physregs.
const TargetRegisterClass *BestRC = nullptr;
for (const TargetRegisterClass *RC : TRI->regclasses()) {
- if ((IsDefault || TRI->isTypeLegalForClass(*RC, Ty)) &&
- RC->contains(Reg1, Reg2) && (!BestRC || BestRC->hasSubClass(RC)))
+ if (RC->contains(Reg1, Reg2) && (!BestRC || BestRC->hasSubClass(RC)))
BestRC = RC;
}
- if constexpr (std::is_same_v<TypeT, MVT>)
- assert(BestRC && "Couldn't find the register class");
+ assert(BestRC && "Couldn't find the register class");
return BestRC;
}
const TargetRegisterClass *
-TargetRegisterInfo::getMinimalPhysRegClass(MCRegister Reg, MVT VT) const {
- return ::getMinimalPhysRegClass(this, Reg, VT);
-}
-
-const TargetRegisterClass *TargetRegisterInfo::getCommonMinimalPhysRegClass(
- MCRegister Reg1, MCRegister Reg2, MVT VT) const {
- return ::getCommonMinimalPhysRegClass(this, Reg1, Reg2, VT);
-}
-
-const TargetRegisterClass *
-TargetRegisterInfo::getMinimalPhysRegClassLLT(MCRegister Reg, LLT Ty) const {
- return ::getMinimalPhysRegClass(this, Reg, Ty);
-}
-
-const TargetRegisterClass *TargetRegisterInfo::getCommonMinimalPhysRegClassLLT(
- MCRegister Reg1, MCRegister Reg2, LLT Ty) const {
- return ::getCommonMinimalPhysRegClass(this, Reg1, Reg2, Ty);
+TargetRegisterInfo::getCommonMinimalPhysRegClass(MCRegister Reg1,
+ MCRegister Reg2) const {
+ return ::getCommonMinimalPhysRegClass(this, Reg1, Reg2);
}
/// getAllocatableSetForRC - Toggle the bits that represent allocatable
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
index 09c9b5952f27b..defac5304e7d4 100644
--- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
@@ -276,8 +276,7 @@ bool SILowerSGPRSpills::spillCalleeSavedRegs(
// CSI list so that it's easier to identify the entire spill and CFI
// can be emitted appropriately.
if (SpillRetAddrReg) {
- const TargetRegisterClass *RC =
- TRI->getMinimalPhysRegClass(RetAddrReg, MVT::i64);
+ const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(RetAddrReg);
int JunkFI = MFI.CreateStackObject(TRI->getSpillSize(*RC),
TRI->getSpillAlign(*RC), true);
CSI.push_back(CalleeSavedInfo(RetAddrReg, JunkFI));
diff --git a/llvm/unittests/CodeGen/MFCommon.inc b/llvm/unittests/CodeGen/MFCommon.inc
index 6180d34160585..6c47461629070 100644
--- a/llvm/unittests/CodeGen/MFCommon.inc
+++ b/llvm/unittests/CodeGen/MFCommon.inc
@@ -62,6 +62,11 @@ public:
return &Bogus[0];
}
+ const TargetRegisterClass *
+ getMinimalPhysRegClass(MCRegister Reg) const override {
+ return nullptr;
+ }
+
Register getFrameRegister(const MachineFunction &MF) const override {
return 0;
}
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index 20c035e293392..cb5b72e0c64b8 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1264,7 +1264,7 @@ void RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, raw_ostream &MainOS,
"const override;\n";
}
if (!RegisterClasses.empty()) {
- OS << " const TargetRegisterClass *getDefaultMinimalPhysRegClass("
+ OS << " const TargetRegisterClass *getMinimalPhysRegClass("
"MCRegister Reg) const override;\n";
}
@@ -1728,7 +1728,7 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, raw_ostream &MainOS,
OS << "\n// Register to minimal register class mapping\n\n";
OS << "const TargetRegisterClass *" << ClassName
- << "::getDefaultMinimalPhysRegClass(MCRegister Reg)" << " const {\n";
+ << "::getMinimalPhysRegClass(MCRegister Reg)" << " const {\n";
OS << " static const uint16_t InvalidRegClassID = UINT16_MAX;\n\n";
OS << " static const uint16_t Mapping[" << Regs.size() + 1 << "] = {\n";
OS << " InvalidRegClassID, // NoRegister\n";
More information about the llvm-commits
mailing list