[llvm] daf0659 - [IRBuilder] Migrate gep-folding to value-based FoldGEP.
Florian Hahn via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 14 03:24:27 PST 2022
Author: Florian Hahn
Date: 2022-01-14T11:24:09Z
New Revision: daf06590dc8f3d117e2744aff0ee0254b2c0d565
URL: https://github.com/llvm/llvm-project/commit/daf06590dc8f3d117e2744aff0ee0254b2c0d565
DIFF: https://github.com/llvm/llvm-project/commit/daf06590dc8f3d117e2744aff0ee0254b2c0d565.diff
LOG: [IRBuilder] Migrate gep-folding to value-based FoldGEP.
Depends on D117038.
Reviewed By: lebedev.ri
Differential Revision: https://reviews.llvm.org/D117039
Added:
Modified:
llvm/include/llvm/Analysis/InstSimplifyFolder.h
llvm/include/llvm/Analysis/TargetFolder.h
llvm/include/llvm/IR/ConstantFolder.h
llvm/include/llvm/IR/IRBuilder.h
llvm/include/llvm/IR/IRBuilderFolder.h
llvm/include/llvm/IR/NoFolder.h
llvm/test/Transforms/LoopVersioning/lcssa.ll
Removed:
################################################################################
diff --git a/llvm/include/llvm/Analysis/InstSimplifyFolder.h b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
index 28d88db2a839..26aa9a4fe041 100644
--- a/llvm/include/llvm/Analysis/InstSimplifyFolder.h
+++ b/llvm/include/llvm/Analysis/InstSimplifyFolder.h
@@ -60,6 +60,11 @@ class InstSimplifyFolder final : public IRBuilderFolder {
return SimplifyICmpInst(P, LHS, RHS, SQ);
}
+ Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ bool IsInBounds = false) const override {
+ return SimplifyGEPInst(Ty, Ptr, IdxList, IsInBounds, SQ);
+ }
+
//===--------------------------------------------------------------------===//
// Binary Operators
//===--------------------------------------------------------------------===//
@@ -144,43 +149,6 @@ class InstSimplifyFolder final : public IRBuilderFolder {
return ConstFolder.CreateUnOp(Opc, C);
}
- //===--------------------------------------------------------------------===//
- // Memory Instructions
- //===--------------------------------------------------------------------===//
-
- Value *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const override {
- return ConstFolder.CreateGetElementPtr(Ty, C, IdxList);
- }
- Value *CreateGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const override {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstFolder.CreateGetElementPtr(Ty, C, Idx);
- }
- Value *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const override {
- return ConstFolder.CreateGetElementPtr(Ty, C, IdxList);
- }
-
- Value *
- CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const override {
- return ConstFolder.CreateInBoundsGetElementPtr(Ty, C, IdxList);
- }
- Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const override {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstFolder.CreateInBoundsGetElementPtr(Ty, C, Idx);
- }
- Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const override {
- return ConstFolder.CreateInBoundsGetElementPtr(Ty, C, IdxList);
- }
-
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/Analysis/TargetFolder.h b/llvm/include/llvm/Analysis/TargetFolder.h
index d1f5d003e8a4..7944181ade67 100644
--- a/llvm/include/llvm/Analysis/TargetFolder.h
+++ b/llvm/include/llvm/Analysis/TargetFolder.h
@@ -73,6 +73,20 @@ class TargetFolder final : public IRBuilderFolder {
return nullptr;
}
+ Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ bool IsInBounds = false) const override {
+ if (auto *PC = dyn_cast<Constant>(Ptr)) {
+ // Every index must be constant.
+ if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
+ return nullptr;
+ if (IsInBounds)
+ return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList));
+ else
+ return Fold(ConstantExpr::getGetElementPtr(Ty, PC, IdxList));
+ }
+ return nullptr;
+ }
+
//===--------------------------------------------------------------------===//
// Binary Operators
//===--------------------------------------------------------------------===//
@@ -157,42 +171,6 @@ class TargetFolder final : public IRBuilderFolder {
return Fold(ConstantExpr::get(Opc, C));
}
- //===--------------------------------------------------------------------===//
- // Memory Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const override {
- return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
- }
- Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const override {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return Fold(ConstantExpr::getGetElementPtr(Ty, C, Idx));
- }
- Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const override {
- return Fold(ConstantExpr::getGetElementPtr(Ty, C, IdxList));
- }
-
- Constant *CreateInBoundsGetElementPtr(
- Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
- return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
- }
- Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const override {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx));
- }
- Constant *CreateInBoundsGetElementPtr(
- Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
- return Fold(ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList));
- }
-
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/IR/ConstantFolder.h b/llvm/include/llvm/IR/ConstantFolder.h
index b8450d422ab9..8154c6442c4c 100644
--- a/llvm/include/llvm/IR/ConstantFolder.h
+++ b/llvm/include/llvm/IR/ConstantFolder.h
@@ -17,10 +17,11 @@
#define LLVM_IR_CONSTANTFOLDER_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/IRBuilderFolder.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
-#include "llvm/IR/IRBuilderFolder.h"
namespace llvm {
@@ -62,6 +63,21 @@ class ConstantFolder final : public IRBuilderFolder {
return nullptr;
}
+ Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ bool IsInBounds = false) const override {
+ if (auto *PC = dyn_cast<Constant>(Ptr)) {
+ // Every index must be constant.
+ if (any_of(IdxList, [](Value *V) { return !isa<Constant>(V); }))
+ return nullptr;
+
+ if (IsInBounds)
+ return ConstantExpr::getInBoundsGetElementPtr(Ty, PC, IdxList);
+ else
+ return ConstantExpr::getGetElementPtr(Ty, PC, IdxList);
+ }
+ return nullptr;
+ }
+
//===--------------------------------------------------------------------===//
// Binary Operators
//===--------------------------------------------------------------------===//
@@ -167,46 +183,6 @@ class ConstantFolder final : public IRBuilderFolder {
return ConstantExpr::get(Opc, C);
}
- //===--------------------------------------------------------------------===//
- // Memory Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const override {
- return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
- }
-
- Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const override {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstantExpr::getGetElementPtr(Ty, C, Idx);
- }
-
- Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const override {
- return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
- }
-
- Constant *CreateInBoundsGetElementPtr(
- Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
- return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
- }
-
- Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const override {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
- }
-
- Constant *CreateInBoundsGetElementPtr(
- Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
- return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
- }
-
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/IR/IRBuilder.h b/llvm/include/llvm/IR/IRBuilder.h
index 6fae6044dc18..49369abc08f7 100644
--- a/llvm/include/llvm/IR/IRBuilder.h
+++ b/llvm/include/llvm/IR/IRBuilder.h
@@ -1739,45 +1739,28 @@ class IRBuilderBase {
Value *CreateGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
- if (auto *PC = dyn_cast<Constant>(Ptr)) {
- // Every index must be constant.
- size_t i, e;
- for (i = 0, e = IdxList.size(); i != e; ++i)
- if (!isa<Constant>(IdxList[i]))
- break;
- if (i == e)
- return Insert(Folder.CreateGetElementPtr(Ty, PC, IdxList), Name);
- }
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, IdxList, /*IsInBounds=*/false))
+ return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, IdxList), Name);
}
Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
const Twine &Name = "") {
- if (auto *PC = dyn_cast<Constant>(Ptr)) {
- // Every index must be constant.
- size_t i, e;
- for (i = 0, e = IdxList.size(); i != e; ++i)
- if (!isa<Constant>(IdxList[i]))
- break;
- if (i == e)
- return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IdxList),
- Name);
- }
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, IdxList, /*IsInBounds=*/true))
+ return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, IdxList), Name);
}
Value *CreateGEP(Type *Ty, Value *Ptr, Value *Idx, const Twine &Name = "") {
- if (auto *PC = dyn_cast<Constant>(Ptr))
- if (auto *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateGetElementPtr(Ty, PC, IC), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, {Idx}, /*IsInBounds=*/false))
+ return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
}
Value *CreateInBoundsGEP(Type *Ty, Value *Ptr, Value *Idx,
const Twine &Name = "") {
- if (auto *PC = dyn_cast<Constant>(Ptr))
- if (auto *IC = dyn_cast<Constant>(Idx))
- return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, IC), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, {Idx}, /*IsInBounds=*/true))
+ return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
}
@@ -1785,8 +1768,8 @@ class IRBuilderBase {
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
- if (auto *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/false))
+ return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
}
@@ -1795,8 +1778,8 @@ class IRBuilderBase {
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
- if (auto *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/true))
+ return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
}
@@ -1808,8 +1791,8 @@ class IRBuilderBase {
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
- if (auto *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/false))
+ return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name);
}
@@ -1821,8 +1804,8 @@ class IRBuilderBase {
ConstantInt::get(Type::getInt32Ty(Context), Idx1)
};
- if (auto *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/true))
+ return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name);
}
@@ -1831,8 +1814,8 @@ class IRBuilderBase {
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
- if (auto *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(Ty, PC, Idx), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/false))
+ return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idx), Name);
}
@@ -1841,8 +1824,8 @@ class IRBuilderBase {
const Twine &Name = "") {
Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
- if (auto *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idx), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idx, /*IsInBounds=*/true))
+ return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idx), Name);
}
@@ -1854,8 +1837,8 @@ class IRBuilderBase {
ConstantInt::get(Type::getInt64Ty(Context), Idx1)
};
- if (auto *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateGetElementPtr(Ty, PC, Idxs), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/false))
+ return V;
return Insert(GetElementPtrInst::Create(Ty, Ptr, Idxs), Name);
}
@@ -1867,8 +1850,8 @@ class IRBuilderBase {
ConstantInt::get(Type::getInt64Ty(Context), Idx1)
};
- if (auto *PC = dyn_cast<Constant>(Ptr))
- return Insert(Folder.CreateInBoundsGetElementPtr(Ty, PC, Idxs), Name);
+ if (auto *V = Folder.FoldGEP(Ty, Ptr, Idxs, /*IsInBounds=*/true))
+ return V;
return Insert(GetElementPtrInst::CreateInBounds(Ty, Ptr, Idxs), Name);
}
diff --git a/llvm/include/llvm/IR/IRBuilderFolder.h b/llvm/include/llvm/IR/IRBuilderFolder.h
index ff9bf4ff72c2..06712cffa110 100644
--- a/llvm/include/llvm/IR/IRBuilderFolder.h
+++ b/llvm/include/llvm/IR/IRBuilderFolder.h
@@ -38,6 +38,9 @@ class IRBuilderFolder {
virtual Value *FoldICmp(CmpInst::Predicate P, Value *LHS,
Value *RHS) const = 0;
+ virtual Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ bool IsInBounds = false) const = 0;
+
//===--------------------------------------------------------------------===//
// Binary Operators
//===--------------------------------------------------------------------===//
@@ -78,29 +81,6 @@ class IRBuilderFolder {
virtual Value *CreateNot(Constant *C) const = 0;
virtual Value *CreateUnOp(Instruction::UnaryOps Opc, Constant *C) const = 0;
- //===--------------------------------------------------------------------===//
- // Memory Instructions
- //===--------------------------------------------------------------------===//
-
- virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const = 0;
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const = 0;
- virtual Value *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const = 0;
- virtual Value *CreateInBoundsGetElementPtr(
- Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const = 0;
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- virtual Value *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const = 0;
- virtual Value *CreateInBoundsGetElementPtr(
- Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const = 0;
-
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/llvm/include/llvm/IR/NoFolder.h b/llvm/include/llvm/IR/NoFolder.h
index d4a9198c368e..6bf58d9dd9c9 100644
--- a/llvm/include/llvm/IR/NoFolder.h
+++ b/llvm/include/llvm/IR/NoFolder.h
@@ -54,6 +54,11 @@ class NoFolder final : public IRBuilderFolder {
return nullptr;
}
+ Value *FoldGEP(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
+ bool IsInBounds = false) const override {
+ return nullptr;
+ }
+
//===--------------------------------------------------------------------===//
// Binary Operators
//===--------------------------------------------------------------------===//
@@ -179,46 +184,6 @@ class NoFolder final : public IRBuilderFolder {
return UnaryOperator::Create(Opc, C);
}
- //===--------------------------------------------------------------------===//
- // Memory Instructions
- //===--------------------------------------------------------------------===//
-
- Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Constant *> IdxList) const override {
- return ConstantExpr::getGetElementPtr(Ty, C, IdxList);
- }
-
- Constant *CreateGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const override {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstantExpr::getGetElementPtr(Ty, C, Idx);
- }
-
- Instruction *CreateGetElementPtr(Type *Ty, Constant *C,
- ArrayRef<Value *> IdxList) const override {
- return GetElementPtrInst::Create(Ty, C, IdxList);
- }
-
- Constant *CreateInBoundsGetElementPtr(
- Type *Ty, Constant *C, ArrayRef<Constant *> IdxList) const override {
- return ConstantExpr::getInBoundsGetElementPtr(Ty, C, IdxList);
- }
-
- Constant *CreateInBoundsGetElementPtr(Type *Ty, Constant *C,
- Constant *Idx) const override {
- // This form of the function only exists to avoid ambiguous overload
- // warnings about whether to convert Idx to ArrayRef<Constant *> or
- // ArrayRef<Value *>.
- return ConstantExpr::getInBoundsGetElementPtr(Ty, C, Idx);
- }
-
- Instruction *CreateInBoundsGetElementPtr(
- Type *Ty, Constant *C, ArrayRef<Value *> IdxList) const override {
- return GetElementPtrInst::CreateInBounds(Ty, C, IdxList);
- }
-
//===--------------------------------------------------------------------===//
// Cast/Conversion Operators
//===--------------------------------------------------------------------===//
diff --git a/llvm/test/Transforms/LoopVersioning/lcssa.ll b/llvm/test/Transforms/LoopVersioning/lcssa.ll
index 1416b1bf600f..c7191a4c293e 100644
--- a/llvm/test/Transforms/LoopVersioning/lcssa.ll
+++ b/llvm/test/Transforms/LoopVersioning/lcssa.ll
@@ -57,8 +57,6 @@ define void @fill_no_null_opt(i8** %ls1.20, i8** %ls2.21, i8* %cse3.22) #0 {
; CHECK-NEXT: [[BOUND1:%.*]] = icmp ult i8* [[LS2_21_PROMOTED]], [[SCEVGEP1]]
; CHECK-NEXT: [[FOUND_CONFLICT:%.*]] = and i1 [[BOUND0]], [[BOUND1]]
; CHECK-NEXT: [[SCEVGEP3:%.*]] = getelementptr i8, i8* [[LS1_20_PROMOTED]], i64 -1
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr i8, i8* [[SCEVGEP3]], i64 0
-; CHECK-NEXT: [[TMP2:%.*]] = getelementptr i8, i8* [[LS1_20_PROMOTED]], i64 0
; CHECK-NEXT: br i1 [[FOUND_CONFLICT]], label %bb1.ph.lver.orig, label %bb1.ph
; CHECK: bb1.ph.lver.orig:
;
More information about the llvm-commits
mailing list