mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Vendor import of llvm-project branch release/16.x llvmorg-16.0.0-rc2-10-g073506d8c15c.
This commit is contained in:
parent
e3b5578096
commit
11edbfca22
64 changed files with 830 additions and 441 deletions
|
|
@ -34,7 +34,7 @@
|
|||
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
|
||||
*/
|
||||
#define CINDEX_VERSION_MAJOR 0
|
||||
#define CINDEX_VERSION_MINOR 62
|
||||
#define CINDEX_VERSION_MINOR 63
|
||||
|
||||
#define CINDEX_VERSION_ENCODE(major, minor) (((major)*10000) + ((minor)*1))
|
||||
|
||||
|
|
|
|||
|
|
@ -1607,11 +1607,6 @@ def err_import_in_wrong_fragment : Error<
|
|||
def err_export_empty : Error<"export declaration cannot be empty">;
|
||||
}
|
||||
|
||||
def ext_offsetof_member_designator : Extension<
|
||||
"using %select{a member access expression|an array subscript expression}0 "
|
||||
"within '%select{__builtin_offsetof|offsetof}1' is a Clang extension">,
|
||||
InGroup<GNUOffsetofExtensions>;
|
||||
|
||||
let CategoryName = "Generics Issue" in {
|
||||
|
||||
def err_objc_expected_type_parameter : Error<
|
||||
|
|
|
|||
|
|
@ -1249,16 +1249,37 @@ def SVZIP1_BF16 : SInst<"svzip1[_{d}]", "ddd", "b", MergeNone, "aarch64_sve
|
|||
def SVZIP2_BF16 : SInst<"svzip2[_{d}]", "ddd", "b", MergeNone, "aarch64_sve_zip2">;
|
||||
}
|
||||
|
||||
def SVREV_B : SInst<"svrev_{d}", "PP", "PcPsPiPl", MergeNone, "aarch64_sve_rev">;
|
||||
def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel">;
|
||||
def SVTRN1_B : SInst<"svtrn1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_trn1">;
|
||||
def SVTRN2_B : SInst<"svtrn2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_trn2">;
|
||||
def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi">;
|
||||
def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo">;
|
||||
def SVUZP1_B : SInst<"svuzp1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_uzp1">;
|
||||
def SVUZP2_B : SInst<"svuzp2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_uzp2">;
|
||||
def SVZIP1_B : SInst<"svzip1_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_zip1">;
|
||||
def SVZIP2_B : SInst<"svzip2_{d}", "PPP", "PcPsPiPl", MergeNone, "aarch64_sve_zip2">;
|
||||
def SVREV_B8 : SInst<"svrev_b8", "PP", "Pc", MergeNone, "aarch64_sve_rev">;
|
||||
def SVREV_B16 : SInst<"svrev_b16", "PP", "Pc", MergeNone, "aarch64_sve_rev_b16", [IsOverloadNone]>;
|
||||
def SVREV_B32 : SInst<"svrev_b32", "PP", "Pc", MergeNone, "aarch64_sve_rev_b32", [IsOverloadNone]>;
|
||||
def SVREV_B64 : SInst<"svrev_b64", "PP", "Pc", MergeNone, "aarch64_sve_rev_b64", [IsOverloadNone]>;
|
||||
def SVSEL_B : SInst<"svsel[_b]", "PPPP", "Pc", MergeNone, "aarch64_sve_sel">;
|
||||
def SVTRN1_B8 : SInst<"svtrn1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn1">;
|
||||
def SVTRN1_B16 : SInst<"svtrn1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b16", [IsOverloadNone]>;
|
||||
def SVTRN1_B32 : SInst<"svtrn1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b32", [IsOverloadNone]>;
|
||||
def SVTRN1_B64 : SInst<"svtrn1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn1_b64", [IsOverloadNone]>;
|
||||
def SVTRN2_B8 : SInst<"svtrn2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_trn2">;
|
||||
def SVTRN2_B16 : SInst<"svtrn2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b16", [IsOverloadNone]>;
|
||||
def SVTRN2_B32 : SInst<"svtrn2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b32", [IsOverloadNone]>;
|
||||
def SVTRN2_B64 : SInst<"svtrn2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_trn2_b64", [IsOverloadNone]>;
|
||||
def SVPUNPKHI : SInst<"svunpkhi[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpkhi">;
|
||||
def SVPUNPKLO : SInst<"svunpklo[_b]", "PP", "Pc", MergeNone, "aarch64_sve_punpklo">;
|
||||
def SVUZP1_B8 : SInst<"svuzp1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1">;
|
||||
def SVUZP1_B16 : SInst<"svuzp1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b16", [IsOverloadNone]>;
|
||||
def SVUZP1_B32 : SInst<"svuzp1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b32", [IsOverloadNone]>;
|
||||
def SVUZP1_B64 : SInst<"svuzp1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp1_b64", [IsOverloadNone]>;
|
||||
def SVUZP2_B8 : SInst<"svuzp2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2">;
|
||||
def SVUZP2_B16 : SInst<"svuzp2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b16", [IsOverloadNone]>;
|
||||
def SVUZP2_B32 : SInst<"svuzp2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b32", [IsOverloadNone]>;
|
||||
def SVUZP2_B64 : SInst<"svuzp2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_uzp2_b64", [IsOverloadNone]>;
|
||||
def SVZIP1_B8 : SInst<"svzip1_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip1">;
|
||||
def SVZIP1_B16 : SInst<"svzip1_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b16", [IsOverloadNone]>;
|
||||
def SVZIP1_B32 : SInst<"svzip1_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b32", [IsOverloadNone]>;
|
||||
def SVZIP1_B64 : SInst<"svzip1_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip1_b64", [IsOverloadNone]>;
|
||||
def SVZIP2_B : SInst<"svzip2_b8", "PPP", "Pc", MergeNone, "aarch64_sve_zip2">;
|
||||
def SVZIP2_B16 : SInst<"svzip2_b16", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b16", [IsOverloadNone]>;
|
||||
def SVZIP2_B32 : SInst<"svzip2_b32", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b32", [IsOverloadNone]>;
|
||||
def SVZIP2_B64 : SInst<"svzip2_b64", "PPP", "Pc", MergeNone, "aarch64_sve_zip2_b64", [IsOverloadNone]>;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Predicate creation
|
||||
|
|
|
|||
|
|
@ -1539,7 +1539,7 @@ enum RVV_CSR {
|
|||
};
|
||||
|
||||
static __inline__ __attribute__((__always_inline__, __nodebug__))
|
||||
unsigned long vread_csr(enum RVV_CSR __csr) {
|
||||
unsigned long __riscv_vread_csr(enum RVV_CSR __csr) {
|
||||
unsigned long __rv = 0;
|
||||
switch (__csr) {
|
||||
case RVV_VSTART:
|
||||
|
|
@ -1559,7 +1559,7 @@ unsigned long vread_csr(enum RVV_CSR __csr) {
|
|||
}
|
||||
|
||||
static __inline__ __attribute__((__always_inline__, __nodebug__))
|
||||
void vwrite_csr(enum RVV_CSR __csr, unsigned long __value) {
|
||||
void __riscv_vwrite_csr(enum RVV_CSR __csr, unsigned long __value) {
|
||||
switch (__csr) {
|
||||
case RVV_VSTART:
|
||||
__asm__ __volatile__ ("csrw\tvstart, %z0" : : "rJ"(__value) : "memory");
|
||||
|
|
@ -1580,7 +1580,7 @@ def vread_vwrite_csr: RVVHeader;
|
|||
|
||||
let HeaderCode =
|
||||
[{
|
||||
#define vlenb() __builtin_rvv_vlenb()
|
||||
#define __riscv_vlenb() __builtin_rvv_vlenb()
|
||||
}] in
|
||||
def vlenb_macro: RVVHeader;
|
||||
|
||||
|
|
@ -1611,62 +1611,62 @@ let HasBuiltinAlias = false, HasVL = false, HasMasked = false,
|
|||
// and LMUL.
|
||||
let HeaderCode =
|
||||
[{
|
||||
#define vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6)
|
||||
#define vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7)
|
||||
#define vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0)
|
||||
#define vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1)
|
||||
#define vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2)
|
||||
#define vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3)
|
||||
#define __riscv_vsetvl_e8mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 6)
|
||||
#define __riscv_vsetvl_e8mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 7)
|
||||
#define __riscv_vsetvl_e8m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 0)
|
||||
#define __riscv_vsetvl_e8m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 1)
|
||||
#define __riscv_vsetvl_e8m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 2)
|
||||
#define __riscv_vsetvl_e8m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 3)
|
||||
|
||||
#define vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7)
|
||||
#define vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0)
|
||||
#define vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1)
|
||||
#define vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2)
|
||||
#define vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3)
|
||||
#define __riscv_vsetvl_e16mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 7)
|
||||
#define __riscv_vsetvl_e16m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 0)
|
||||
#define __riscv_vsetvl_e16m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 1)
|
||||
#define __riscv_vsetvl_e16m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 2)
|
||||
#define __riscv_vsetvl_e16m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 3)
|
||||
|
||||
#define vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0)
|
||||
#define vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1)
|
||||
#define vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2)
|
||||
#define vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3)
|
||||
#define __riscv_vsetvl_e32m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 0)
|
||||
#define __riscv_vsetvl_e32m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 1)
|
||||
#define __riscv_vsetvl_e32m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 2)
|
||||
#define __riscv_vsetvl_e32m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 3)
|
||||
|
||||
#if __riscv_v_elen >= 64
|
||||
#define vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5)
|
||||
#define vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6)
|
||||
#define vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7)
|
||||
#define __riscv_vsetvl_e8mf8(avl) __builtin_rvv_vsetvli((size_t)(avl), 0, 5)
|
||||
#define __riscv_vsetvl_e16mf4(avl) __builtin_rvv_vsetvli((size_t)(avl), 1, 6)
|
||||
#define __riscv_vsetvl_e32mf2(avl) __builtin_rvv_vsetvli((size_t)(avl), 2, 7)
|
||||
|
||||
#define vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0)
|
||||
#define vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1)
|
||||
#define vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2)
|
||||
#define vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3)
|
||||
#define __riscv_vsetvl_e64m1(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 0)
|
||||
#define __riscv_vsetvl_e64m2(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 1)
|
||||
#define __riscv_vsetvl_e64m4(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 2)
|
||||
#define __riscv_vsetvl_e64m8(avl) __builtin_rvv_vsetvli((size_t)(avl), 3, 3)
|
||||
#endif
|
||||
|
||||
#define vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6)
|
||||
#define vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7)
|
||||
#define vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0)
|
||||
#define vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1)
|
||||
#define vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2)
|
||||
#define vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3)
|
||||
#define __riscv_vsetvlmax_e8mf4() __builtin_rvv_vsetvlimax(0, 6)
|
||||
#define __riscv_vsetvlmax_e8mf2() __builtin_rvv_vsetvlimax(0, 7)
|
||||
#define __riscv_vsetvlmax_e8m1() __builtin_rvv_vsetvlimax(0, 0)
|
||||
#define __riscv_vsetvlmax_e8m2() __builtin_rvv_vsetvlimax(0, 1)
|
||||
#define __riscv_vsetvlmax_e8m4() __builtin_rvv_vsetvlimax(0, 2)
|
||||
#define __riscv_vsetvlmax_e8m8() __builtin_rvv_vsetvlimax(0, 3)
|
||||
|
||||
#define vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7)
|
||||
#define vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0)
|
||||
#define vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1)
|
||||
#define vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2)
|
||||
#define vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3)
|
||||
#define __riscv_vsetvlmax_e16mf2() __builtin_rvv_vsetvlimax(1, 7)
|
||||
#define __riscv_vsetvlmax_e16m1() __builtin_rvv_vsetvlimax(1, 0)
|
||||
#define __riscv_vsetvlmax_e16m2() __builtin_rvv_vsetvlimax(1, 1)
|
||||
#define __riscv_vsetvlmax_e16m4() __builtin_rvv_vsetvlimax(1, 2)
|
||||
#define __riscv_vsetvlmax_e16m8() __builtin_rvv_vsetvlimax(1, 3)
|
||||
|
||||
#define vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0)
|
||||
#define vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1)
|
||||
#define vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2)
|
||||
#define vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3)
|
||||
#define __riscv_vsetvlmax_e32m1() __builtin_rvv_vsetvlimax(2, 0)
|
||||
#define __riscv_vsetvlmax_e32m2() __builtin_rvv_vsetvlimax(2, 1)
|
||||
#define __riscv_vsetvlmax_e32m4() __builtin_rvv_vsetvlimax(2, 2)
|
||||
#define __riscv_vsetvlmax_e32m8() __builtin_rvv_vsetvlimax(2, 3)
|
||||
|
||||
#if __riscv_v_elen >= 64
|
||||
#define vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5)
|
||||
#define vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6)
|
||||
#define vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7)
|
||||
#define __riscv_vsetvlmax_e8mf8() __builtin_rvv_vsetvlimax(0, 5)
|
||||
#define __riscv_vsetvlmax_e16mf4() __builtin_rvv_vsetvlimax(1, 6)
|
||||
#define __riscv_vsetvlmax_e32mf2() __builtin_rvv_vsetvlimax(2, 7)
|
||||
|
||||
#define vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0)
|
||||
#define vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1)
|
||||
#define vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2)
|
||||
#define vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3)
|
||||
#define __riscv_vsetvlmax_e64m1() __builtin_rvv_vsetvlimax(3, 0)
|
||||
#define __riscv_vsetvlmax_e64m2() __builtin_rvv_vsetvlimax(3, 1)
|
||||
#define __riscv_vsetvlmax_e64m4() __builtin_rvv_vsetvlimax(3, 2)
|
||||
#define __riscv_vsetvlmax_e64m8() __builtin_rvv_vsetvlimax(3, 3)
|
||||
#endif
|
||||
|
||||
}] in
|
||||
|
|
|
|||
|
|
@ -506,16 +506,8 @@ public:
|
|||
assert(isTypeRep((TST) TypeSpecType) && "DeclSpec does not store a type");
|
||||
return TypeRep;
|
||||
}
|
||||
// Returns the underlying decl, if any.
|
||||
Decl *getRepAsDecl() const {
|
||||
auto *D = getRepAsFoundDecl();
|
||||
if (const auto *Using = dyn_cast_or_null<UsingShadowDecl>(D))
|
||||
return Using->getTargetDecl();
|
||||
return D;
|
||||
}
|
||||
// Returns the originally found decl, if any.
|
||||
Decl *getRepAsFoundDecl() const {
|
||||
assert(isDeclRep((TST)TypeSpecType) && "DeclSpec does not store a decl");
|
||||
assert(isDeclRep((TST) TypeSpecType) && "DeclSpec does not store a decl");
|
||||
return DeclRep;
|
||||
}
|
||||
Expr *getRepAsExpr() const {
|
||||
|
|
|
|||
|
|
@ -3327,9 +3327,7 @@ public:
|
|||
SourceLocation ScopedEnumKWLoc,
|
||||
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
|
||||
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
|
||||
OffsetOfKind OOK,
|
||||
UsingShadowDecl*& FoundUsingShadow,
|
||||
SkipBodyInfo *SkipBody = nullptr);
|
||||
OffsetOfKind OOK, SkipBodyInfo *SkipBody = nullptr);
|
||||
|
||||
DeclResult ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc,
|
||||
unsigned TagSpec, SourceLocation TagLoc,
|
||||
|
|
@ -7281,24 +7279,34 @@ private:
|
|||
|
||||
private:
|
||||
// The current stack of constraint satisfactions, so we can exit-early.
|
||||
llvm::SmallVector<llvm::FoldingSetNodeID, 10> SatisfactionStack;
|
||||
using SatisfactionStackEntryTy =
|
||||
std::pair<const NamedDecl *, llvm::FoldingSetNodeID>;
|
||||
llvm::SmallVector<SatisfactionStackEntryTy, 10>
|
||||
SatisfactionStack;
|
||||
|
||||
public:
|
||||
void PushSatisfactionStackEntry(const llvm::FoldingSetNodeID &ID) {
|
||||
SatisfactionStack.push_back(ID);
|
||||
void PushSatisfactionStackEntry(const NamedDecl *D,
|
||||
const llvm::FoldingSetNodeID &ID) {
|
||||
const NamedDecl *Can = cast<NamedDecl>(D->getCanonicalDecl());
|
||||
SatisfactionStack.emplace_back(Can, ID);
|
||||
}
|
||||
|
||||
void PopSatisfactionStackEntry() { SatisfactionStack.pop_back(); }
|
||||
|
||||
bool SatisfactionStackContains(const llvm::FoldingSetNodeID &ID) const {
|
||||
return llvm::find(SatisfactionStack, ID) != SatisfactionStack.end();
|
||||
bool SatisfactionStackContains(const NamedDecl *D,
|
||||
const llvm::FoldingSetNodeID &ID) const {
|
||||
const NamedDecl *Can = cast<NamedDecl>(D->getCanonicalDecl());
|
||||
return llvm::find(SatisfactionStack,
|
||||
SatisfactionStackEntryTy{Can, ID}) !=
|
||||
SatisfactionStack.end();
|
||||
}
|
||||
|
||||
// Resets the current SatisfactionStack for cases where we are instantiating
|
||||
// constraints as a 'side effect' of normal instantiation in a way that is not
|
||||
// indicative of recursive definition.
|
||||
class SatisfactionStackResetRAII {
|
||||
llvm::SmallVector<llvm::FoldingSetNodeID, 10> BackupSatisfactionStack;
|
||||
llvm::SmallVector<SatisfactionStackEntryTy, 10>
|
||||
BackupSatisfactionStack;
|
||||
Sema &SemaRef;
|
||||
|
||||
public:
|
||||
|
|
@ -7311,8 +7319,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void
|
||||
SwapSatisfactionStack(llvm::SmallVectorImpl<llvm::FoldingSetNodeID> &NewSS) {
|
||||
void SwapSatisfactionStack(
|
||||
llvm::SmallVectorImpl<SatisfactionStackEntryTy> &NewSS) {
|
||||
SatisfactionStack.swap(NewSS);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,25 +92,24 @@ enum class TypeModifier : uint8_t {
|
|||
LLVM_MARK_AS_BITMASK_ENUM(LMUL1),
|
||||
};
|
||||
|
||||
struct Policy {
|
||||
bool IsUnspecified = false;
|
||||
class Policy {
|
||||
public:
|
||||
enum PolicyType {
|
||||
Undisturbed,
|
||||
Agnostic,
|
||||
};
|
||||
PolicyType TailPolicy = Agnostic;
|
||||
PolicyType MaskPolicy = Agnostic;
|
||||
bool HasTailPolicy, HasMaskPolicy;
|
||||
Policy(bool HasTailPolicy, bool HasMaskPolicy)
|
||||
: IsUnspecified(true), HasTailPolicy(HasTailPolicy),
|
||||
HasMaskPolicy(HasMaskPolicy) {}
|
||||
Policy(PolicyType TailPolicy, bool HasTailPolicy, bool HasMaskPolicy)
|
||||
: TailPolicy(TailPolicy), HasTailPolicy(HasTailPolicy),
|
||||
HasMaskPolicy(HasMaskPolicy) {}
|
||||
Policy(PolicyType TailPolicy, PolicyType MaskPolicy, bool HasTailPolicy,
|
||||
bool HasMaskPolicy)
|
||||
: TailPolicy(TailPolicy), MaskPolicy(MaskPolicy),
|
||||
HasTailPolicy(HasTailPolicy), HasMaskPolicy(HasMaskPolicy) {}
|
||||
|
||||
private:
|
||||
// The default assumption for an RVV instruction is TAMA, as an undisturbed
|
||||
// policy generally will affect the performance of an out-of-order core.
|
||||
const PolicyType TailPolicy = Agnostic;
|
||||
const PolicyType MaskPolicy = Agnostic;
|
||||
|
||||
public:
|
||||
Policy() = default;
|
||||
Policy(PolicyType TailPolicy) : TailPolicy(TailPolicy) {}
|
||||
Policy(PolicyType TailPolicy, PolicyType MaskPolicy)
|
||||
: TailPolicy(TailPolicy), MaskPolicy(MaskPolicy) {}
|
||||
|
||||
bool isTAMAPolicy() const {
|
||||
return TailPolicy == Agnostic && MaskPolicy == Agnostic;
|
||||
|
|
@ -136,17 +135,8 @@ struct Policy {
|
|||
|
||||
bool isMUPolicy() const { return MaskPolicy == Undisturbed; }
|
||||
|
||||
bool hasTailPolicy() const { return HasTailPolicy; }
|
||||
|
||||
bool hasMaskPolicy() const { return HasMaskPolicy; }
|
||||
|
||||
bool isUnspecified() const { return IsUnspecified; }
|
||||
|
||||
bool operator==(const Policy &Other) const {
|
||||
return IsUnspecified == Other.IsUnspecified &&
|
||||
TailPolicy == Other.TailPolicy && MaskPolicy == Other.MaskPolicy &&
|
||||
HasTailPolicy == Other.HasTailPolicy &&
|
||||
HasMaskPolicy == Other.HasMaskPolicy;
|
||||
return TailPolicy == Other.TailPolicy && MaskPolicy == Other.MaskPolicy;
|
||||
}
|
||||
|
||||
bool operator!=(const Policy &Other) const { return !(*this == Other); }
|
||||
|
|
@ -422,7 +412,6 @@ public:
|
|||
return IntrinsicTypes;
|
||||
}
|
||||
Policy getPolicyAttrs() const {
|
||||
assert(PolicyAttrs.IsUnspecified == false);
|
||||
return PolicyAttrs;
|
||||
}
|
||||
unsigned getPolicyAttrsBits() const {
|
||||
|
|
@ -431,8 +420,6 @@ public:
|
|||
// The 1st bit simulates the `vma` of RVV
|
||||
// int PolicyAttrs = 0;
|
||||
|
||||
assert(PolicyAttrs.IsUnspecified == false);
|
||||
|
||||
if (PolicyAttrs.isTUMAPolicy())
|
||||
return 2;
|
||||
if (PolicyAttrs.isTAMAPolicy())
|
||||
|
|
@ -459,8 +446,7 @@ public:
|
|||
unsigned NF, PolicyScheme DefaultScheme,
|
||||
Policy PolicyAttrs);
|
||||
|
||||
static llvm::SmallVector<Policy>
|
||||
getSupportedUnMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy);
|
||||
static llvm::SmallVector<Policy> getSupportedUnMaskedPolicies();
|
||||
static llvm::SmallVector<Policy>
|
||||
getSupportedMaskedPolicies(bool HasTailPolicy, bool HasMaskPolicy);
|
||||
|
||||
|
|
|
|||
|
|
@ -687,9 +687,13 @@ void AArch64TargetInfo::setFeatureEnabled(llvm::StringMap<bool> &Features,
|
|||
if (ArchInfo == llvm::AArch64::INVALID)
|
||||
return; // Not an architecure, nothing more to do.
|
||||
|
||||
// Disabling an architecture feature does not affect dependent features
|
||||
if (!Enabled)
|
||||
return;
|
||||
|
||||
for (const auto *OtherArch : llvm::AArch64::ArchInfos)
|
||||
if (ArchInfo.implies(*OtherArch))
|
||||
Features[OtherArch->getSubArch()] = Enabled;
|
||||
Features[OtherArch->getSubArch()] = true;
|
||||
|
||||
// Set any features implied by the architecture
|
||||
uint64_t Extensions =
|
||||
|
|
|
|||
|
|
@ -197,8 +197,8 @@ void RISCVTargetInfo::getTargetDefines(const LangOptions &Opts,
|
|||
|
||||
if (ISAInfo->hasExtension("zve32x")) {
|
||||
Builder.defineMacro("__riscv_vector");
|
||||
// Currently we support the v0.10 RISC-V V intrinsics.
|
||||
Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 10)));
|
||||
// Currently we support the v0.11 RISC-V V intrinsics.
|
||||
Builder.defineMacro("__riscv_v_intrinsic", Twine(getVersionValue(0, 11)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -795,13 +795,13 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts,
|
|||
if (HasHRESET)
|
||||
Builder.defineMacro("__HRESET__");
|
||||
if (HasAMXTILE)
|
||||
Builder.defineMacro("__AMXTILE__");
|
||||
Builder.defineMacro("__AMX_TILE__");
|
||||
if (HasAMXINT8)
|
||||
Builder.defineMacro("__AMXINT8__");
|
||||
Builder.defineMacro("__AMX_INT8__");
|
||||
if (HasAMXBF16)
|
||||
Builder.defineMacro("__AMXBF16__");
|
||||
Builder.defineMacro("__AMX_BF16__");
|
||||
if (HasAMXFP16)
|
||||
Builder.defineMacro("__AMXFP16__");
|
||||
Builder.defineMacro("__AMX_FP16__");
|
||||
if (HasCMPCCXADD)
|
||||
Builder.defineMacro("__CMPCCXADD__");
|
||||
if (HasRAOINT)
|
||||
|
|
|
|||
|
|
@ -7418,18 +7418,28 @@ public:
|
|||
};
|
||||
|
||||
class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
|
||||
ASTContext &Ctx;
|
||||
|
||||
const SystemZABIInfo &getABIInfo() const {
|
||||
return static_cast<const SystemZABIInfo&>(TargetCodeGenInfo::getABIInfo());
|
||||
}
|
||||
|
||||
// These are used for speeding up the search for a visible vector ABI.
|
||||
mutable bool HasVisibleVecABIFlag = false;
|
||||
mutable std::set<const Type *> SeenTypes;
|
||||
|
||||
// Returns true (the first time) if Ty is or found to make use of a vector
|
||||
// type (e.g. as a function argument).
|
||||
bool isVectorTypeBased(const Type *Ty) const;
|
||||
// Returns true (the first time) if Ty is, or is found to include, a vector
|
||||
// type that exposes the vector ABI. This is any vector >=16 bytes which
|
||||
// with vector support are aligned to only 8 bytes. When IsParam is true,
|
||||
// the type belongs to a value as passed between functions. If it is a
|
||||
// vector <=16 bytes it will be passed in a vector register (if supported).
|
||||
bool isVectorTypeBased(const Type *Ty, bool IsParam) const;
|
||||
|
||||
public:
|
||||
SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI)
|
||||
: TargetCodeGenInfo(
|
||||
std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)) {
|
||||
std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)),
|
||||
Ctx(CGT.getContext()) {
|
||||
SwiftInfo =
|
||||
std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
|
||||
}
|
||||
|
|
@ -7439,9 +7449,9 @@ public:
|
|||
// indicating a visible vector ABI is added. Eventually this will result in
|
||||
// a GNU attribute indicating the vector ABI of the module. Ty is the type
|
||||
// of a variable or function parameter that is globally visible.
|
||||
void handleExternallyVisibleObjABI(const Type *Ty,
|
||||
CodeGen::CodeGenModule &M) const {
|
||||
if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty)) {
|
||||
void handleExternallyVisibleObjABI(const Type *Ty, CodeGen::CodeGenModule &M,
|
||||
bool IsParam) const {
|
||||
if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty, IsParam)) {
|
||||
M.getModule().addModuleFlag(llvm::Module::Warning,
|
||||
"s390x-visible-vector-ABI", 1);
|
||||
HasVisibleVecABIFlag = true;
|
||||
|
|
@ -7457,11 +7467,13 @@ public:
|
|||
// variable or function.
|
||||
if (const auto *VD = dyn_cast<VarDecl>(D)) {
|
||||
if (VD->isExternallyVisible())
|
||||
handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M);
|
||||
handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M,
|
||||
/*IsParam*/false);
|
||||
}
|
||||
else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
if (FD->isExternallyVisible())
|
||||
handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M);
|
||||
handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M,
|
||||
/*IsParam*/false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7571,17 +7583,18 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
|
|||
|
||||
// If this is a C++ record, check the bases first.
|
||||
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
|
||||
for (const auto &I : CXXRD->bases()) {
|
||||
QualType Base = I.getType();
|
||||
if (CXXRD->hasDefinition())
|
||||
for (const auto &I : CXXRD->bases()) {
|
||||
QualType Base = I.getType();
|
||||
|
||||
// Empty bases don't affect things either way.
|
||||
if (isEmptyRecord(getContext(), Base, true))
|
||||
continue;
|
||||
// Empty bases don't affect things either way.
|
||||
if (isEmptyRecord(getContext(), Base, true))
|
||||
continue;
|
||||
|
||||
if (!Found.isNull())
|
||||
return Ty;
|
||||
Found = GetSingleElementType(Base);
|
||||
}
|
||||
if (!Found.isNull())
|
||||
return Ty;
|
||||
Found = GetSingleElementType(Base);
|
||||
}
|
||||
|
||||
// Check the fields.
|
||||
for (const auto *FD : RD->fields()) {
|
||||
|
|
@ -7635,7 +7648,8 @@ Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
|
|||
bool IsVector = false;
|
||||
CharUnits UnpaddedSize;
|
||||
CharUnits DirectAlign;
|
||||
SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM());
|
||||
SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM(),
|
||||
/*IsParam*/true);
|
||||
if (IsIndirect) {
|
||||
DirectTy = llvm::PointerType::getUnqual(DirectTy);
|
||||
UnpaddedSize = DirectAlign = CharUnits::fromQuantity(8);
|
||||
|
|
@ -7843,35 +7857,57 @@ void SystemZABIInfo::computeInfo(CGFunctionInfo &FI) const {
|
|||
// Check if a vararg vector argument is passed, in which case the
|
||||
// vector ABI becomes visible as the va_list could be passed on to
|
||||
// other functions.
|
||||
SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM());
|
||||
SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM(),
|
||||
/*IsParam*/true);
|
||||
}
|
||||
}
|
||||
|
||||
bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty) const {
|
||||
while (Ty->isPointerType() || Ty->isArrayType())
|
||||
Ty = Ty->getPointeeOrArrayElementType();
|
||||
bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty,
|
||||
bool IsParam) const {
|
||||
if (!SeenTypes.insert(Ty).second)
|
||||
return false;
|
||||
if (Ty->isVectorType())
|
||||
return true;
|
||||
|
||||
if (IsParam) {
|
||||
// A narrow (<16 bytes) vector will as a parameter also expose the ABI as
|
||||
// it will be passed in a vector register. A wide (>16 bytes) vector will
|
||||
// be passed via "hidden" pointer where any extra alignment is not
|
||||
// required (per GCC).
|
||||
const Type *SingleEltTy =
|
||||
getABIInfo().GetSingleElementType(QualType(Ty, 0)).getTypePtr();
|
||||
bool SingleVecEltStruct = SingleEltTy != Ty && SingleEltTy->isVectorType() &&
|
||||
Ctx.getTypeSize(SingleEltTy) == Ctx.getTypeSize(Ty);
|
||||
if (Ty->isVectorType() || SingleVecEltStruct)
|
||||
return Ctx.getTypeSize(Ty) / 8 <= 16;
|
||||
}
|
||||
|
||||
// Assume pointers are dereferenced.
|
||||
while (Ty->isPointerType() || Ty->isArrayType())
|
||||
Ty = Ty->getPointeeOrArrayElementType();
|
||||
|
||||
// Vectors >= 16 bytes expose the ABI through alignment requirements.
|
||||
if (Ty->isVectorType() && Ctx.getTypeSize(Ty) / 8 >= 16)
|
||||
return true;
|
||||
|
||||
if (const auto *RecordTy = Ty->getAs<RecordType>()) {
|
||||
const RecordDecl *RD = RecordTy->getDecl();
|
||||
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
|
||||
if (CXXRD->hasDefinition())
|
||||
for (const auto &I : CXXRD->bases())
|
||||
if (isVectorTypeBased(I.getType().getTypePtr()))
|
||||
if (isVectorTypeBased(I.getType().getTypePtr(), /*IsParam*/false))
|
||||
return true;
|
||||
for (const auto *FD : RD->fields())
|
||||
if (isVectorTypeBased(FD->getType().getTypePtr()))
|
||||
if (isVectorTypeBased(FD->getType().getTypePtr(), /*IsParam*/false))
|
||||
return true;
|
||||
}
|
||||
|
||||
if (const auto *FT = Ty->getAs<FunctionType>())
|
||||
if (isVectorTypeBased(FT->getReturnType().getTypePtr()))
|
||||
if (isVectorTypeBased(FT->getReturnType().getTypePtr(), /*IsParam*/true))
|
||||
return true;
|
||||
if (const FunctionProtoType *Proto = Ty->getAs<FunctionProtoType>())
|
||||
for (auto ParamType : Proto->getParamTypes())
|
||||
if (isVectorTypeBased(ParamType.getTypePtr()))
|
||||
if (isVectorTypeBased(ParamType.getTypePtr(), /*IsParam*/true))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -443,7 +443,7 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
CmdArgs.push_back("--gpu-name");
|
||||
CmdArgs.push_back(Args.MakeArgString(CudaArchToString(gpu_arch)));
|
||||
CmdArgs.push_back("--output-file");
|
||||
const char *OutputFileName = Args.MakeArgString(TC.getInputFilename(Output));
|
||||
std::string OutputFileName = TC.getInputFilename(Output);
|
||||
|
||||
// If we are invoking `nvlink` internally we need to output a `.cubin` file.
|
||||
// Checking if the output is a temporary is the cleanest way to determine
|
||||
|
|
@ -455,12 +455,12 @@ void NVPTX::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
|
|||
C.getTempFiles().end()) {
|
||||
SmallString<256> Filename(Output.getFilename());
|
||||
llvm::sys::path::replace_extension(Filename, "cubin");
|
||||
OutputFileName = Args.MakeArgString(Filename);
|
||||
OutputFileName = Filename.str();
|
||||
}
|
||||
if (Output.isFilename() && OutputFileName != Output.getFilename())
|
||||
C.addTempFile(OutputFileName);
|
||||
C.addTempFile(Args.MakeArgString(OutputFileName));
|
||||
|
||||
CmdArgs.push_back(OutputFileName);
|
||||
CmdArgs.push_back(Args.MakeArgString(OutputFileName));
|
||||
for (const auto &II : Inputs)
|
||||
CmdArgs.push_back(Args.MakeArgString(II.getFilename()));
|
||||
|
||||
|
|
|
|||
|
|
@ -3833,6 +3833,9 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
|
|||
return true;
|
||||
|
||||
if (Style.isCpp()) {
|
||||
// Space between UDL and dot: auto b = 4s .count();
|
||||
if (Right.is(tok::period) && Left.is(tok::numeric_constant))
|
||||
return true;
|
||||
// Space between import <iostream>.
|
||||
// or import .....;
|
||||
if (Left.is(Keywords.kw_import) && Right.isOneOf(tok::less, tok::ellipsis))
|
||||
|
|
|
|||
|
|
@ -524,7 +524,7 @@ _storebe_i64(void * __P, long long __D) {
|
|||
#include <invpcidintrin.h>
|
||||
#endif
|
||||
#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
|
||||
defined(__AMXFP16__)
|
||||
defined(__AMX_FP16__)
|
||||
#include <amxfp16intrin.h>
|
||||
#endif
|
||||
|
||||
|
|
@ -534,7 +534,7 @@ _storebe_i64(void * __P, long long __D) {
|
|||
#endif
|
||||
|
||||
#if !(defined(_MSC_VER) || defined(__SCE__)) || __has_feature(modules) || \
|
||||
defined(__AMXTILE__) || defined(__AMXINT8__) || defined(__AMXBF16__)
|
||||
defined(__AMX_TILE__) || defined(__AMX_INT8__) || defined(__AMX_BF16__)
|
||||
#include <amxintrin.h>
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -1145,7 +1145,7 @@ static __inline__ int __DEFAULT_FN_ATTRS _mm_testnzc_si128(__m128i __M,
|
|||
/// A 128-bit integer vector containing the bits to be tested.
|
||||
/// \returns TRUE if the bits specified in the operand are all set to 1; FALSE
|
||||
/// otherwise.
|
||||
#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_cmpeq_epi32((V), (V)))
|
||||
#define _mm_test_all_ones(V) _mm_testc_si128((V), _mm_set1_epi32(-1))
|
||||
|
||||
/// Tests whether the specified bits in a 128-bit integer vector are
|
||||
/// neither all zeros nor all ones.
|
||||
|
|
|
|||
|
|
@ -4965,7 +4965,6 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
|||
bool IsDependent = false;
|
||||
const char *PrevSpec = nullptr;
|
||||
unsigned DiagID;
|
||||
UsingShadowDecl* FoundUsing = nullptr;
|
||||
Decl *TagDecl =
|
||||
Actions.ActOnTag(getCurScope(), DeclSpec::TST_enum, TUK, StartLoc, SS,
|
||||
Name, NameLoc, attrs, AS, DS.getModulePrivateSpecLoc(),
|
||||
|
|
@ -4974,7 +4973,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
|||
BaseType, DSC == DeclSpecContext::DSC_type_specifier,
|
||||
DSC == DeclSpecContext::DSC_template_param ||
|
||||
DSC == DeclSpecContext::DSC_template_type_arg,
|
||||
OffsetOfState, FoundUsing, &SkipBody).get();
|
||||
OffsetOfState, &SkipBody).get();
|
||||
|
||||
if (SkipBody.ShouldSkip) {
|
||||
assert(TUK == Sema::TUK_Definition && "can only skip a definition");
|
||||
|
|
@ -4984,8 +4983,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
|||
T.skipToEnd();
|
||||
|
||||
if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
|
||||
NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,
|
||||
DiagID, FoundUsing ? FoundUsing : TagDecl, Owned,
|
||||
NameLoc.isValid() ? NameLoc : StartLoc,
|
||||
PrevSpec, DiagID, TagDecl, Owned,
|
||||
Actions.getASTContext().getPrintingPolicy()))
|
||||
Diag(StartLoc, DiagID) << PrevSpec;
|
||||
return;
|
||||
|
|
@ -5039,8 +5038,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
|||
}
|
||||
|
||||
if (DS.SetTypeSpecType(DeclSpec::TST_enum, StartLoc,
|
||||
NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,
|
||||
DiagID, FoundUsing ? FoundUsing : TagDecl, Owned,
|
||||
NameLoc.isValid() ? NameLoc : StartLoc,
|
||||
PrevSpec, DiagID, TagDecl, Owned,
|
||||
Actions.getASTContext().getPrintingPolicy()))
|
||||
Diag(StartLoc, DiagID) << PrevSpec;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1934,7 +1934,6 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
// Create the tag portion of the class or class template.
|
||||
DeclResult TagOrTempResult = true; // invalid
|
||||
TypeResult TypeResult = true; // invalid
|
||||
UsingShadowDecl *FoundUsing = nullptr;
|
||||
|
||||
bool Owned = false;
|
||||
Sema::SkipBodyInfo SkipBody;
|
||||
|
|
@ -2075,7 +2074,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
DSC == DeclSpecContext::DSC_type_specifier,
|
||||
DSC == DeclSpecContext::DSC_template_param ||
|
||||
DSC == DeclSpecContext::DSC_template_type_arg,
|
||||
OffsetOfState, FoundUsing, &SkipBody);
|
||||
OffsetOfState, &SkipBody);
|
||||
|
||||
// If ActOnTag said the type was dependent, try again with the
|
||||
// less common call.
|
||||
|
|
@ -2134,7 +2133,7 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
|
|||
} else if (!TagOrTempResult.isInvalid()) {
|
||||
Result = DS.SetTypeSpecType(
|
||||
TagType, StartLoc, NameLoc.isValid() ? NameLoc : StartLoc, PrevSpec,
|
||||
DiagID, FoundUsing ? FoundUsing : TagOrTempResult.get(), Owned, Policy);
|
||||
DiagID, TagOrTempResult.get(), Owned, Policy);
|
||||
} else {
|
||||
DS.SetTypeSpecError();
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -2629,12 +2629,6 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
|||
Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
|
||||
Comps.back().LocStart = Comps.back().LocEnd = ConsumeToken();
|
||||
|
||||
enum class Kind { MemberAccess, ArraySubscript };
|
||||
auto DiagExt = [&](SourceLocation Loc, Kind K) {
|
||||
Diag(Loc, diag::ext_offsetof_member_designator)
|
||||
<< (K == Kind::ArraySubscript) << (OOK == Sema::OOK_Macro);
|
||||
};
|
||||
|
||||
// FIXME: This loop leaks the index expressions on error.
|
||||
while (true) {
|
||||
if (Tok.is(tok::period)) {
|
||||
|
|
@ -2648,7 +2642,6 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
|||
SkipUntil(tok::r_paren, StopAtSemi);
|
||||
return ExprError();
|
||||
}
|
||||
DiagExt(Comps.back().LocStart, Kind::MemberAccess);
|
||||
Comps.back().U.IdentInfo = Tok.getIdentifierInfo();
|
||||
Comps.back().LocEnd = ConsumeToken();
|
||||
} else if (Tok.is(tok::l_square)) {
|
||||
|
|
@ -2666,7 +2659,6 @@ ExprResult Parser::ParseBuiltinPrimaryExpression() {
|
|||
SkipUntil(tok::r_paren, StopAtSemi);
|
||||
return Res;
|
||||
}
|
||||
DiagExt(Comps.back().LocStart, Kind::ArraySubscript);
|
||||
Comps.back().U.E = Res.get();
|
||||
|
||||
ST.consumeClose();
|
||||
|
|
|
|||
|
|
@ -150,11 +150,19 @@ bool Sema::CheckConstraintExpression(const Expr *ConstraintExpression,
|
|||
namespace {
|
||||
struct SatisfactionStackRAII {
|
||||
Sema &SemaRef;
|
||||
SatisfactionStackRAII(Sema &SemaRef, llvm::FoldingSetNodeID FSNID)
|
||||
bool Inserted = false;
|
||||
SatisfactionStackRAII(Sema &SemaRef, const NamedDecl *ND,
|
||||
llvm::FoldingSetNodeID FSNID)
|
||||
: SemaRef(SemaRef) {
|
||||
SemaRef.PushSatisfactionStackEntry(FSNID);
|
||||
if (ND) {
|
||||
SemaRef.PushSatisfactionStackEntry(ND, FSNID);
|
||||
Inserted = true;
|
||||
}
|
||||
}
|
||||
~SatisfactionStackRAII() {
|
||||
if (Inserted)
|
||||
SemaRef.PopSatisfactionStackEntry();
|
||||
}
|
||||
~SatisfactionStackRAII() { SemaRef.PopSatisfactionStackEntry(); }
|
||||
};
|
||||
} // namespace
|
||||
|
||||
|
|
@ -273,7 +281,8 @@ calculateConstraintSatisfaction(Sema &S, const Expr *ConstraintExpr,
|
|||
}
|
||||
|
||||
static bool
|
||||
DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const Expr *E,
|
||||
DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID,
|
||||
const NamedDecl *Templ, const Expr *E,
|
||||
const MultiLevelTemplateArgumentList &MLTAL) {
|
||||
E->Profile(ID, S.Context, /*Canonical=*/true);
|
||||
for (const auto &List : MLTAL)
|
||||
|
|
@ -286,7 +295,7 @@ DiagRecursiveConstraintEval(Sema &S, llvm::FoldingSetNodeID &ID, const Expr *E,
|
|||
// expression, or when trying to determine the constexpr-ness of special
|
||||
// members. Otherwise we could just use the
|
||||
// Sema::InstantiatingTemplate::isAlreadyBeingInstantiated function.
|
||||
if (S.SatisfactionStackContains(ID)) {
|
||||
if (S.SatisfactionStackContains(Templ, ID)) {
|
||||
S.Diag(E->getExprLoc(), diag::err_constraint_depends_on_self)
|
||||
<< const_cast<Expr *>(E) << E->getSourceRange();
|
||||
return true;
|
||||
|
|
@ -317,13 +326,14 @@ static ExprResult calculateConstraintSatisfaction(
|
|||
return ExprError();
|
||||
|
||||
llvm::FoldingSetNodeID ID;
|
||||
if (DiagRecursiveConstraintEval(S, ID, AtomicExpr, MLTAL)) {
|
||||
if (Template &&
|
||||
DiagRecursiveConstraintEval(S, ID, Template, AtomicExpr, MLTAL)) {
|
||||
Satisfaction.IsSatisfied = false;
|
||||
Satisfaction.ContainsErrors = true;
|
||||
return ExprEmpty();
|
||||
}
|
||||
|
||||
SatisfactionStackRAII StackRAII(S, ID);
|
||||
SatisfactionStackRAII StackRAII(S, Template, ID);
|
||||
|
||||
// We do not want error diagnostics escaping here.
|
||||
Sema::SFINAETrap Trap(S);
|
||||
|
|
@ -1132,8 +1142,7 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N,
|
|||
Sema::InstantiatingTemplate Inst(
|
||||
S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(),
|
||||
Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept,
|
||||
SourceRange(ArgsAsWritten->arguments()[0].getSourceRange().getBegin(),
|
||||
ArgsAsWritten->arguments().back().getSourceRange().getEnd()));
|
||||
ArgsAsWritten->arguments().front().getSourceRange());
|
||||
if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
|
||||
return true;
|
||||
|
||||
|
|
|
|||
|
|
@ -13088,9 +13088,10 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
|
|||
// C++ [module.import/6] external definitions are not permitted in header
|
||||
// units.
|
||||
if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
|
||||
VDecl->isThisDeclarationADefinition() &&
|
||||
!VDecl->isInvalidDecl() && VDecl->isThisDeclarationADefinition() &&
|
||||
VDecl->getFormalLinkage() == Linkage::ExternalLinkage &&
|
||||
!VDecl->isInline()) {
|
||||
!VDecl->isInline() && !VDecl->isTemplated() &&
|
||||
!isa<VarTemplateSpecializationDecl>(VDecl)) {
|
||||
Diag(VDecl->getLocation(), diag::err_extern_def_in_header_unit);
|
||||
VDecl->setInvalidDecl();
|
||||
}
|
||||
|
|
@ -15259,9 +15260,10 @@ Decl *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Decl *D,
|
|||
// FIXME: Consider an alternate location for the test where the inlined()
|
||||
// state is complete.
|
||||
if (getLangOpts().CPlusPlusModules && currentModuleIsHeaderUnit() &&
|
||||
!FD->isInvalidDecl() && !FD->isInlined() &&
|
||||
BodyKind != FnBodyKind::Delete && BodyKind != FnBodyKind::Default &&
|
||||
FD->getFormalLinkage() == Linkage::ExternalLinkage &&
|
||||
!FD->isInvalidDecl() && BodyKind != FnBodyKind::Delete &&
|
||||
BodyKind != FnBodyKind::Default && !FD->isInlined()) {
|
||||
!FD->isTemplated() && !FD->isTemplateInstantiation()) {
|
||||
assert(FD->isThisDeclarationADefinition());
|
||||
Diag(FD->getLocation(), diag::err_extern_def_in_header_unit);
|
||||
FD->setInvalidDecl();
|
||||
|
|
@ -16616,8 +16618,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
|
|||
bool &IsDependent, SourceLocation ScopedEnumKWLoc,
|
||||
bool ScopedEnumUsesClassTag, TypeResult UnderlyingType,
|
||||
bool IsTypeSpecifier, bool IsTemplateParamOrArg,
|
||||
OffsetOfKind OOK, UsingShadowDecl *&FoundUsingShadow,
|
||||
SkipBodyInfo *SkipBody) {
|
||||
OffsetOfKind OOK, SkipBodyInfo *SkipBody) {
|
||||
// If this is not a definition, it must have a name.
|
||||
IdentifierInfo *OrigName = Name;
|
||||
assert((Name != nullptr || TUK == TUK_Definition) &&
|
||||
|
|
@ -17052,7 +17053,6 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
|
|||
// redefinition if either context is within the other.
|
||||
if (auto *Shadow = dyn_cast<UsingShadowDecl>(DirectPrevDecl)) {
|
||||
auto *OldTag = dyn_cast<TagDecl>(PrevDecl);
|
||||
FoundUsingShadow = Shadow;
|
||||
if (SS.isEmpty() && TUK != TUK_Reference && TUK != TUK_Friend &&
|
||||
isDeclInScope(Shadow, SearchDC, S, isMemberSpecialization) &&
|
||||
!(OldTag && isAcceptableTagRedeclContext(
|
||||
|
|
@ -18871,10 +18871,24 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
|
|||
ProcessDeclAttributeList(S, Record, Attrs);
|
||||
|
||||
// Check to see if a FieldDecl is a pointer to a function.
|
||||
auto IsFunctionPointer = [&](const Decl *D) {
|
||||
auto IsFunctionPointerOrForwardDecl = [&](const Decl *D) {
|
||||
const FieldDecl *FD = dyn_cast<FieldDecl>(D);
|
||||
if (!FD)
|
||||
if (!FD) {
|
||||
// Check whether this is a forward declaration that was inserted by
|
||||
// Clang. This happens when a non-forward declared / defined type is
|
||||
// used, e.g.:
|
||||
//
|
||||
// struct foo {
|
||||
// struct bar *(*f)();
|
||||
// struct bar *(*g)();
|
||||
// };
|
||||
//
|
||||
// "struct bar" shows up in the decl AST as a "RecordDecl" with an
|
||||
// incomplete definition.
|
||||
if (const auto *TD = dyn_cast<TagDecl>(D))
|
||||
return !TD->isCompleteDefinition();
|
||||
return false;
|
||||
}
|
||||
QualType FieldType = FD->getType().getDesugaredType(Context);
|
||||
if (isa<PointerType>(FieldType)) {
|
||||
QualType PointeeType = cast<PointerType>(FieldType)->getPointeeType();
|
||||
|
|
@ -18888,7 +18902,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
|
|||
if (!getLangOpts().CPlusPlus &&
|
||||
(Record->hasAttr<RandomizeLayoutAttr>() ||
|
||||
(!Record->hasAttr<NoRandomizeLayoutAttr>() &&
|
||||
llvm::all_of(Record->decls(), IsFunctionPointer))) &&
|
||||
llvm::all_of(Record->decls(), IsFunctionPointerOrForwardDecl))) &&
|
||||
!Record->isUnion() && !getLangOpts().RandstructSeed.empty() &&
|
||||
!Record->isRandomized()) {
|
||||
SmallVector<Decl *, 32> NewDeclOrdering;
|
||||
|
|
|
|||
|
|
@ -16977,7 +16977,6 @@ DeclResult Sema::ActOnTemplatedFriendTag(
|
|||
if (SS.isEmpty()) {
|
||||
bool Owned = false;
|
||||
bool IsDependent = false;
|
||||
UsingShadowDecl* FoundUsing = nullptr;
|
||||
return ActOnTag(S, TagSpec, TUK_Friend, TagLoc, SS, Name, NameLoc, Attr,
|
||||
AS_public,
|
||||
/*ModulePrivateLoc=*/SourceLocation(),
|
||||
|
|
@ -16986,7 +16985,7 @@ DeclResult Sema::ActOnTemplatedFriendTag(
|
|||
/*ScopedEnumUsesClassTag=*/false,
|
||||
/*UnderlyingType=*/TypeResult(),
|
||||
/*IsTypeSpecifier=*/false,
|
||||
/*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside, FoundUsing);
|
||||
/*IsTemplateParamOrArg=*/false, /*OOK=*/OOK_Outside);
|
||||
}
|
||||
|
||||
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
|
||||
|
|
|
|||
|
|
@ -1483,13 +1483,14 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
|
|||
// Otherwise, if the type contains a placeholder type, it is replaced by the
|
||||
// type determined by placeholder type deduction.
|
||||
DeducedType *Deduced = Ty->getContainedDeducedType();
|
||||
if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) {
|
||||
if (Deduced && !Deduced->isDeduced() &&
|
||||
isa<DeducedTemplateSpecializationType>(Deduced)) {
|
||||
Ty = DeduceTemplateSpecializationFromInitializer(TInfo, Entity,
|
||||
Kind, Exprs);
|
||||
if (Ty.isNull())
|
||||
return ExprError();
|
||||
Entity = InitializedEntity::InitializeTemporary(TInfo, Ty);
|
||||
} else if (Deduced) {
|
||||
} else if (Deduced && !Deduced->isDeduced()) {
|
||||
MultiExprArg Inits = Exprs;
|
||||
if (ListInitialization) {
|
||||
auto *ILE = cast<InitListExpr>(Exprs[0]);
|
||||
|
|
@ -2016,7 +2017,8 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
|
|||
|
||||
// C++11 [dcl.spec.auto]p6. Deduce the type which 'auto' stands in for.
|
||||
auto *Deduced = AllocType->getContainedDeducedType();
|
||||
if (Deduced && isa<DeducedTemplateSpecializationType>(Deduced)) {
|
||||
if (Deduced && !Deduced->isDeduced() &&
|
||||
isa<DeducedTemplateSpecializationType>(Deduced)) {
|
||||
if (ArraySize)
|
||||
return ExprError(
|
||||
Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(),
|
||||
|
|
@ -2030,7 +2032,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
|
|||
AllocTypeInfo, Entity, Kind, Exprs);
|
||||
if (AllocType.isNull())
|
||||
return ExprError();
|
||||
} else if (Deduced) {
|
||||
} else if (Deduced && !Deduced->isDeduced()) {
|
||||
MultiExprArg Inits = Exprs;
|
||||
bool Braced = (initStyle == CXXNewExpr::ListInit);
|
||||
if (Braced) {
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
|
|||
PolicyScheme MaskedPolicyScheme =
|
||||
static_cast<PolicyScheme>(Record.MaskedPolicyScheme);
|
||||
|
||||
const Policy DefaultPolicy(Record.HasTailPolicy, Record.HasMaskPolicy);
|
||||
const Policy DefaultPolicy;
|
||||
|
||||
llvm::SmallVector<PrototypeDescriptor> ProtoSeq =
|
||||
RVVIntrinsic::computeBuiltinTypes(BasicProtoSeq, /*IsMasked=*/false,
|
||||
|
|
@ -208,8 +208,7 @@ void RISCVIntrinsicManagerImpl::InitIntrinsicList() {
|
|||
bool UnMaskedHasPolicy = UnMaskedPolicyScheme != PolicyScheme::SchemeNone;
|
||||
bool MaskedHasPolicy = MaskedPolicyScheme != PolicyScheme::SchemeNone;
|
||||
SmallVector<Policy> SupportedUnMaskedPolicies =
|
||||
RVVIntrinsic::getSupportedUnMaskedPolicies(Record.HasTailPolicy,
|
||||
Record.HasMaskPolicy);
|
||||
RVVIntrinsic::getSupportedUnMaskedPolicies();
|
||||
SmallVector<Policy> SupportedMaskedPolicies =
|
||||
RVVIntrinsic::getSupportedMaskedPolicies(Record.HasTailPolicy,
|
||||
Record.HasMaskPolicy);
|
||||
|
|
|
|||
|
|
@ -10181,14 +10181,11 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc,
|
|||
|
||||
bool Owned = false;
|
||||
bool IsDependent = false;
|
||||
UsingShadowDecl* FoundUsing = nullptr;
|
||||
Decl *TagD =
|
||||
ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name, NameLoc, Attr,
|
||||
AS_none, /*ModulePrivateLoc=*/SourceLocation(),
|
||||
Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference, KWLoc, SS, Name,
|
||||
NameLoc, Attr, AS_none, /*ModulePrivateLoc=*/SourceLocation(),
|
||||
MultiTemplateParamsArg(), Owned, IsDependent, SourceLocation(),
|
||||
false, TypeResult(), /*IsTypeSpecifier*/ false,
|
||||
/*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside, FoundUsing)
|
||||
.get();
|
||||
/*IsTemplateParamOrArg*/ false, /*OOK=*/OOK_Outside).get();
|
||||
assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
|
||||
|
||||
if (!TagD)
|
||||
|
|
|
|||
|
|
@ -1588,9 +1588,6 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
|||
|
||||
// TypeQuals handled by caller.
|
||||
Result = Context.getTypeDeclType(D);
|
||||
if (const auto *Using =
|
||||
dyn_cast_or_null<UsingShadowDecl>(DS.getRepAsFoundDecl()))
|
||||
Result = Context.getUsingType(Using, Result);
|
||||
|
||||
// In both C and C++, make an ElaboratedType.
|
||||
ElaboratedTypeKeyword Keyword
|
||||
|
|
@ -6256,9 +6253,6 @@ namespace {
|
|||
void VisitTagTypeLoc(TagTypeLoc TL) {
|
||||
TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
|
||||
}
|
||||
void VisitUsingTypeLoc(UsingTypeLoc TL) {
|
||||
TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
|
||||
}
|
||||
void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
|
||||
// An AtomicTypeLoc can come from either an _Atomic(...) type specifier
|
||||
// or an _Atomic qualifier.
|
||||
|
|
|
|||
|
|
@ -966,40 +966,26 @@ llvm::SmallVector<PrototypeDescriptor> RVVIntrinsic::computeBuiltinTypes(
|
|||
return NewPrototype;
|
||||
}
|
||||
|
||||
llvm::SmallVector<Policy>
|
||||
RVVIntrinsic::getSupportedUnMaskedPolicies(bool HasTailPolicy,
|
||||
bool HasMaskPolicy) {
|
||||
return {
|
||||
Policy(Policy::PolicyType::Undisturbed, HasTailPolicy,
|
||||
HasMaskPolicy), // TU
|
||||
Policy(Policy::PolicyType::Agnostic, HasTailPolicy, HasMaskPolicy)}; // TA
|
||||
llvm::SmallVector<Policy> RVVIntrinsic::getSupportedUnMaskedPolicies() {
|
||||
return {Policy(Policy::PolicyType::Undisturbed)}; // TU
|
||||
}
|
||||
|
||||
llvm::SmallVector<Policy>
|
||||
RVVIntrinsic::getSupportedMaskedPolicies(bool HasTailPolicy,
|
||||
bool HasMaskPolicy) {
|
||||
if (HasTailPolicy && HasMaskPolicy)
|
||||
return {
|
||||
Policy(Policy::PolicyType::Undisturbed, Policy::PolicyType::Agnostic,
|
||||
HasTailPolicy, HasMaskPolicy), // TUMA
|
||||
Policy(Policy::PolicyType::Agnostic, Policy::PolicyType::Agnostic,
|
||||
HasTailPolicy, HasMaskPolicy), // TAMA
|
||||
Policy(Policy::PolicyType::Undisturbed, Policy::PolicyType::Undisturbed,
|
||||
HasTailPolicy, HasMaskPolicy), // TUMU
|
||||
Policy(Policy::PolicyType::Agnostic, Policy::PolicyType::Undisturbed,
|
||||
HasTailPolicy, HasMaskPolicy)}; // TAMU
|
||||
return {Policy(Policy::PolicyType::Undisturbed,
|
||||
Policy::PolicyType::Agnostic), // TUM
|
||||
Policy(Policy::PolicyType::Undisturbed,
|
||||
Policy::PolicyType::Undisturbed), // TUMU
|
||||
Policy(Policy::PolicyType::Agnostic,
|
||||
Policy::PolicyType::Undisturbed)}; // MU
|
||||
if (HasTailPolicy && !HasMaskPolicy)
|
||||
return {Policy(Policy::PolicyType::Undisturbed,
|
||||
Policy::PolicyType::Agnostic, HasTailPolicy,
|
||||
HasMaskPolicy), // TUM
|
||||
Policy(Policy::PolicyType::Agnostic, Policy::PolicyType::Agnostic,
|
||||
HasTailPolicy, HasMaskPolicy)}; // TAM
|
||||
Policy::PolicyType::Agnostic)}; // TU
|
||||
if (!HasTailPolicy && HasMaskPolicy)
|
||||
return {Policy(Policy::PolicyType::Agnostic, Policy::PolicyType::Agnostic,
|
||||
HasTailPolicy, HasMaskPolicy), // MA
|
||||
Policy(Policy::PolicyType::Agnostic,
|
||||
Policy::PolicyType::Undisturbed, HasTailPolicy,
|
||||
HasMaskPolicy)}; // MU
|
||||
return {Policy(Policy::PolicyType::Agnostic,
|
||||
Policy::PolicyType::Undisturbed)}; // MU
|
||||
llvm_unreachable("An RVV instruction should not be without both tail policy "
|
||||
"and mask policy");
|
||||
}
|
||||
|
|
@ -1016,46 +1002,34 @@ void RVVIntrinsic::updateNamesAndPolicy(bool IsMasked, bool HasPolicy,
|
|||
OverloadedName += suffix;
|
||||
};
|
||||
|
||||
if (PolicyAttrs.isUnspecified()) {
|
||||
PolicyAttrs.IsUnspecified = false;
|
||||
if (IsMasked) {
|
||||
// This follows the naming guideline under riscv-c-api-doc to add the
|
||||
// `__riscv_` suffix for all RVV intrinsics.
|
||||
Name = "__riscv_" + Name;
|
||||
OverloadedName = "__riscv_" + OverloadedName;
|
||||
|
||||
if (IsMasked) {
|
||||
if (PolicyAttrs.isTUMUPolicy())
|
||||
appendPolicySuffix("_tumu");
|
||||
else if (PolicyAttrs.isTUMAPolicy())
|
||||
appendPolicySuffix("_tum");
|
||||
else if (PolicyAttrs.isTAMUPolicy())
|
||||
appendPolicySuffix("_mu");
|
||||
else if (PolicyAttrs.isTAMAPolicy()) {
|
||||
Name += "_m";
|
||||
if (HasPolicy)
|
||||
BuiltinName += "_tama";
|
||||
else
|
||||
BuiltinName += "_m";
|
||||
} else {
|
||||
} else
|
||||
llvm_unreachable("Unhandled policy condition");
|
||||
} else {
|
||||
if (PolicyAttrs.isTUPolicy())
|
||||
appendPolicySuffix("_tu");
|
||||
else if (PolicyAttrs.isTAPolicy()) {
|
||||
if (HasPolicy)
|
||||
BuiltinName += "_ta";
|
||||
}
|
||||
} else {
|
||||
if (IsMasked) {
|
||||
if (PolicyAttrs.isTUMAPolicy() && !PolicyAttrs.hasMaskPolicy())
|
||||
appendPolicySuffix("_tum");
|
||||
else if (PolicyAttrs.isTAMAPolicy() && !PolicyAttrs.hasMaskPolicy())
|
||||
appendPolicySuffix("_tam");
|
||||
else if (PolicyAttrs.isMUPolicy() && !PolicyAttrs.hasTailPolicy())
|
||||
appendPolicySuffix("_mu");
|
||||
else if (PolicyAttrs.isMAPolicy() && !PolicyAttrs.hasTailPolicy())
|
||||
appendPolicySuffix("_ma");
|
||||
else if (PolicyAttrs.isTUMUPolicy())
|
||||
appendPolicySuffix("_tumu");
|
||||
else if (PolicyAttrs.isTAMUPolicy())
|
||||
appendPolicySuffix("_tamu");
|
||||
else if (PolicyAttrs.isTUMAPolicy())
|
||||
appendPolicySuffix("_tuma");
|
||||
else if (PolicyAttrs.isTAMAPolicy())
|
||||
appendPolicySuffix("_tama");
|
||||
else
|
||||
llvm_unreachable("Unhandled policy condition");
|
||||
} else {
|
||||
if (PolicyAttrs.isTUPolicy())
|
||||
appendPolicySuffix("_tu");
|
||||
else if (PolicyAttrs.isTAPolicy())
|
||||
appendPolicySuffix("_ta");
|
||||
else
|
||||
llvm_unreachable("Unhandled policy condition");
|
||||
}
|
||||
} else
|
||||
llvm_unreachable("Unhandled policy condition");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -521,10 +521,9 @@ void RVVEmitter::createRVVIntrinsics(
|
|||
StringRef MaskedIRName = R->getValueAsString("MaskedIRName");
|
||||
unsigned NF = R->getValueAsInt("NF");
|
||||
|
||||
const Policy DefaultPolicy(HasTailPolicy, HasMaskPolicy);
|
||||
const Policy DefaultPolicy;
|
||||
SmallVector<Policy> SupportedUnMaskedPolicies =
|
||||
RVVIntrinsic::getSupportedUnMaskedPolicies(HasTailPolicy,
|
||||
HasMaskPolicy);
|
||||
RVVIntrinsic::getSupportedUnMaskedPolicies();
|
||||
SmallVector<Policy> SupportedMaskedPolicies =
|
||||
RVVIntrinsic::getSupportedMaskedPolicies(HasTailPolicy, HasMaskPolicy);
|
||||
|
||||
|
|
|
|||
|
|
@ -134,6 +134,15 @@
|
|||
# define _LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON
|
||||
// According to the Standard, `bitset::operator[] const` returns bool
|
||||
# define _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
|
||||
// Fix the implementation of CityHash used for std::hash<fundamental-type>.
|
||||
// This is an ABI break because `std::hash` will return a different result,
|
||||
// which means that hashing the same object in translation units built against
|
||||
// different versions of libc++ can return inconsistent results. This is especially
|
||||
// tricky since std::hash is used in the implementation of unordered containers.
|
||||
//
|
||||
// The incorrect implementation of CityHash has the problem that it drops some
|
||||
// bits on the floor.
|
||||
# define _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION
|
||||
// Remove the base 10 implementation of std::to_chars from the dylib.
|
||||
// The implementation moved to the header, but we still export the symbols from
|
||||
// the dylib for backwards compatibility.
|
||||
|
|
@ -629,7 +638,11 @@ typedef __char32_t char32_t;
|
|||
# else
|
||||
# define _LIBCPP_HIDE_FROM_ABI _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
|
||||
# endif
|
||||
# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
|
||||
# define _LIBCPP_HIDE_FROM_ABI_VIRTUAL _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
|
||||
|
||||
// This macro provides a HIDE_FROM_ABI equivalent that can be applied to extern
|
||||
// "C" function, as those lack mangling.
|
||||
# define _LIBCPP_HIDE_FROM_ABI_C _LIBCPP_HIDDEN _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION
|
||||
|
||||
# ifdef _LIBCPP_BUILDING_LIBRARY
|
||||
# if _LIBCPP_ABI_VERSION > 1
|
||||
|
|
@ -1223,12 +1236,12 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD
|
|||
// functions are declared by the C library.
|
||||
# define _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
|
||||
// GNU libc 2.36 and newer declare c8rtomb() and mbrtoc8() in C++ modes if
|
||||
// __cpp_char8_t is defined or if C2X extensions are enabled. Unfortunately,
|
||||
// determining the latter depends on internal GNU libc details. If the
|
||||
// __cpp_char8_t feature test macro is not defined, then a char8_t typedef
|
||||
// will be declared as well.
|
||||
# if defined(_LIBCPP_GLIBC_PREREQ) && defined(__GLIBC_USE)
|
||||
# if _LIBCPP_GLIBC_PREREQ(2, 36) && (defined(__cpp_char8_t) || __GLIBC_USE(ISOC2X))
|
||||
// __cpp_char8_t is defined or if C2X extensions are enabled. Determining
|
||||
// the latter depends on internal GNU libc details that are not appropriate
|
||||
// to depend on here, so any declarations present when __cpp_char8_t is not
|
||||
// defined are ignored.
|
||||
# if defined(_LIBCPP_GLIBC_PREREQ)
|
||||
# if _LIBCPP_GLIBC_PREREQ(2, 36) && defined(__cpp_char8_t)
|
||||
# undef _LIBCPP_HAS_NO_C8RTOMB_MBRTOC8
|
||||
# endif
|
||||
# endif
|
||||
|
|
|
|||
|
|
@ -258,10 +258,12 @@ __handle_replacement_field(const _CharT* __begin, const _CharT* __end,
|
|||
|
||||
if constexpr (same_as<_Ctx, __compile_time_basic_format_context<_CharT>>) {
|
||||
__arg_t __type = __ctx.arg(__r.__value);
|
||||
if (__type == __arg_t::__handle)
|
||||
if (__type == __arg_t::__none)
|
||||
std::__throw_format_error("Argument index out of bounds");
|
||||
else if (__type == __arg_t::__handle)
|
||||
__ctx.__handle(__r.__value).__parse(__parse_ctx);
|
||||
else
|
||||
__format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
|
||||
else if (__parse)
|
||||
__format::__compile_time_visit_format_arg(__parse_ctx, __ctx, __type);
|
||||
} else
|
||||
_VSTD::__visit_format_arg(
|
||||
[&](auto __arg) {
|
||||
|
|
|
|||
|
|
@ -140,7 +140,11 @@ struct __murmur2_or_cityhash<_Size, 64>
|
|||
if (__len >= 4) {
|
||||
const uint32_t __a = std::__loadword<uint32_t>(__s);
|
||||
const uint32_t __b = std::__loadword<uint32_t>(__s + __len - 4);
|
||||
#ifdef _LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION
|
||||
return __hash_len_16(__len + (static_cast<_Size>(__a) << 3), __b);
|
||||
#else
|
||||
return __hash_len_16(__len + (__a << 3), __b);
|
||||
#endif
|
||||
}
|
||||
if (__len > 0) {
|
||||
const unsigned char __a = static_cast<unsigned char>(__s[0]);
|
||||
|
|
|
|||
|
|
@ -40,7 +40,10 @@
|
|||
|
||||
_LIBCPP_BEGIN_NAMESPACE_STD
|
||||
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
// Note: `join_view` is still marked experimental because there is an ABI-breaking change that affects `join_view` in
|
||||
// the pipeline (https://isocpp.org/files/papers/D2770R0.html).
|
||||
// TODO: make `join_view` non-experimental once D2770 is implemented.
|
||||
#if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
|
||||
|
||||
namespace ranges {
|
||||
template<class>
|
||||
|
|
@ -445,7 +448,7 @@ struct __segmented_iterator_traits<ranges::__join_view_iterator<_View, _Const>>
|
|||
}
|
||||
};
|
||||
|
||||
#endif // _LIBCPP_STD_VER > 17
|
||||
#endif // #if _LIBCPP_STD_VER > 17 && defined(_LIBCPP_ENABLE_EXPERIMENTAL)
|
||||
|
||||
_LIBCPP_END_NAMESPACE_STD
|
||||
|
||||
|
|
|
|||
|
|
@ -755,13 +755,19 @@ module std [system] {
|
|||
module derived_from { private header "__concepts/derived_from.h" }
|
||||
module destructible { private header "__concepts/destructible.h" }
|
||||
module different_from { private header "__concepts/different_from.h" }
|
||||
module equality_comparable { private header "__concepts/equality_comparable.h" }
|
||||
module equality_comparable {
|
||||
private header "__concepts/equality_comparable.h"
|
||||
export type_traits.common_reference
|
||||
}
|
||||
module invocable { private header "__concepts/invocable.h" }
|
||||
module movable { private header "__concepts/movable.h" }
|
||||
module predicate { private header "__concepts/predicate.h" }
|
||||
module regular { private header "__concepts/regular.h" }
|
||||
module relation { private header "__concepts/relation.h" }
|
||||
module same_as { private header "__concepts/same_as.h" }
|
||||
module same_as {
|
||||
private header "__concepts/same_as.h"
|
||||
export type_traits.is_same
|
||||
}
|
||||
module semiregular { private header "__concepts/semiregular.h" }
|
||||
module swappable { private header "__concepts/swappable.h" }
|
||||
module totally_ordered { private header "__concepts/totally_ordered.h" }
|
||||
|
|
@ -979,7 +985,11 @@ module std [system] {
|
|||
module back_insert_iterator { private header "__iterator/back_insert_iterator.h" }
|
||||
module bounded_iter { private header "__iterator/bounded_iter.h" }
|
||||
module common_iterator { private header "__iterator/common_iterator.h" }
|
||||
module concepts { private header "__iterator/concepts.h" }
|
||||
module concepts {
|
||||
private header "__iterator/concepts.h"
|
||||
export concepts.equality_comparable
|
||||
export type_traits.common_reference
|
||||
}
|
||||
module counted_iterator { private header "__iterator/counted_iterator.h" }
|
||||
module data { private header "__iterator/data.h" }
|
||||
module default_sentinel { private header "__iterator/default_sentinel.h" }
|
||||
|
|
|
|||
|
|
@ -1079,7 +1079,15 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
|
|||
return;
|
||||
}
|
||||
|
||||
bool canWrite = (sec->flags & SHF_WRITE) || !config->zText;
|
||||
// Use a simple -z notext rule that treats all sections except .eh_frame as
|
||||
// writable. GNU ld does not produce dynamic relocations in .eh_frame (and our
|
||||
// SectionBase::getOffset would incorrectly adjust the offset).
|
||||
//
|
||||
// For MIPS, we don't implement GNU ld's DW_EH_PE_absptr to DW_EH_PE_pcrel
|
||||
// conversion. We still emit a dynamic relocation.
|
||||
bool canWrite = (sec->flags & SHF_WRITE) ||
|
||||
!(config->zText ||
|
||||
(isa<EhInputSection>(sec) && config->emachine != EM_MIPS));
|
||||
if (canWrite) {
|
||||
RelType rel = target->getDynRel(type);
|
||||
if (expr == R_GOT || (rel == target->symbolicRel && !sym.isPreemptible)) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,10 @@ Non-comprehensive list of changes in this release
|
|||
ELF Improvements
|
||||
----------------
|
||||
|
||||
* Link speed improved greatly compared with lld 15.0. Notably input section
|
||||
initialization and relocation scanning are now parallel.
|
||||
(`D130810 <https://reviews.llvm.org/D130810>`_)
|
||||
(`D133003 <https://reviews.llvm.org/D133003>`_)
|
||||
* ``ELFCOMPRESS_ZSTD`` compressed input sections are now supported.
|
||||
(`D129406 <https://reviews.llvm.org/D129406>`_)
|
||||
* ``--compress-debug-sections=zstd`` is now available to compress debug
|
||||
|
|
@ -36,12 +40,25 @@ ELF Improvements
|
|||
* ``DT_RISCV_VARIANT_CC`` is now produced if at least one ``R_RISCV_JUMP_SLOT``
|
||||
relocation references a symbol with the ``STO_RISCV_VARIANT_CC`` bit.
|
||||
(`D107951 <https://reviews.llvm.org/D107951>`_)
|
||||
* ``DT_STATIC_TLS`` is now set for AArch64/PPC32/PPC64 initial-exec TLS models
|
||||
when producing a shared object.
|
||||
* ``--no-undefined-version`` is now the default; symbols named in version
|
||||
scripts that have no matching symbol in the output will be reported. Use
|
||||
``--undefined-version`` to revert to the old behavior.
|
||||
(`D135402 <https://reviews.llvm.org/D135402>`_)
|
||||
* ``-V`` is now an alias for ``-v`` to support ``gcc -fuse-ld=lld -v`` on many targets.
|
||||
* ``-r`` no longer defines ``__global_pointer$`` or ``_TLS_MODULE_BASE_``.
|
||||
* A corner case of mixed GCC and Clang object files (``STB_WEAK`` and
|
||||
``STB_GNU_UNIQUE`` in different COMDATs) is now supported.
|
||||
(`D136381 <https://reviews.llvm.org/D136381>`_)
|
||||
* The output ``SHT_RISCV_ATTRIBUTES`` section now merges all input components
|
||||
instead of picking the first input component.
|
||||
(`D138550 <https://reviews.llvm.org/D138550>`_)
|
||||
* For x86-32, ``-fno-plt`` GD/LD TLS models ``call *___tls_get_addr@GOT(%reg)``
|
||||
are now supported. Previous output might have runtime crash.
|
||||
* Armv4(T) thunks are now supported.
|
||||
(`D139888 <https://reviews.llvm.org/D139888>`_)
|
||||
(`D141272 <https://reviews.llvm.org/D141272>`_)
|
||||
|
||||
Breaking changes
|
||||
----------------
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ NativeRegisterContextFreeBSD_mips64::ReadRegister(const RegisterInfo *reg_info,
|
|||
return error;
|
||||
}
|
||||
|
||||
RegSetKind set = opt_set.getValue();
|
||||
RegSetKind set = *opt_set;
|
||||
error = ReadRegisterSet(set);
|
||||
if (error.Fail())
|
||||
return error;
|
||||
|
|
@ -164,7 +164,7 @@ Status NativeRegisterContextFreeBSD_mips64::WriteRegister(
|
|||
return error;
|
||||
}
|
||||
|
||||
RegSetKind set = opt_set.getValue();
|
||||
RegSetKind set = *opt_set;
|
||||
error = ReadRegisterSet(set);
|
||||
if (error.Fail())
|
||||
return error;
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ NativeRegisterContextFreeBSD_powerpc::ReadRegister(const RegisterInfo *reg_info,
|
|||
return error;
|
||||
}
|
||||
|
||||
RegSetKind set = opt_set.getValue();
|
||||
RegSetKind set = *opt_set;
|
||||
error = ReadRegisterSet(set);
|
||||
if (error.Fail())
|
||||
return error;
|
||||
|
|
@ -215,7 +215,7 @@ Status NativeRegisterContextFreeBSD_powerpc::WriteRegister(
|
|||
return error;
|
||||
}
|
||||
|
||||
RegSetKind set = opt_set.getValue();
|
||||
RegSetKind set = *opt_set;
|
||||
error = ReadRegisterSet(set);
|
||||
if (error.Fail())
|
||||
return error;
|
||||
|
|
|
|||
|
|
@ -38,9 +38,13 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
/// Returns false if a debuginfod lookup can be determined to have no chance of
|
||||
/// succeeding.
|
||||
bool canUseDebuginfod();
|
||||
|
||||
/// Finds default array of Debuginfod server URLs by checking DEBUGINFOD_URLS
|
||||
/// environment variable.
|
||||
Expected<SmallVector<StringRef>> getDefaultDebuginfodUrls();
|
||||
SmallVector<StringRef> getDefaultDebuginfodUrls();
|
||||
|
||||
/// Finds a default local file caching directory for the debuginfod client,
|
||||
/// first checking DEBUGINFOD_CACHE_PATH.
|
||||
|
|
|
|||
|
|
@ -1391,6 +1391,16 @@ let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
|
|||
|
||||
let TargetPrefix = "aarch64" in { // All intrinsics start with "llvm.aarch64.".
|
||||
|
||||
class AdvSIMD_SVE_2SVBoolArg_Intrinsic
|
||||
: DefaultAttrsIntrinsic<[llvm_nxv16i1_ty],
|
||||
[llvm_nxv16i1_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class AdvSIMD_SVE_3SVBoolArg_Intrinsic
|
||||
: DefaultAttrsIntrinsic<[llvm_nxv16i1_ty],
|
||||
[llvm_nxv16i1_ty, llvm_nxv16i1_ty],
|
||||
[IntrNoMem]>;
|
||||
|
||||
class AdvSIMD_SVE_Reduce_Intrinsic
|
||||
: DefaultAttrsIntrinsic<[LLVMVectorElementType<0>],
|
||||
[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>,
|
||||
|
|
@ -1836,22 +1846,43 @@ def int_aarch64_sve_sel : AdvSIMD_Pred2VectorArg_Intrinsic;
|
|||
def int_aarch64_sve_lasta : AdvSIMD_SVE_Reduce_Intrinsic;
|
||||
def int_aarch64_sve_lastb : AdvSIMD_SVE_Reduce_Intrinsic;
|
||||
def int_aarch64_sve_rev : AdvSIMD_1VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_rev_b16 : AdvSIMD_SVE_2SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_rev_b32 : AdvSIMD_SVE_2SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_rev_b64 : AdvSIMD_SVE_2SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_splice : AdvSIMD_Pred2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_sunpkhi : AdvSIMD_SVE_Unpack_Intrinsic;
|
||||
def int_aarch64_sve_sunpklo : AdvSIMD_SVE_Unpack_Intrinsic;
|
||||
def int_aarch64_sve_tbl : AdvSIMD_SVE_TBL_Intrinsic;
|
||||
def int_aarch64_sve_trn1 : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_trn1_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_trn1_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_trn1_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_trn2 : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_trn2_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_trn2_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_trn2_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_trn1q : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_trn2q : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_uunpkhi : AdvSIMD_SVE_Unpack_Intrinsic;
|
||||
def int_aarch64_sve_uunpklo : AdvSIMD_SVE_Unpack_Intrinsic;
|
||||
def int_aarch64_sve_uzp1 : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp1_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp1_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp1_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp2 : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp2_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp2_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp2_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp1q : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_uzp2q : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_zip1 : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_zip1_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_zip1_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_zip1_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_zip2 : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_zip2_b16 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_zip2_b32 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_zip2_b64 : AdvSIMD_SVE_3SVBoolArg_Intrinsic;
|
||||
def int_aarch64_sve_zip1q : AdvSIMD_2VectorArg_Intrinsic;
|
||||
def int_aarch64_sve_zip2q : AdvSIMD_2VectorArg_Intrinsic;
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/iterator.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include "llvm/Object/BuildID.h"
|
||||
#include "llvm/ProfileData/InstrProf.h"
|
||||
#include "llvm/Support/Alignment.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
|
|
@ -42,6 +43,10 @@ namespace llvm {
|
|||
|
||||
class IndexedInstrProfReader;
|
||||
|
||||
namespace object {
|
||||
class BuildIDFetcher;
|
||||
} // namespace object
|
||||
|
||||
namespace coverage {
|
||||
|
||||
class CoverageMappingReader;
|
||||
|
|
@ -579,6 +584,13 @@ class CoverageMapping {
|
|||
ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
|
||||
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage);
|
||||
|
||||
// Load coverage records from file.
|
||||
static Error
|
||||
loadFromFile(StringRef Filename, StringRef Arch, StringRef CompilationDir,
|
||||
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
|
||||
bool &DataFound,
|
||||
SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr);
|
||||
|
||||
/// Add a function record corresponding to \p Record.
|
||||
Error loadFunctionRecord(const CoverageMappingRecord &Record,
|
||||
IndexedInstrProfReader &ProfileReader);
|
||||
|
|
@ -604,8 +616,8 @@ public:
|
|||
/// Ignores non-instrumented object files unless all are not instrumented.
|
||||
static Expected<std::unique_ptr<CoverageMapping>>
|
||||
load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
|
||||
ArrayRef<StringRef> Arches = std::nullopt,
|
||||
StringRef CompilationDir = "");
|
||||
ArrayRef<StringRef> Arches = std::nullopt, StringRef CompilationDir = "",
|
||||
const object::BuildIDFetcher *BIDFetcher = nullptr);
|
||||
|
||||
/// The number of functions that couldn't have their profiles mapped.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ public:
|
|||
static Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
|
||||
create(MemoryBufferRef ObjectBuffer, StringRef Arch,
|
||||
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
|
||||
StringRef CompilationDir = "");
|
||||
StringRef CompilationDir = "",
|
||||
SmallVectorImpl<object::BuildIDRef> *BinaryIDs = nullptr);
|
||||
|
||||
static Expected<std::unique_ptr<BinaryCoverageReader>>
|
||||
createCoverageReaderFromBuffer(StringRef Coverage,
|
||||
|
|
|
|||
|
|
@ -37,13 +37,25 @@ KernelSet getDeviceKernels(Module &M);
|
|||
/// OpenMP optimizations pass.
|
||||
class OpenMPOptPass : public PassInfoMixin<OpenMPOptPass> {
|
||||
public:
|
||||
OpenMPOptPass() : LTOPhase(ThinOrFullLTOPhase::None) {}
|
||||
OpenMPOptPass(ThinOrFullLTOPhase LTOPhase) : LTOPhase(LTOPhase) {}
|
||||
|
||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
|
||||
|
||||
private:
|
||||
const ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None;
|
||||
};
|
||||
|
||||
class OpenMPOptCGSCCPass : public PassInfoMixin<OpenMPOptCGSCCPass> {
|
||||
public:
|
||||
OpenMPOptCGSCCPass() : LTOPhase(ThinOrFullLTOPhase::None) {}
|
||||
OpenMPOptCGSCCPass(ThinOrFullLTOPhase LTOPhase) : LTOPhase(LTOPhase) {}
|
||||
|
||||
PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM,
|
||||
LazyCallGraph &CG, CGSCCUpdateResult &UR);
|
||||
|
||||
private:
|
||||
const ThinOrFullLTOPhase LTOPhase = ThinOrFullLTOPhase::None;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
|
|||
|
|
@ -2235,6 +2235,8 @@ bool AsmPrinter::doFinalization(Module &M) {
|
|||
SmallVector<const GlobalAlias *, 16> AliasStack;
|
||||
SmallPtrSet<const GlobalAlias *, 16> AliasVisited;
|
||||
for (const auto &Alias : M.aliases()) {
|
||||
if (Alias.hasAvailableExternallyLinkage())
|
||||
continue;
|
||||
for (const GlobalAlias *Cur = &Alias; Cur;
|
||||
Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) {
|
||||
if (!AliasVisited.insert(Cur).second)
|
||||
|
|
|
|||
|
|
@ -2244,6 +2244,15 @@ void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI, bool AddEdges) {
|
|||
assert(!FromMBB.hasAddressTaken() &&
|
||||
"Removing a BB whose address is taken!");
|
||||
|
||||
// If we're about to splice an INLINEASM_BR from FromBBI, we need to update
|
||||
// ToBBI's successor list accordingly.
|
||||
if (FromMBB.mayHaveInlineAsmBr())
|
||||
for (MachineInstr &MI : FromMBB)
|
||||
if (MI.getOpcode() == TargetOpcode::INLINEASM_BR)
|
||||
for (MachineOperand &MO : MI.operands())
|
||||
if (MO.isMBB() && !ToBBI.BB->isSuccessor(MO.getMBB()))
|
||||
ToBBI.BB->addSuccessor(MO.getMBB(), BranchProbability::getZero());
|
||||
|
||||
// In case FromMBB contains terminators (e.g. return instruction),
|
||||
// first move the non-terminator instructions, then the terminators.
|
||||
MachineBasicBlock::iterator FromTI = FromMBB.getFirstTerminator();
|
||||
|
|
|
|||
|
|
@ -55,7 +55,11 @@ static std::string buildIDToString(BuildIDRef ID) {
|
|||
return llvm::toHex(ID, /*LowerCase=*/true);
|
||||
}
|
||||
|
||||
Expected<SmallVector<StringRef>> getDefaultDebuginfodUrls() {
|
||||
bool canUseDebuginfod() {
|
||||
return HTTPClient::isAvailable() && !getDefaultDebuginfodUrls().empty();
|
||||
}
|
||||
|
||||
SmallVector<StringRef> getDefaultDebuginfodUrls() {
|
||||
const char *DebuginfodUrlsEnv = std::getenv("DEBUGINFOD_URLS");
|
||||
if (DebuginfodUrlsEnv == nullptr)
|
||||
return SmallVector<StringRef>();
|
||||
|
|
@ -126,13 +130,8 @@ Expected<std::string> getCachedOrDownloadArtifact(StringRef UniqueKey,
|
|||
return CacheDirOrErr.takeError();
|
||||
CacheDir = *CacheDirOrErr;
|
||||
|
||||
Expected<SmallVector<StringRef>> DebuginfodUrlsOrErr =
|
||||
getDefaultDebuginfodUrls();
|
||||
if (!DebuginfodUrlsOrErr)
|
||||
return DebuginfodUrlsOrErr.takeError();
|
||||
SmallVector<StringRef> &DebuginfodUrls = *DebuginfodUrlsOrErr;
|
||||
return getCachedOrDownloadArtifact(UniqueKey, UrlPath, CacheDir,
|
||||
DebuginfodUrls,
|
||||
getDefaultDebuginfodUrls(),
|
||||
getDefaultDebuginfodTimeout());
|
||||
}
|
||||
|
||||
|
|
@ -159,7 +158,8 @@ public:
|
|||
|
||||
Error StreamedHTTPResponseHandler::handleBodyChunk(StringRef BodyChunk) {
|
||||
if (!FileStream) {
|
||||
if (Client.responseCode() != 200)
|
||||
unsigned Code = Client.responseCode();
|
||||
if (Code && Code != 200)
|
||||
return Error::success();
|
||||
Expected<std::unique_ptr<CachedFileStream>> FileStreamOrError =
|
||||
CreateStream();
|
||||
|
|
@ -259,7 +259,8 @@ Expected<std::string> getCachedOrDownloadArtifact(
|
|||
if (Err)
|
||||
return std::move(Err);
|
||||
|
||||
if (Client.responseCode() != 200)
|
||||
unsigned Code = Client.responseCode();
|
||||
if (Code && Code != 200)
|
||||
continue;
|
||||
|
||||
// Return the path to the artifact on disk.
|
||||
|
|
|
|||
|
|
@ -125,6 +125,10 @@ void IRMaterializationUnit::discard(const JITDylib &JD,
|
|||
assert(!I->second->isDeclaration() &&
|
||||
"Discard should only apply to definitions");
|
||||
I->second->setLinkage(GlobalValue::AvailableExternallyLinkage);
|
||||
// According to the IR verifier, "Declaration[s] may not be in a Comdat!"
|
||||
// Remove it, if this is a GlobalObject.
|
||||
if (auto *GO = dyn_cast<GlobalObject>(I->second))
|
||||
GO->setComdat(nullptr);
|
||||
SymbolToDefinition.erase(I);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -730,9 +730,6 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
|
|||
GV.getName() == "llvm.global_dtors")) {
|
||||
Check(!GV.hasInitializer() || GV.hasAppendingLinkage(),
|
||||
"invalid linkage for intrinsic global variable", &GV);
|
||||
Check(GV.materialized_use_empty(),
|
||||
"invalid uses of intrinsic global variable", &GV);
|
||||
|
||||
// Don't worry about emitting an error for it not being an array,
|
||||
// visitGlobalValue will complain on appending non-array.
|
||||
if (ArrayType *ATy = dyn_cast<ArrayType>(GV.getValueType())) {
|
||||
|
|
@ -759,9 +756,6 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) {
|
|||
GV.getName() == "llvm.compiler.used")) {
|
||||
Check(!GV.hasInitializer() || GV.hasAppendingLinkage(),
|
||||
"invalid linkage for intrinsic global variable", &GV);
|
||||
Check(GV.materialized_use_empty(),
|
||||
"invalid uses of intrinsic global variable", &GV);
|
||||
|
||||
Type *GVType = GV.getValueType();
|
||||
if (ArrayType *ATy = dyn_cast<ArrayType>(GVType)) {
|
||||
PointerType *PTy = dyn_cast<PointerType>(ATy->getElementType());
|
||||
|
|
|
|||
|
|
@ -1604,7 +1604,7 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
|
|||
}
|
||||
|
||||
// Try to run OpenMP optimizations, quick no-op if no OpenMP metadata present.
|
||||
MPM.addPass(OpenMPOptPass());
|
||||
MPM.addPass(OpenMPOptPass(ThinOrFullLTOPhase::FullLTOPostLink));
|
||||
|
||||
// Remove unused virtual tables to improve the quality of code generated by
|
||||
// whole-program devirtualization and bitset lowering.
|
||||
|
|
@ -1712,6 +1712,9 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
|
|||
// Optimize globals again after we ran the inliner.
|
||||
MPM.addPass(GlobalOptPass());
|
||||
|
||||
// Run the OpenMPOpt pass again after global optimizations.
|
||||
MPM.addPass(OpenMPOptPass(ThinOrFullLTOPhase::FullLTOPostLink));
|
||||
|
||||
// Garbage collect dead functions.
|
||||
MPM.addPass(GlobalDCEPass());
|
||||
|
||||
|
|
@ -1808,7 +1811,8 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
|
|||
addVectorPasses(Level, MainFPM, /* IsFullLTO */ true);
|
||||
|
||||
// Run the OpenMPOpt CGSCC pass again late.
|
||||
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(OpenMPOptCGSCCPass()));
|
||||
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(
|
||||
OpenMPOptCGSCCPass(ThinOrFullLTOPhase::FullLTOPostLink)));
|
||||
|
||||
invokePeepholeEPCallbacks(MainFPM, Level);
|
||||
MainFPM.addPass(JumpThreadingPass());
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ MODULE_PASS("always-inline", AlwaysInlinerPass())
|
|||
MODULE_PASS("attributor", AttributorPass())
|
||||
MODULE_PASS("annotation2metadata", Annotation2MetadataPass())
|
||||
MODULE_PASS("openmp-opt", OpenMPOptPass())
|
||||
MODULE_PASS("openmp-opt-postlink", OpenMPOptPass(ThinOrFullLTOPhase::FullLTOPostLink))
|
||||
MODULE_PASS("called-value-propagation", CalledValuePropagationPass())
|
||||
MODULE_PASS("canonicalize-aliases", CanonicalizeAliasesPass())
|
||||
MODULE_PASS("cg-profile", CGProfilePass())
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "llvm/ADT/SmallBitVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Object/BuildID.h"
|
||||
#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
|
||||
#include "llvm/ProfileData/InstrProfReader.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
|
@ -342,10 +343,49 @@ static Error handleMaybeNoDataFoundError(Error E) {
|
|||
});
|
||||
}
|
||||
|
||||
Error CoverageMapping::loadFromFile(
|
||||
StringRef Filename, StringRef Arch, StringRef CompilationDir,
|
||||
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
|
||||
bool &DataFound, SmallVectorImpl<object::BuildID> *FoundBinaryIDs) {
|
||||
auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(
|
||||
Filename, /*IsText=*/false, /*RequiresNullTerminator=*/false);
|
||||
if (std::error_code EC = CovMappingBufOrErr.getError())
|
||||
return createFileError(Filename, errorCodeToError(EC));
|
||||
MemoryBufferRef CovMappingBufRef =
|
||||
CovMappingBufOrErr.get()->getMemBufferRef();
|
||||
SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
|
||||
|
||||
SmallVector<object::BuildIDRef> BinaryIDs;
|
||||
auto CoverageReadersOrErr = BinaryCoverageReader::create(
|
||||
CovMappingBufRef, Arch, Buffers, CompilationDir,
|
||||
FoundBinaryIDs ? &BinaryIDs : nullptr);
|
||||
if (Error E = CoverageReadersOrErr.takeError()) {
|
||||
E = handleMaybeNoDataFoundError(std::move(E));
|
||||
if (E)
|
||||
return createFileError(Filename, std::move(E));
|
||||
return E;
|
||||
}
|
||||
|
||||
SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
|
||||
for (auto &Reader : CoverageReadersOrErr.get())
|
||||
Readers.push_back(std::move(Reader));
|
||||
if (FoundBinaryIDs && !Readers.empty()) {
|
||||
llvm::append_range(*FoundBinaryIDs,
|
||||
llvm::map_range(BinaryIDs, [](object::BuildIDRef BID) {
|
||||
return object::BuildID(BID);
|
||||
}));
|
||||
}
|
||||
DataFound |= !Readers.empty();
|
||||
if (Error E = loadFromReaders(Readers, ProfileReader, Coverage))
|
||||
return createFileError(Filename, std::move(E));
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<CoverageMapping>>
|
||||
CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
|
||||
StringRef ProfileFilename, ArrayRef<StringRef> Arches,
|
||||
StringRef CompilationDir) {
|
||||
StringRef CompilationDir,
|
||||
const object::BuildIDFetcher *BIDFetcher) {
|
||||
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
|
||||
if (Error E = ProfileReaderOrErr.takeError())
|
||||
return createFileError(ProfileFilename, std::move(E));
|
||||
|
|
@ -353,35 +393,53 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
|
|||
auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
|
||||
bool DataFound = false;
|
||||
|
||||
auto GetArch = [&](size_t Idx) {
|
||||
if (Arches.empty())
|
||||
return StringRef();
|
||||
if (Arches.size() == 1)
|
||||
return Arches.front();
|
||||
return Arches[Idx];
|
||||
};
|
||||
|
||||
SmallVector<object::BuildID> FoundBinaryIDs;
|
||||
for (const auto &File : llvm::enumerate(ObjectFilenames)) {
|
||||
auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(
|
||||
File.value(), /*IsText=*/false, /*RequiresNullTerminator=*/false);
|
||||
if (std::error_code EC = CovMappingBufOrErr.getError())
|
||||
return createFileError(File.value(), errorCodeToError(EC));
|
||||
StringRef Arch = Arches.empty() ? StringRef() : Arches[File.index()];
|
||||
MemoryBufferRef CovMappingBufRef =
|
||||
CovMappingBufOrErr.get()->getMemBufferRef();
|
||||
SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
|
||||
auto CoverageReadersOrErr = BinaryCoverageReader::create(
|
||||
CovMappingBufRef, Arch, Buffers, CompilationDir);
|
||||
if (Error E = CoverageReadersOrErr.takeError()) {
|
||||
E = handleMaybeNoDataFoundError(std::move(E));
|
||||
if (E)
|
||||
return createFileError(File.value(), std::move(E));
|
||||
// E == success (originally a no_data_found error).
|
||||
continue;
|
||||
if (Error E =
|
||||
loadFromFile(File.value(), GetArch(File.index()), CompilationDir,
|
||||
*ProfileReader, *Coverage, DataFound, &FoundBinaryIDs))
|
||||
return std::move(E);
|
||||
}
|
||||
|
||||
if (BIDFetcher) {
|
||||
std::vector<object::BuildID> ProfileBinaryIDs;
|
||||
if (Error E = ProfileReader->readBinaryIds(ProfileBinaryIDs))
|
||||
return createFileError(ProfileFilename, std::move(E));
|
||||
|
||||
SmallVector<object::BuildIDRef> BinaryIDsToFetch;
|
||||
if (!ProfileBinaryIDs.empty()) {
|
||||
const auto &Compare = [](object::BuildIDRef A, object::BuildIDRef B) {
|
||||
return std::lexicographical_compare(A.begin(), A.end(), B.begin(),
|
||||
B.end());
|
||||
};
|
||||
llvm::sort(FoundBinaryIDs, Compare);
|
||||
std::set_difference(
|
||||
ProfileBinaryIDs.begin(), ProfileBinaryIDs.end(),
|
||||
FoundBinaryIDs.begin(), FoundBinaryIDs.end(),
|
||||
std::inserter(BinaryIDsToFetch, BinaryIDsToFetch.end()), Compare);
|
||||
}
|
||||
|
||||
SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
|
||||
for (auto &Reader : CoverageReadersOrErr.get())
|
||||
Readers.push_back(std::move(Reader));
|
||||
DataFound |= !Readers.empty();
|
||||
if (Error E = loadFromReaders(Readers, *ProfileReader, *Coverage))
|
||||
return createFileError(File.value(), std::move(E));
|
||||
for (object::BuildIDRef BinaryID : BinaryIDsToFetch) {
|
||||
std::optional<std::string> PathOpt = BIDFetcher->fetch(BinaryID);
|
||||
if (!PathOpt)
|
||||
continue;
|
||||
std::string Path = std::move(*PathOpt);
|
||||
StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
|
||||
if (Error E = loadFromFile(Path, Arch, CompilationDir, *ProfileReader,
|
||||
*Coverage, DataFound))
|
||||
return std::move(E);
|
||||
}
|
||||
}
|
||||
// If no readers were created, either no objects were provided or none of them
|
||||
// had coverage data. Return an error in the latter case.
|
||||
if (!DataFound && !ObjectFilenames.empty())
|
||||
|
||||
if (!DataFound)
|
||||
return createFileError(
|
||||
join(ObjectFilenames.begin(), ObjectFilenames.end(), ", "),
|
||||
make_error<CoverageMapError>(coveragemap_error::no_data_found));
|
||||
|
|
|
|||
|
|
@ -954,7 +954,8 @@ static Expected<std::vector<SectionRef>> lookupSections(ObjectFile &OF,
|
|||
|
||||
static Expected<std::unique_ptr<BinaryCoverageReader>>
|
||||
loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
|
||||
StringRef CompilationDir = "") {
|
||||
StringRef CompilationDir = "",
|
||||
std::optional<object::BuildIDRef> *BinaryID = nullptr) {
|
||||
std::unique_ptr<ObjectFile> OF;
|
||||
if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
|
||||
// If we have a universal binary, try to look up the object for the
|
||||
|
|
@ -1052,6 +1053,9 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
|
|||
FuncRecords = std::move(WritableBuffer);
|
||||
}
|
||||
|
||||
if (BinaryID)
|
||||
*BinaryID = getBuildID(OF.get());
|
||||
|
||||
return BinaryCoverageReader::createCoverageReaderFromBuffer(
|
||||
CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
|
||||
BytesInAddress, Endian, CompilationDir);
|
||||
|
|
@ -1074,7 +1078,7 @@ Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
|
|||
BinaryCoverageReader::create(
|
||||
MemoryBufferRef ObjectBuffer, StringRef Arch,
|
||||
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
|
||||
StringRef CompilationDir) {
|
||||
StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
|
||||
std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
|
||||
|
||||
if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) {
|
||||
|
|
@ -1114,7 +1118,7 @@ BinaryCoverageReader::create(
|
|||
|
||||
return BinaryCoverageReader::create(
|
||||
ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
|
||||
CompilationDir);
|
||||
CompilationDir, BinaryIDs);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1127,7 +1131,8 @@ BinaryCoverageReader::create(
|
|||
return ChildBufOrErr.takeError();
|
||||
|
||||
auto ChildReadersOrErr = BinaryCoverageReader::create(
|
||||
ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir);
|
||||
ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
|
||||
BinaryIDs);
|
||||
if (!ChildReadersOrErr)
|
||||
return ChildReadersOrErr.takeError();
|
||||
for (auto &Reader : ChildReadersOrErr.get())
|
||||
|
|
@ -1146,10 +1151,14 @@ BinaryCoverageReader::create(
|
|||
return std::move(Readers);
|
||||
}
|
||||
|
||||
auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir);
|
||||
std::optional<object::BuildIDRef> BinaryID;
|
||||
auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
|
||||
BinaryIDs ? &BinaryID : nullptr);
|
||||
if (!ReaderOrErr)
|
||||
return ReaderOrErr.takeError();
|
||||
Readers.push_back(std::move(ReaderOrErr.get()));
|
||||
if (BinaryID)
|
||||
BinaryIDs->push_back(*BinaryID);
|
||||
return std::move(Readers);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -214,8 +214,12 @@ void llvm::parallelFor(size_t Begin, size_t End,
|
|||
Fn(I);
|
||||
});
|
||||
}
|
||||
for (; Begin != End; ++Begin)
|
||||
Fn(Begin);
|
||||
if (Begin != End) {
|
||||
TG.spawn([=, &Fn] {
|
||||
for (size_t I = Begin; I != End; ++I)
|
||||
Fn(I);
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -802,8 +802,6 @@ uint64_t raw_fd_ostream::seek(uint64_t off) {
|
|||
flush();
|
||||
#ifdef _WIN32
|
||||
pos = ::_lseeki64(FD, off, SEEK_SET);
|
||||
#elif defined(HAVE_LSEEK64)
|
||||
pos = ::lseek64(FD, off, SEEK_SET);
|
||||
#else
|
||||
pos = ::lseek(FD, off, SEEK_SET);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -839,7 +839,7 @@ let Predicates = [HasSVEorSME] in {
|
|||
defm REVH_ZPmZ : sve_int_perm_rev_revh<"revh", AArch64revh_mt>;
|
||||
defm REVW_ZPmZ : sve_int_perm_rev_revw<"revw", AArch64revw_mt>;
|
||||
|
||||
defm REV_PP : sve_int_perm_reverse_p<"rev", vector_reverse>;
|
||||
defm REV_PP : sve_int_perm_reverse_p<"rev", vector_reverse, int_aarch64_sve_rev_b16, int_aarch64_sve_rev_b32, int_aarch64_sve_rev_b64>;
|
||||
defm REV_ZZ : sve_int_perm_reverse_z<"rev", vector_reverse>;
|
||||
|
||||
defm SUNPKLO_ZZ : sve_int_perm_unpk<0b00, "sunpklo", AArch64sunpklo>;
|
||||
|
|
@ -1672,12 +1672,12 @@ let Predicates = [HasSVEorSME] in {
|
|||
defm TRN1_ZZZ : sve_int_perm_bin_perm_zz<0b100, "trn1", AArch64trn1>;
|
||||
defm TRN2_ZZZ : sve_int_perm_bin_perm_zz<0b101, "trn2", AArch64trn2>;
|
||||
|
||||
defm ZIP1_PPP : sve_int_perm_bin_perm_pp<0b000, "zip1", AArch64zip1>;
|
||||
defm ZIP2_PPP : sve_int_perm_bin_perm_pp<0b001, "zip2", AArch64zip2>;
|
||||
defm UZP1_PPP : sve_int_perm_bin_perm_pp<0b010, "uzp1", AArch64uzp1>;
|
||||
defm UZP2_PPP : sve_int_perm_bin_perm_pp<0b011, "uzp2", AArch64uzp2>;
|
||||
defm TRN1_PPP : sve_int_perm_bin_perm_pp<0b100, "trn1", AArch64trn1>;
|
||||
defm TRN2_PPP : sve_int_perm_bin_perm_pp<0b101, "trn2", AArch64trn2>;
|
||||
defm ZIP1_PPP : sve_int_perm_bin_perm_pp<0b000, "zip1", AArch64zip1, int_aarch64_sve_zip1_b16, int_aarch64_sve_zip1_b32, int_aarch64_sve_zip1_b64>;
|
||||
defm ZIP2_PPP : sve_int_perm_bin_perm_pp<0b001, "zip2", AArch64zip2, int_aarch64_sve_zip2_b16, int_aarch64_sve_zip2_b32, int_aarch64_sve_zip2_b64>;
|
||||
defm UZP1_PPP : sve_int_perm_bin_perm_pp<0b010, "uzp1", AArch64uzp1, int_aarch64_sve_uzp1_b16, int_aarch64_sve_uzp1_b32, int_aarch64_sve_uzp1_b64>;
|
||||
defm UZP2_PPP : sve_int_perm_bin_perm_pp<0b011, "uzp2", AArch64uzp2, int_aarch64_sve_uzp2_b16, int_aarch64_sve_uzp2_b32, int_aarch64_sve_uzp2_b64>;
|
||||
defm TRN1_PPP : sve_int_perm_bin_perm_pp<0b100, "trn1", AArch64trn1, int_aarch64_sve_trn1_b16, int_aarch64_sve_trn1_b32, int_aarch64_sve_trn1_b64>;
|
||||
defm TRN2_PPP : sve_int_perm_bin_perm_pp<0b101, "trn2", AArch64trn2, int_aarch64_sve_trn2_b16, int_aarch64_sve_trn2_b32, int_aarch64_sve_trn2_b64>;
|
||||
|
||||
// Extract lo/hi halves of legal predicate types.
|
||||
def : Pat<(nxv1i1 (extract_subvector (nxv2i1 PPR:$Ps), (i64 0))),
|
||||
|
|
|
|||
|
|
@ -1448,11 +1448,12 @@ multiclass sve_int_perm_reverse_z<string asm, SDPatternOperator op> {
|
|||
def : SVE_1_Op_Pat<nxv8bf16, op, nxv8bf16, !cast<Instruction>(NAME # _H)>;
|
||||
}
|
||||
|
||||
class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty>
|
||||
class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty,
|
||||
SDPatternOperator op>
|
||||
: I<(outs pprty:$Pd), (ins pprty:$Pn),
|
||||
asm, "\t$Pd, $Pn",
|
||||
"",
|
||||
[]>, Sched<[]> {
|
||||
[(set nxv16i1:$Pd, (op nxv16i1:$Pn))]>, Sched<[]> {
|
||||
bits<4> Pd;
|
||||
bits<4> Pn;
|
||||
let Inst{31-24} = 0b00000101;
|
||||
|
|
@ -1463,16 +1464,18 @@ class sve_int_perm_reverse_p<bits<2> sz8_64, string asm, PPRRegOp pprty>
|
|||
let Inst{3-0} = Pd;
|
||||
}
|
||||
|
||||
multiclass sve_int_perm_reverse_p<string asm, SDPatternOperator op> {
|
||||
def _B : sve_int_perm_reverse_p<0b00, asm, PPR8>;
|
||||
def _H : sve_int_perm_reverse_p<0b01, asm, PPR16>;
|
||||
def _S : sve_int_perm_reverse_p<0b10, asm, PPR32>;
|
||||
def _D : sve_int_perm_reverse_p<0b11, asm, PPR64>;
|
||||
multiclass sve_int_perm_reverse_p<string asm, SDPatternOperator ir_op,
|
||||
SDPatternOperator op_b16,
|
||||
SDPatternOperator op_b32,
|
||||
SDPatternOperator op_b64> {
|
||||
def _B : sve_int_perm_reverse_p<0b00, asm, PPR8, ir_op>;
|
||||
def _H : sve_int_perm_reverse_p<0b01, asm, PPR16, op_b16>;
|
||||
def _S : sve_int_perm_reverse_p<0b10, asm, PPR32, op_b32>;
|
||||
def _D : sve_int_perm_reverse_p<0b11, asm, PPR64, op_b64>;
|
||||
|
||||
def : SVE_1_Op_Pat<nxv16i1, op, nxv16i1, !cast<Instruction>(NAME # _B)>;
|
||||
def : SVE_1_Op_Pat<nxv8i1, op, nxv8i1, !cast<Instruction>(NAME # _H)>;
|
||||
def : SVE_1_Op_Pat<nxv4i1, op, nxv4i1, !cast<Instruction>(NAME # _S)>;
|
||||
def : SVE_1_Op_Pat<nxv2i1, op, nxv2i1, !cast<Instruction>(NAME # _D)>;
|
||||
def : SVE_1_Op_Pat<nxv8i1, ir_op, nxv8i1, !cast<Instruction>(NAME # _H)>;
|
||||
def : SVE_1_Op_Pat<nxv4i1, ir_op, nxv4i1, !cast<Instruction>(NAME # _S)>;
|
||||
def : SVE_1_Op_Pat<nxv2i1, ir_op, nxv2i1, !cast<Instruction>(NAME # _D)>;
|
||||
}
|
||||
|
||||
class sve_int_perm_unpk<bits<2> sz16_64, bits<2> opc, string asm,
|
||||
|
|
@ -6327,10 +6330,11 @@ multiclass sve_mem_p_spill<string asm> {
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
|
||||
PPRRegOp pprty>
|
||||
PPRRegOp pprty, SDPatternOperator op>
|
||||
: I<(outs pprty:$Pd), (ins pprty:$Pn, pprty:$Pm),
|
||||
asm, "\t$Pd, $Pn, $Pm",
|
||||
"", []>, Sched<[]> {
|
||||
"",
|
||||
[(set nxv16i1:$Pd, (op nxv16i1:$Pn, nxv16i1:$Pm))]>, Sched<[]> {
|
||||
bits<4> Pd;
|
||||
bits<4> Pm;
|
||||
bits<4> Pn;
|
||||
|
|
@ -6347,16 +6351,18 @@ class sve_int_perm_bin_perm_pp<bits<3> opc, bits<2> sz8_64, string asm,
|
|||
}
|
||||
|
||||
multiclass sve_int_perm_bin_perm_pp<bits<3> opc, string asm,
|
||||
SDPatternOperator op> {
|
||||
def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8>;
|
||||
def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16>;
|
||||
def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32>;
|
||||
def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64>;
|
||||
SDPatternOperator ir_op,
|
||||
SDPatternOperator op_b16,
|
||||
SDPatternOperator op_b32,
|
||||
SDPatternOperator op_b64> {
|
||||
def _B : sve_int_perm_bin_perm_pp<opc, 0b00, asm, PPR8, ir_op>;
|
||||
def _H : sve_int_perm_bin_perm_pp<opc, 0b01, asm, PPR16, op_b16>;
|
||||
def _S : sve_int_perm_bin_perm_pp<opc, 0b10, asm, PPR32, op_b32>;
|
||||
def _D : sve_int_perm_bin_perm_pp<opc, 0b11, asm, PPR64, op_b64>;
|
||||
|
||||
def : SVE_2_Op_Pat<nxv16i1, op, nxv16i1, nxv16i1, !cast<Instruction>(NAME # _B)>;
|
||||
def : SVE_2_Op_Pat<nxv8i1, op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
|
||||
def : SVE_2_Op_Pat<nxv4i1, op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
|
||||
def : SVE_2_Op_Pat<nxv2i1, op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
|
||||
def : SVE_2_Op_Pat<nxv8i1, ir_op, nxv8i1, nxv8i1, !cast<Instruction>(NAME # _H)>;
|
||||
def : SVE_2_Op_Pat<nxv4i1, ir_op, nxv4i1, nxv4i1, !cast<Instruction>(NAME # _S)>;
|
||||
def : SVE_2_Op_Pat<nxv2i1, ir_op, nxv2i1, nxv2i1, !cast<Instruction>(NAME # _D)>;
|
||||
}
|
||||
|
||||
class sve_int_perm_punpk<bit opc, string asm>
|
||||
|
|
|
|||
|
|
@ -175,8 +175,9 @@ static bool isSignExtendedW(Register SrcReg, const MachineRegisterInfo &MRI,
|
|||
|
||||
const AttributeSet &Attrs = CalleeFn->getAttributes().getRetAttrs();
|
||||
unsigned BitWidth = IntTy->getBitWidth();
|
||||
return (BitWidth <= 32 && Attrs.hasAttribute(Attribute::SExt)) ||
|
||||
(BitWidth < 32 && Attrs.hasAttribute(Attribute::ZExt));
|
||||
if ((BitWidth <= 32 && Attrs.hasAttribute(Attribute::SExt)) ||
|
||||
(BitWidth < 32 && Attrs.hasAttribute(Attribute::ZExt)))
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!AddRegDefToWorkList(CopySrcReg))
|
||||
|
|
|
|||
|
|
@ -1154,11 +1154,11 @@ def CSR_64_CXX_TLS_Darwin_PE : CalleeSavedRegs<(add RBP)>;
|
|||
// CSRs that are handled explicitly via copies.
|
||||
def CSR_64_CXX_TLS_Darwin_ViaCopy : CalleeSavedRegs<(sub CSR_64_TLS_Darwin, RBP)>;
|
||||
|
||||
// All GPRs - except r11 and return registers.
|
||||
// All GPRs - except r11
|
||||
def CSR_64_RT_MostRegs : CalleeSavedRegs<(add CSR_64, RAX, RCX, RDX, RSI, RDI,
|
||||
R8, R9, R10)>;
|
||||
|
||||
// All registers - except r11 and return registers.
|
||||
// All registers - except r11
|
||||
def CSR_64_RT_AllRegs : CalleeSavedRegs<(add CSR_64_RT_MostRegs,
|
||||
(sequence "XMM%u", 0, 15))>;
|
||||
def CSR_64_RT_AllRegs_AVX : CalleeSavedRegs<(add CSR_64_RT_MostRegs,
|
||||
|
|
|
|||
|
|
@ -104,20 +104,6 @@ static void errorUnsupported(SelectionDAG &DAG, const SDLoc &dl,
|
|||
DiagnosticInfoUnsupported(MF.getFunction(), Msg, dl.getDebugLoc()));
|
||||
}
|
||||
|
||||
/// Returns true if a CC can dynamically exclude a register from the list of
|
||||
/// callee-saved-registers (TargetRegistryInfo::getCalleeSavedRegs()) based on
|
||||
/// params/returns.
|
||||
static bool shouldDisableCalleeSavedRegisterCC(CallingConv::ID CC) {
|
||||
switch (CC) {
|
||||
default:
|
||||
return false;
|
||||
case CallingConv::X86_RegCall:
|
||||
case CallingConv::PreserveMost:
|
||||
case CallingConv::PreserveAll:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
|
||||
const X86Subtarget &STI)
|
||||
: TargetLowering(TM), Subtarget(STI) {
|
||||
|
|
@ -3181,7 +3167,7 @@ X86TargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv,
|
|||
// In some cases we need to disable registers from the default CSR list.
|
||||
// For example, when they are used for argument passing.
|
||||
bool ShouldDisableCalleeSavedRegister =
|
||||
shouldDisableCalleeSavedRegisterCC(CallConv) ||
|
||||
CallConv == CallingConv::X86_RegCall ||
|
||||
MF.getFunction().hasFnAttribute("no_caller_saved_registers");
|
||||
|
||||
if (CallConv == CallingConv::X86_INTR && !Outs.empty())
|
||||
|
|
@ -4333,7 +4319,7 @@ SDValue X86TargetLowering::LowerFormalArguments(
|
|||
}
|
||||
}
|
||||
|
||||
if (shouldDisableCalleeSavedRegisterCC(CallConv) ||
|
||||
if (CallConv == CallingConv::X86_RegCall ||
|
||||
F.hasFnAttribute("no_caller_saved_registers")) {
|
||||
MachineRegisterInfo &MRI = MF.getRegInfo();
|
||||
for (std::pair<Register, Register> Pair : MRI.liveins())
|
||||
|
|
@ -4894,7 +4880,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
|
|||
|
||||
// In some calling conventions we need to remove the used physical registers
|
||||
// from the reg mask.
|
||||
if (shouldDisableCalleeSavedRegisterCC(CallConv) || HasNCSR) {
|
||||
if (CallConv == CallingConv::X86_RegCall || HasNCSR) {
|
||||
const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo();
|
||||
|
||||
// Allocate a new Reg Mask and copy Mask.
|
||||
|
|
@ -22000,15 +21986,25 @@ SDValue X86TargetLowering::LowerUINT_TO_FP(SDValue Op,
|
|||
// Extend everything to 80 bits to force it to be done on x87.
|
||||
// TODO: Are there any fast-math-flags to propagate here?
|
||||
if (IsStrict) {
|
||||
SDValue Add = DAG.getNode(ISD::STRICT_FADD, dl, {MVT::f80, MVT::Other},
|
||||
{Chain, Fild, Fudge});
|
||||
unsigned Opc = ISD::STRICT_FADD;
|
||||
// Windows needs the precision control changed to 80bits around this add.
|
||||
if (Subtarget.isOSWindows() && DstVT == MVT::f32)
|
||||
Opc = X86ISD::STRICT_FP80_ADD;
|
||||
|
||||
SDValue Add =
|
||||
DAG.getNode(Opc, dl, {MVT::f80, MVT::Other}, {Chain, Fild, Fudge});
|
||||
// STRICT_FP_ROUND can't handle equal types.
|
||||
if (DstVT == MVT::f80)
|
||||
return Add;
|
||||
return DAG.getNode(ISD::STRICT_FP_ROUND, dl, {DstVT, MVT::Other},
|
||||
{Add.getValue(1), Add, DAG.getIntPtrConstant(0, dl)});
|
||||
}
|
||||
SDValue Add = DAG.getNode(ISD::FADD, dl, MVT::f80, Fild, Fudge);
|
||||
unsigned Opc = ISD::FADD;
|
||||
// Windows needs the precision control changed to 80bits around this add.
|
||||
if (Subtarget.isOSWindows() && DstVT == MVT::f32)
|
||||
Opc = X86ISD::FP80_ADD;
|
||||
|
||||
SDValue Add = DAG.getNode(Opc, dl, MVT::f80, Fild, Fudge);
|
||||
return DAG.getNode(ISD::FP_ROUND, dl, DstVT, Add,
|
||||
DAG.getIntPtrConstant(0, dl, /*isTarget=*/true));
|
||||
}
|
||||
|
|
@ -34804,6 +34800,8 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
|
|||
NODE_NAME_CASE(AESDECWIDE256KL)
|
||||
NODE_NAME_CASE(CMPCCXADD)
|
||||
NODE_NAME_CASE(TESTUI)
|
||||
NODE_NAME_CASE(FP80_ADD)
|
||||
NODE_NAME_CASE(STRICT_FP80_ADD)
|
||||
}
|
||||
return nullptr;
|
||||
#undef NODE_NAME_CASE
|
||||
|
|
@ -37314,6 +37312,69 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI,
|
|||
return BB;
|
||||
}
|
||||
|
||||
case X86::FP80_ADDr:
|
||||
case X86::FP80_ADDm32: {
|
||||
// Change the floating point control register to use double extended
|
||||
// precision when performing the addition.
|
||||
int OrigCWFrameIdx =
|
||||
MF->getFrameInfo().CreateStackObject(2, Align(2), false);
|
||||
addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::FNSTCW16m)),
|
||||
OrigCWFrameIdx);
|
||||
|
||||
// Load the old value of the control word...
|
||||
Register OldCW = MF->getRegInfo().createVirtualRegister(&X86::GR32RegClass);
|
||||
addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::MOVZX32rm16), OldCW),
|
||||
OrigCWFrameIdx);
|
||||
|
||||
// OR 0b11 into bit 8 and 9. 0b11 is the encoding for double extended
|
||||
// precision.
|
||||
Register NewCW = MF->getRegInfo().createVirtualRegister(&X86::GR32RegClass);
|
||||
BuildMI(*BB, MI, DL, TII->get(X86::OR32ri), NewCW)
|
||||
.addReg(OldCW, RegState::Kill)
|
||||
.addImm(0x300);
|
||||
|
||||
// Extract to 16 bits.
|
||||
Register NewCW16 =
|
||||
MF->getRegInfo().createVirtualRegister(&X86::GR16RegClass);
|
||||
BuildMI(*BB, MI, DL, TII->get(TargetOpcode::COPY), NewCW16)
|
||||
.addReg(NewCW, RegState::Kill, X86::sub_16bit);
|
||||
|
||||
// Prepare memory for FLDCW.
|
||||
int NewCWFrameIdx =
|
||||
MF->getFrameInfo().CreateStackObject(2, Align(2), false);
|
||||
addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::MOV16mr)),
|
||||
NewCWFrameIdx)
|
||||
.addReg(NewCW16, RegState::Kill);
|
||||
|
||||
// Reload the modified control word now...
|
||||
addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::FLDCW16m)),
|
||||
NewCWFrameIdx);
|
||||
|
||||
// Do the addition.
|
||||
if (MI.getOpcode() == X86::FP80_ADDr) {
|
||||
BuildMI(*BB, MI, DL, TII->get(X86::ADD_Fp80))
|
||||
.add(MI.getOperand(0))
|
||||
.add(MI.getOperand(1))
|
||||
.add(MI.getOperand(2));
|
||||
} else {
|
||||
BuildMI(*BB, MI, DL, TII->get(X86::ADD_Fp80m32))
|
||||
.add(MI.getOperand(0))
|
||||
.add(MI.getOperand(1))
|
||||
.add(MI.getOperand(2))
|
||||
.add(MI.getOperand(3))
|
||||
.add(MI.getOperand(4))
|
||||
.add(MI.getOperand(5))
|
||||
.add(MI.getOperand(6));
|
||||
}
|
||||
|
||||
// Reload the original control word now.
|
||||
addFrameReference(BuildMI(*BB, MI, DL, TII->get(X86::FLDCW16m)),
|
||||
OrigCWFrameIdx);
|
||||
|
||||
MI.eraseFromParent(); // The pseudo instruction is gone now.
|
||||
return BB;
|
||||
}
|
||||
|
||||
case X86::FP32_TO_INT16_IN_MEM:
|
||||
case X86::FP32_TO_INT32_IN_MEM:
|
||||
case X86::FP32_TO_INT64_IN_MEM:
|
||||
|
|
|
|||
|
|
@ -740,6 +740,9 @@ namespace llvm {
|
|||
// User level interrupts - testui
|
||||
TESTUI,
|
||||
|
||||
// Perform an FP80 add after changing precision control in FPCW.
|
||||
FP80_ADD,
|
||||
|
||||
/// X86 strict FP compare instructions.
|
||||
STRICT_FCMP = ISD::FIRST_TARGET_STRICTFP_OPCODE,
|
||||
STRICT_FCMPS,
|
||||
|
|
@ -779,6 +782,9 @@ namespace llvm {
|
|||
STRICT_CVTPS2PH,
|
||||
STRICT_CVTPH2PS,
|
||||
|
||||
// Perform an FP80 add after changing precision control in FPCW.
|
||||
STRICT_FP80_ADD,
|
||||
|
||||
// WARNING: Only add nodes here if they are strict FP nodes. Non-memory and
|
||||
// non-strict FP nodes should be above FIRST_TARGET_STRICTFP_OPCODE.
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,13 @@ def SDTX86Fist : SDTypeProfile<0, 2, [SDTCisFP<0>, SDTCisPtrTy<1>]>;
|
|||
def SDTX86CwdStore : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
||||
def SDTX86CwdLoad : SDTypeProfile<0, 1, [SDTCisPtrTy<0>]>;
|
||||
|
||||
def X86fp80_add : SDNode<"X86ISD::FP80_ADD", SDTFPBinOp, [SDNPCommutative]>;
|
||||
def X86strict_fp80_add : SDNode<"X86ISD::STRICT_FP80_ADD", SDTFPBinOp,
|
||||
[SDNPHasChain,SDNPCommutative]>;
|
||||
def any_X86fp80_add : PatFrags<(ops node:$lhs, node:$rhs),
|
||||
[(X86strict_fp80_add node:$lhs, node:$rhs),
|
||||
(X86fp80_add node:$lhs, node:$rhs)]>;
|
||||
|
||||
def X86fld : SDNode<"X86ISD::FLD", SDTX86Fld,
|
||||
[SDNPHasChain, SDNPMayLoad, SDNPMemOperand]>;
|
||||
def X86fst : SDNode<"X86ISD::FST", SDTX86Fst,
|
||||
|
|
@ -141,6 +148,14 @@ let usesCustomInserter = 1, hasNoSchedulingInfo = 1, Defs = [EFLAGS] in {
|
|||
[(X86fp_to_i32mem RFP80:$src, addr:$dst)]>;
|
||||
def FP80_TO_INT64_IN_MEM : PseudoI<(outs), (ins i64mem:$dst, RFP80:$src),
|
||||
[(X86fp_to_i64mem RFP80:$src, addr:$dst)]>;
|
||||
|
||||
def FP80_ADDr : PseudoI<(outs RFP80:$dst), (ins RFP80:$src1, RFP80:$src2),
|
||||
[(set RFP80:$dst,
|
||||
(any_X86fp80_add RFP80:$src1, RFP80:$src2))]>;
|
||||
def FP80_ADDm32 : PseudoI<(outs RFP80:$dst), (ins RFP80:$src1, f32mem:$src2),
|
||||
[(set RFP80:$dst,
|
||||
(any_X86fp80_add RFP80:$src1,
|
||||
(f80 (extloadf32 addr:$src2))))]>;
|
||||
}
|
||||
|
||||
// All FP Stack operations are represented with four instructions here. The
|
||||
|
|
|
|||
|
|
@ -1043,12 +1043,14 @@ struct AAPointerInfoImpl
|
|||
const auto &NoSyncAA = A.getAAFor<AANoSync>(
|
||||
QueryingAA, IRPosition::function(Scope), DepClassTy::OPTIONAL);
|
||||
const auto *ExecDomainAA = A.lookupAAFor<AAExecutionDomain>(
|
||||
IRPosition::function(Scope), &QueryingAA, DepClassTy::OPTIONAL);
|
||||
IRPosition::function(Scope), &QueryingAA, DepClassTy::NONE);
|
||||
bool AllInSameNoSyncFn = NoSyncAA.isAssumedNoSync();
|
||||
bool InstIsExecutedByInitialThreadOnly =
|
||||
ExecDomainAA && ExecDomainAA->isExecutedByInitialThreadOnly(I);
|
||||
bool InstIsExecutedInAlignedRegion =
|
||||
ExecDomainAA && ExecDomainAA->isExecutedInAlignedRegion(A, I);
|
||||
if (InstIsExecutedInAlignedRegion || InstIsExecutedByInitialThreadOnly)
|
||||
A.recordDependence(*ExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
|
||||
|
||||
InformationCache &InfoCache = A.getInfoCache();
|
||||
bool IsThreadLocalObj =
|
||||
|
|
@ -1063,14 +1065,24 @@ struct AAPointerInfoImpl
|
|||
auto CanIgnoreThreadingForInst = [&](const Instruction &I) -> bool {
|
||||
if (IsThreadLocalObj || AllInSameNoSyncFn)
|
||||
return true;
|
||||
if (!ExecDomainAA)
|
||||
const auto *FnExecDomainAA =
|
||||
I.getFunction() == &Scope
|
||||
? ExecDomainAA
|
||||
: A.lookupAAFor<AAExecutionDomain>(
|
||||
IRPosition::function(*I.getFunction()), &QueryingAA,
|
||||
DepClassTy::NONE);
|
||||
if (!FnExecDomainAA)
|
||||
return false;
|
||||
if (InstIsExecutedInAlignedRegion ||
|
||||
ExecDomainAA->isExecutedInAlignedRegion(A, I))
|
||||
FnExecDomainAA->isExecutedInAlignedRegion(A, I)) {
|
||||
A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
|
||||
return true;
|
||||
}
|
||||
if (InstIsExecutedByInitialThreadOnly &&
|
||||
ExecDomainAA->isExecutedByInitialThreadOnly(I))
|
||||
FnExecDomainAA->isExecutedByInitialThreadOnly(I)) {
|
||||
A.recordDependence(*FnExecDomainAA, QueryingAA, DepClassTy::OPTIONAL);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
|
@ -4161,12 +4173,14 @@ struct AAIsDeadFloating : public AAIsDeadValueImpl {
|
|||
return true;
|
||||
if (auto *LI = dyn_cast<LoadInst>(V)) {
|
||||
if (llvm::all_of(LI->uses(), [&](const Use &U) {
|
||||
return InfoCache.isOnlyUsedByAssume(
|
||||
cast<Instruction>(*U.getUser())) ||
|
||||
A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
|
||||
auto &UserI = cast<Instruction>(*U.getUser());
|
||||
if (InfoCache.isOnlyUsedByAssume(UserI)) {
|
||||
if (AssumeOnlyInst)
|
||||
AssumeOnlyInst->insert(&UserI);
|
||||
return true;
|
||||
}
|
||||
return A.isAssumedDead(U, this, nullptr, UsedAssumedInformation);
|
||||
})) {
|
||||
if (AssumeOnlyInst)
|
||||
AssumeOnlyInst->insert(LI);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,9 +188,9 @@ struct AAICVTracker;
|
|||
struct OMPInformationCache : public InformationCache {
|
||||
OMPInformationCache(Module &M, AnalysisGetter &AG,
|
||||
BumpPtrAllocator &Allocator, SetVector<Function *> *CGSCC,
|
||||
KernelSet &Kernels)
|
||||
KernelSet &Kernels, bool OpenMPPostLink)
|
||||
: InformationCache(M, AG, Allocator, CGSCC), OMPBuilder(M),
|
||||
Kernels(Kernels) {
|
||||
Kernels(Kernels), OpenMPPostLink(OpenMPPostLink) {
|
||||
|
||||
OMPBuilder.initialize();
|
||||
initializeRuntimeFunctions(M);
|
||||
|
|
@ -448,6 +448,24 @@ struct OMPInformationCache : public InformationCache {
|
|||
CI->setCallingConv(Fn->getCallingConv());
|
||||
}
|
||||
|
||||
// Helper function to determine if it's legal to create a call to the runtime
|
||||
// functions.
|
||||
bool runtimeFnsAvailable(ArrayRef<RuntimeFunction> Fns) {
|
||||
// We can always emit calls if we haven't yet linked in the runtime.
|
||||
if (!OpenMPPostLink)
|
||||
return true;
|
||||
|
||||
// Once the runtime has been already been linked in we cannot emit calls to
|
||||
// any undefined functions.
|
||||
for (RuntimeFunction Fn : Fns) {
|
||||
RuntimeFunctionInfo &RFI = RFIs[Fn];
|
||||
|
||||
if (RFI.Declaration && RFI.Declaration->isDeclaration())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Helper to initialize all runtime function information for those defined
|
||||
/// in OpenMPKinds.def.
|
||||
void initializeRuntimeFunctions(Module &M) {
|
||||
|
|
@ -523,6 +541,9 @@ struct OMPInformationCache : public InformationCache {
|
|||
|
||||
/// Collection of known OpenMP runtime functions..
|
||||
DenseSet<const Function *> RTLFunctions;
|
||||
|
||||
/// Indicates if we have already linked in the OpenMP device library.
|
||||
bool OpenMPPostLink = false;
|
||||
};
|
||||
|
||||
template <typename Ty, bool InsertInvalidates = true>
|
||||
|
|
@ -1412,7 +1433,10 @@ private:
|
|||
Changed |= WasSplit;
|
||||
return WasSplit;
|
||||
};
|
||||
RFI.foreachUse(SCC, SplitMemTransfers);
|
||||
if (OMPInfoCache.runtimeFnsAvailable(
|
||||
{OMPRTL___tgt_target_data_begin_mapper_issue,
|
||||
OMPRTL___tgt_target_data_begin_mapper_wait}))
|
||||
RFI.foreachUse(SCC, SplitMemTransfers);
|
||||
|
||||
return Changed;
|
||||
}
|
||||
|
|
@ -2656,7 +2680,9 @@ struct AAExecutionDomainFunction : public AAExecutionDomain {
|
|||
|
||||
bool isExecutedInAlignedRegion(Attributor &A,
|
||||
const Instruction &I) const override {
|
||||
if (!isValidState() || isa<CallBase>(I))
|
||||
assert(I.getFunction() == getAnchorScope() &&
|
||||
"Instruction is out of scope!");
|
||||
if (!isValidState())
|
||||
return false;
|
||||
|
||||
const Instruction *CurI;
|
||||
|
|
@ -2667,14 +2693,18 @@ struct AAExecutionDomainFunction : public AAExecutionDomain {
|
|||
auto *CB = dyn_cast<CallBase>(CurI);
|
||||
if (!CB)
|
||||
continue;
|
||||
if (CB != &I && AlignedBarriers.contains(const_cast<CallBase *>(CB))) {
|
||||
break;
|
||||
}
|
||||
const auto &It = CEDMap.find(CB);
|
||||
if (It == CEDMap.end())
|
||||
continue;
|
||||
if (!It->getSecond().IsReachedFromAlignedBarrierOnly)
|
||||
if (!It->getSecond().IsReachingAlignedBarrierOnly)
|
||||
return false;
|
||||
break;
|
||||
} while ((CurI = CurI->getNextNonDebugInstruction()));
|
||||
|
||||
if (!CurI && !BEDMap.lookup(I.getParent()).IsReachedFromAlignedBarrierOnly)
|
||||
if (!CurI && !BEDMap.lookup(I.getParent()).IsReachingAlignedBarrierOnly)
|
||||
return false;
|
||||
|
||||
// Check backward until a call or the block beginning is reached.
|
||||
|
|
@ -2683,12 +2713,16 @@ struct AAExecutionDomainFunction : public AAExecutionDomain {
|
|||
auto *CB = dyn_cast<CallBase>(CurI);
|
||||
if (!CB)
|
||||
continue;
|
||||
if (CB != &I && AlignedBarriers.contains(const_cast<CallBase *>(CB))) {
|
||||
break;
|
||||
}
|
||||
const auto &It = CEDMap.find(CB);
|
||||
if (It == CEDMap.end())
|
||||
continue;
|
||||
if (!AA::isNoSyncInst(A, *CB, *this)) {
|
||||
if (It->getSecond().IsReachedFromAlignedBarrierOnly)
|
||||
if (It->getSecond().IsReachedFromAlignedBarrierOnly) {
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -2984,7 +3018,8 @@ ChangeStatus AAExecutionDomainFunction::updateImpl(Attributor &A) {
|
|||
if (EDAA.getState().isValidState()) {
|
||||
const auto &CalleeED = EDAA.getFunctionExecutionDomain();
|
||||
ED.IsReachedFromAlignedBarrierOnly =
|
||||
CalleeED.IsReachedFromAlignedBarrierOnly;
|
||||
CallED.IsReachedFromAlignedBarrierOnly =
|
||||
CalleeED.IsReachedFromAlignedBarrierOnly;
|
||||
AlignedBarrierLastInBlock = ED.IsReachedFromAlignedBarrierOnly;
|
||||
if (IsNoSync || !CalleeED.IsReachedFromAlignedBarrierOnly)
|
||||
ED.EncounteredNonLocalSideEffect |=
|
||||
|
|
@ -2999,8 +3034,9 @@ ChangeStatus AAExecutionDomainFunction::updateImpl(Attributor &A) {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
ED.IsReachedFromAlignedBarrierOnly =
|
||||
IsNoSync && ED.IsReachedFromAlignedBarrierOnly;
|
||||
if (!IsNoSync)
|
||||
ED.IsReachedFromAlignedBarrierOnly =
|
||||
CallED.IsReachedFromAlignedBarrierOnly = false;
|
||||
AlignedBarrierLastInBlock &= ED.IsReachedFromAlignedBarrierOnly;
|
||||
ED.EncounteredNonLocalSideEffect |= !CB->doesNotAccessMemory();
|
||||
if (!IsNoSync)
|
||||
|
|
@ -3914,6 +3950,12 @@ struct AAKernelInfoFunction : AAKernelInfo {
|
|||
bool changeToSPMDMode(Attributor &A, ChangeStatus &Changed) {
|
||||
auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache());
|
||||
|
||||
// We cannot change to SPMD mode if the runtime functions aren't availible.
|
||||
if (!OMPInfoCache.runtimeFnsAvailable(
|
||||
{OMPRTL___kmpc_get_hardware_thread_id_in_block,
|
||||
OMPRTL___kmpc_barrier_simple_spmd}))
|
||||
return false;
|
||||
|
||||
if (!SPMDCompatibilityTracker.isAssumed()) {
|
||||
for (Instruction *NonCompatibleI : SPMDCompatibilityTracker) {
|
||||
if (!NonCompatibleI)
|
||||
|
|
@ -4021,6 +4063,13 @@ struct AAKernelInfoFunction : AAKernelInfo {
|
|||
if (!ReachedKnownParallelRegions.isValidState())
|
||||
return ChangeStatus::UNCHANGED;
|
||||
|
||||
auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache());
|
||||
if (!OMPInfoCache.runtimeFnsAvailable(
|
||||
{OMPRTL___kmpc_get_hardware_num_threads_in_block,
|
||||
OMPRTL___kmpc_get_warp_size, OMPRTL___kmpc_barrier_simple_generic,
|
||||
OMPRTL___kmpc_kernel_parallel, OMPRTL___kmpc_kernel_end_parallel}))
|
||||
return ChangeStatus::UNCHANGED;
|
||||
|
||||
const int InitModeArgNo = 1;
|
||||
const int InitUseStateMachineArgNo = 2;
|
||||
|
||||
|
|
@ -4167,7 +4216,6 @@ struct AAKernelInfoFunction : AAKernelInfo {
|
|||
BranchInst::Create(IsWorkerCheckBB, UserCodeEntryBB, IsWorker, InitBB);
|
||||
|
||||
Module &M = *Kernel->getParent();
|
||||
auto &OMPInfoCache = static_cast<OMPInformationCache &>(A.getInfoCache());
|
||||
FunctionCallee BlockHwSizeFn =
|
||||
OMPInfoCache.OMPBuilder.getOrCreateRuntimeFunction(
|
||||
M, OMPRTL___kmpc_get_hardware_num_threads_in_block);
|
||||
|
|
@ -5343,7 +5391,10 @@ PreservedAnalyses OpenMPOptPass::run(Module &M, ModuleAnalysisManager &AM) {
|
|||
BumpPtrAllocator Allocator;
|
||||
CallGraphUpdater CGUpdater;
|
||||
|
||||
OMPInformationCache InfoCache(M, AG, Allocator, /*CGSCC*/ nullptr, Kernels);
|
||||
bool PostLink = LTOPhase == ThinOrFullLTOPhase::FullLTOPostLink ||
|
||||
LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink;
|
||||
OMPInformationCache InfoCache(M, AG, Allocator, /*CGSCC*/ nullptr, Kernels,
|
||||
PostLink);
|
||||
|
||||
unsigned MaxFixpointIterations =
|
||||
(isOpenMPDevice(M)) ? SetFixpointIterations : 32;
|
||||
|
|
@ -5417,9 +5468,11 @@ PreservedAnalyses OpenMPOptCGSCCPass::run(LazyCallGraph::SCC &C,
|
|||
CallGraphUpdater CGUpdater;
|
||||
CGUpdater.initialize(CG, C, AM, UR);
|
||||
|
||||
bool PostLink = LTOPhase == ThinOrFullLTOPhase::FullLTOPostLink ||
|
||||
LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink;
|
||||
SetVector<Function *> Functions(SCC.begin(), SCC.end());
|
||||
OMPInformationCache InfoCache(*(Functions.back()->getParent()), AG, Allocator,
|
||||
/*CGSCC*/ &Functions, Kernels);
|
||||
/*CGSCC*/ &Functions, Kernels, PostLink);
|
||||
|
||||
unsigned MaxFixpointIterations =
|
||||
(isOpenMPDevice(M)) ? SetFixpointIterations : 32;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,10 @@
|
|||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Debuginfod/BuildIDFetcher.h"
|
||||
#include "llvm/Debuginfod/Debuginfod.h"
|
||||
#include "llvm/Debuginfod/HTTPClient.h"
|
||||
#include "llvm/Object/BuildID.h"
|
||||
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
|
||||
#include "llvm/ProfileData/InstrProfReader.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
|
|
@ -179,6 +183,8 @@ private:
|
|||
|
||||
/// Allowlist from -name-allowlist to be used for filtering.
|
||||
std::unique_ptr<SpecialCaseList> NameAllowlist;
|
||||
|
||||
std::unique_ptr<object::BuildIDFetcher> BIDFetcher;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -435,7 +441,7 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
|
|||
ObjectFilename);
|
||||
auto CoverageOrErr =
|
||||
CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArches,
|
||||
ViewOpts.CompilationDirectory);
|
||||
ViewOpts.CompilationDirectory, BIDFetcher.get());
|
||||
if (Error E = CoverageOrErr.takeError()) {
|
||||
error("Failed to load coverage: " + toString(std::move(E)));
|
||||
return nullptr;
|
||||
|
|
@ -647,6 +653,14 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
|
|||
cl::opt<bool> DebugDump("dump", cl::Optional,
|
||||
cl::desc("Show internal debug dump"));
|
||||
|
||||
cl::list<std::string> DebugFileDirectory(
|
||||
"debug-file-directory",
|
||||
cl::desc("Directories to search for object files by build ID"));
|
||||
cl::opt<bool> Debuginfod(
|
||||
"debuginfod", cl::ZeroOrMore,
|
||||
cl::desc("Use debuginfod to look up object files from profile"),
|
||||
cl::init(canUseDebuginfod()));
|
||||
|
||||
cl::opt<CoverageViewOptions::OutputFormat> Format(
|
||||
"format", cl::desc("Output format for line-based coverage reports"),
|
||||
cl::values(clEnumValN(CoverageViewOptions::OutputFormat::Text, "text",
|
||||
|
|
@ -749,12 +763,18 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
|
|||
auto commandLineParser = [&, this](int argc, const char **argv) -> int {
|
||||
cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
|
||||
ViewOpts.Debug = DebugDump;
|
||||
if (Debuginfod) {
|
||||
HTTPClient::initialize();
|
||||
BIDFetcher = std::make_unique<DebuginfodFetcher>(DebugFileDirectory);
|
||||
} else {
|
||||
BIDFetcher = std::make_unique<object::BuildIDFetcher>(DebugFileDirectory);
|
||||
}
|
||||
|
||||
if (!CovFilename.empty())
|
||||
ObjectFilenames.emplace_back(CovFilename);
|
||||
for (const std::string &Filename : CovFilenames)
|
||||
ObjectFilenames.emplace_back(Filename);
|
||||
if (ObjectFilenames.empty()) {
|
||||
if (ObjectFilenames.empty() && !Debuginfod && DebugFileDirectory.empty()) {
|
||||
errs() << "No filenames specified!\n";
|
||||
::exit(1);
|
||||
}
|
||||
|
|
@ -867,10 +887,8 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
|
|||
}
|
||||
CoverageArches.emplace_back(Arch);
|
||||
}
|
||||
if (CoverageArches.size() == 1)
|
||||
CoverageArches.insert(CoverageArches.end(), ObjectFilenames.size() - 1,
|
||||
CoverageArches[0]);
|
||||
if (CoverageArches.size() != ObjectFilenames.size()) {
|
||||
if (CoverageArches.size() != 1 &&
|
||||
CoverageArches.size() != ObjectFilenames.size()) {
|
||||
error("Number of architectures doesn't match the number of objects");
|
||||
return 1;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3198,9 +3198,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
// Initialize debuginfod.
|
||||
const bool ShouldUseDebuginfodByDefault =
|
||||
InputArgs.hasArg(OBJDUMP_build_id) ||
|
||||
(HTTPClient::isAvailable() &&
|
||||
!ExitOnErr(getDefaultDebuginfodUrls()).empty());
|
||||
InputArgs.hasArg(OBJDUMP_build_id) || canUseDebuginfod();
|
||||
std::vector<std::string> DebugFileDirectories =
|
||||
InputArgs.getAllArgValues(OBJDUMP_debug_file_directory);
|
||||
if (InputArgs.hasFlag(OBJDUMP_debuginfod, OBJDUMP_no_debuginfod,
|
||||
|
|
|
|||
|
|
@ -443,13 +443,7 @@ int main(int argc, char **argv) {
|
|||
|
||||
LLVMSymbolizer Symbolizer(Opts);
|
||||
|
||||
// A debuginfod lookup could succeed if a HTTP client is available and at
|
||||
// least one backing URL is configured.
|
||||
bool ShouldUseDebuginfodByDefault =
|
||||
HTTPClient::isAvailable() &&
|
||||
!ExitOnErr(getDefaultDebuginfodUrls()).empty();
|
||||
if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod,
|
||||
ShouldUseDebuginfodByDefault))
|
||||
if (Args.hasFlag(OPT_debuginfod, OPT_no_debuginfod, canUseDebuginfod()))
|
||||
enableDebuginfod(Symbolizer, Args);
|
||||
|
||||
if (Args.hasArg(OPT_filter_markup)) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue