[clang] [llvm] [X86][AMX] Add AMX FP8 new APIs (PR #115829)
https://github.com/fzou1 updated https://github.com/llvm/llvm-project/pull/115829 >From 9fd6e9e598423b6cc58a25fe70cc12a846483be5 Mon Sep 17 00:00:00 2001 From: Feng Zou Date: Thu, 7 Nov 2024 11:56:17 +0800 Subject: [PATCH 1/2] [X86][AMX] Add AMX FP8 new APIs This is a follow-up to #113850. Ref.: https://cdrdv2.intel.com/v1/dl/getContent/671368 --- clang/include/clang/Basic/BuiltinsX86_64.def | 4 + clang/lib/Headers/amxfp8intrin.h | 175 --- clang/test/CodeGen/X86/amx_fp8_api.c | 36 llvm/include/llvm/IR/IntrinsicsX86.td| 25 +++ llvm/lib/Target/X86/X86ExpandPseudo.cpp | 18 +- llvm/lib/Target/X86/X86InstrAMX.td | 31 llvm/lib/Target/X86/X86RegisterInfo.cpp | 6 +- 7 files changed, 272 insertions(+), 23 deletions(-) create mode 100644 clang/test/CodeGen/X86/amx_fp8_api.c diff --git a/clang/include/clang/Basic/BuiltinsX86_64.def b/clang/include/clang/Basic/BuiltinsX86_64.def index 25c10d39df32e2..8653fc217bdddb 100644 --- a/clang/include/clang/Basic/BuiltinsX86_64.def +++ b/clang/include/clang/Basic/BuiltinsX86_64.def @@ -141,6 +141,10 @@ TARGET_BUILTIN(__builtin_ia32_tcvtrowps2phl_internal, "V32xUsUsV256iUi", "n", "a TARGET_BUILTIN(__builtin_ia32_tilemovrow_internal, "V16iUsUsV256iUi", "n", "amx-avx512,avx10.2-512") TARGET_BUILTIN(__builtin_ia32_tmmultf32ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-tf32") TARGET_BUILTIN(__builtin_ia32_ttmmultf32ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-tf32,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_tdpbf8ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-fp8") +TARGET_BUILTIN(__builtin_ia32_tdpbhf8ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-fp8") +TARGET_BUILTIN(__builtin_ia32_tdphbf8ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-fp8") +TARGET_BUILTIN(__builtin_ia32_tdphf8ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-fp8") // AMX TARGET_BUILTIN(__builtin_ia32_tile_loadconfig, "vvC*", "n", "amx-tile") diff --git a/clang/lib/Headers/amxfp8intrin.h b/clang/lib/Headers/amxfp8intrin.h index 0f5ddc87e5a752..4ada936a5d40af 100644 --- a/clang/lib/Headers/amxfp8intrin.h +++ b/clang/lib/Headers/amxfp8intrin.h @@ -15,81 +15,214 @@ #define __AMXFP8INTRIN_H #ifdef __x86_64__ -/// Peform the dot product of a BF8 value \a a by a BF8 value \a b accumulating -/// into a Single Precision (FP32) source/dest \a dst. +#define __DEFAULT_FN_ATTRS_FP8 \ + __attribute__((__always_inline__, __nodebug__, __target__("amx-fp8"))) + +static __inline__ _tile1024i __DEFAULT_FN_ATTRS_FP8 +_tile_dpbf8ps_internal(unsigned short m, unsigned short n, unsigned short k, + _tile1024i dst, _tile1024i src1, _tile1024i src2) { + return __builtin_ia32_tdpbf8ps_internal(m, n, k, dst, src1, src2); +} + +/// Perform the dot product of a BF8 value \a src1 by a BF8 value \a src2 +/// accumulating into a Single Precision (FP32) source/dest \a dst. /// /// \headerfile /// /// \code -/// void _tile_dpbf8ps (__tile dst, __tile a, __tile b) +/// void __tile_dpbf8ps (__tile1024i *dst, __tile1024i src1, __tile1024i src2) +/// \endcode +/// +/// \code{.operation} +/// FOR m := 0 TO dst.rows - 1 +/// temp1[(dst.colsb / 4 - 1) : 0] = 0 +/// FOR k := 0 TO src1.colsb / 4 - 1 +/// FOR n := 0 TO dst.colsb / 4 - 1 +/// temp1[n] += +/// INT64(src1.row[m].float8[4*k+0]) * INT64(src2.row[k].float8[4*n+0]) +/// + INT64(src1.row[m].float8[4*k+1]) * INT64(src2.row[k].float8[4*n+1]) +/// + INT64(src1.row[m].float8[4*k+2]) * INT64(src2.row[k].float8[4*n+2]) +/// + INT64(src1.row[m].float8[4*k+3]) * INT64(src2.row[k].float8[4*n+3]) +/// ENDFOR +/// ENDFOR +/// FOR n := 0 TO dst.colsb / 4 - 1 +/// tmp.row[m].fp32[n] = dst.row[m].fp32[n] + FP32(temp1[n]) +/// ENDFOR +/// write_row_and_zero(dst, m, tmp, dst.colsb) +/// zero_upper_rows(dst, dst.rows) +/// zero_tileconfig_start() /// \endcode /// /// This intrinsic corresponds to the \c TDPBF8PS instruction. /// /// \param dst ///The destination tile. Max size is 1024 Bytes. -/// \param a +/// \param src1 ///The 1st source tile. Max size is 1024 Bytes. -/// \param b +/// \param src2 ///The 2nd source tile. Max size is 1024 Bytes. -#define _tile_dpbf8ps(dst, a, b) __builtin_ia32_tdpbf8ps((dst), (a), (b)) +__DEFAULT_FN_ATTRS_FP8 static void +__tile_dpbf8ps(__tile1024i *dst, __tile1024i src1, __tile1024i src2) { + dst->tile = _tile_dpbf8ps_internal(src1.row, src2.col, src1.col, dst->tile, + src1.tile, src2.tile); +} + +static __inline__ _tile1024i __DEFAULT_FN_ATTRS_FP8 +_tile_dpbhf8ps_internal(unsigned short m, unsigned short n, unsigned short k, +_tile1024i dst, _tile1024i src1, _tile1024i src2) { + return __builtin_ia32_tdpbhf8ps_internal(m, n, k, dst, src1, src2); +} -/// Perform the dot product of a BF8 value \a a by an
[clang] [llvm] [X86][AMX] Add AMX FP8 new APIs (PR #115829)
@@ -15,81 +15,214 @@ #define __AMXFP8INTRIN_H #ifdef __x86_64__ -/// Peform the dot product of a BF8 value \a a by a BF8 value \a b accumulating -/// into a Single Precision (FP32) source/dest \a dst. +#define __DEFAULT_FN_ATTRS_FP8 \ + __attribute__((__always_inline__, __nodebug__, __target__("amx-fp8"))) + +static __inline__ _tile1024i __DEFAULT_FN_ATTRS_FP8 +_tile_dpbf8ps_internal(unsigned short m, unsigned short n, unsigned short k, + _tile1024i dst, _tile1024i src1, _tile1024i src2) { + return __builtin_ia32_tdpbf8ps_internal(m, n, k, dst, src1, src2); +} + +/// Perform the dot product of a BF8 value \a src1 by a BF8 value \a src2 +/// accumulating into a Single Precision (FP32) source/dest \a dst. /// /// \headerfile /// /// \code -/// void _tile_dpbf8ps (__tile dst, __tile a, __tile b) +/// void __tile_dpbf8ps (__tile1024i *dst, __tile1024i src1, __tile1024i src2) +/// \endcode +/// +/// \code{.operation} +/// FOR m := 0 TO dst.rows - 1 +/// temp1[(dst.colsb / 4 - 1) : 0] = 0 +/// FOR k := 0 TO src1.colsb / 4 - 1 +/// FOR n := 0 TO dst.colsb / 4 - 1 +/// temp1[n] += +/// INT64(src1.row[m].float8[4*k+0]) * INT64(src2.row[k].float8[4*n+0]) +/// + INT64(src1.row[m].float8[4*k+1]) * INT64(src2.row[k].float8[4*n+1]) +/// + INT64(src1.row[m].float8[4*k+2]) * INT64(src2.row[k].float8[4*n+2]) +/// + INT64(src1.row[m].float8[4*k+3]) * INT64(src2.row[k].float8[4*n+3]) +/// ENDFOR +/// ENDFOR +/// FOR n := 0 TO dst.colsb / 4 - 1 +/// tmp.row[m].fp32[n] = dst.row[m].fp32[n] + FP32(temp1[n]) +/// ENDFOR +/// write_row_and_zero(dst, m, tmp, dst.colsb) +/// zero_upper_rows(dst, dst.rows) +/// zero_tileconfig_start() /// \endcode /// /// This intrinsic corresponds to the \c TDPBF8PS instruction. /// /// \param dst ///The destination tile. Max size is 1024 Bytes. -/// \param a +/// \param src1 ///The 1st source tile. Max size is 1024 Bytes. -/// \param b +/// \param src2 ///The 2nd source tile. Max size is 1024 Bytes. -#define _tile_dpbf8ps(dst, a, b) __builtin_ia32_tdpbf8ps((dst), (a), (b)) +__DEFAULT_FN_ATTRS_FP8 static void +__tile_dpbf8ps(__tile1024i *dst, __tile1024i src1, __tile1024i src2) { + dst->tile = _tile_dpbf8ps_internal(src1.row, src2.col, src1.col, dst->tile, + src1.tile, src2.tile); +} + +static __inline__ _tile1024i __DEFAULT_FN_ATTRS_FP8 +_tile_dpbhf8ps_internal(unsigned short m, unsigned short n, unsigned short k, +_tile1024i dst, _tile1024i src1, _tile1024i src2) { + return __builtin_ia32_tdpbhf8ps_internal(m, n, k, dst, src1, src2); +} -/// Perform the dot product of a BF8 value \a a by an HF8 value \a b +/// Perform the dot product of a BF8 value \a src1 by an HF8 value \a src2 /// accumulating into a Single Precision (FP32) source/dest \a dst. /// /// \headerfile /// /// \code -/// void _tile_dpbhf8ps (__tile dst, __tile a, __tile b) +/// void __tile_dpbhf8ps (__tile1024i dst, __tile1024i src1, __tile1024i src2) +/// \endcode +/// +/// \code{.operation} +/// FOR m := 0 TO dst.rows - 1 +/// temp1[(dst.colsb / 4 - 1) : 0] = 0 +/// FOR k := 0 TO src1.colsb / 4 - 1 +/// FOR n := 0 TO dst.colsb / 4 - 1 +/// temp1[n] += +/// INT64(src1.row[m].float8[4*k+0]) * INT64(src2.row[k].float8[4*n+0]) +/// + INT64(src1.row[m].float8[4*k+1]) * INT64(src2.row[k].float8[4*n+1]) +/// + INT64(src1.row[m].float8[4*k+2]) * INT64(src2.row[k].float8[4*n+2]) +/// + INT64(src1.row[m].float8[4*k+3]) * INT64(src2.row[k].float8[4*n+3]) +/// ENDFOR +/// ENDFOR +/// FOR n := 0 TO dst.colsb / 4 - 1 +/// tmp.row[m].fp32[n] = dst.row[m].fp32[n] + FP32(temp1[n]) +/// ENDFOR +/// write_row_and_zero(dst, m, tmp, dst.colsb) +/// zero_upper_rows(dst, dst.rows) +/// zero_tileconfig_start() /// \endcode /// /// This intrinsic corresponds to the \c TDPBHF8PS instruction. /// /// \param dst ///The destination tile. Max size is 1024 Bytes. -/// \param a +/// \param src1 ///The 1st source tile. Max size is 1024 Bytes. -/// \param b +/// \param src2 ///The 2nd source tile. Max size is 1024 Bytes. -#define _tile_dpbhf8ps(dst, a, b) __builtin_ia32_tdpbhf8ps((dst), (a), (b)) +__DEFAULT_FN_ATTRS_FP8 static void +__tile_dpbhf8ps(__tile1024i *dst, __tile1024i src1, __tile1024i src2) { + dst->tile = _tile_dpbhf8ps_internal(src1.row, src2.col, src1.col, dst->tile, + src1.tile, src2.tile); +} -/// Perform the dot product of an HF8 value \a a by a BF8 value \a b +static __inline__ _tile1024i __DEFAULT_FN_ATTRS_FP8 +_tile_dphbf8ps_internal(unsigned short m, unsigned short n, unsigned short k, +_tile1024i dst, _tile1024i src1, _tile1024i src2) { + return __builtin_ia32_tdphbf8ps_internal(m, n, k, dst, src1, src2); +} + +/// Perform the dot product of an HF8
[clang] [llvm] Reland [clang][AArch64] Add getHostCPUFeatures to query for enabled f… (PR #115467)
davemgreen wrote: I'm not sure I understood the original error properly but if we can come up with a fix like this it sounds sensible to me. Is the test still failing in the pre-commit tests? You might need something stronger - like only running the test on aarch64 host machines. There are some other tests for -mcpu=native that have comments that it is difficult to test. https://github.com/llvm/llvm-project/pull/115467 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [LoongArch] add la v1.1 features for sys::getHostCPUFeatures (PR #115832)
https://github.com/tangaac created https://github.com/llvm/llvm-project/pull/115832 None >From 10d2d8e0be2faeedcdfe67d97f3e2f89a3770a71 Mon Sep 17 00:00:00 2001 From: tangaac Date: Fri, 8 Nov 2024 17:04:19 +0800 Subject: [PATCH] add la v1.1 features for getHostCPUFeatures --- clang/lib/Driver/ToolChains/Arch/LoongArch.cpp | 7 ++- llvm/lib/TargetParser/Host.cpp | 9 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index e69a5562137ccd..2dc7550176f5f0 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -135,8 +135,13 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, Features.push_back("+lsx"); std::string ArchName; - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { ArchName = A->getValue(); +if (ArchName == "native") + for (auto &F : llvm::sys::getHostCPUFeatures()) +Features.push_back( +Args.MakeArgString((F.second ? "+" : "-") + F.first())); + } ArchName = postProcessTargetCPUString(ArchName, Triple); llvm::LoongArch::getArchFeatures(ArchName, Features); diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 58ba2553633221..d0f3bbc26716e7 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2006,6 +2006,15 @@ const StringMap sys::getHostCPUFeatures() { Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ + Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE + Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH + + // TODO: Need to complete. + // Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32 + // Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS + // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL + // Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ + // Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA return Features; } #elif defined(__linux__) && defined(__riscv) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [LoongArch] add la v1.1 features for sys::getHostCPUFeatures (PR #115832)
llvmbot wrote: @llvm/pr-subscribers-clang-driver Author: None (tangaac) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/115832.diff 2 Files Affected: - (modified) clang/lib/Driver/ToolChains/Arch/LoongArch.cpp (+6-1) - (modified) llvm/lib/TargetParser/Host.cpp (+9) ``diff diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index e69a5562137ccd..2dc7550176f5f0 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -135,8 +135,13 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, Features.push_back("+lsx"); std::string ArchName; - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { ArchName = A->getValue(); +if (ArchName == "native") + for (auto &F : llvm::sys::getHostCPUFeatures()) +Features.push_back( +Args.MakeArgString((F.second ? "+" : "-") + F.first())); + } ArchName = postProcessTargetCPUString(ArchName, Triple); llvm::LoongArch::getArchFeatures(ArchName, Features); diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 58ba2553633221..d0f3bbc26716e7 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2006,6 +2006,15 @@ const StringMap sys::getHostCPUFeatures() { Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ + Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE + Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH + + // TODO: Need to complete. + // Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32 + // Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS + // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL + // Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ + // Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA return Features; } #elif defined(__linux__) && defined(__riscv) `` https://github.com/llvm/llvm-project/pull/115832 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[clang] Introduce [[clang::lifetime_capture_by(X)]] (PR #115823)
@@ -3867,6 +3868,112 @@ static void handleCallbackAttr(Sema &S, Decl *D, const ParsedAttr &AL) { S.Context, AL, EncodingIndices.data(), EncodingIndices.size())); } +LifetimeCaptureByAttr *Sema::ParseLifetimeCaptureByAttr(const ParsedAttr &AL, +StringRef ParamName) { + // Atleast one capture by is required. + if (AL.getNumArgs() == 0) { +Diag(AL.getLoc(), diag::err_capture_by_attribute_no_entity) +<< AL.getRange(); +return nullptr; + } + SmallVector ParamIdents; + SmallVector ParamLocs; + for (unsigned I = 0; I < AL.getNumArgs(); ++I) { +if (AL.isArgExpr(I)) { + Expr *E = AL.getArgAsExpr(I); + Diag(E->getExprLoc(), diag::err_capture_by_attribute_argument_unknown) + << E << E->getExprLoc(); + continue; +} +assert(AL.isArgIdent(I)); +IdentifierLoc *IdLoc = AL.getArgAsIdent(I); +if (IdLoc->Ident->getName() == ParamName) { + Diag(IdLoc->Loc, diag::err_capture_by_references_itself) << IdLoc->Loc; + continue; +} +ParamIdents.push_back(IdLoc->Ident); +ParamLocs.push_back(IdLoc->Loc); + } + SmallVector FakeParamIndices(ParamIdents.size(), +LifetimeCaptureByAttr::INVALID); + LifetimeCaptureByAttr *CapturedBy = ::new (Context) LifetimeCaptureByAttr( + Context, AL, FakeParamIndices.data(), FakeParamIndices.size()); + CapturedBy->setArgs(std::move(ParamIdents), std::move(ParamLocs)); + return CapturedBy; +} + +static void handleLifetimeCaptureByAttr(Sema &S, Decl *D, +const ParsedAttr &AL) { + // Do not allow multiple attributes. + if (D->hasAttr()) { +S.Diag(AL.getLoc(), diag::err_capture_by_attribute_multiple) +<< AL.getRange(); +return; + } + auto *PVD = dyn_cast(D); + assert(PVD); + auto *CaptureByAttr = S.ParseLifetimeCaptureByAttr(AL, PVD->getName()); + if (CaptureByAttr) +D->addAttr(CaptureByAttr); +} + +void Sema::LazyProcessLifetimeCaptureByParams(FunctionDecl *FD) { + bool HasImplicitThisParam = isInstanceMethod(FD); + SmallVector Attrs; + for (ParmVarDecl *PVD : FD->parameters()) +if (auto *A = PVD->getAttr()) + Attrs.push_back(A); + if (HasImplicitThisParam) { +TypeSourceInfo *TSI = FD->getTypeSourceInfo(); +if (!TSI) + return; +AttributedTypeLoc ATL; +for (TypeLoc TL = TSI->getTypeLoc(); + (ATL = TL.getAsAdjusted()); + TL = ATL.getModifiedLoc()) { + if (auto *A = ATL.getAttrAs()) +Attrs.push_back(const_cast(A)); +} + } + if (Attrs.empty()) +return; + llvm::StringMap NameIdxMapping; + NameIdxMapping["global"] = LifetimeCaptureByAttr::GLOBAL; + NameIdxMapping["unknown"] = LifetimeCaptureByAttr::UNKNOWN; usx95 wrote: Done. https://github.com/llvm/llvm-project/pull/115823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Add 'IgnoreTemplateParmDepth' to structural equivalence cache (PR #115518)
balazske wrote: It is a realistic requirement that new similar parameters are added, I had already an (experimental) fix where this is needed. Still I like better the solution with separate caches because efficiency reasons (`IgnoreTemplateParmDepth = true` is rarely used, not at all for C code). For new parameters we have the similar set of choices (add more new caches or extend cache key or not use the cache at all). https://github.com/llvm/llvm-project/pull/115518 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[clang] Introduce [[clang::lifetime_capture_by(X)]] (PR #115823)
usx95 wrote: Looks like I have not fully resolved the memory leak and only avoided it by having larger portion of vector on stack. The leak happens for the allocation: ``` SmallVector ParamIdents; ParamIdents.push_back(IdLoc->Ident); // <- allocated here. ``` Suprisingly commenting out the `move` makes things go back to normal. ` // CapturedBy->setArgs(std::move(ParamIdents), std::move(ParamLocs));` https://github.com/llvm/llvm-project/pull/115823 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [LoongArch] add la v1.1 features for sys::getHostCPUFeatures (PR #115832)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 93589057830b2c3c35500ee8cac25c717a1e98f9 10d2d8e0be2faeedcdfe67d97f3e2f89a3770a71 --extensions cpp -- clang/lib/Driver/ToolChains/Arch/LoongArch.cpp llvm/lib/TargetParser/Host.cpp `` View the diff from clang-format here. ``diff diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index d0f3bbc267..0250aac9a7 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2006,8 +2006,8 @@ const StringMap sys::getHostCPUFeatures() { Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ - Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE - Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH + Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE + Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH // TODO: Need to complete. // Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32 `` https://github.com/llvm/llvm-project/pull/115832 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [LoongArch] add la v1.1 features for sys::getHostCPUFeatures (PR #115832)
https://github.com/tangaac updated https://github.com/llvm/llvm-project/pull/115832 >From 3d204daae016cdb43e2e01ecdb39dc0fc299595a Mon Sep 17 00:00:00 2001 From: tangaac Date: Tue, 12 Nov 2024 16:31:57 +0800 Subject: [PATCH] add la v1.1 features for sys::getHostCPUFeatures --- clang/lib/Driver/ToolChains/Arch/LoongArch.cpp | 7 ++- llvm/lib/TargetParser/Host.cpp | 9 + 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp index e69a5562137ccd..2dc7550176f5f0 100644 --- a/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp +++ b/clang/lib/Driver/ToolChains/Arch/LoongArch.cpp @@ -135,8 +135,13 @@ void loongarch::getLoongArchTargetFeatures(const Driver &D, Features.push_back("+lsx"); std::string ArchName; - if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) + if (const Arg *A = Args.getLastArg(options::OPT_march_EQ)) { ArchName = A->getValue(); +if (ArchName == "native") + for (auto &F : llvm::sys::getHostCPUFeatures()) +Features.push_back( +Args.MakeArgString((F.second ? "+" : "-") + F.first())); + } ArchName = postProcessTargetCPUString(ArchName, Triple); llvm::LoongArch::getArchFeatures(ArchName, Features); diff --git a/llvm/lib/TargetParser/Host.cpp b/llvm/lib/TargetParser/Host.cpp index 58ba2553633221..0250aac9a7cb86 100644 --- a/llvm/lib/TargetParser/Host.cpp +++ b/llvm/lib/TargetParser/Host.cpp @@ -2006,6 +2006,15 @@ const StringMap sys::getHostCPUFeatures() { Features["lasx"] = hwcap & (1UL << 5); // HWCAP_LOONGARCH_LASX Features["lvz"] = hwcap & (1UL << 9); // HWCAP_LOONGARCH_LVZ + Features["frecipe"] = cpucfg2 & (1U << 25); // CPUCFG.2.FRECIPE + Features["lam-bh"] = cpucfg2 & (1U << 27); // CPUCFG.2.LAM_BH + + // TODO: Need to complete. + // Features["div32"] = cpucfg2 & (1U << 26); // CPUCFG.2.DIV32 + // Features["lamcas"] = cpucfg2 & (1U << 28); // CPUCFG.2.LAMCAS + // Features["llacq-screl"] = cpucfg2 & (1U << 29); // CPUCFG.2.LLACQ_SCREL + // Features["scq"] = cpucfg2 & (1U << 30); // CPUCFG.2.SCQ + // Features["ld-seq-sa"] = cpucfg3 & (1U << 23); // CPUCFG.3.LD_SEQ_SA return Features; } #elif defined(__linux__) && defined(__riscv) ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + + void remove(StringRef ModuleName); + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +std::shared_ptr +ModuleFileCache::getModule(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return nullptr; + + if (Iter->second.expired()) { +ModuleFiles.erase(Iter); +return nullptr; + } + + return Iter->second.lock(); +} + +void ModuleFileCache::remove(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return; + + ModuleFiles.erase(Iter); +} + +/// Collect the directly and indirectly required module names for \param +/// ModuleName in topological order. The \param ModuleName is guaranteed to +/// be the last element in \param ModuleNames. +llvm::SmallVector getAllRequiredModules(ProjectModules &MDB, + StringRef ModuleName) { + llvm::SmallVector ModuleNames; + llvm::StringSet<> ModuleNamesSet; + + auto traversal = [&](StringRef ModuleName, auto recursionHelper) -> void { +ModuleNamesSet.insert(ModuleName); + +for (StringRef RequiredModuleName : + MDB.getRequiredModules(MDB.getSourceForModuleName(ModuleName))) + if (ModuleNamesSet.insert(RequiredModuleName).second) +recursionHelper(RequiredModuleName, recursionHelper); + +ModuleNames.push_back(ModuleName); + }; + traversal(ModuleName, traversal); + + return ModuleNames; +} + } // namespace +class ModulesBuilder::ModulesBuilderImpl { +public: + ModulesBuilderImpl(const GlobalCompilationDatabase &CDB) : Cache(CDB) {} + + const GlobalCompilationDatabase &getCDB() const { return Cache.getCDB(); } + + llvm::Error + getOrBuildModuleFile(StringRef ModuleName, const ThreadsafeFS &TFS, + ProjectModules &MDB, + ReusablePrerequisiteModules &BuiltModuleFiles); + +private: + ModuleFileCache Cache; +}; + +llvm::Error ModulesBuilder::ModulesBuilderImpl::getOrBuildModuleFile( +StringRef ModuleName, const ThreadsafeFS &TFS, ProjectModules &MDB, +ReusablePrerequisiteModules &BuiltModuleFiles) { + if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName)) +return llvm::Error::success(); + + PathRef ModuleUnitFileName = MDB.getSourceForModuleName(ModuleName); + /// It is possible that we're meeting third party modules (modules whose + /// source are not in the project. e.g, the std module may be a third-party + /// module for most project) or something wrong with the implementation of + /// ProjectModules. + /// FIXME: How should we treat third party modules here? If we want to ignore + /// third party modules, we should return true instead of false here. + /// Currently we simply bail out. + if (ModuleUnitFileName.empty()) +return llvm::createStringError( +llvm::formatv("Don't get the module unit for module {0}", ModuleName)); + + // Get Required modules in topological order. + auto ReqModuleNames = getAllRequiredModules(MDB, ModuleName); + for (llvm::StringRef ReqModuleName : ReqModuleNames) { +if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName)) + continue; + +if (auto Cached = Cache.getModule(ReqModuleName)) { + if (IsModuleFileUpToDate(Cached->getModuleFilePath(), BuiltModuleFiles, + TFS.view(std::nullopt))) { +log("Reusing module {0} from {1}", ModuleName, +Cached->getModuleFilePath()); +BuiltModuleFiles.addModuleFile(std::move(Cached)); +continue; + } + Cache.remove(ReqModuleName); +} + +llvm::SmallString<256> ModuleFilesPrefix = +getUniqueModuleFilesPa
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/kadircet requested changes to this pull request. thanks, i think this looks great! some little comments/nits. https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); kadircet wrote: nit: `ModuleFiles[ModuleName] = std::move(ModuleFile);` https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + + void remove(StringRef ModuleName); + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +std::shared_ptr +ModuleFileCache::getModule(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return nullptr; + + if (Iter->second.expired()) { +ModuleFiles.erase(Iter); +return nullptr; + } + + return Iter->second.lock(); +} + +void ModuleFileCache::remove(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return; + + ModuleFiles.erase(Iter); +} + +/// Collect the directly and indirectly required module names for \param +/// ModuleName in topological order. The \param ModuleName is guaranteed to +/// be the last element in \param ModuleNames. +llvm::SmallVector getAllRequiredModules(ProjectModules &MDB, + StringRef ModuleName) { + llvm::SmallVector ModuleNames; + llvm::StringSet<> ModuleNamesSet; + + auto traversal = [&](StringRef ModuleName, auto recursionHelper) -> void { kadircet wrote: s/traversal/VisitDeps/ s/recursionHelper/Visitor/ https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [X86][AMX] Add AMX FP8 new APIs (PR #115829)
https://github.com/phoebewang approved this pull request. LGTM. https://github.com/llvm/llvm-project/pull/115829 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; kadircet wrote: nit: `llvm::SmallVector` and `llvm::StringRef` https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/kadircet edited https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
https://github.com/SahilPatidar closed https://github.com/llvm/llvm-project/pull/110418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 3183b3a - [Clang-Repl] Add support for out-of-process execution. (#110418)
Author: SahilPatidar Date: 2024-11-12T14:39:30+05:30 New Revision: 3183b3aad130ac6754f294046c008a85b9925894 URL: https://github.com/llvm/llvm-project/commit/3183b3aad130ac6754f294046c008a85b9925894 DIFF: https://github.com/llvm/llvm-project/commit/3183b3aad130ac6754f294046c008a85b9925894.diff LOG: [Clang-Repl] Add support for out-of-process execution. (#110418) This PR introduces out-of-process (OOP) execution support for Clang-Repl. With this enhancement, two new flags, `oop-executor` and `oop-executor-connect`, are added to the Clang-Repl interface. These flags enable the launch of an external executor (`llvm-jitlink-executor`), which handles code execution in a separate process. Added: clang/include/clang/Interpreter/RemoteJITUtils.h clang/lib/Interpreter/RemoteJITUtils.cpp clang/test/Interpreter/out-of-process.cpp Modified: clang/include/clang/Interpreter/Interpreter.h clang/lib/Interpreter/CMakeLists.txt clang/lib/Interpreter/Interpreter.cpp clang/tools/clang-repl/CMakeLists.txt clang/tools/clang-repl/ClangRepl.cpp Removed: diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index 1230a3a7016fae..42486304083f4e 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -20,6 +20,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" #include "llvm/Support/Error.h" #include @@ -129,10 +130,14 @@ class Interpreter { public: virtual ~Interpreter(); static llvm::Expected> - create(std::unique_ptr CI); + create(std::unique_ptr CI, + std::unique_ptr JITBuilder = nullptr); static llvm::Expected> createWithCUDA(std::unique_ptr CI, std::unique_ptr DCI); + static llvm::Expected> + createLLJITBuilder(std::unique_ptr EPC, + llvm::StringRef OrcRuntimePath); const ASTContext &getASTContext() const; ASTContext &getASTContext(); const CompilerInstance *getCompilerInstance() const; diff --git a/clang/include/clang/Interpreter/RemoteJITUtils.h b/clang/include/clang/Interpreter/RemoteJITUtils.h new file mode 100644 index 00..8705a3b1f669de --- /dev/null +++ b/clang/include/clang/Interpreter/RemoteJITUtils.h @@ -0,0 +1,38 @@ +//===-- RemoteJITUtils.h - Utilities for remote-JITing --*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===--===// +// +// Utilities for ExecutorProcessControl-based remote JITing with Orc and +// JITLink. +// +//===--===// + +#ifndef LLVM_CLANG_INTERPRETER_REMOTEJITUTILS_H +#define LLVM_CLANG_INTERPRETER_REMOTEJITUTILS_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/ExecutionEngine/Orc/Core.h" +#include "llvm/ExecutionEngine/Orc/Layer.h" +#include "llvm/ExecutionEngine/Orc/SimpleRemoteEPC.h" +#include "llvm/Support/Error.h" + +#include +#include +#include + +llvm::Expected> +launchExecutor(llvm::StringRef ExecutablePath, bool UseSharedMemory, + llvm::StringRef SlabAllocateSizeString); + +/// Create a JITLinkExecutor that connects to the given network address +/// through a TCP socket. A valid NetworkAddress provides hostname and port, +/// e.g. localhost:2. +llvm::Expected> +connectTCPSocket(llvm::StringRef NetworkAddress, bool UseSharedMemory, + llvm::StringRef SlabAllocateSizeString); + +#endif // LLVM_CLANG_INTERPRETER_REMOTEJITUTILS_H diff --git a/clang/lib/Interpreter/CMakeLists.txt b/clang/lib/Interpreter/CMakeLists.txt index d5ffe78251d253..eb99e316ebc0a7 100644 --- a/clang/lib/Interpreter/CMakeLists.txt +++ b/clang/lib/Interpreter/CMakeLists.txt @@ -25,6 +25,7 @@ add_clang_library(clangInterpreter Interpreter.cpp InterpreterValuePrinter.cpp InterpreterUtils.cpp + RemoteJITUtils.cpp Value.cpp ${WASM_SRC} PARTIAL_SOURCES_INTENDED diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index bc96da811d44cb..8eacbc6b713a19 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -44,6 +44,7 @@ #include "clang/Sema/Lookup.h" #include "clang/Serialization/ObjectFilePCHContainerReader.h" #include "llvm/ExecutionEngine/JITSymbol.h" +#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" #include "llvm/IR/Module.h" #include "llvm/Support/Errc.h" @@ -456,10 +457,11 @@ const char *const Runtimes
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + + void remove(StringRef ModuleName); + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +std::shared_ptr +ModuleFileCache::getModule(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return nullptr; + + if (Iter->second.expired()) { +ModuleFiles.erase(Iter); +return nullptr; + } + + return Iter->second.lock(); kadircet wrote: again we can actually lose the reference between `expired` and `lock` call here (e.g. another thread destroys the last reference right after we called `expired`). can you instead do: ```cpp if (auto Res = Iter->second.lock()) return Res; ModuleFiles.erase(Iter); return nullptr; ``` here `lock` atomically makes a copy, if weak_ptr hasn't expired. https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + + void remove(StringRef ModuleName); + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +std::shared_ptr +ModuleFileCache::getModule(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return nullptr; + + if (Iter->second.expired()) { +ModuleFiles.erase(Iter); +return nullptr; + } + + return Iter->second.lock(); +} + +void ModuleFileCache::remove(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return; + + ModuleFiles.erase(Iter); +} + +/// Collect the directly and indirectly required module names for \param +/// ModuleName in topological order. The \param ModuleName is guaranteed to +/// be the last element in \param ModuleNames. +llvm::SmallVector getAllRequiredModules(ProjectModules &MDB, + StringRef ModuleName) { + llvm::SmallVector ModuleNames; + llvm::StringSet<> ModuleNamesSet; + + auto traversal = [&](StringRef ModuleName, auto recursionHelper) -> void { +ModuleNamesSet.insert(ModuleName); + +for (StringRef RequiredModuleName : + MDB.getRequiredModules(MDB.getSourceForModuleName(ModuleName))) + if (ModuleNamesSet.insert(RequiredModuleName).second) +recursionHelper(RequiredModuleName, recursionHelper); + +ModuleNames.push_back(ModuleName); + }; + traversal(ModuleName, traversal); + + return ModuleNames; +} + } // namespace +class ModulesBuilder::ModulesBuilderImpl { +public: + ModulesBuilderImpl(const GlobalCompilationDatabase &CDB) : Cache(CDB) {} + + const GlobalCompilationDatabase &getCDB() const { return Cache.getCDB(); } + + llvm::Error + getOrBuildModuleFile(StringRef ModuleName, const ThreadsafeFS &TFS, + ProjectModules &MDB, + ReusablePrerequisiteModules &BuiltModuleFiles); + +private: + ModuleFileCache Cache; +}; + +llvm::Error ModulesBuilder::ModulesBuilderImpl::getOrBuildModuleFile( +StringRef ModuleName, const ThreadsafeFS &TFS, ProjectModules &MDB, +ReusablePrerequisiteModules &BuiltModuleFiles) { + if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName)) +return llvm::Error::success(); + + PathRef ModuleUnitFileName = MDB.getSourceForModuleName(ModuleName); + /// It is possible that we're meeting third party modules (modules whose + /// source are not in the project. e.g, the std module may be a third-party + /// module for most project) or something wrong with the implementation of + /// ProjectModules. + /// FIXME: How should we treat third party modules here? If we want to ignore + /// third party modules, we should return true instead of false here. + /// Currently we simply bail out. + if (ModuleUnitFileName.empty()) +return llvm::createStringError( +llvm::formatv("Don't get the module unit for module {0}", ModuleName)); + + // Get Required modules in topological order. + auto ReqModuleNames = getAllRequiredModules(MDB, ModuleName); + for (llvm::StringRef ReqModuleName : ReqModuleNames) { +if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName)) + continue; + +if (auto Cached = Cache.getModule(ReqModuleName)) { + if (IsModuleFileUpToDate(Cached->getModuleFilePath(), BuiltModuleFiles, + TFS.view(std::nullopt))) { +log("Reusing module {0} from {1}", ModuleName, +Cached->getModuleFilePath()); +BuiltModuleFiles.addModuleFile(std::move(Cached)); +continue; + } + Cache.remove(ReqModuleName); +} + +llvm::SmallString<256> ModuleFilesPrefix = +getUniqueModuleFilesPa
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `llvm-clang-x86_64-sie-ubuntu-fast` running on `sie-linux-worker` while building `clang` at step 6 "test-build-unified-tree-check-all". Full details are available at: https://lab.llvm.org/buildbot/#/builders/144/builds/11400 Here is the relevant piece of the build log for the reference ``` Step 6 (test-build-unified-tree-check-all) failure: test (failure) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stderr): -- RUN: at line 3: cat /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/Interpreter/out-of-process.cpp | /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang-repl -oop-executor -orc-runtime | /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/Interpreter/out-of-process.cpp + /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/clang-repl -oop-executor -orc-runtime + /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/Interpreter/out-of-process.cpp + cat /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/Interpreter/out-of-process.cpp clang-repl: No such file or directory FileCheck error: '' is empty. FileCheck command line: /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/llvm-project/clang/test/Interpreter/out-of-process.cpp -- ``` https://github.com/llvm/llvm-project/pull/110418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/106683 >From 15aa6af1f5d22e4b837e8e2fd49469310ffbe7f1 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Fri, 30 Aug 2024 15:11:07 +0800 Subject: [PATCH 1/6] [clangd] [Modules] Support Reusable Modules Builder --- clang-tools-extra/clangd/ModulesBuilder.cpp | 375 ++ clang-tools-extra/clangd/ModulesBuilder.h | 8 +- .../unittests/PrerequisiteModulesTest.cpp | 36 ++ 3 files changed, 344 insertions(+), 75 deletions(-) diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp index 97f67ddf5495a2..c4fb3d4010d370 100644 --- a/clang-tools-extra/clangd/ModulesBuilder.cpp +++ b/clang-tools-extra/clangd/ModulesBuilder.cpp @@ -13,6 +13,7 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/InMemoryModuleCache.h" +#include "llvm/ADT/ScopeExit.h" namespace clang { namespace clangd { @@ -192,33 +193,27 @@ bool IsModuleFilesUpToDate( }); } -// StandalonePrerequisiteModules - stands for PrerequisiteModules for which all +// ReusablePrerequisiteModules - stands for PrerequisiteModules for which all // the required modules are built successfully. All the module files -// are owned by the StandalonePrerequisiteModules class. -// -// Any of the built module files won't be shared with other instances of the -// class. So that we can avoid worrying thread safety. -// -// We don't need to worry about duplicated module names here since the standard -// guarantees the module names should be unique to a program. -class StandalonePrerequisiteModules : public PrerequisiteModules { +// are owned by the modules builder. +class ReusablePrerequisiteModules : public PrerequisiteModules { public: - StandalonePrerequisiteModules() = default; + ReusablePrerequisiteModules() = default; - StandalonePrerequisiteModules(const StandalonePrerequisiteModules &) = delete; - StandalonePrerequisiteModules - operator=(const StandalonePrerequisiteModules &) = delete; - StandalonePrerequisiteModules(StandalonePrerequisiteModules &&) = delete; - StandalonePrerequisiteModules - operator=(StandalonePrerequisiteModules &&) = delete; + ReusablePrerequisiteModules(const ReusablePrerequisiteModules &) = delete; + ReusablePrerequisiteModules + operator=(const ReusablePrerequisiteModules &) = delete; + ReusablePrerequisiteModules(ReusablePrerequisiteModules &&) = delete; + ReusablePrerequisiteModules + operator=(ReusablePrerequisiteModules &&) = delete; - ~StandalonePrerequisiteModules() override = default; + ~ReusablePrerequisiteModules() override = default; void adjustHeaderSearchOptions(HeaderSearchOptions &Options) const override { // Appending all built module files. for (auto &RequiredModule : RequiredModules) Options.PrebuiltModuleFiles.insert_or_assign( - RequiredModule.ModuleName, RequiredModule.ModuleFilePath); + RequiredModule->ModuleName, RequiredModule->ModuleFilePath); } bool canReuse(const CompilerInvocation &CI, @@ -228,54 +223,30 @@ class StandalonePrerequisiteModules : public PrerequisiteModules { return BuiltModuleNames.contains(ModuleName); } - void addModuleFile(llvm::StringRef ModuleName, - llvm::StringRef ModuleFilePath) { -RequiredModules.emplace_back(ModuleName, ModuleFilePath); -BuiltModuleNames.insert(ModuleName); + void addModuleFile(std::shared_ptr BMI) { +BuiltModuleNames.insert(BMI->ModuleName); +RequiredModules.emplace_back(std::move(BMI)); } private: - llvm::SmallVector RequiredModules; + mutable llvm::SmallVector, 8> RequiredModules; // A helper class to speedup the query if a module is built. llvm::StringSet<> BuiltModuleNames; }; -// Build a module file for module with `ModuleName`. The information of built -// module file are stored in \param BuiltModuleFiles. -llvm::Error buildModuleFile(llvm::StringRef ModuleName, -const GlobalCompilationDatabase &CDB, -const ThreadsafeFS &TFS, ProjectModules &MDB, -PathRef ModuleFilesPrefix, -StandalonePrerequisiteModules &BuiltModuleFiles) { - if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName)) -return llvm::Error::success(); - - PathRef ModuleUnitFileName = MDB.getSourceForModuleName(ModuleName); - // It is possible that we're meeting third party modules (modules whose - // source are not in the project. e.g, the std module may be a third-party - // module for most projects) or something wrong with the implementation of - // ProjectModules. - // FIXME: How should we treat third party modules here? If we want to ignore - // third party modules, we should return true instead of false here. - // Currently we simply bail out. - if (ModuleUnitFileName.empty()) -return llvm::createStringErro
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
https://github.com/SahilPatidar updated https://github.com/llvm/llvm-project/pull/110418 >From 519dd2c99bc2200d364a184e416ec03b609e1910 Mon Sep 17 00:00:00 2001 From: SahilPatidar Date: Fri, 7 Jun 2024 13:30:08 +0530 Subject: [PATCH 01/15] [Clang-Repl] Implement out-of-process execution interface for clang-repl --- clang/include/clang/Interpreter/Interpreter.h | 9 +- clang/lib/Interpreter/Interpreter.cpp | 33 ++- clang/tools/clang-repl/CMakeLists.txt | 2 + clang/tools/clang-repl/ClangRepl.cpp | 75 ++- clang/tools/clang-repl/RemoteJITUtils.cpp | 208 ++ clang/tools/clang-repl/RemoteJITUtils.h | 42 llvm/lib/ExecutionEngine/Orc/LLJIT.cpp| 3 + 7 files changed, 364 insertions(+), 8 deletions(-) create mode 100644 clang/tools/clang-repl/RemoteJITUtils.cpp create mode 100644 clang/tools/clang-repl/RemoteJITUtils.h diff --git a/clang/include/clang/Interpreter/Interpreter.h b/clang/include/clang/Interpreter/Interpreter.h index 1230a3a7016fae..147794c5870335 100644 --- a/clang/include/clang/Interpreter/Interpreter.h +++ b/clang/include/clang/Interpreter/Interpreter.h @@ -21,6 +21,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h" +#include "llvm/ExecutionEngine/Orc/ExecutorProcessControl.h" #include "llvm/Support/Error.h" #include #include @@ -129,7 +130,13 @@ class Interpreter { public: virtual ~Interpreter(); static llvm::Expected> - create(std::unique_ptr CI); + create(std::unique_ptr CI, + std::unique_ptr JITBuilder = nullptr); + static llvm::Expected> + createWithOOPExecutor( + std::unique_ptr CI, + std::unique_ptr EI, + llvm::StringRef OrcRuntimePath); static llvm::Expected> createWithCUDA(std::unique_ptr CI, std::unique_ptr DCI); diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index bc96da811d44cb..21507906618c39 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -45,6 +45,7 @@ #include "clang/Serialization/ObjectFilePCHContainerReader.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/LLJIT.h" +#include "llvm/ExecutionEngine/Orc/EPCDynamicLibrarySearchGenerator.h" #include "llvm/IR/Module.h" #include "llvm/Support/Errc.h" #include "llvm/Support/ErrorHandling.h" @@ -456,10 +457,12 @@ const char *const Runtimes = R"( )"; llvm::Expected> -Interpreter::create(std::unique_ptr CI) { +Interpreter::create(std::unique_ptr CI, +std::unique_ptr JB) { llvm::Error Err = llvm::Error::success(); auto Interp = - std::unique_ptr(new Interpreter(std::move(CI), Err)); + std::unique_ptr(new Interpreter(std::move(CI), Err, + JB? std::move(JB): nullptr)); if (Err) return std::move(Err); @@ -578,6 +581,26 @@ createJITTargetMachineBuilder(const std::string &TT) { return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT)); } +llvm::Expected> +Interpreter::createWithOOPExecutor( +std::unique_ptr CI, +std::unique_ptr EPC, +llvm::StringRef OrcRuntimePath) { + const std::string &TT = CI->getTargetOpts().Triple; + auto JTMB = createJITTargetMachineBuilder(TT); + if (!JTMB) +return JTMB.takeError(); + auto JB = IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB)); + if (!JB) +return JB.takeError(); + if (EPC) { +JB.get()->setExecutorProcessControl(std::move(EPC)); + JB.get()->setPlatformSetUp(llvm::orc::ExecutorNativePlatform(OrcRuntimePath.str())); + } + + return Interpreter::create(std::move(CI), std::move(*JB)); +} + llvm::Error Interpreter::CreateExecutor() { if (IncrExecutor) return llvm::make_error("Operation failed. " @@ -702,10 +725,10 @@ llvm::Error Interpreter::LoadDynamicLibrary(const char *name) { if (!EE) return EE.takeError(); - auto &DL = EE->getDataLayout(); + // auto &DL = EE->getDataLayout(); - if (auto DLSG = llvm::orc::DynamicLibrarySearchGenerator::Load( - name, DL.getGlobalPrefix())) + if (auto DLSG = llvm::orc::EPCDynamicLibrarySearchGenerator::Load( + EE->getExecutionSession(), name)) EE->getMainJITDylib().addGenerator(std::move(*DLSG)); else return DLSG.takeError(); diff --git a/clang/tools/clang-repl/CMakeLists.txt b/clang/tools/clang-repl/CMakeLists.txt index 7aebbe7a19436a..11164e3b8f5c65 100644 --- a/clang/tools/clang-repl/CMakeLists.txt +++ b/clang/tools/clang-repl/CMakeLists.txt @@ -4,7 +4,9 @@ set( LLVM_LINK_COMPONENTS LineEditor Option OrcJIT + OrcShared Support + TargetParser ) add_clang_tool(clang-repl diff --git a/clang/tools/clang-repl/ClangRepl.cpp b/clang/tools/clang-repl/ClangRepl.cpp index 08c54e6cafa901..21359df01c270f 100644 --- a/clang/tools/clang-repl/ClangRepl.cpp +++ b/clang/tools/clang-repl/C
[clang] [Clang] [NFC] Add "human" diagnostic argument format (PR #115835)
https://github.com/bricknerb created https://github.com/llvm/llvm-project/pull/115835 This allows formatting large integers in a human friendly way. Example: "5321584" -> "5.32M". Use it where such human numbers are generated manually today. >From ccf18e49f884b4430dff70d59fb3236259661f9d Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Tue, 12 Nov 2024 10:19:58 +0100 Subject: [PATCH] [Clang] [NFC] Add "human" diagnostic argument format This allows formatting large integers in a human friendly way. Example: "5321584" -> "5.32M". Use it where such human numbers are generated manually today. --- clang/docs/InternalsManual.rst| 12 +++ .../clang/Basic/DiagnosticCommonKinds.td | 12 +++ clang/lib/Basic/Diagnostic.cpp| 31 clang/lib/Basic/SourceManager.cpp | 35 +++ .../TableGen/ClangDiagnosticsEmitter.cpp | 7 +++- 5 files changed, 59 insertions(+), 38 deletions(-) diff --git a/clang/docs/InternalsManual.rst b/clang/docs/InternalsManual.rst index b70ec35f3da229..e7dd41c8595bd4 100644 --- a/clang/docs/InternalsManual.rst +++ b/clang/docs/InternalsManual.rst @@ -315,6 +315,18 @@ Description: than ``1`` are not supported. This formatter is currently hard-coded to use English ordinals. +**"human" format** + +Example: + ``"total size is %human0 bytes"`` +Class: + Integers +Description: + This is a formatter which represents the argument number in a human readable + format: the value ``123`` stays ``123``, ``12345`` becomes ``12.34k``, + ``666` becomes ``6.67M``, and so on for 'G' and 'T'. Values less than + ``0`` are not supported. + **"objcclass" format** Example: diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 457abea0b81471..0c131166aff28d 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -389,14 +389,14 @@ def remark_sloc_usage : Remark< "source manager location address space usage:">, InGroup>, DefaultRemark, ShowInSystemHeader; def note_total_sloc_usage : Note< - "%0B (%1B) in local locations, %2B (%3B) " - "in locations loaded from AST files, for a total of %4B (%5B) " - "(%6%% of available space)">; + "%0B (%human0B) in local locations, %1B (%human1B) " + "in locations loaded from AST files, for a total of %2B (%human2B) " + "(%3%% of available space)">; def note_file_sloc_usage : Note< - "file entered %0 time%s0 using %1B (%2B) of space" - "%plural{0:|: plus %3B (%4B) for macro expansions}3">; + "file entered %0 time%s0 using %1B (%human1B) of space" + "%plural{0:|: plus %2B (%human2B) for macro expansions}2">; def note_file_misc_sloc_usage : Note< - "%0 additional files entered using a total of %1B (%2B) of space">; + "%0 additional files entered using a total of %1B (%human1B) of space">; // Modules def err_module_format_unhandled : Error< diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index e23362fc7af00d..9a3f2aec5df6fa 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -652,6 +652,33 @@ static void HandleOrdinalModifier(unsigned ValNo, Out << ValNo << llvm::getOrdinalSuffix(ValNo); } +// 123 -> "123". +// 1234 -> "1.23k". +// 123456 -> "123.46k". +// 1234567 -> "1.23M". +// 1234567890 -> "1.23G". +// 1234567890123 -> "1.23T". +static void HandleIntegerHumanModifier(unsigned ValNo, + SmallVectorImpl &OutStr) { + static constexpr std::array, 4> Units = { + {{1'000'000'000'000UL, 'T'}, + {1'000'000'000UL, 'G'}, + {1'000'000UL, 'M'}, + {1'000UL, 'k'}}}; + + llvm::raw_svector_ostream Out(OutStr); + for (const auto &[UnitSize, UnitSign] : Units) { +if (ValNo >= UnitSize) { + // Out << llvm::formatv("{0:F}{1}", ValNo / static_cast(UnitSize), + // UnitSign); + Out << llvm::format("%0.2f%c", ValNo / static_cast(UnitSize), + UnitSign); + return; +} + } + Out << ValNo; +} + /// PluralNumber - Parse an unsigned integer and advance Start. static unsigned PluralNumber(const char *&Start, const char *End) { // Programming 101: Parse a decimal number :-) @@ -988,6 +1015,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, OutStr); } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { HandleOrdinalModifier((unsigned)Val, OutStr); + } else if (ModifierIs(Modifier, ModifierLen, "human")) { +HandleIntegerHumanModifier(Val, OutStr); } else { assert(ModifierLen == 0 && "Unknown integer modifier"); llvm::raw_svector_ostream(OutStr) << Val; @@ -1006,6 +1035,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, OutStr); } else if (ModifierIs(Modifier, ModifierLen, "ordi
[clang] [clang][AST] Add 'IgnoreTemplateParmDepth' to structural equivalence cache (PR #115518)
Michael137 wrote: > It is a realistic requirement that new similar parameters are added, I had > already an (experimental) fix where this is needed. Still I like better the > solution with separate caches because efficiency reasons > (`IgnoreTemplateParmDepth = true` is rarely used, not at all for C code). For > new parameters we have the similar set of choices (add more new caches or > extend cache key or not use the cache at all). We wouldn't just have to add a single extra cache, but each parameter would require us to add caches for all permutations of the parameters. Also, I'd be surprised if there's a noticeable difference in performance between the two to be honest. So I still prefer your first solution, but I don't want to block this if you prefer the other approach https://github.com/llvm/llvm-project/pull/115518 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `clang-ve-ninja` running on `hpce-ve-main` while building `clang` at step 4 "annotate". Full details are available at: https://lab.llvm.org/buildbot/#/builders/12/builds/9402 Here is the relevant piece of the build log for the reference ``` Step 4 (annotate) failure: 'python ../llvm-zorg/zorg/buildbot/builders/annotated/ve-linux.py ...' (failure) ... [295/301] Linking CXX executable tools/clang/unittests/Driver/ClangDriverTests [296/301] Linking CXX executable tools/clang/unittests/CodeGen/ClangCodeGenTests [297/301] Linking CXX executable tools/clang/unittests/Tooling/ToolingTests [298/301] Linking CXX executable tools/clang/unittests/Frontend/FrontendTests [299/301] Linking CXX executable tools/clang/unittests/Interpreter/ExceptionTests/ClangReplInterpreterExceptionTests [300/301] Linking CXX executable tools/clang/unittests/Interpreter/ClangReplInterpreterTests [300/301] Running the Clang regression tests -- Testing: 21293 tests, 48 workers -- llvm-lit: /scratch/buildbot/bothome/clang-ve-ninja/llvm-project/llvm/utils/lit/lit/llvm/config.py:506: note: using clang: /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/bin/clang Testing: 0.. 10.. 20.. 30.. 40.. 50.. FAIL: Clang :: Interpreter/out-of-process.cpp (12608 of 21293) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stderr): -- RUN: at line 3: cat /scratch/buildbot/bothome/clang-ve-ninja/llvm-project/clang/test/Interpreter/out-of-process.cpp | /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/bin/clang-repl -oop-executor -orc-runtime | /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/bin/FileCheck /scratch/buildbot/bothome/clang-ve-ninja/llvm-project/clang/test/Interpreter/out-of-process.cpp + /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/bin/FileCheck /scratch/buildbot/bothome/clang-ve-ninja/llvm-project/clang/test/Interpreter/out-of-process.cpp + cat /scratch/buildbot/bothome/clang-ve-ninja/llvm-project/clang/test/Interpreter/out-of-process.cpp + /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/bin/clang-repl -oop-executor -orc-runtime clang-repl: No such file or directory FileCheck error: '' is empty. FileCheck command line: /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/bin/FileCheck /scratch/buildbot/bothome/clang-ve-ninja/llvm-project/clang/test/Interpreter/out-of-process.cpp -- Testing: 0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. Failed Tests (1): Clang :: Interpreter/out-of-process.cpp Testing Time: 50.72s Total Discovered Tests: 45608 Skipped :10 (0.02%) Unsupported : 3799 (8.33%) Passed : 41772 (91.59%) Expectedly Failed:26 (0.06%) Failed : 1 (0.00%) FAILED: tools/clang/test/CMakeFiles/check-clang /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/tools/clang/test/CMakeFiles/check-clang cd /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/tools/clang/test && /home/buildbot/sandbox/bin/python3 /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/./bin/llvm-lit -sv --param USE_Z3_SOLVER=0 /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/tools/clang/test ninja: build stopped: subcommand failed. make: *** [check-llvm] Error 1 ['make', '-f', '/scratch/buildbot/bothome/clang-ve-ninja/llvm-zorg/zorg/buildbot/builders/annotated/ve-linux-steps.make', 'check-llvm', 'BUILDROOT=/scratch/buildbot/bothome/clang-ve-ninja/build'] exited with return code 2. The build step threw an exception... Traceback (most recent call last): File "../llvm-zorg/zorg/buildbot/builders/annotated/ve-linux.py", line 47, in step Step 8 (check-llvm) failure: check-llvm (failure) ... [295/301] Linking CXX executable tools/clang/unittests/Driver/ClangDriverTests [296/301] Linking CXX executable tools/clang/unittests/CodeGen/ClangCodeGenTests [297/301] Linking CXX executable tools/clang/unittests/Tooling/ToolingTests [298/301] Linking CXX executable tools/clang/unittests/Frontend/FrontendTests [299/301] Linking CXX executable tools/clang/unittests/Interpreter/ExceptionTests/ClangReplInterpreterExceptionTests [300/301] Linking CXX executable tools/clang/unittests/Interpreter/ClangReplInterpreterTests [300/301] Running the Clang regression tests -- Testing: 21293 tests, 48 workers -- llvm-lit: /scratch/buildbot/bothome/clang-ve-ninja/llvm-project/llvm/utils/lit/lit/llvm/config.py:506: note: using clang: /scratch/buildbot/bothome/clang-ve-ninja/build/build_llvm/bin/clang Testing: 0.. 10.. 20.. 30.. 40.. 50.. FAIL: Clang :: Interpreter/out-of-process.cpp (12608 of 21293) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stderr): -- RUN: at line 3: cat /scratch/buildbot/bothome/clang-ve-ninja/llvm-project/clang/test/Interpreter
[clang] [Clang] [NFC] Add "human" diagnostic argument format (PR #115835)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Boaz Brickner (bricknerb) Changes This allows formatting large integers in a human friendly way. Example: "5321584" -> "5.32M". Use it where such human numbers are generated manually today. --- Full diff: https://github.com/llvm/llvm-project/pull/115835.diff 5 Files Affected: - (modified) clang/docs/InternalsManual.rst (+12) - (modified) clang/include/clang/Basic/DiagnosticCommonKinds.td (+6-6) - (modified) clang/lib/Basic/Diagnostic.cpp (+31) - (modified) clang/lib/Basic/SourceManager.cpp (+4-31) - (modified) clang/utils/TableGen/ClangDiagnosticsEmitter.cpp (+6-1) ``diff diff --git a/clang/docs/InternalsManual.rst b/clang/docs/InternalsManual.rst index b70ec35f3da229..e7dd41c8595bd4 100644 --- a/clang/docs/InternalsManual.rst +++ b/clang/docs/InternalsManual.rst @@ -315,6 +315,18 @@ Description: than ``1`` are not supported. This formatter is currently hard-coded to use English ordinals. +**"human" format** + +Example: + ``"total size is %human0 bytes"`` +Class: + Integers +Description: + This is a formatter which represents the argument number in a human readable + format: the value ``123`` stays ``123``, ``12345`` becomes ``12.34k``, + ``666` becomes ``6.67M``, and so on for 'G' and 'T'. Values less than + ``0`` are not supported. + **"objcclass" format** Example: diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 457abea0b81471..0c131166aff28d 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -389,14 +389,14 @@ def remark_sloc_usage : Remark< "source manager location address space usage:">, InGroup>, DefaultRemark, ShowInSystemHeader; def note_total_sloc_usage : Note< - "%0B (%1B) in local locations, %2B (%3B) " - "in locations loaded from AST files, for a total of %4B (%5B) " - "(%6%% of available space)">; + "%0B (%human0B) in local locations, %1B (%human1B) " + "in locations loaded from AST files, for a total of %2B (%human2B) " + "(%3%% of available space)">; def note_file_sloc_usage : Note< - "file entered %0 time%s0 using %1B (%2B) of space" - "%plural{0:|: plus %3B (%4B) for macro expansions}3">; + "file entered %0 time%s0 using %1B (%human1B) of space" + "%plural{0:|: plus %2B (%human2B) for macro expansions}2">; def note_file_misc_sloc_usage : Note< - "%0 additional files entered using a total of %1B (%2B) of space">; + "%0 additional files entered using a total of %1B (%human1B) of space">; // Modules def err_module_format_unhandled : Error< diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index e23362fc7af00d..9a3f2aec5df6fa 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -652,6 +652,33 @@ static void HandleOrdinalModifier(unsigned ValNo, Out << ValNo << llvm::getOrdinalSuffix(ValNo); } +// 123 -> "123". +// 1234 -> "1.23k". +// 123456 -> "123.46k". +// 1234567 -> "1.23M". +// 1234567890 -> "1.23G". +// 1234567890123 -> "1.23T". +static void HandleIntegerHumanModifier(unsigned ValNo, + SmallVectorImpl &OutStr) { + static constexpr std::array, 4> Units = { + {{1'000'000'000'000UL, 'T'}, + {1'000'000'000UL, 'G'}, + {1'000'000UL, 'M'}, + {1'000UL, 'k'}}}; + + llvm::raw_svector_ostream Out(OutStr); + for (const auto &[UnitSize, UnitSign] : Units) { +if (ValNo >= UnitSize) { + // Out << llvm::formatv("{0:F}{1}", ValNo / static_cast(UnitSize), + // UnitSign); + Out << llvm::format("%0.2f%c", ValNo / static_cast(UnitSize), + UnitSign); + return; +} + } + Out << ValNo; +} + /// PluralNumber - Parse an unsigned integer and advance Start. static unsigned PluralNumber(const char *&Start, const char *End) { // Programming 101: Parse a decimal number :-) @@ -988,6 +1015,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, OutStr); } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { HandleOrdinalModifier((unsigned)Val, OutStr); + } else if (ModifierIs(Modifier, ModifierLen, "human")) { +HandleIntegerHumanModifier(Val, OutStr); } else { assert(ModifierLen == 0 && "Unknown integer modifier"); llvm::raw_svector_ostream(OutStr) << Val; @@ -1006,6 +1035,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, OutStr); } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { HandleOrdinalModifier(Val, OutStr); + } else if (ModifierIs(Modifier, ModifierLen, "human")) { +HandleIntegerHumanModifier(Val, OutStr); } else { assert(ModifierLen == 0 && "Unknown integer modifier"); llvm::raw_svector_ostream(OutStr) << Val; diff --git a/clang/lib/B
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `openmp-offload-sles-build-only` running on `rocm-worker-hw-04-sles` while building `clang` at step 6 "Add check check-clang". Full details are available at: https://lab.llvm.org/buildbot/#/builders/140/builds/10680 Here is the relevant piece of the build log for the reference ``` Step 6 (Add check check-clang) failure: test (failure) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stderr): -- RUN: at line 3: cat /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/clang/test/Interpreter/out-of-process.cpp | /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/clang-repl -oop-executor -orc-runtime | /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/FileCheck /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/clang/test/Interpreter/out-of-process.cpp + /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/clang-repl -oop-executor -orc-runtime + cat /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/clang/test/Interpreter/out-of-process.cpp + /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/FileCheck /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/clang/test/Interpreter/out-of-process.cpp clang-repl: No such file or directory FileCheck error: '' is empty. FileCheck command line: /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.build/bin/FileCheck /home/botworker/bbot/builds/openmp-offload-sles-build/llvm.src/clang/test/Interpreter/out-of-process.cpp -- ``` https://github.com/llvm/llvm-project/pull/110418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + + void remove(StringRef ModuleName); + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +std::shared_ptr +ModuleFileCache::getModule(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return nullptr; + + if (Iter->second.expired()) { +ModuleFiles.erase(Iter); +return nullptr; + } + + return Iter->second.lock(); +} + +void ModuleFileCache::remove(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return; + + ModuleFiles.erase(Iter); kadircet wrote: just `Modulefiles.erase(ModuleName)` ? https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [NFC] Add "human" diagnostic argument format (PR #115835)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff 89aaf2cf68d00e86dfd102a449fc68ff7ea5c85c ccf18e49f884b4430dff70d59fb3236259661f9d --extensions cpp -- clang/lib/Basic/Diagnostic.cpp clang/lib/Basic/SourceManager.cpp clang/utils/TableGen/ClangDiagnosticsEmitter.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 9a3f2aec5d..acd8c00162 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -670,7 +670,7 @@ static void HandleIntegerHumanModifier(unsigned ValNo, for (const auto &[UnitSize, UnitSign] : Units) { if (ValNo >= UnitSize) { // Out << llvm::formatv("{0:F}{1}", ValNo / static_cast(UnitSize), - // UnitSign); + // UnitSign); Out << llvm::format("%0.2f%c", ValNo / static_cast(UnitSize), UnitSign); return; `` https://github.com/llvm/llvm-project/pull/115835 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + + void remove(StringRef ModuleName); + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +std::shared_ptr +ModuleFileCache::getModule(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return nullptr; + + if (Iter->second.expired()) { +ModuleFiles.erase(Iter); +return nullptr; + } + + return Iter->second.lock(); ChuanqiXu9 wrote: Done https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); ChuanqiXu9 wrote: Done https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + + void remove(StringRef ModuleName); + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +std::shared_ptr +ModuleFileCache::getModule(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return nullptr; + + if (Iter->second.expired()) { +ModuleFiles.erase(Iter); +return nullptr; + } + + return Iter->second.lock(); +} + +void ModuleFileCache::remove(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return; + + ModuleFiles.erase(Iter); +} + +/// Collect the directly and indirectly required module names for \param +/// ModuleName in topological order. The \param ModuleName is guaranteed to +/// be the last element in \param ModuleNames. +llvm::SmallVector getAllRequiredModules(ProjectModules &MDB, + StringRef ModuleName) { + llvm::SmallVector ModuleNames; + llvm::StringSet<> ModuleNamesSet; + + auto traversal = [&](StringRef ModuleName, auto recursionHelper) -> void { ChuanqiXu9 wrote: Done https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/ChuanqiXu9 commented: Thanks for reviewing! https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; ChuanqiXu9 wrote: Done https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] [NFC] Add "human" diagnostic argument format (PR #115835)
https://github.com/bricknerb updated https://github.com/llvm/llvm-project/pull/115835 >From ccf18e49f884b4430dff70d59fb3236259661f9d Mon Sep 17 00:00:00 2001 From: Boaz Brickner Date: Tue, 12 Nov 2024 10:19:58 +0100 Subject: [PATCH 1/2] [Clang] [NFC] Add "human" diagnostic argument format This allows formatting large integers in a human friendly way. Example: "5321584" -> "5.32M". Use it where such human numbers are generated manually today. --- clang/docs/InternalsManual.rst| 12 +++ .../clang/Basic/DiagnosticCommonKinds.td | 12 +++ clang/lib/Basic/Diagnostic.cpp| 31 clang/lib/Basic/SourceManager.cpp | 35 +++ .../TableGen/ClangDiagnosticsEmitter.cpp | 7 +++- 5 files changed, 59 insertions(+), 38 deletions(-) diff --git a/clang/docs/InternalsManual.rst b/clang/docs/InternalsManual.rst index b70ec35f3da229..e7dd41c8595bd4 100644 --- a/clang/docs/InternalsManual.rst +++ b/clang/docs/InternalsManual.rst @@ -315,6 +315,18 @@ Description: than ``1`` are not supported. This formatter is currently hard-coded to use English ordinals. +**"human" format** + +Example: + ``"total size is %human0 bytes"`` +Class: + Integers +Description: + This is a formatter which represents the argument number in a human readable + format: the value ``123`` stays ``123``, ``12345`` becomes ``12.34k``, + ``666` becomes ``6.67M``, and so on for 'G' and 'T'. Values less than + ``0`` are not supported. + **"objcclass" format** Example: diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.td b/clang/include/clang/Basic/DiagnosticCommonKinds.td index 457abea0b81471..0c131166aff28d 100644 --- a/clang/include/clang/Basic/DiagnosticCommonKinds.td +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.td @@ -389,14 +389,14 @@ def remark_sloc_usage : Remark< "source manager location address space usage:">, InGroup>, DefaultRemark, ShowInSystemHeader; def note_total_sloc_usage : Note< - "%0B (%1B) in local locations, %2B (%3B) " - "in locations loaded from AST files, for a total of %4B (%5B) " - "(%6%% of available space)">; + "%0B (%human0B) in local locations, %1B (%human1B) " + "in locations loaded from AST files, for a total of %2B (%human2B) " + "(%3%% of available space)">; def note_file_sloc_usage : Note< - "file entered %0 time%s0 using %1B (%2B) of space" - "%plural{0:|: plus %3B (%4B) for macro expansions}3">; + "file entered %0 time%s0 using %1B (%human1B) of space" + "%plural{0:|: plus %2B (%human2B) for macro expansions}2">; def note_file_misc_sloc_usage : Note< - "%0 additional files entered using a total of %1B (%2B) of space">; + "%0 additional files entered using a total of %1B (%human1B) of space">; // Modules def err_module_format_unhandled : Error< diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index e23362fc7af00d..9a3f2aec5df6fa 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -652,6 +652,33 @@ static void HandleOrdinalModifier(unsigned ValNo, Out << ValNo << llvm::getOrdinalSuffix(ValNo); } +// 123 -> "123". +// 1234 -> "1.23k". +// 123456 -> "123.46k". +// 1234567 -> "1.23M". +// 1234567890 -> "1.23G". +// 1234567890123 -> "1.23T". +static void HandleIntegerHumanModifier(unsigned ValNo, + SmallVectorImpl &OutStr) { + static constexpr std::array, 4> Units = { + {{1'000'000'000'000UL, 'T'}, + {1'000'000'000UL, 'G'}, + {1'000'000UL, 'M'}, + {1'000UL, 'k'}}}; + + llvm::raw_svector_ostream Out(OutStr); + for (const auto &[UnitSize, UnitSign] : Units) { +if (ValNo >= UnitSize) { + // Out << llvm::formatv("{0:F}{1}", ValNo / static_cast(UnitSize), + // UnitSign); + Out << llvm::format("%0.2f%c", ValNo / static_cast(UnitSize), + UnitSign); + return; +} + } + Out << ValNo; +} + /// PluralNumber - Parse an unsigned integer and advance Start. static unsigned PluralNumber(const char *&Start, const char *End) { // Programming 101: Parse a decimal number :-) @@ -988,6 +1015,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, OutStr); } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { HandleOrdinalModifier((unsigned)Val, OutStr); + } else if (ModifierIs(Modifier, ModifierLen, "human")) { +HandleIntegerHumanModifier(Val, OutStr); } else { assert(ModifierLen == 0 && "Unknown integer modifier"); llvm::raw_svector_ostream(OutStr) << Val; @@ -1006,6 +1035,8 @@ FormatDiagnostic(const char *DiagStr, const char *DiagEnd, OutStr); } else if (ModifierIs(Modifier, ModifierLen, "ordinal")) { HandleOrdinalModifier(Val, OutStr); + } else if (ModifierIs(Modifier, ModifierLen, "human")) { +HandleIntegerHumanModifier(
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `llvm-clang-aarch64-darwin` running on `doug-worker-4` while building `clang` at step 6 "test-build-unified-tree-check-all". Full details are available at: https://lab.llvm.org/buildbot/#/builders/190/builds/9307 Here is the relevant piece of the build log for the reference ``` Step 6 (test-build-unified-tree-check-all) failure: test (failure) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stderr): -- RUN: at line 3: cat /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Interpreter/out-of-process.cpp | /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/clang-repl -oop-executor -orc-runtime | /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Interpreter/out-of-process.cpp + cat /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Interpreter/out-of-process.cpp + /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/clang-repl -oop-executor -orc-runtime + /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Interpreter/out-of-process.cpp clang-repl: No such file or directory FileCheck error: '' is empty. FileCheck command line: /Users/buildbot/buildbot-root/aarch64-darwin/build/bin/FileCheck /Users/buildbot/buildbot-root/aarch64-darwin/llvm-project/clang/test/Interpreter/out-of-process.cpp -- ``` https://github.com/llvm/llvm-project/pull/110418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/ChuanqiXu9 updated https://github.com/llvm/llvm-project/pull/106683 >From 15aa6af1f5d22e4b837e8e2fd49469310ffbe7f1 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Fri, 30 Aug 2024 15:11:07 +0800 Subject: [PATCH 1/7] [clangd] [Modules] Support Reusable Modules Builder --- clang-tools-extra/clangd/ModulesBuilder.cpp | 375 ++ clang-tools-extra/clangd/ModulesBuilder.h | 8 +- .../unittests/PrerequisiteModulesTest.cpp | 36 ++ 3 files changed, 344 insertions(+), 75 deletions(-) diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp index 97f67ddf5495a2..c4fb3d4010d370 100644 --- a/clang-tools-extra/clangd/ModulesBuilder.cpp +++ b/clang-tools-extra/clangd/ModulesBuilder.cpp @@ -13,6 +13,7 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/InMemoryModuleCache.h" +#include "llvm/ADT/ScopeExit.h" namespace clang { namespace clangd { @@ -192,33 +193,27 @@ bool IsModuleFilesUpToDate( }); } -// StandalonePrerequisiteModules - stands for PrerequisiteModules for which all +// ReusablePrerequisiteModules - stands for PrerequisiteModules for which all // the required modules are built successfully. All the module files -// are owned by the StandalonePrerequisiteModules class. -// -// Any of the built module files won't be shared with other instances of the -// class. So that we can avoid worrying thread safety. -// -// We don't need to worry about duplicated module names here since the standard -// guarantees the module names should be unique to a program. -class StandalonePrerequisiteModules : public PrerequisiteModules { +// are owned by the modules builder. +class ReusablePrerequisiteModules : public PrerequisiteModules { public: - StandalonePrerequisiteModules() = default; + ReusablePrerequisiteModules() = default; - StandalonePrerequisiteModules(const StandalonePrerequisiteModules &) = delete; - StandalonePrerequisiteModules - operator=(const StandalonePrerequisiteModules &) = delete; - StandalonePrerequisiteModules(StandalonePrerequisiteModules &&) = delete; - StandalonePrerequisiteModules - operator=(StandalonePrerequisiteModules &&) = delete; + ReusablePrerequisiteModules(const ReusablePrerequisiteModules &) = delete; + ReusablePrerequisiteModules + operator=(const ReusablePrerequisiteModules &) = delete; + ReusablePrerequisiteModules(ReusablePrerequisiteModules &&) = delete; + ReusablePrerequisiteModules + operator=(ReusablePrerequisiteModules &&) = delete; - ~StandalonePrerequisiteModules() override = default; + ~ReusablePrerequisiteModules() override = default; void adjustHeaderSearchOptions(HeaderSearchOptions &Options) const override { // Appending all built module files. for (auto &RequiredModule : RequiredModules) Options.PrebuiltModuleFiles.insert_or_assign( - RequiredModule.ModuleName, RequiredModule.ModuleFilePath); + RequiredModule->ModuleName, RequiredModule->ModuleFilePath); } bool canReuse(const CompilerInvocation &CI, @@ -228,54 +223,30 @@ class StandalonePrerequisiteModules : public PrerequisiteModules { return BuiltModuleNames.contains(ModuleName); } - void addModuleFile(llvm::StringRef ModuleName, - llvm::StringRef ModuleFilePath) { -RequiredModules.emplace_back(ModuleName, ModuleFilePath); -BuiltModuleNames.insert(ModuleName); + void addModuleFile(std::shared_ptr BMI) { +BuiltModuleNames.insert(BMI->ModuleName); +RequiredModules.emplace_back(std::move(BMI)); } private: - llvm::SmallVector RequiredModules; + mutable llvm::SmallVector, 8> RequiredModules; // A helper class to speedup the query if a module is built. llvm::StringSet<> BuiltModuleNames; }; -// Build a module file for module with `ModuleName`. The information of built -// module file are stored in \param BuiltModuleFiles. -llvm::Error buildModuleFile(llvm::StringRef ModuleName, -const GlobalCompilationDatabase &CDB, -const ThreadsafeFS &TFS, ProjectModules &MDB, -PathRef ModuleFilesPrefix, -StandalonePrerequisiteModules &BuiltModuleFiles) { - if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName)) -return llvm::Error::success(); - - PathRef ModuleUnitFileName = MDB.getSourceForModuleName(ModuleName); - // It is possible that we're meeting third party modules (modules whose - // source are not in the project. e.g, the std module may be a third-party - // module for most projects) or something wrong with the implementation of - // ProjectModules. - // FIXME: How should we treat third party modules here? If we want to ignore - // third party modules, we should return true instead of false here. - // Currently we simply bail out. - if (ModuleUnitFileName.empty()) -return llvm::createStringErro
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/kadircet approved this pull request. thanks a lot for bearing with me! LGTM, let's ship it! https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `llvm-clang-x86_64-gcc-ubuntu` running on `sie-linux-worker3` while building `clang` at step 6 "test-build-unified-tree-check-all". Full details are available at: https://lab.llvm.org/buildbot/#/builders/174/builds/8290 Here is the relevant piece of the build log for the reference ``` Step 6 (test-build-unified-tree-check-all) failure: test (failure) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stderr): -- RUN: at line 3: cat /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/clang/test/Interpreter/out-of-process.cpp | /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/bin/clang-repl -oop-executor -orc-runtime | /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/clang/test/Interpreter/out-of-process.cpp + /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/bin/clang-repl -oop-executor -orc-runtime + cat /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/clang/test/Interpreter/out-of-process.cpp + /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/clang/test/Interpreter/out-of-process.cpp clang-repl: No such file or directory FileCheck error: '' is empty. FileCheck command line: /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-clang-x86_64-gcc-ubuntu/llvm-project/clang/test/Interpreter/out-of-process.cpp -- ``` https://github.com/llvm/llvm-project/pull/110418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `clang-armv8-quick` running on `linaro-clang-armv8-quick` while building `clang` at step 5 "ninja check 1". Full details are available at: https://lab.llvm.org/buildbot/#/builders/154/builds/7335 Here is the relevant piece of the build log for the reference ``` Step 5 (ninja check 1) failure: stage 1 checked (failure) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stderr): -- RUN: at line 3: cat /home/tcwg-buildbot/worker/clang-armv8-quick/llvm/clang/test/Interpreter/out-of-process.cpp | /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/bin/clang-repl -oop-executor -orc-runtime | /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/bin/FileCheck /home/tcwg-buildbot/worker/clang-armv8-quick/llvm/clang/test/Interpreter/out-of-process.cpp + /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/bin/clang-repl -oop-executor -orc-runtime + cat /home/tcwg-buildbot/worker/clang-armv8-quick/llvm/clang/test/Interpreter/out-of-process.cpp + /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/bin/FileCheck /home/tcwg-buildbot/worker/clang-armv8-quick/llvm/clang/test/Interpreter/out-of-process.cpp clang-repl: No such file or directory FileCheck error: '' is empty. FileCheck command line: /home/tcwg-buildbot/worker/clang-armv8-quick/stage1/bin/FileCheck /home/tcwg-buildbot/worker/clang-armv8-quick/llvm/clang/test/Interpreter/out-of-process.cpp -- ``` https://github.com/llvm/llvm-project/pull/110418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
https://github.com/ChuanqiXu9 edited https://github.com/llvm/llvm-project/pull/106683 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [TableGen] Use heterogenous lookups with std::map (NFC) (PR #115810)
https://github.com/nikic approved this pull request. https://github.com/llvm/llvm-project/pull/115810 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] [clangd] [Modules] Support Reusable Modules Builder (PR #106683)
@@ -316,36 +295,187 @@ llvm::Error buildModuleFile(llvm::StringRef ModuleName, if (Clang->getDiagnostics().hasErrorOccurred()) return llvm::createStringError("Compilation failed"); - BuiltModuleFiles.addModuleFile(ModuleName, Inputs.CompileCommand.Output); - return llvm::Error::success(); + return ModuleFile{ModuleName, Inputs.CompileCommand.Output}; } + +bool ReusablePrerequisiteModules::canReuse( +const CompilerInvocation &CI, +llvm::IntrusiveRefCntPtr VFS) const { + if (RequiredModules.empty()) +return true; + + SmallVector BMIPaths; + for (auto &MF : RequiredModules) +BMIPaths.push_back(MF->getModuleFilePath()); + return IsModuleFilesUpToDate(BMIPaths, *this, VFS); +} + +class ModuleFileCache { +public: + ModuleFileCache(const GlobalCompilationDatabase &CDB) : CDB(CDB) {} + const GlobalCompilationDatabase &getCDB() const { return CDB; } + + std::shared_ptr getModule(StringRef ModuleName); + + void add(StringRef ModuleName, std::shared_ptr ModuleFile) { +std::lock_guard Lock(ModuleFilesMutex); + +ModuleFiles.insert_or_assign(ModuleName, ModuleFile); + } + + void remove(StringRef ModuleName); + +private: + const GlobalCompilationDatabase &CDB; + + llvm::StringMap> ModuleFiles; + // Mutex to guard accesses to ModuleFiles. + std::mutex ModuleFilesMutex; +}; + +std::shared_ptr +ModuleFileCache::getModule(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return nullptr; + + if (Iter->second.expired()) { +ModuleFiles.erase(Iter); +return nullptr; + } + + return Iter->second.lock(); +} + +void ModuleFileCache::remove(StringRef ModuleName) { + std::lock_guard Lock(ModuleFilesMutex); + + auto Iter = ModuleFiles.find(ModuleName); + if (Iter == ModuleFiles.end()) +return; + + ModuleFiles.erase(Iter); +} + +/// Collect the directly and indirectly required module names for \param +/// ModuleName in topological order. The \param ModuleName is guaranteed to +/// be the last element in \param ModuleNames. +llvm::SmallVector getAllRequiredModules(ProjectModules &MDB, + StringRef ModuleName) { + llvm::SmallVector ModuleNames; + llvm::StringSet<> ModuleNamesSet; + + auto traversal = [&](StringRef ModuleName, auto recursionHelper) -> void { +ModuleNamesSet.insert(ModuleName); + +for (StringRef RequiredModuleName : + MDB.getRequiredModules(MDB.getSourceForModuleName(ModuleName))) + if (ModuleNamesSet.insert(RequiredModuleName).second) +recursionHelper(RequiredModuleName, recursionHelper); + +ModuleNames.push_back(ModuleName); + }; + traversal(ModuleName, traversal); + + return ModuleNames; +} + } // namespace +class ModulesBuilder::ModulesBuilderImpl { +public: + ModulesBuilderImpl(const GlobalCompilationDatabase &CDB) : Cache(CDB) {} + + const GlobalCompilationDatabase &getCDB() const { return Cache.getCDB(); } + + llvm::Error + getOrBuildModuleFile(StringRef ModuleName, const ThreadsafeFS &TFS, + ProjectModules &MDB, + ReusablePrerequisiteModules &BuiltModuleFiles); + +private: + ModuleFileCache Cache; +}; + +llvm::Error ModulesBuilder::ModulesBuilderImpl::getOrBuildModuleFile( +StringRef ModuleName, const ThreadsafeFS &TFS, ProjectModules &MDB, +ReusablePrerequisiteModules &BuiltModuleFiles) { + if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName)) +return llvm::Error::success(); + + PathRef ModuleUnitFileName = MDB.getSourceForModuleName(ModuleName); + /// It is possible that we're meeting third party modules (modules whose + /// source are not in the project. e.g, the std module may be a third-party + /// module for most project) or something wrong with the implementation of + /// ProjectModules. + /// FIXME: How should we treat third party modules here? If we want to ignore + /// third party modules, we should return true instead of false here. + /// Currently we simply bail out. + if (ModuleUnitFileName.empty()) +return llvm::createStringError( +llvm::formatv("Don't get the module unit for module {0}", ModuleName)); + + // Get Required modules in topological order. + auto ReqModuleNames = getAllRequiredModules(MDB, ModuleName); + for (llvm::StringRef ReqModuleName : ReqModuleNames) { +if (BuiltModuleFiles.isModuleUnitBuilt(ModuleName)) + continue; + +if (auto Cached = Cache.getModule(ReqModuleName)) { + if (IsModuleFileUpToDate(Cached->getModuleFilePath(), BuiltModuleFiles, + TFS.view(std::nullopt))) { +log("Reusing module {0} from {1}", ModuleName, +Cached->getModuleFilePath()); +BuiltModuleFiles.addModuleFile(std::move(Cached)); +continue; + } + Cache.remove(ReqModuleName); +} + +llvm::SmallString<256> ModuleFilesPrefix = +getUniqueModuleFilesPa
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `clang-aarch64-quick` running on `linaro-clang-aarch64-quick` while building `clang` at step 5 "ninja check 1". Full details are available at: https://lab.llvm.org/buildbot/#/builders/65/builds/7627 Here is the relevant piece of the build log for the reference ``` Step 5 (ninja check 1) failure: stage 1 checked (failure) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stderr): -- RUN: at line 3: cat /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Interpreter/out-of-process.cpp | /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/clang-repl -oop-executor -orc-runtime | /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/FileCheck /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Interpreter/out-of-process.cpp + /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/FileCheck /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Interpreter/out-of-process.cpp + cat /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Interpreter/out-of-process.cpp + /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/clang-repl -oop-executor -orc-runtime clang-repl: No such file or directory FileCheck error: '' is empty. FileCheck command line: /home/tcwg-buildbot/worker/clang-aarch64-quick/stage1/bin/FileCheck /home/tcwg-buildbot/worker/clang-aarch64-quick/llvm/clang/test/Interpreter/out-of-process.cpp -- ``` https://github.com/llvm/llvm-project/pull/110418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang-Repl] Add support for out-of-process execution. (PR #110418)
llvm-ci wrote: LLVM Buildbot has detected a new failure on builder `llvm-clang-x86_64-sie-win` running on `sie-win-worker` while building `clang` at step 7 "test-build-unified-tree-check-all". Full details are available at: https://lab.llvm.org/buildbot/#/builders/46/builds/7740 Here is the relevant piece of the build log for the reference ``` Step 7 (test-build-unified-tree-check-all) failure: test (failure) TEST 'Clang :: Interpreter/out-of-process.cpp' FAILED Exit Code: 2 Command Output (stdout): -- # RUN: at line 3 cat Z:\b\llvm-clang-x86_64-sie-win\llvm-project\clang\test\Interpreter\out-of-process.cpp | z:\b\llvm-clang-x86_64-sie-win\build\bin\clang-repl.exe -oop-executor -orc-runtime | z:\b\llvm-clang-x86_64-sie-win\build\bin\filecheck.exe Z:\b\llvm-clang-x86_64-sie-win\llvm-project\clang\test\Interpreter\out-of-process.cpp # executed command: cat 'Z:\b\llvm-clang-x86_64-sie-win\llvm-project\clang\test\Interpreter\out-of-process.cpp' # .---command stdout # | // REQUIRES: host-supports-jit # | # | // RUN: cat %s | clang-repl -oop-executor -orc-runtime | FileCheck %s # | # | extern "C" int printf(const char *, ...); # | # | int intVar = 0; # | double doubleVar = 3.14; # | %undo # | double doubleVar = 2.71; # | # | auto r1 = printf("intVar = %d\n", intVar); # | // CHECK: intVar = 0 # | auto r2 = printf("doubleVar = %.2f\n", doubleVar); # | // CHECK: doubleVar = 2.71 # | # | // Test redefinition with inline and static functions. # | int add(int a, int b, int c) { return a + b + c; } # | %undo // Revert to the initial version of add # | inline int add(int a, int b) { return a + b; } # | # | auto r3 = printf("add(1, 2) = %d\n", add(1, 2)); # | // CHECK-NEXT: add(1, 2) = 3 # | # | // Test inline and lambda functions with variations. # | inline int square(int x) { return x * x; } # | auto lambdaSquare = [](int x) { return x * x; }; # | auto lambdaMult = [](int a, int b) { return a * b; }; # | # | auto r4 = printf("square(4) = %d\n", square(4)); # | // CHECK-NEXT: square(4) = 16 # | auto lambda_r1 = printf("lambdaSquare(5) = %d\n", lambdaSquare(5)); # | // CHECK-NEXT: lambdaSquare(5) = 25 # | auto lambda_r2 = printf("lambdaMult(2, 3) = %d\n", lambdaMult(2, 3)); # | // CHECK-NEXT: lambdaMult(2, 3) = 6 # | # | %undo // Undo previous lambda assignments # | auto lambda_r3 = lambdaMult(3, 4); // Should fail or revert to the original lambda # | # | // Test weak and strong symbol linkage. # | int __attribute__((weak)) weakFunc() { return 42; } ... ``` https://github.com/llvm/llvm-project/pull/110418 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] enhance diagnostic message for __builtin_bit_cast size mismatch (PR #115940)
https://github.com/a-tarasyuk created https://github.com/llvm/llvm-project/pull/115940 Fixes #115870 >From 2132ccb175f1eb37a4b4e60c8ee8ade90ba5bb18 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Tue, 12 Nov 2024 23:09:06 +0200 Subject: [PATCH] [Clang] enhance diagnostic message for __builtin_bit_cast size mismatch --- clang/docs/ReleaseNotes.rst | 2 ++ clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ++- clang/lib/Sema/SemaCast.cpp | 3 ++- clang/test/AST/ByteCode/builtin-bit-cast.cpp | 4 ++-- clang/test/SemaCXX/builtin-bit-cast.cpp | 2 +- clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ffed972ed120d0..d401dbfaf23aaa 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -528,6 +528,8 @@ Improvements to Clang's diagnostics - Clang now diagnoses ``[[deprecated]]`` attribute usage on local variables (#GH90073). +- Improved diagnostic message for __builtin_bit_cast size mismatch (#GH115870). + Improvements to Clang's time-trace -- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 509d45c0867590..9bf3196c4f7cd3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12354,7 +12354,8 @@ def err_preserve_enum_value_not_const: Error< def err_bit_cast_non_trivially_copyable : Error< "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">; def err_bit_cast_type_size_mismatch : Error< - "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">; + "__builtin_bit_cast source type %0 size (%1 %plural{1:byte|:bytes}1) " + "does not match destination type %2 size (%3 %plural{1:byte|:bytes}3)">; // SYCL-specific diagnostics def warn_sycl_kernel_num_of_template_params : Warning< diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 6ac6201843476b..211e4dbfe682e7 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -3283,7 +3283,8 @@ void CastOperation::CheckBuiltinBitCast() { CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType); if (DestSize != SourceSize) { Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch) -<< (int)SourceSize.getQuantity() << (int)DestSize.getQuantity(); + << SrcType << (int)SourceSize.getQuantity() + << DestType << (int)DestSize.getQuantity(); SrcExpr = ExprError(); return; } diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp index 7d1fcbda10965f..62f5e9eff4b1fd 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp @@ -496,7 +496,7 @@ typedef bool bool32 __attribute__((ext_vector_type(32))); typedef bool bool128 __attribute__((ext_vector_type(128))); static_assert(bit_cast(bool8{1,0,1,0,1,0,1,0}) == (LITTLE_END ? 0x55 : 0xAA), ""); -constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source size does not equal destination size (4 vs 1)}} +constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source type 'int' size (4 bytes) does not match destination type 'bool8' (vector of 8 'bool' values) size (1 byte)}} #if 0 static_assert(check_round_trip(static_cast(0)), ""); static_assert(check_round_trip(static_cast(1)), ""); @@ -535,5 +535,5 @@ namespace test_complex { static_assert(TF.A == 1.0f && TF.B == 2.0f); constexpr double D = __builtin_bit_cast(double, test_float_complex); - constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source size does not equal destination size}} + constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source type 'const _Complex unsigned int' size (8 bytes) does not match destination type 'int' size (4 bytes)}} } diff --git a/clang/test/SemaCXX/builtin-bit-cast.cpp b/clang/test/SemaCXX/builtin-bit-cast.cpp index 87919d9d9d2865..cce700dffb6cdf 100644 --- a/clang/test/SemaCXX/builtin-bit-cast.cpp +++ b/clang/test/SemaCXX/builtin-bit-cast.cpp @@ -24,7 +24,7 @@ void test1() { void test2() { constexpr int i = 0; - // expected-error@+1{{__builtin_bit_cast source size does not equal destination size (4 vs 1)}} + // expected-error@+1{{__builtin_bit_cast source type 'const int' size (4 bytes) does not match destination type 'char' size (1 byte)}} constexpr char c = __builtin_bit_cast(char, i); } diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp index 5ddb77b35ff145..2e26c31d3613de 100644 --- a/clang/test/SemaCXX/constexpr-builtin-bit-cas
[clang-tools-extra] Extend bugprone-use-after-move check to handle std::optional::reset() and std::any::reset() (PR #114255)
https://github.com/higher-performance updated https://github.com/llvm/llvm-project/pull/114255 >From 873f5a25b2a381b8d57aa2671bf2f0dc97483142 Mon Sep 17 00:00:00 2001 From: higher-performance Date: Wed, 30 Oct 2024 12:01:00 -0400 Subject: [PATCH] Extend bugprone-use-after-move check to handle std::optional::reset() and std::any::reset() similarly to smart pointers --- .../clang-tidy/bugprone/UseAfterMoveCheck.cpp | 9 +++-- clang-tools-extra/docs/ReleaseNotes.rst | 5 +++ .../checks/bugprone/use-after-move.rst| 15 --- .../checkers/bugprone/use-after-move.cpp | 39 ++- 4 files changed, 56 insertions(+), 12 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp index 8f4b5e8092ddaa..960133159dbbf5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -315,9 +315,10 @@ void UseAfterMoveFinder::getReinits( "::std::unordered_map", "::std::unordered_multiset", "::std::unordered_multimap")); - auto StandardSmartPointerTypeMatcher = hasType(hasUnqualifiedDesugaredType( - recordType(hasDeclaration(cxxRecordDecl(hasAnyName( - "::std::unique_ptr", "::std::shared_ptr", "::std::weak_ptr")); + auto StandardResettableOwnerTypeMatcher = hasType( + hasUnqualifiedDesugaredType(recordType(hasDeclaration(cxxRecordDecl( + hasAnyName("::std::unique_ptr", "::std::shared_ptr", + "::std::weak_ptr", "::std::optional", "::std::any")); // Matches different types of reinitialization. auto ReinitMatcher = @@ -340,7 +341,7 @@ void UseAfterMoveFinder::getReinits( callee(cxxMethodDecl(hasAnyName("clear", "assign", // reset() on standard smart pointers. cxxMemberCallExpr( - on(expr(DeclRefMatcher, StandardSmartPointerTypeMatcher)), + on(expr(DeclRefMatcher, StandardResettableOwnerTypeMatcher)), callee(cxxMethodDecl(hasName("reset", // Methods that have the [[clang::reinitializes]] attribute. cxxMemberCallExpr( diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index db971f08ca3dbc..096ce6af4f0ac2 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -191,6 +191,11 @@ Changes in existing checks ` check to allow specifying additional functions to match. +- Improved :doc:`bugprone-use-after-move + ` to avoid triggering on + ``reset()`` calls on moved-from ``std::optional`` and ``std::any`` objects, + similarly to smart pointers. + - Improved :doc:`cert-flp30-c ` check to fix false positive that floating point variable is only used in increment expression. diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/use-after-move.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/use-after-move.rst index 08bb5374bab1f4..965fc2d3c29e24 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/use-after-move.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/use-after-move.rst @@ -196,11 +196,13 @@ Any occurrence of the moved variable that is not a reinitialization (see below) is considered to be a use. An exception to this are objects of type ``std::unique_ptr``, -``std::shared_ptr`` and ``std::weak_ptr``, which have defined move behavior -(objects of these classes are guaranteed to be empty after they have been moved -from). Therefore, an object of these classes will only be considered to be used -if it is dereferenced, i.e. if ``operator*``, ``operator->`` or ``operator[]`` -(in the case of ``std::unique_ptr``) is called on it. +``std::shared_ptr``, ``std::weak_ptr``, ``std::optional``, and ``std::any``. +An exception to this are objects of type ``std::unique_ptr``, +``std::shared_ptr``, ``std::weak_ptr``, ``std::optional``, and ``std::any``, which +can be reinitialized via ``reset``. For smart pointers specifically, the +moved-from objects have a well-defined state of being ``nullptr``s, and only +``operator*``, ``operator->`` and ``operator[]`` are considered bad accesses as +they would be dereferencing a ``nullptr``. If multiple uses occur after a move, only the first of these is flagged. @@ -222,7 +224,8 @@ The check considers a variable to be reinitialized in the following cases: ``unordered_multimap``. - ``reset()`` is called on the variable and the variable is of type -``std::unique_ptr``, ``std::shared_ptr`` or ``std::weak_ptr``. +``std::unique_ptr``, ``std::shared_ptr``, ``std::weak_ptr``, +``std::optional``, or ``std::any``. - A member function marked with the ``[[clang::reinitializes]]`` attribute is called on the variable. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/u
[clang] [clang][Fuchsia] Have global dtors use llvm.global_dtors over atexit (PR #115788)
efriedma-quic wrote: Also, I'm not sure objects are destroyed in the correct order. - As far as I know, fini_array existed at the time the Itanium ABI was written; I assume it intentionally was not used because there were issues ensuring the correct objects are destroyed in the correct order. https://github.com/llvm/llvm-project/pull/115788 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] enhance diagnostic message for __builtin_bit_cast size mismatch (PR #115940)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Oleksandr T. (a-tarasyuk) Changes Fixes #115870 --- Full diff: https://github.com/llvm/llvm-project/pull/115940.diff 6 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+2) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+2-1) - (modified) clang/lib/Sema/SemaCast.cpp (+2-1) - (modified) clang/test/AST/ByteCode/builtin-bit-cast.cpp (+2-2) - (modified) clang/test/SemaCXX/builtin-bit-cast.cpp (+1-1) - (modified) clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp (+1-1) ``diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ffed972ed120d0..d401dbfaf23aaa 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -528,6 +528,8 @@ Improvements to Clang's diagnostics - Clang now diagnoses ``[[deprecated]]`` attribute usage on local variables (#GH90073). +- Improved diagnostic message for __builtin_bit_cast size mismatch (#GH115870). + Improvements to Clang's time-trace -- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 509d45c0867590..9bf3196c4f7cd3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12354,7 +12354,8 @@ def err_preserve_enum_value_not_const: Error< def err_bit_cast_non_trivially_copyable : Error< "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">; def err_bit_cast_type_size_mismatch : Error< - "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">; + "__builtin_bit_cast source type %0 size (%1 %plural{1:byte|:bytes}1) " + "does not match destination type %2 size (%3 %plural{1:byte|:bytes}3)">; // SYCL-specific diagnostics def warn_sycl_kernel_num_of_template_params : Warning< diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 6ac6201843476b..211e4dbfe682e7 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -3283,7 +3283,8 @@ void CastOperation::CheckBuiltinBitCast() { CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType); if (DestSize != SourceSize) { Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch) -<< (int)SourceSize.getQuantity() << (int)DestSize.getQuantity(); + << SrcType << (int)SourceSize.getQuantity() + << DestType << (int)DestSize.getQuantity(); SrcExpr = ExprError(); return; } diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp index 7d1fcbda10965f..62f5e9eff4b1fd 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp @@ -496,7 +496,7 @@ typedef bool bool32 __attribute__((ext_vector_type(32))); typedef bool bool128 __attribute__((ext_vector_type(128))); static_assert(bit_cast(bool8{1,0,1,0,1,0,1,0}) == (LITTLE_END ? 0x55 : 0xAA), ""); -constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source size does not equal destination size (4 vs 1)}} +constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source type 'int' size (4 bytes) does not match destination type 'bool8' (vector of 8 'bool' values) size (1 byte)}} #if 0 static_assert(check_round_trip(static_cast(0)), ""); static_assert(check_round_trip(static_cast(1)), ""); @@ -535,5 +535,5 @@ namespace test_complex { static_assert(TF.A == 1.0f && TF.B == 2.0f); constexpr double D = __builtin_bit_cast(double, test_float_complex); - constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source size does not equal destination size}} + constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source type 'const _Complex unsigned int' size (8 bytes) does not match destination type 'int' size (4 bytes)}} } diff --git a/clang/test/SemaCXX/builtin-bit-cast.cpp b/clang/test/SemaCXX/builtin-bit-cast.cpp index 87919d9d9d2865..cce700dffb6cdf 100644 --- a/clang/test/SemaCXX/builtin-bit-cast.cpp +++ b/clang/test/SemaCXX/builtin-bit-cast.cpp @@ -24,7 +24,7 @@ void test1() { void test2() { constexpr int i = 0; - // expected-error@+1{{__builtin_bit_cast source size does not equal destination size (4 vs 1)}} + // expected-error@+1{{__builtin_bit_cast source type 'const int' size (4 bytes) does not match destination type 'char' size (1 byte)}} constexpr char c = __builtin_bit_cast(char, i); } diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp index 5ddb77b35ff145..2e26c31d3613de 100644 --- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp +++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp @@ -525,5 +525,5 @@ namespace test_complex { static_assert(TF.A == 1.0f && TF.B == 2.0f);
[clang] [Clang] enhance diagnostic message for __builtin_bit_cast size mismatch (PR #115940)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff d922045381347a9d5c7301bf870ee0482bfdf0d4 2132ccb175f1eb37a4b4e60c8ee8ade90ba5bb18 --extensions cpp -- clang/lib/Sema/SemaCast.cpp clang/test/AST/ByteCode/builtin-bit-cast.cpp clang/test/SemaCXX/builtin-bit-cast.cpp clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 211e4dbfe6..fea7a15c31 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -3283,8 +3283,8 @@ void CastOperation::CheckBuiltinBitCast() { CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType); if (DestSize != SourceSize) { Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch) - << SrcType << (int)SourceSize.getQuantity() - << DestType << (int)DestSize.getQuantity(); +<< SrcType << (int)SourceSize.getQuantity() << DestType +<< (int)DestSize.getQuantity(); SrcExpr = ExprError(); return; } `` https://github.com/llvm/llvm-project/pull/115940 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [OpenMP][OMPIRBuilder] Handle non-failing calls properly (PR #115863)
Meinersbur wrote: `cantFail` is not guaranteed to crash, e.g. in `-DLLVM_ENABLE_ASSERTIONS=OFF -DLLVM_UNREACHABLE_OPTIMIZE=ON`. I think this is fine for implementation code, for which `LLVM_UNREACHABLE_OPTIMIZE` is meant to improve performance, but for unittests such tests could silently pass in release builds. Ideas: * `ASSERT_FALSE(errorToBool(Err))` * `if (Err) report_fatal_error(Err)` * Some new helper function https://github.com/llvm/llvm-project/pull/115863 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] enhance diagnostic message for __builtin_bit_cast size mismatch (PR #115940)
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/115940 >From 2132ccb175f1eb37a4b4e60c8ee8ade90ba5bb18 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Tue, 12 Nov 2024 23:09:06 +0200 Subject: [PATCH 1/2] [Clang] enhance diagnostic message for __builtin_bit_cast size mismatch --- clang/docs/ReleaseNotes.rst | 2 ++ clang/include/clang/Basic/DiagnosticSemaKinds.td | 3 ++- clang/lib/Sema/SemaCast.cpp | 3 ++- clang/test/AST/ByteCode/builtin-bit-cast.cpp | 4 ++-- clang/test/SemaCXX/builtin-bit-cast.cpp | 2 +- clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp | 2 +- 6 files changed, 10 insertions(+), 6 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ffed972ed120d0..d401dbfaf23aaa 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -528,6 +528,8 @@ Improvements to Clang's diagnostics - Clang now diagnoses ``[[deprecated]]`` attribute usage on local variables (#GH90073). +- Improved diagnostic message for __builtin_bit_cast size mismatch (#GH115870). + Improvements to Clang's time-trace -- diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 509d45c0867590..9bf3196c4f7cd3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12354,7 +12354,8 @@ def err_preserve_enum_value_not_const: Error< def err_bit_cast_non_trivially_copyable : Error< "__builtin_bit_cast %select{source|destination}0 type must be trivially copyable">; def err_bit_cast_type_size_mismatch : Error< - "__builtin_bit_cast source size does not equal destination size (%0 vs %1)">; + "__builtin_bit_cast source type %0 size (%1 %plural{1:byte|:bytes}1) " + "does not match destination type %2 size (%3 %plural{1:byte|:bytes}3)">; // SYCL-specific diagnostics def warn_sycl_kernel_num_of_template_params : Warning< diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp index 6ac6201843476b..211e4dbfe682e7 100644 --- a/clang/lib/Sema/SemaCast.cpp +++ b/clang/lib/Sema/SemaCast.cpp @@ -3283,7 +3283,8 @@ void CastOperation::CheckBuiltinBitCast() { CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType); if (DestSize != SourceSize) { Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch) -<< (int)SourceSize.getQuantity() << (int)DestSize.getQuantity(); + << SrcType << (int)SourceSize.getQuantity() + << DestType << (int)DestSize.getQuantity(); SrcExpr = ExprError(); return; } diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp index 7d1fcbda10965f..62f5e9eff4b1fd 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp @@ -496,7 +496,7 @@ typedef bool bool32 __attribute__((ext_vector_type(32))); typedef bool bool128 __attribute__((ext_vector_type(128))); static_assert(bit_cast(bool8{1,0,1,0,1,0,1,0}) == (LITTLE_END ? 0x55 : 0xAA), ""); -constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source size does not equal destination size (4 vs 1)}} +constexpr bool8 b8 = __builtin_bit_cast(bool8, 0x55); // both-error {{__builtin_bit_cast source type 'int' size (4 bytes) does not match destination type 'bool8' (vector of 8 'bool' values) size (1 byte)}} #if 0 static_assert(check_round_trip(static_cast(0)), ""); static_assert(check_round_trip(static_cast(1)), ""); @@ -535,5 +535,5 @@ namespace test_complex { static_assert(TF.A == 1.0f && TF.B == 2.0f); constexpr double D = __builtin_bit_cast(double, test_float_complex); - constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source size does not equal destination size}} + constexpr int M = __builtin_bit_cast(int, test_int_complex); // both-error {{__builtin_bit_cast source type 'const _Complex unsigned int' size (8 bytes) does not match destination type 'int' size (4 bytes)}} } diff --git a/clang/test/SemaCXX/builtin-bit-cast.cpp b/clang/test/SemaCXX/builtin-bit-cast.cpp index 87919d9d9d2865..cce700dffb6cdf 100644 --- a/clang/test/SemaCXX/builtin-bit-cast.cpp +++ b/clang/test/SemaCXX/builtin-bit-cast.cpp @@ -24,7 +24,7 @@ void test1() { void test2() { constexpr int i = 0; - // expected-error@+1{{__builtin_bit_cast source size does not equal destination size (4 vs 1)}} + // expected-error@+1{{__builtin_bit_cast source type 'const int' size (4 bytes) does not match destination type 'char' size (1 byte)}} constexpr char c = __builtin_bit_cast(char, i); } diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp index 5ddb77b35ff145..2e26c31d3613de 100644 --- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp +++ b
[clang] f539674 - [clang][flang] Support -time in both clang and flang
Author: Tarun Prabhu Date: 2024-11-12T14:27:22-07:00 New Revision: f5396748c7da3d9f278fcd42e2a10a3214920d82 URL: https://github.com/llvm/llvm-project/commit/f5396748c7da3d9f278fcd42e2a10a3214920d82 DIFF: https://github.com/llvm/llvm-project/commit/f5396748c7da3d9f278fcd42e2a10a3214920d82.diff LOG: [clang][flang] Support -time in both clang and flang The -time option prints timing information for the subcommands (compiler, linker) in a format similar to that used by gcc/gfortran. This partially addresses requests from #89888 Added: clang/test/Driver/time.c flang/test/Driver/time.f90 Modified: clang/include/clang/Driver/Options.td clang/lib/Driver/Compilation.cpp clang/lib/Driver/Driver.cpp Removed: diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9fb7f8bb6489b0..0bbab21120f2b6 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -5896,6 +5896,7 @@ def print_enabled_extensions : Flag<["-", "--"], "print-enabled-extensions">, def : Flag<["-"], "mcpu=help">, Alias; def : Flag<["-"], "mtune=help">, Alias; def time : Flag<["-"], "time">, + Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, HelpText<"Time individual commands">; def traditional_cpp : Flag<["-", "--"], "traditional-cpp">, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/Driver/Compilation.cpp b/clang/lib/Driver/Compilation.cpp index ad077d5bbfa69a..6965e59367c95d 100644 --- a/clang/lib/Driver/Compilation.cpp +++ b/clang/lib/Driver/Compilation.cpp @@ -21,6 +21,9 @@ #include "llvm/Option/OptSpecifier.h" #include "llvm/Option/Option.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TargetParser/Triple.h" #include @@ -194,11 +197,28 @@ int Compilation::ExecuteCommand(const Command &C, if (LogOnly) return 0; + // We don't use any timers or llvm::TimeGroup's because those are tied into + // the global static timer list which, in principle, could be cleared without + // us knowing about it. + llvm::TimeRecord StartTime; + if (getArgs().hasArg(options::OPT_time)) +StartTime = llvm::TimeRecord::getCurrentTime(/*Start=*/true); + std::string Error; bool ExecutionFailed; int Res = C.Execute(Redirects, &Error, &ExecutionFailed); if (PostCallback) PostCallback(C, Res); + + if (getArgs().hasArg(options::OPT_time)) { +llvm::TimeRecord Time = llvm::TimeRecord::getCurrentTime(/*Start=*/false); +Time -= StartTime; +llvm::StringRef Name = llvm::sys::path::filename(C.getExecutable()); +llvm::errs() << "# " << Name << " " + << llvm::format("%0.2f", Time.getUserTime()) << " " + << llvm::format("%0.2f", Time.getSystemTime()) << "\n"; + } + if (!Error.empty()) { assert(Res && "Error string set with 0 result code!"); getDriver().Diag(diag::err_drv_command_failure) << Error; diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 93e85f7dffe35a..a0fd459967a6b2 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1315,6 +1315,9 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { // Ignore -pipe. Args.ClaimAllArgs(options::OPT_pipe); + // Ignore -time. + Args.ClaimAllArgs(options::OPT_time); + // Extract -ccc args. // // FIXME: We need to figure out where this behavior should live. Most of it diff --git a/clang/test/Driver/time.c b/clang/test/Driver/time.c new file mode 100644 index 00..a9a95b073afb73 --- /dev/null +++ b/clang/test/Driver/time.c @@ -0,0 +1,33 @@ +// The -time option prints timing information for the various subcommands in a +// format similar to that used by gcc. When compiling and linking, this will +// include the time to call clang-${LLVM_VERSION_MAJOR} and the linker. Since +// the name of the linker could vary across platforms, and name of the compiler +// could be something diff erent, just check that whatever is printed to stderr +// looks like timing information. + +// Ideally, this should be tested on various platforms, but that requires the +// the full toolchain, including a linker to be present. The initial author of +// the test only had access to Linux on x86 which is why this is only enabled +// there. More platforms ought to be added if possible. + +// REQUIRES: x86-registered-target +// REQUIRES: x86_64-linux + +// RUN: %clang --target=x86_64-pc-linux -time -c -o /dev/null %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=COMPILE-ONLY +// RUN: %clang --target=x86_64-pc-linux -time -S -emit-llvm -o /dev/null %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=COMPILE-ONLY +// RUN: %clang --target=x86_64-pc-linux -time -S -o /dev/null %s 2>&1 \ +// RUN: |
[clang] [flang] [clang][flang] Support -time in both clang and flang (PR #109165)
https://github.com/tarunprabhu closed https://github.com/llvm/llvm-project/pull/109165 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] 5c2a133 - Emit constrained atan2 intrinsic for clang builtin (#113636)
Author: Tex Riddell Date: 2024-11-12T13:34:29-08:00 New Revision: 5c2a133b1342881dc4f42a896e7e5f4b85d20508 URL: https://github.com/llvm/llvm-project/commit/5c2a133b1342881dc4f42a896e7e5f4b85d20508 DIFF: https://github.com/llvm/llvm-project/commit/5c2a133b1342881dc4f42a896e7e5f4b85d20508.diff LOG: Emit constrained atan2 intrinsic for clang builtin (#113636) This change is part of this proposal: https://discourse.llvm.org/t/rfc-all-the-math-intrinsics/78294 - `Builtins.td` - Add f16 support for libm atan2 builtin - `CGBuiltin.cpp` - Emit constraint atan2 intrinsic for clang builtin - `clang/test/CodeGenCXX/builtin-calling-conv.cpp` - Use erff instead of atan2 for clang builtin to lib call calling convention check, now that atan2 maps to an intrinsic. - add atan2 cases to llvm.experimental.constrained tests for more backends: ARM, PowerPC, RISCV, SystemZ. - LangRef.rst: add llvm.experimental.constrained.atan2, revise llvm.atan2 description. Last part of Implement the atan2 HLSL Function. Fixes #70096. Added: Modified: clang/include/clang/Basic/Builtins.td clang/lib/CodeGen/CGBuiltin.cpp clang/test/CodeGen/X86/math-builtins.c clang/test/CodeGen/constrained-math-builtins.c clang/test/CodeGen/libcalls.c clang/test/CodeGen/math-libcalls.c clang/test/CodeGenCXX/builtin-calling-conv.cpp clang/test/CodeGenOpenCL/builtins-f16.cl llvm/docs/LangRef.rst llvm/test/CodeGen/ARM/fp-intrinsics.ll llvm/test/CodeGen/PowerPC/ctrloop-constrained-fp.ll llvm/test/CodeGen/PowerPC/ppcf128-constrained-fp-intrinsics.ll llvm/test/CodeGen/PowerPC/vector-constrained-fp-intrinsics.ll llvm/test/CodeGen/RISCV/double-intrinsics-strict.ll llvm/test/CodeGen/RISCV/float-intrinsics-strict.ll llvm/test/CodeGen/SystemZ/vector-constrained-fp-intrinsics.ll Removed: diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index 4360e0bf9840f1..e866605ac05c09 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -227,10 +227,10 @@ def FminimumNumF16F128 : Builtin, F16F128MathTemplate { let Prototype = "T(T, T)"; } -def Atan2F128 : Builtin { - let Spellings = ["__builtin_atan2f128"]; +def Atan2F16F128 : Builtin, F16F128MathTemplate { + let Spellings = ["__builtin_atan2"]; let Attributes = [FunctionWithBuiltinPrefix, NoThrow, ConstIgnoringErrnoAndExceptions]; - let Prototype = "__float128(__float128, __float128)"; + let Prototype = "T(T, T)"; } def CopysignF16 : Builtin { diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 0807542825f634..9e0c0bff0125c0 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -2798,6 +2798,18 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, return RValue::get(emitUnaryMaybeConstrainedFPBuiltin( *this, E, Intrinsic::atan, Intrinsic::experimental_constrained_atan)); +case Builtin::BIatan2: +case Builtin::BIatan2f: +case Builtin::BIatan2l: +case Builtin::BI__builtin_atan2: +case Builtin::BI__builtin_atan2f: +case Builtin::BI__builtin_atan2f16: +case Builtin::BI__builtin_atan2l: +case Builtin::BI__builtin_atan2f128: + return RValue::get(emitBinaryMaybeConstrainedFPBuiltin( + *this, E, Intrinsic::atan2, + Intrinsic::experimental_constrained_atan2)); + case Builtin::BIceil: case Builtin::BIceilf: case Builtin::BIceill: diff --git a/clang/test/CodeGen/X86/math-builtins.c b/clang/test/CodeGen/X86/math-builtins.c index 48465df21cca19..bf107437fc63a3 100644 --- a/clang/test/CodeGen/X86/math-builtins.c +++ b/clang/test/CodeGen/X86/math-builtins.c @@ -45,10 +45,10 @@ void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { __builtin_atan2(f,f);__builtin_atan2f(f,f) ; __builtin_atan2l(f, f); __builtin_atan2f128(f,f); -// NO__ERRNO: declare double @atan2(double noundef, double noundef) [[READNONE:#[0-9]+]] -// NO__ERRNO: declare float @atan2f(float noundef, float noundef) [[READNONE]] -// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 noundef) [[READNONE]] -// NO__ERRNO: declare fp128 @atan2f128(fp128 noundef, fp128 noundef) [[READNONE]] +// NO__ERRNO: declare double @llvm.atan2.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] +// NO__ERRNO: declare float @llvm.atan2.f32(float, float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.atan2.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare fp128 @llvm.atan2.f128(fp128, fp128) [[READNONE_INTRINSIC]] // HAS_ERRNO: declare double @atan2(double noundef, double noundef) [[NOT_READNONE]] // HAS_ERRNO: declare float @atan2f(float noundef, float noundef) [[NOT_READNONE]] // HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80 noundef, x86_fp80 nound
[clang] [clang][APINotes] Add support for the SwiftEscapable attribute (PR #115866)
https://github.com/Xazax-hun closed https://github.com/llvm/llvm-project/pull/115866 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][AST] Add 'IgnoreTemplateParmDepth' to structural equivalence cache (PR #115518)
https://github.com/NagyDonat approved this pull request. https://github.com/llvm/llvm-project/pull/115518 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Reapply "[analyzer][NFC] Make RegionStore dumps deterministic" (PR #115884)
https://github.com/NagyDonat approved this pull request. LGTM, and sorry for delaying this commit with the tuple-based suggestion! https://github.com/llvm/llvm-project/pull/115884 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] Reland [clang][AArch64] Add getHostCPUFeatures to query for enabled f… (PR #115467)
ElvinaYakubova wrote: Oh yes, you were right, thanks for the explanation. I modified the test to run it only in case the host is AArch64. https://github.com/llvm/llvm-project/pull/115467 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] ae7392b - Reapply "[analyzer][NFC] Make RegionStore dumps deterministic" (#115884)
Author: Balazs Benics Date: 2024-11-12T18:56:02+01:00 New Revision: ae7392bf5c5d4c34c901ba4f472282206e68bf7b URL: https://github.com/llvm/llvm-project/commit/ae7392bf5c5d4c34c901ba4f472282206e68bf7b DIFF: https://github.com/llvm/llvm-project/commit/ae7392bf5c5d4c34c901ba4f472282206e68bf7b.diff LOG: Reapply "[analyzer][NFC] Make RegionStore dumps deterministic" (#115884) This is reapplies #115615 without using tuples. The eager call of `getRegion()` and `getOffset()` could cause crashes when the Store had symbolic bindings. Here I'm fixing the crash by lazily calling those getters. Also, the tuple version poorly sorted the Clusters. The memory spaces should have come before the regular clusters. Now, that is also fixed here, demonstrated by the test. Added: clang/test/Analysis/store-dump-orders.cpp Modified: clang/lib/StaticAnalyzer/Core/RegionStore.cpp Removed: diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index 674099dd7e1f0f..6bad9a93a30169 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -67,9 +67,10 @@ class BindingKey { isa(r)) && "Not a base"); } -public: +public: bool isDirect() const { return P.getInt() & Direct; } + bool isDefault() const { return !isDirect(); } bool hasSymbolicOffset() const { return P.getInt() & Symbolic; } const MemRegion *getRegion() const { return P.getPointer(); } @@ -232,27 +233,86 @@ class RegionBindingsRef : public llvm::ImmutableMapRef StringifyCache; +auto ToString = [&StringifyCache](const MemRegion *R) { + auto [Place, Inserted] = StringifyCache.try_emplace(R); + if (!Inserted) +return Place->second; + std::string Res; + raw_string_ostream OS(Res); + OS << R; + Place->second = Res; + return Res; +}; + +using Cluster = +std::pair>; +using Binding = std::pair; + +const auto MemSpaceBeforeRegionName = [&ToString](const Cluster *L, + const Cluster *R) { + if (isa(L->first) && !isa(R->first)) +return true; + if (!isa(L->first) && isa(R->first)) +return false; + return ToString(L->first) < ToString(R->first); +}; + +const auto SymbolicBeforeOffset = [&ToString](const BindingKey &L, + const BindingKey &R) { + if (L.hasSymbolicOffset() && !R.hasSymbolicOffset()) +return true; + if (!L.hasSymbolicOffset() && R.hasSymbolicOffset()) +return false; + if (L.hasSymbolicOffset() && R.hasSymbolicOffset()) +return ToString(L.getRegion()) < ToString(R.getRegion()); + return L.getOffset() < R.getOffset(); +}; + +const auto DefaultBindingBeforeDirectBindings = +[&SymbolicBeforeOffset](const Binding *LPtr, const Binding *RPtr) { + const BindingKey &L = LPtr->first; + const BindingKey &R = RPtr->first; + if (L.isDefault() && !R.isDefault()) +return true; + if (!L.isDefault() && R.isDefault()) +return false; + assert(L.isDefault() == R.isDefault()); + return SymbolicBeforeOffset(L, R); +}; + +const auto AddrOf = [](const auto &Item) { return &Item; }; + +std::vector SortedClusters; +SortedClusters.reserve(std::distance(begin(), end())); +append_range(SortedClusters, map_range(*this, AddrOf)); +llvm::sort(SortedClusters, MemSpaceBeforeRegionName); + +for (auto [Idx, C] : llvm::enumerate(SortedClusters)) { + const auto &[BaseRegion, Bindings] = *C; Indent(Out, Space, IsDot) - << "{ \"cluster\": \"" << I.getKey() << "\", \"pointer\": \"" - << (const void *)I.getKey() << "\", \"items\": [" << NL; + << "{ \"cluster\": \"" << BaseRegion << "\", \"pointer\": \"" + << (const void *)BaseRegion << "\", \"items\": [" << NL; + + std::vector SortedBindings; + SortedBindings.reserve(std::distance(Bindings.begin(), Bindings.end())); + append_range(SortedBindings, map_range(Bindings, AddrOf)); + llvm::sort(SortedBindings, DefaultBindingBeforeDirectBindings); ++Space; - const ClusterBindings &CB = I.getData(); - for (ClusterBindings::iterator CI = CB.begin(), CE = CB.end(); CI != CE; - ++CI) { -Indent(Out, Space, IsDot) << "{ " << CI.getKey() << ", \"value\": "; -CI.getData().printJson(Out, /*AddQuotes=*/true); + for (auto [Idx, B] : llvm::enumerate(SortedBindings)) { +const auto &[Key, Value] = *B; +Indent(Out, Space, IsDot) << "{ " << Key << ", \"value\": "; +Value.printJson(Out, /*AddQuotes=*/true); Out << " }"; -if (std::next(CI) != CE) +if (Idx != SortedBindings.size() - 1) Out
[clang] [Clang] enhance diagnostic by attaching source location to deduced type in trailing return without auto (PR #115786)
https://github.com/AaronBallman approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/115786 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Extend clang's to define *LONG_LONG*_ macros for bionic (PR #115406)
https://github.com/AaronBallman commented: Release note and test coverage? https://github.com/llvm/llvm-project/pull/115406 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CIR] Change buildX functions to emitX (PR #115568)
https://github.com/smeenai closed https://github.com/llvm/llvm-project/pull/115568 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang] Use range for loops in ClangDiagnosticsEmitter (PR #115573)
@@ -1570,8 +1541,7 @@ static void emitDiagSubGroups(std::map &DiagsInGroup, for (auto const &Group : GroupsInPedantic) { const std::string &GroupName = std::string(Group->getValueAsString("GroupName")); - std::map::const_iterator RI = - DiagsInGroup.find(GroupName); + auto RI = DiagsInGroup.find(GroupName); jurahul wrote: See above. auto seems ok here https://github.com/llvm/llvm-project/pull/115573 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Inline Assembly Support for GPR Pairs ('Pr') (PR #112983)
lenary wrote: > > Gentle Ping. I'm looking for answers to two questions: > > > > * [Should I] prepare a fixup commit that [uses `MVT::Untyped`] (and removes > > the `riscv_*_pair` MVTs), if we think that's a better target-independent > > approach? > > I guess so. I didn't know about the SystemZ change before. I'll try it, and push a separate commit, so we can see what else is needed. > > I do find it a little weird having 2 register classes with the same spill > size and registers. I believe the tablegen generated code considers them > subclasses of each other. X86 has some register classes like this too so I > guess its not a big deal. I'm not very happy about the duplication either, but it's because of a limitation where fairly early on, selectiondag uses the first legal type in a class, rather than the one you might want. > > * Any advice on whether I should be digging deeply into changing > > SelectionDAGBuilder.cpp (affecting all targets) so we don't need the > > `getNumRegisters` override? The options here IMO are a) live with the > > override, b) change SelectionDAGBuilder now, c) change SelectionDAGBuilder > > in a follow-up and remove the override once it is not needed. > > I think we can live with the override since SystemZ is doing it too. https://github.com/llvm/llvm-project/pull/112983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [IR] Allow fast math flags on fptrunc and fpext (PR #115894)
@@ -42,6 +42,14 @@ entry: %f = fneg float %x ; CHECK: %f_vec = fneg <3 x float> %vec %f_vec = fneg <3 x float> %vec +; CHECK: %g = fpext float %x to double arsenm wrote: Needs bitcode compatibility test https://github.com/llvm/llvm-project/pull/115894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [IR] Allow fast math flags on fptrunc and fpext (PR #115894)
@@ -148,6 +172,14 @@ entry: %e = frem nnan float %x, %y ; CHECK: %e_vec = frem nnan ninf <3 x float> %vec, %vec %e_vec = frem ninf nnan <3 x float> %vec, %vec +; CHECK: %f = fpext nnan ninf float %x to double + %f = fpext ninf nnan float %x to double +; CHECK: %f_vec = fpext nnan ninf <3 x float> %vec to <3 x double> + %f_vec = fpext ninf nnan <3 x float> %vec to <3 x double> +; CHECK: %g = fptrunc nnan ninf float %x to half + %g = fptrunc ninf nnan float %x to half +; CHECK: %g_vec = fptrunc nnan ninf <3 x float> %vec to <3 x half> + %g_vec = fptrunc ninf nnan <3 x float> %vec to <3 x half> ; CHECK: ret float %e ret float %e arsenm wrote: Test scalable vector case https://github.com/llvm/llvm-project/pull/115894 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [Clang] Match MSVC handling of duplicate header search paths in Microsoft compatibility modes. (PR #105738)
AaronBallman wrote: > Opinions on whether the current `-fms-compatibility` controlled behavior to > search the directories of the include stack for `#include "xxx"` headers > should be switched to this new option is welcome. I tend to think it should > be. My intuition is that it should be switched to the new option; we want `-fms-compatibility` to mean "be compatible with MSVC" and that shouldn't require additional flags except in exceptional cases. This doesn't feel like an exceptional case to me. https://github.com/llvm/llvm-project/pull/105738 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add wraps and no_wraps attributes (PR #115094)
https://github.com/JustinStitt edited https://github.com/llvm/llvm-project/pull/115094 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add wraps and no_wraps attributes (PR #115094)
https://github.com/JustinStitt edited https://github.com/llvm/llvm-project/pull/115094 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add wraps and no_wraps attributes (PR #115094)
https://github.com/JustinStitt edited https://github.com/llvm/llvm-project/pull/115094 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Instantiate attributes on other decl types (PR #115924)
erichkeane wrote: > > The change is reasonable, but I need to see tests for each of the types. > > In general, we've had the attitude of "we can enable this instantiation > > once we see examples of it being useful", so we need tests to make sure it > > is instantiated, AND that it is useful. > > This makes a lot of sense... but I'm not sure there's currently a way to > write a FileCheck test for (e.g.) attributes on labels, which is actually my > motivating case here. It'd be a pretty big change to start dumping label > attributes in text AST dumps when the LabelDecl isn't even shown. Any > suggestions? the others make sense for it. `LabelDecl` is an interesting beast, and it actually is a little awkward that `LabelDecl` can have attributes, since it is actually the statement that has them written on it. IMO, we should have it ast-dump the attributes for the `LabelStmt`, and it should just print the ones from the `Decl`. It isn't really possible AFAIK to have an 'implicit' `LabelDecl` have attributes anyway, so it makes sense to print them there. https://github.com/llvm/llvm-project/pull/115924 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Implement WaveActiveAnyTrue intrinsic (PR #115902)
@@ -19108,6 +19108,21 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_any_true: { +IntegerType *Int1Ty = +llvm::Type::getInt1Ty(CGM.getTypes().getLLVMContext()); +Value *Op = EmitScalarExpr(E->getArg(0)); +assert(Op->getType() == Int1Ty && + "wave_active_any_true operand must be a bool"); + +llvm::FunctionType *FT = V-FEXrt wrote: I originally had something like this ```hlsl case Builtin::BI__builtin_hlsl_wave_active_any_true: { Value *Op = EmitScalarExpr(E->getArg(0)); return Builder.CreateIntrinsic( Op->getType(), CGM.getHLSLRuntime().getWaveActiveAnyTrueIntrinsic(), Op, nullptr, "hlsl.wave.activeanytrue" ); } ``` but that was failing with a convergence error `Cannot mix controlled and uncontrolled convergence in the same function.`. I also though I tried `Intrinsic::getOrInsertDeclaration` but I can't remember what happened with that. I'll give it another try https://github.com/llvm/llvm-project/pull/115902 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [AArch64][ARM] Treat __bf16 as vendor extension type for C++ name mangling substitution (PR #115956)
llvmbot wrote: @llvm/pr-subscribers-backend-aarch64 @llvm/pr-subscribers-clang Author: Konstantin Schwarz (konstantinschwarz) Changes This attempts to fix [#115521](https://github.com/llvm/llvm-project/issues/115521). According to the Itanium C++ mangling rules, vendor extended builtin types are considered substitution candidates. However, enabling this behavior on AArch64 and ARM is an ABI breaking change, and I'm not sure how problematic that is. Note that gcc implements the same wrong behavior https://godbolt.org/z/1h4EcYrET An alternative could be to detect the "u6__bf16" mangling in the demangler and specifically disable the substitution for this type. --- Full diff: https://github.com/llvm/llvm-project/pull/115956.diff 8 Files Affected: - (modified) clang/include/clang/Basic/TargetInfo.h (+4) - (modified) clang/lib/AST/ItaniumMangle.cpp (+9) - (modified) clang/lib/Basic/Targets/AArch64.h (+3) - (modified) clang/lib/Basic/Targets/ARM.h (+2) - (modified) clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c (+1-1) - (modified) clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilerw-bfloat.c (+1-1) - (modified) clang/test/CodeGen/AArch64/sve2-intrinsics/acle_sve2_whilewr-bfloat.c (+1-1) - (modified) clang/test/CodeGen/arm-mangle-bf16.cpp (+13-1) ``diff diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 25eda907d20a7b..d4456c83a0eefa 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -810,6 +810,10 @@ class TargetInfo : public TransferrableTargetInfo, /// Return the mangled code of bfloat. virtual const char *getBFloat16Mangling() const { return "DF16b"; } + /// Returns whether to treat bfloat as a vendor extension type for the purpose + /// of Itanium C++ name mangling compression rules + virtual bool treatBFloat16AsVendorType() const { return false; } + /// Return the value for the C99 FLT_EVAL_METHOD macro. virtual LangOptions::FPEvalMethodKind getFPEvalMethod() const { return LangOptions::FPEvalMethodKind::FEM_Source; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 14bc260d0245fb..30164ad5ebbd7f 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2923,6 +2923,15 @@ static bool isTypeSubstitutable(Qualifiers Quals, const Type *Ty, return true; if (Ty->isSpecificBuiltinType(BuiltinType::ObjCSel)) return true; + if (Ty->isSpecificBuiltinType(BuiltinType::BFloat16)) { +const TargetInfo *TI = +Ctx.getLangOpts().OpenMP && Ctx.getLangOpts().OpenMPIsTargetDevice +? Ctx.getAuxTargetInfo() +: &Ctx.getTargetInfo(); +// Some targets mangle bfloat16 as a vendor extension type, thus making them +// candidates for substitution +return TI->treatBFloat16AsVendorType(); + } if (Ty->isOpenCLSpecificType()) return true; // From Clang 18.0 we correctly treat SVE types as substitution candidates. diff --git a/clang/lib/Basic/Targets/AArch64.h b/clang/lib/Basic/Targets/AArch64.h index ea3e4015d84265..55a9f9d076b2bd 100644 --- a/clang/lib/Basic/Targets/AArch64.h +++ b/clang/lib/Basic/Targets/AArch64.h @@ -227,6 +227,9 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo { bool validatePointerAuthKey(const llvm::APSInt &value) const override; const char *getBFloat16Mangling() const override { return "u6__bf16"; }; + + bool treatBFloat16AsVendorType() const override { return true; } + bool hasInt128Type() const override; bool hasBitIntType() const override { return true; } diff --git a/clang/lib/Basic/Targets/ARM.h b/clang/lib/Basic/Targets/ARM.h index 55ecb99d82d8fb..647f11691d 100644 --- a/clang/lib/Basic/Targets/ARM.h +++ b/clang/lib/Basic/Targets/ARM.h @@ -226,6 +226,8 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo { const char *getBFloat16Mangling() const override { return "u6__bf16"; }; + bool treatBFloat16AsVendorType() const override { return true; } + std::pair hardwareInterferenceSizes() const override { return std::make_pair(getTriple().isArch64Bit() ? 256 : 64, 64); } diff --git a/clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c b/clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c index 45e30aa20f29a7..2d533642446152 100644 --- a/clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c +++ b/clang/test/CodeGen/AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c @@ -51,7 +51,7 @@ svbfloat16_t test_svdupq_lane_bf16(svbfloat16_t data, uint64_t index) MODE_ATTR // CHECK-NEXT:[[TMP9:%.*]] = tail call @llvm.aarch64.sve.dupq.lane.nxv8bf16( [[TMP8]], i64 0) // CHECK-NEXT:ret [[TMP9]] // -// CPP-CHECK-LABEL: @_Z18test_svdupq_n_bf16u6__bf16u6__bf16u6__bf16u6__bf16u6__bf16u6__bf16u6__bf16u6__bf16( +// CPP-CHECK-LABEL: @_Z18test_svdupq_n_bf16u6__bf16S_S_S_S_S_S_S_( // CPP-CHECK-N
[clang] [AArch64][ARM] Treat __bf16 as vendor extension type for C++ name mangling substitution (PR #115956)
https://github.com/konstantinschwarz created https://github.com/llvm/llvm-project/pull/115956 This attempts to fix [#115521](https://github.com/llvm/llvm-project/issues/115521). According to the Itanium C++ mangling rules, vendor extended builtin types are considered substitution candidates. However, enabling this behavior on AArch64 and ARM is an ABI breaking change, and I'm not sure how problematic that is. Note that gcc implements the same wrong behavior https://godbolt.org/z/1h4EcYrET An alternative could be to detect the "u6__bf16" mangling in the demangler and specifically disable the substitution for this type. >From 40ca031c0fd1b3e9997b2a2e0ed455233f781a9c Mon Sep 17 00:00:00 2001 From: Konstantin Schwarz Date: Tue, 12 Nov 2024 21:47:33 + Subject: [PATCH 1/2] [AArch64][ARM] Pre-commit mangling test for wrong __bf16 substitution behavior --- clang/test/CodeGen/arm-mangle-bf16.cpp | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/clang/test/CodeGen/arm-mangle-bf16.cpp b/clang/test/CodeGen/arm-mangle-bf16.cpp index 1d85c7b2733ac8..267fc5270f9387 100644 --- a/clang/test/CodeGen/arm-mangle-bf16.cpp +++ b/clang/test/CodeGen/arm-mangle-bf16.cpp @@ -2,6 +2,18 @@ // RUN: %clang_cc1 -triple aarch64 -target-feature -bf16 -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi hard -emit-llvm -o - %s | FileCheck %s // RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi softfp -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple aarch64 -target-feature +bf16 -emit-llvm -o - %s | llvm-cxxfilt -n | FileCheck %s --check-prefix=DEMANGLE +// RUN: %clang_cc1 -triple aarch64 -target-feature -bf16 -emit-llvm -o - %s | llvm-cxxfilt -n | FileCheck %s --check-prefix=DEMANGLE +// RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi hard -emit-llvm -o - %s | llvm-cxxfilt -n | FileCheck %s --check-prefix=DEMANGLE +// RUN: %clang_cc1 -triple arm-arm-none-eabi -target-feature +bf16 -mfloat-abi softfp -emit-llvm -o - %s | llvm-cxxfilt -n | FileCheck %s --check-prefix=DEMANGLE -// CHECK: define {{.*}}void @_Z3foou6__bf16(bfloat noundef %b) +// CHECK:define {{.*}}void @_Z3foou6__bf16(bfloat noundef %b) +// DEMANGLE: define {{.*}}void @foo(__bf16) void foo(__bf16 b) {} + +struct bar; + +// CHECK:define {{.*}}void @_Z10substituteu6__bf16R3barS0_ +// DEMANGLE: define {{.*}}void @substitute(__bf16, bar&, bar) +void substitute(__bf16 a, bar &b, bar &c) { +} >From 68609247bcd3cce8521337ad6a69acc4aa5f1a3b Mon Sep 17 00:00:00 2001 From: Konstantin Schwarz Date: Tue, 12 Nov 2024 22:29:49 + Subject: [PATCH 2/2] [AArch64][ARM] Treat __bf16 as vendor extension type for C++ name mangling substitution On AArch64 and ARM targets, __bf16 is mangled as "u6__bf16", which makes the type a vendor extended type. According to the Itanium C++ mangling rules, such types are considered substitution candidates: >From https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling-compression: "There are two exceptions that appear to be substitution candidates from the grammar, but are explicitly excluded: - other than vendor extended types - function and operator names other than extern "C" functions." This attempts to fix #115521 --- clang/include/clang/Basic/TargetInfo.h | 4 clang/lib/AST/ItaniumMangle.cpp | 9 + clang/lib/Basic/Targets/AArch64.h| 3 +++ clang/lib/Basic/Targets/ARM.h| 2 ++ .../AArch64/sve-intrinsics/acle_sve_dupq-bfloat.c| 2 +- .../AArch64/sve2-intrinsics/acle_sve2_whilerw-bfloat.c | 2 +- .../AArch64/sve2-intrinsics/acle_sve2_whilewr-bfloat.c | 2 +- clang/test/CodeGen/arm-mangle-bf16.cpp | 4 ++-- 8 files changed, 23 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 25eda907d20a7b..d4456c83a0eefa 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -810,6 +810,10 @@ class TargetInfo : public TransferrableTargetInfo, /// Return the mangled code of bfloat. virtual const char *getBFloat16Mangling() const { return "DF16b"; } + /// Returns whether to treat bfloat as a vendor extension type for the purpose + /// of Itanium C++ name mangling compression rules + virtual bool treatBFloat16AsVendorType() const { return false; } + /// Return the value for the C99 FLT_EVAL_METHOD macro. virtual LangOptions::FPEvalMethodKind getFPEvalMethod() const { return LangOptions::FPEvalMethodKind::FEM_Source; diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 14bc260d0245fb..30164ad5ebbd7f 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -2923,6 +2923,15 @@ static bool isTypeSubstitutable(Qualifiers Quals
[clang] [NFC][Clang] Use StringRef instead of string in ClangDiagnosticEmitter (PR #115959)
https://github.com/jurahul created https://github.com/llvm/llvm-project/pull/115959 Use StringRef instead of std::string in ClangDiagnosticEmitter. >From 5f67dd57f3e6333da438dc07a2efdfcb0c1874b1 Mon Sep 17 00:00:00 2001 From: Rahul Joshi Date: Tue, 12 Nov 2024 15:38:02 -0800 Subject: [PATCH] [NFC][Clang] Use StringRef instead of string in ClangDiagnosticEmitter Use StringRef instead of std::string in ClangDiagnosticEmitter. --- .../TableGen/ClangDiagnosticsEmitter.cpp | 79 --- 1 file changed, 32 insertions(+), 47 deletions(-) diff --git a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index b7fd59090cd995..9aab37514d12b1 100644 --- a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -55,11 +55,11 @@ class DiagGroupParentMap { }; } // end anonymous namespace. -static std::string +static StringRef getCategoryFromDiagGroup(const Record *Group, DiagGroupParentMap &DiagGroupParents) { // If the DiagGroup has a category, return it. - std::string CatName = std::string(Group->getValueAsString("CategoryName")); + StringRef CatName = Group->getValueAsString("CategoryName"); if (!CatName.empty()) return CatName; // The diag group may the subgroup of one or more other diagnostic groups, @@ -73,25 +73,26 @@ getCategoryFromDiagGroup(const Record *Group, /// getDiagnosticCategory - Return the category that the specified diagnostic /// lives in. -static std::string getDiagnosticCategory(const Record *R, - DiagGroupParentMap &DiagGroupParents) { +static StringRef getDiagnosticCategory(const Record *R, + DiagGroupParentMap &DiagGroupParents) { // If the diagnostic is in a group, and that group has a category, use it. if (const auto *Group = dyn_cast(R->getValueInit("Group"))) { // Check the diagnostic's diag group for a category. -std::string CatName = getCategoryFromDiagGroup(Group->getDef(), - DiagGroupParents); +StringRef CatName = +getCategoryFromDiagGroup(Group->getDef(), DiagGroupParents); if (!CatName.empty()) return CatName; } // If the diagnostic itself has a category, get it. - return std::string(R->getValueAsString("CategoryName")); + return R->getValueAsString("CategoryName"); } namespace { class DiagCategoryIDMap { const RecordKeeper &Records; StringMap CategoryIDs; -std::vector CategoryStrings; +std::vector CategoryStrings; + public: DiagCategoryIDMap(const RecordKeeper &records) : Records(records) { DiagGroupParentMap ParentInfo(Records); @@ -102,7 +103,7 @@ namespace { for (const Record *Diag : Records.getAllDerivedDefinitions("Diagnostic")) { -std::string Category = getDiagnosticCategory(Diag, ParentInfo); +StringRef Category = getDiagnosticCategory(Diag, ParentInfo); if (Category.empty()) continue; // Skip diags with no category. unsigned &ID = CategoryIDs[Category]; @@ -117,7 +118,7 @@ namespace { return CategoryIDs[CategoryString]; } -typedef std::vector::const_iterator const_iterator; +typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return CategoryStrings.begin(); } const_iterator end() const { return CategoryStrings.end(); } }; @@ -125,7 +126,7 @@ namespace { struct GroupInfo { StringRef GroupName; std::vector DiagsInGroup; -std::vector SubGroups; +std::vector SubGroups; unsigned IDNo = 0; SmallVector Defs; @@ -145,7 +146,7 @@ static bool diagGroupBeforeByName(const Record *LHS, const Record *RHS) { RHS->getValueAsString("GroupName"); } -using DiagsInGroupTy = std::map>; +using DiagsInGroupTy = std::map>; /// Invert the 1-[0/1] mapping of diags to group into a one to many /// mapping of groups to diags in the group. @@ -158,16 +159,14 @@ static void groupDiagnostics(ArrayRef Diags, continue; assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" && "Note can't be in a DiagGroup"); -std::string GroupName = -std::string(DI->getDef()->getValueAsString("GroupName")); +StringRef GroupName = DI->getDef()->getValueAsString("GroupName"); DiagsInGroup[GroupName].DiagsInGroup.push_back(R); } // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty // groups (these are warnings that GCC supports that clang never produces). for (const Record *Group : DiagGroups) { -GroupInfo &GI = -DiagsInGroup[std::string(Group->getValueAsString("GroupName"))]; +GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; GI.GroupName = Group->getName(); GI.Defs.push_back(Group); @@ -281,8 +280,7 @@ class InferPedantic { } // end anonymous n
[clang] [llvm] [MTE] Apply alignment / size in AsmPrinter rather than IR (PR #111918)
https://github.com/fmayer edited https://github.com/llvm/llvm-project/pull/111918 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Clang] add wraps and no_wraps attributes (PR #115094)
@@ -6536,6 +6536,30 @@ static void HandleBTFTypeTagAttribute(QualType &Type, const ParsedAttr &Attr, ::new (Ctx) BTFTypeTagAttr(Ctx, Attr, BTFTypeTag), Type); } +static void handleWrapsAttr(QualType &Type, const ParsedAttr &Attr, +TypeProcessingState &State, bool NoWraps = false) { + Sema &S = State.getSema(); + ASTContext &Ctx = S.Context; + + // wraps and no_wraps are most useful and consistent when used with C. Other + // languages have better alternatives within their type systems. + if (S.LangOpts.CPlusPlus || S.LangOpts.ObjC) JustinStitt wrote: For whatever reason, the execution still ends up here during parsing. Can't be an assert :( https://github.com/llvm/llvm-project/pull/115094 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang] Add steakhal to the Clang Static Analyzer maintainers (PR #114991)
https://github.com/haoNoQ approved this pull request. I wholeheartedly support this. I agree with everything you said here. Right now you're much more of a maintainer than me. https://github.com/llvm/llvm-project/pull/114991 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [MTE] Apply alignment / size in AsmPrinter rather than IR (PR #111918)
https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/111918 >From 3a962270521aa7b48b64e5ac5fa0edb900990023 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Thu, 10 Oct 2024 16:05:50 -0700 Subject: [PATCH 1/5] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 --- clang/lib/CodeGen/SanitizerMetadata.cpp | 45 - llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp| 7 +- llvm/lib/Target/AArch64/AArch64.h | 2 - .../Target/AArch64/AArch64GlobalsTagging.cpp | 155 -- .../Target/AArch64/AArch64TargetMachine.cpp | 2 - llvm/lib/Target/AArch64/CMakeLists.txt| 1 - .../llvm/lib/Target/AArch64/BUILD.gn | 1 - 7 files changed, 46 insertions(+), 167 deletions(-) delete mode 100644 llvm/lib/Target/AArch64/AArch64GlobalsTagging.cpp diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp index 5b212a163611dc..784d9061647f5c 100644 --- a/clang/lib/CodeGen/SanitizerMetadata.cpp +++ b/clang/lib/CodeGen/SanitizerMetadata.cpp @@ -34,6 +34,37 @@ static SanitizerMask expandKernelSanitizerMasks(SanitizerMask Mask) { return Mask; } +static bool shouldTagGlobal(const llvm::GlobalVariable &G) { + // For now, don't instrument constant data, as it'll be in .rodata anyway. It + // may be worth instrumenting these in future to stop them from being used as + // gadgets. + if (G.getName().starts_with("llvm.") || G.isThreadLocal() || G.isConstant()) +return false; + + // Globals can be placed implicitly or explicitly in sections. There's two + // different types of globals that meet this criteria that cause problems: + // 1. Function pointers that are going into various init arrays (either + // explicitly through `__attribute__((section()))` or implicitly + // through `__attribute__((constructor)))`, such as ".(pre)init(_array)", + // ".fini(_array)", ".ctors", and ".dtors". These function pointers end up + // overaligned and overpadded, making iterating over them problematic, and + // each function pointer is individually tagged (so the iteration over + // them causes SIGSEGV/MTE[AS]ERR). + // 2. Global variables put into an explicit section, where the section's name + // is a valid C-style identifier. The linker emits a `__start_` and + // `__stop_` symbol for the section, so that you can iterate over + // globals within this section. Unfortunately, again, these globals would + // be tagged and so iteration causes SIGSEGV/MTE[AS]ERR. + // + // To mitigate both these cases, and because specifying a section is rare + // outside of these two cases, disable MTE protection for globals in any + // section. + if (G.hasSection()) +return false; + + return true; +} + void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, SourceLocation Loc, StringRef Name, QualType Ty, @@ -60,11 +91,15 @@ void SanitizerMetadata::reportGlobal(llvm::GlobalVariable *GV, Meta.NoHWAddress |= CGM.isInNoSanitizeList( FsanitizeArgument.Mask & SanitizerKind::HWAddress, GV, Loc, Ty); - Meta.Memtag |= - static_cast(FsanitizeArgument.Mask & SanitizerKind::MemtagGlobals); - Meta.Memtag &= !NoSanitizeAttrSet.hasOneOf(SanitizerKind::MemTag); - Meta.Memtag &= !CGM.isInNoSanitizeList( - FsanitizeArgument.Mask & SanitizerKind::MemTag, GV, Loc, Ty); + if (shouldTagGlobal(*GV)) { +Meta.Memtag |= +static_cast(FsanitizeArgument.Mask & SanitizerKind::MemtagGlobals); +Meta.Memtag &= !NoSanitizeAttrSet.hasOneOf(SanitizerKind::MemTag); +Meta.Memtag &= !CGM.isInNoSanitizeList( +FsanitizeArgument.Mask & SanitizerKind::MemTag, GV, Loc, Ty); + } else { +Meta.Memtag = false; + } Meta.IsDynInit = IsDynInit && !Meta.NoAddress && FsanitizeArgument.has(SanitizerKind::Address) && diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 3a8cde7330efc0..6a2817f417d30d 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -764,11 +764,16 @@ void AsmPrinter::emitGlobalVariable(const GlobalVariable *GV) { const DataLayout &DL = GV->getDataLayout(); uint64_t Size = DL.getTypeAllocSize(GV->getValueType()); + if (GV->isTagged()) Size = alignTo(Size, 16); // If the alignment is specified, we *must* obey it. Overaligning a global // with a specified alignment is a prompt way to break globals emitted to // sections and expected to be contiguous (e.g. ObjC metadata). - const Align Alignment = getGVAlignment(GV, DL); + Align Alignment = getGVAlignment(GV, DL); + if (GV->isTagged() && Alignment < 16) { +assert(!GV->hasSection()); +Alignment = Al
[clang] [Xtensa] Default to unsigned char (PR #115967)
https://github.com/arichardson created https://github.com/llvm/llvm-project/pull/115967 This matches GCC. Partially fixes https://github.com/llvm/llvm-project/pull/115964 >From e428a45e9638d0d310bd21e46acf4175b09815c9 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 12 Nov 2024 16:24:08 -0800 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?= =?UTF-8?q?l=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6-beta.1 --- clang/lib/Driver/ToolChains/Clang.cpp | 1 + clang/test/Driver/xtensa-char.c | 4 2 files changed, 5 insertions(+) create mode 100644 clang/test/Driver/xtensa-char.c diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0952262c360185..29954bfbc560c1 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1347,6 +1347,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { case llvm::Triple::riscv64: case llvm::Triple::systemz: case llvm::Triple::xcore: + case llvm::Triple::xtensa: return false; } } diff --git a/clang/test/Driver/xtensa-char.c b/clang/test/Driver/xtensa-char.c new file mode 100644 index 00..13f8f67727e75d --- /dev/null +++ b/clang/test/Driver/xtensa-char.c @@ -0,0 +1,4 @@ +/// Check that char is unsigned by default. +// RUN: %clang -### %s --target=xtensa -c 2>&1 | FileCheck %s +// CHECK: "-cc1" "-triple" "xtensa" +// CHECK-SAME: "-fno-signed-char" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [Xtensa] Default to unsigned char (PR #115967)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Alexander Richardson (arichardson) Changes This matches GCC. Partially fixes https://github.com/llvm/llvm-project/pull/115964 --- Full diff: https://github.com/llvm/llvm-project/pull/115967.diff 2 Files Affected: - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+1) - (added) clang/test/Driver/xtensa-char.c (+4) ``diff diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0952262c360185..29954bfbc560c1 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1347,6 +1347,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { case llvm::Triple::riscv64: case llvm::Triple::systemz: case llvm::Triple::xcore: + case llvm::Triple::xtensa: return false; } } diff --git a/clang/test/Driver/xtensa-char.c b/clang/test/Driver/xtensa-char.c new file mode 100644 index 00..13f8f67727e75d --- /dev/null +++ b/clang/test/Driver/xtensa-char.c @@ -0,0 +1,4 @@ +/// Check that char is unsigned by default. +// RUN: %clang -### %s --target=xtensa -c 2>&1 | FileCheck %s +// CHECK: "-cc1" "-triple" "xtensa" +// CHECK-SAME: "-fno-signed-char" `` https://github.com/llvm/llvm-project/pull/115967 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang] Use StringRef instead of string in ClangDiagnosticEmitter (PR #115959)
https://github.com/jurahul updated https://github.com/llvm/llvm-project/pull/115959 >From 5ba5485bbc8895743130f58779cf5c78eb0941aa Mon Sep 17 00:00:00 2001 From: Rahul Joshi Date: Tue, 12 Nov 2024 15:38:02 -0800 Subject: [PATCH] [NFC][Clang] Use StringRef instead of string in ClangDiagnosticEmitter Use StringRef instead of std::string in ClangDiagnosticEmitter. --- .../TableGen/ClangDiagnosticsEmitter.cpp | 88 --- 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index b7fd59090cd995..982809169e6bfd 100644 --- a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -55,11 +55,11 @@ class DiagGroupParentMap { }; } // end anonymous namespace. -static std::string +static StringRef getCategoryFromDiagGroup(const Record *Group, DiagGroupParentMap &DiagGroupParents) { // If the DiagGroup has a category, return it. - std::string CatName = std::string(Group->getValueAsString("CategoryName")); + StringRef CatName = Group->getValueAsString("CategoryName"); if (!CatName.empty()) return CatName; // The diag group may the subgroup of one or more other diagnostic groups, @@ -73,25 +73,26 @@ getCategoryFromDiagGroup(const Record *Group, /// getDiagnosticCategory - Return the category that the specified diagnostic /// lives in. -static std::string getDiagnosticCategory(const Record *R, - DiagGroupParentMap &DiagGroupParents) { +static StringRef getDiagnosticCategory(const Record *R, + DiagGroupParentMap &DiagGroupParents) { // If the diagnostic is in a group, and that group has a category, use it. if (const auto *Group = dyn_cast(R->getValueInit("Group"))) { // Check the diagnostic's diag group for a category. -std::string CatName = getCategoryFromDiagGroup(Group->getDef(), - DiagGroupParents); +StringRef CatName = +getCategoryFromDiagGroup(Group->getDef(), DiagGroupParents); if (!CatName.empty()) return CatName; } // If the diagnostic itself has a category, get it. - return std::string(R->getValueAsString("CategoryName")); + return R->getValueAsString("CategoryName"); } namespace { class DiagCategoryIDMap { const RecordKeeper &Records; StringMap CategoryIDs; -std::vector CategoryStrings; +std::vector CategoryStrings; + public: DiagCategoryIDMap(const RecordKeeper &records) : Records(records) { DiagGroupParentMap ParentInfo(Records); @@ -102,7 +103,7 @@ namespace { for (const Record *Diag : Records.getAllDerivedDefinitions("Diagnostic")) { -std::string Category = getDiagnosticCategory(Diag, ParentInfo); +StringRef Category = getDiagnosticCategory(Diag, ParentInfo); if (Category.empty()) continue; // Skip diags with no category. unsigned &ID = CategoryIDs[Category]; @@ -117,7 +118,7 @@ namespace { return CategoryIDs[CategoryString]; } -typedef std::vector::const_iterator const_iterator; +typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return CategoryStrings.begin(); } const_iterator end() const { return CategoryStrings.end(); } }; @@ -125,7 +126,7 @@ namespace { struct GroupInfo { StringRef GroupName; std::vector DiagsInGroup; -std::vector SubGroups; +std::vector SubGroups; unsigned IDNo = 0; SmallVector Defs; @@ -145,7 +146,7 @@ static bool diagGroupBeforeByName(const Record *LHS, const Record *RHS) { RHS->getValueAsString("GroupName"); } -using DiagsInGroupTy = std::map>; +using DiagsInGroupTy = std::map>; /// Invert the 1-[0/1] mapping of diags to group into a one to many /// mapping of groups to diags in the group. @@ -158,21 +159,19 @@ static void groupDiagnostics(ArrayRef Diags, continue; assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" && "Note can't be in a DiagGroup"); -std::string GroupName = -std::string(DI->getDef()->getValueAsString("GroupName")); +StringRef GroupName = DI->getDef()->getValueAsString("GroupName"); DiagsInGroup[GroupName].DiagsInGroup.push_back(R); } // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty // groups (these are warnings that GCC supports that clang never produces). for (const Record *Group : DiagGroups) { -GroupInfo &GI = -DiagsInGroup[std::string(Group->getValueAsString("GroupName"))]; +GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; GI.GroupName = Group->getName(); GI.Defs.push_back(Group); for (const Record *SubGroup : Group->getValueAsListOfDefs("SubGroups")) - GI.SubGroups.push_back(SubGroup->getValueAsS
[clang] [MSP430] Default to unsigned char (PR #115964)
https://github.com/arichardson updated https://github.com/llvm/llvm-project/pull/115964 >From 712bbc59b1976a35c8aba4bdea8728d7e9f2b425 Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 12 Nov 2024 16:02:17 -0800 Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?= =?UTF-8?q?itial=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.6-beta.1 --- clang/lib/Driver/ToolChains/Clang.cpp | 1 + clang/test/Driver/msp430-char.c | 5 + 2 files changed, 6 insertions(+) create mode 100644 clang/test/Driver/msp430-char.c diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 0952262c360185..75379e0a00b981 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1341,6 +1341,7 @@ static bool isSignedCharDefault(const llvm::Triple &Triple) { return false; case llvm::Triple::hexagon: + case llvm::Triple::msp430: case llvm::Triple::ppcle: case llvm::Triple::ppc64le: case llvm::Triple::riscv32: diff --git a/clang/test/Driver/msp430-char.c b/clang/test/Driver/msp430-char.c new file mode 100644 index 00..4f62eb167e1c84 --- /dev/null +++ b/clang/test/Driver/msp430-char.c @@ -0,0 +1,5 @@ +/// Check that char is unsigned by default. +// RUN: %clang -### %s --target=msp430 -c 2>&1 +// RUN: %clang -### %s --target=msp430 -c 2>&1 | FileCheck%s +// CHECK: "-cc1" "-triple" "msp430" +// CHECK-SAME: "-fno-signed-char" >From c719eb0c5868dc62f739a76b05a389102cf1500e Mon Sep 17 00:00:00 2001 From: Alex Richardson Date: Tue, 12 Nov 2024 16:08:40 -0800 Subject: [PATCH 2/2] remove debug print Created using spr 1.3.6-beta.1 --- clang/test/Driver/msp430-char.c | 1 - 1 file changed, 1 deletion(-) diff --git a/clang/test/Driver/msp430-char.c b/clang/test/Driver/msp430-char.c index 4f62eb167e1c84..88ab443bafcaf2 100644 --- a/clang/test/Driver/msp430-char.c +++ b/clang/test/Driver/msp430-char.c @@ -1,5 +1,4 @@ /// Check that char is unsigned by default. -// RUN: %clang -### %s --target=msp430 -c 2>&1 // RUN: %clang -### %s --target=msp430 -c 2>&1 | FileCheck%s // CHECK: "-cc1" "-triple" "msp430" // CHECK-SAME: "-fno-signed-char" ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][Fuchsia] Have global dtors use llvm.global_dtors over atexit (PR #115788)
PiJoules wrote: > I'm not sure we can just unconditionally call the destructor. We need to > ensure the constructor runs first. If a constructor throws an exception or > calls exit(), not all constructors will run before we start cleaning up. This > works out naturally with atexit... but if you use global_dtors, I think you > end up calling the destructor on an uninitialized object. Ah yeah you're right. I didn't consider this. Since we're willing to make ABI changes, my colleague @mysterymath came up with another idea that might help address this: 1. Instrument in a dso_local global counter that indicates how many ctors we successfully called. 2. After each successful ctor call for each global, increment the counter by 1. 3. Inside the function that would be added to `llvm.global_dtors` and would invoke all the dtors, have a global switch that jumps to the appropriate case based on the number of correctly initialized globals. This would be akin to Duff's device. ``` // Given globals: // // A first; // A second; // A third; static int SuccessfulInits = 0; void module_ctor() { construct_A(&first); SuccessfulInits++; construct_A(&second); SuccessfulInits++; construct_A(&third); SuccessfulInits++; } void module_dtor() { switch (SuccessfulInits) { case 3: destruct_A(&third); // fallthrough case 2: destruct_A(&second); // falthrough case 1: destruct_A(&first); // fallthrough case 0: break; // No destructors invoked } } ``` An alternative approach might be using a lookup table with a decrementing pointer: ``` void __dtor_first() { destruct_A(&first); } void __dtor_second() { destruct_A(&second); } void __dtor_third() { destruct_A(&third); } void (*dtor_list[])() = {__dtor_first, __dtor_second, __dtor_third}; void (*dtor_ptr)() = dtor_list; void module_ctor() { construct_A(&first); dtor_ptr++; construct_A(&second); dtor_ptr++; construct_A(&third); dtor_ptr++; } void module_dtor() { while (dtor_ptr != dtor_list) { (--dtor_ptr)(); // Invoke one of the functions in dtor_list } } ``` I probably won't implement these here or continue with the patch, but these are some ideas we had. > Also, I'm not sure objects are destroyed in the correct order. Do you mean for the test case I added? I think they should be destroyed in reverse order. https://github.com/llvm/llvm-project/pull/115788 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [X86][AMX] Support AMX-TRANSPOSE, part 2 (PR #115660)
https://github.com/phoebewang updated https://github.com/llvm/llvm-project/pull/115660 >From f2fc493149d75f0be13207bc1893a48c7fab84a3 Mon Sep 17 00:00:00 2001 From: "Wang, Phoebe" Date: Sun, 10 Nov 2024 22:37:15 +0800 Subject: [PATCH] [X86][AMX] Support AMX-TRANSPOSE, part 2 Ref.: https://cdrdv2.intel.com/v1/dl/getContent/671368 --- clang/include/clang/Basic/BuiltinsX86_64.def | 12 + clang/lib/Headers/CMakeLists.txt | 3 + clang/lib/Headers/amxbf16transposeintrin.h| 94 ++ clang/lib/Headers/amxcomplextransposeintrin.h | 301 ++ clang/lib/Headers/amxfp16intrin.h | 35 ++ clang/lib/Headers/amxfp16transposeintrin.h| 94 ++ clang/lib/Headers/amxintrin.h | 32 -- clang/lib/Headers/immintrin.h | 22 +- clang/lib/Sema/SemaX86.cpp| 6 + clang/test/CodeGen/X86/amx_transpose.c| 39 +++ clang/test/CodeGen/X86/amx_transpose_api.c| 50 ++- clang/test/CodeGen/X86/amx_transpose_errors.c | 50 ++- llvm/include/llvm/IR/IntrinsicsX86.td | 57 llvm/lib/Target/X86/X86ExpandPseudo.cpp | 28 +- llvm/lib/Target/X86/X86ISelLowering.cpp | 58 ++-- llvm/lib/Target/X86/X86InstrAMX.td| 89 ++ llvm/lib/Target/X86/X86LowerAMXType.cpp | 24 +- llvm/lib/Target/X86/X86RegisterInfo.cpp | 8 +- .../CodeGen/X86/amx_transpose_intrinsics.ll | 77 - .../MC/Disassembler/X86/amx-transpose-att.txt | 48 +++ llvm/test/MC/X86/amx-transpose-att.s | 48 +++ llvm/test/MC/X86/amx-transpose-intel.s| 48 +++ 22 files changed, 1154 insertions(+), 69 deletions(-) create mode 100644 clang/lib/Headers/amxbf16transposeintrin.h create mode 100644 clang/lib/Headers/amxcomplextransposeintrin.h create mode 100644 clang/lib/Headers/amxfp16transposeintrin.h diff --git a/clang/include/clang/Basic/BuiltinsX86_64.def b/clang/include/clang/Basic/BuiltinsX86_64.def index 9f7462b1e0d962..cc8637ed9c50da 100644 --- a/clang/include/clang/Basic/BuiltinsX86_64.def +++ b/clang/include/clang/Basic/BuiltinsX86_64.def @@ -133,6 +133,12 @@ TARGET_BUILTIN(__builtin_ia32_t2rpntlvwz0t1_internal, "vUsUsUsV256i*V256i*vC*z", TARGET_BUILTIN(__builtin_ia32_t2rpntlvwz1_internal, "vUsUsUsV256i*V256i*vC*z", "n", "amx-transpose") TARGET_BUILTIN(__builtin_ia32_t2rpntlvwz1t1_internal, "vUsUsUsV256i*V256i*vC*z", "n", "amx-transpose") TARGET_BUILTIN(__builtin_ia32_ttransposed_internal, "V256iUsUsV256i", "n", "amx-transpose") +TARGET_BUILTIN(__builtin_ia32_ttdpbf16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-bf16,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_ttdpfp16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-fp16,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_ttcmmimfp16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-complex,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_ttcmmrlfp16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-complex,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_tconjtcmmimfp16ps_internal, "V256iUsUsUsV256iV256iV256i", "n", "amx-complex,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_tconjtfp16_internal, "V256iUsUsV256i", "n", "amx-complex,amx-transpose") TARGET_BUILTIN(__builtin_ia32_tcvtrowd2ps_internal, "V16fUsUsV256iUi", "n", "amx-avx512,avx10.2-512") TARGET_BUILTIN(__builtin_ia32_tcvtrowps2pbf16h_internal, "V32yUsUsV256iUi", "n", "amx-avx512,avx10.2-512") TARGET_BUILTIN(__builtin_ia32_tcvtrowps2pbf16l_internal, "V32yUsUsV256iUi", "n", "amx-avx512,avx10.2-512") @@ -164,6 +170,12 @@ TARGET_BUILTIN(__builtin_ia32_t2rpntlvwz0t1, "vIUcvC*z", "n","amx-transpose") TARGET_BUILTIN(__builtin_ia32_t2rpntlvwz1, "vIUcvC*z", "n", "amx-transpose") TARGET_BUILTIN(__builtin_ia32_t2rpntlvwz1t1, "vIUcvC*z", "n","amx-transpose") TARGET_BUILTIN(__builtin_ia32_ttransposed, "vIUcIUc", "n", "amx-transpose") +TARGET_BUILTIN(__builtin_ia32_ttdpbf16ps, "vIUcIUcIUc", "n", "amx-bf16,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_ttdpfp16ps, "vIUcIUcIUc", "n", "amx-fp16,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_ttcmmimfp16ps, "vIUcIUcIUc", "n", "amx-complex,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_ttcmmrlfp16ps, "vIUcIUcIUc", "n", "amx-complex,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_tconjtcmmimfp16ps, "vIUcIUcIUc", "n", "amx-complex,amx-transpose") +TARGET_BUILTIN(__builtin_ia32_tconjtfp16, "vIUcIUc", "n", "amx-complex,amx-transpose") TARGET_BUILTIN(__builtin_ia32_tcvtrowd2ps, "V16fIUcUi", "n", "amx-avx512,avx10.2-512") TARGET_BUILTIN(__builtin_ia32_tcvtrowps2pbf16h, "V32yIUcUi", "n", "amx-avx512,avx10.2-512") diff --git a/clang/lib/Headers/CMakeLists.txt b/clang/lib/Headers/CMakeLists.txt index 76366ca1f108e9..19013d37f46ef7 100644 --- a/clang/lib/Headers/CMakeLists.txt +++ b/clang/lib/Headers/CMakeLists.txt @@ -147,8 +147,11 @@ set(x86_files adxintrin.h ammintrin.h amxavx512intrin.h + amxbf16transposeintrin.h amxcomplexintrin.h + amxcomplextransposeintrin.h amxfp16intrin.h +
[clang] [llvm] [HLSL] Print struct body definition when within the context of defining a target extension type (PR #115971)
https://github.com/bob80905 created https://github.com/llvm/llvm-project/pull/115971 This PR changes the way that final DXIL is printed by adjusting the way the type definition section of the DXIL output is printed. Specifically, when defining a target extension type, if the RHS involves a struct type, then rather than printing the entire struct type definition, only the struct body is printed. This prevents repetitive phrases like "struct = type {...}" from being repeated over and over in the RHS. Additionally, it should allow opt to not crash when parsing the DXIL output. Fixes [#114131](https://github.com/llvm/llvm-project/issues/114131) >From 7413ceb21a6e0ac9212ef6317763ee0eff559612 Mon Sep 17 00:00:00 2001 From: Joshua Batista Date: Tue, 12 Nov 2024 16:44:00 -0800 Subject: [PATCH] print struct body within target ext ty context --- .../test/AST/HLSL/StructuredBuffer-AST-2.hlsl | 30 +++ llvm/lib/IR/AsmWriter.cpp | 10 +-- 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl diff --git a/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl new file mode 100644 index 00..73073b3f6f2839 --- /dev/null +++ b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl @@ -0,0 +1,30 @@ +// RUN: %clang_dxc -T cs_6_6 %s | FileCheck %s + +// The purpose of this test is to ensure that the AST writer +// only emits struct bodies when within the context of a +// larger object that is being outputted on the RHS. + + +// note that "{ <4 x float> }" in the check below is a struct type, but only the +// body is emitted on the RHS because we are already in the context of a +// target extension type definition (class.hlsl::StructuredBuffer) +// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", { <4 x float> }, 0, 0), %struct.mystruct } +// CHECK: %struct.mystruct = type { <4 x float> } +// CHECK: %dx.types.Handle = type { ptr } +// CHECK: %dx.types.ResBind = type { i32, i32, i32, i8 } +// CHECK: %dx.types.ResourceProperties = type { i32, i32 } + +struct mystruct +{ +float4 Color; +}; + +StructuredBuffer my_buffer : register(t2, space4); + +export float4 test() +{ +return my_buffer[0].Color; +} + +[numthreads(1,1,1)] +void main() {} diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 3c1cb76622bbb7..d2705ff4b30fb8 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -649,8 +649,14 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { OS << "target(\""; printEscapedString(Ty->getTargetExtName(), OS); OS << "\""; -for (Type *Inner : TETy->type_params()) - OS << ", " << *Inner; +for (Type *Inner : TETy->type_params()) { + OS << ", "; + if (Inner->isStructTy()) { +StructType *STy = cast(Inner); +printStructBody(STy, OS); + } else +OS << *Inner; +} for (unsigned IntParam : TETy->int_params()) OS << ", " << IntParam; OS << ")"; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [HLSL] Print struct body definition when within the context of defining a target extension type (PR #115971)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Joshua Batista (bob80905) Changes This PR changes the way that final DXIL is printed by adjusting the way the type definition section of the DXIL output is printed. Specifically, when defining a target extension type, if the RHS involves a struct type, then rather than printing the entire struct type definition, only the struct body is printed. This prevents repetitive phrases like "struct = type {...}" from being repeated over and over in the RHS. Additionally, it should allow opt to not crash when parsing the DXIL output. Fixes [#114131](https://github.com/llvm/llvm-project/issues/114131) --- Full diff: https://github.com/llvm/llvm-project/pull/115971.diff 2 Files Affected: - (added) clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl (+30) - (modified) llvm/lib/IR/AsmWriter.cpp (+8-2) ``diff diff --git a/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl new file mode 100644 index 00..73073b3f6f2839 --- /dev/null +++ b/clang/test/AST/HLSL/StructuredBuffer-AST-2.hlsl @@ -0,0 +1,30 @@ +// RUN: %clang_dxc -T cs_6_6 %s | FileCheck %s + +// The purpose of this test is to ensure that the AST writer +// only emits struct bodies when within the context of a +// larger object that is being outputted on the RHS. + + +// note that "{ <4 x float> }" in the check below is a struct type, but only the +// body is emitted on the RHS because we are already in the context of a +// target extension type definition (class.hlsl::StructuredBuffer) +// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", { <4 x float> }, 0, 0), %struct.mystruct } +// CHECK: %struct.mystruct = type { <4 x float> } +// CHECK: %dx.types.Handle = type { ptr } +// CHECK: %dx.types.ResBind = type { i32, i32, i32, i8 } +// CHECK: %dx.types.ResourceProperties = type { i32, i32 } + +struct mystruct +{ +float4 Color; +}; + +StructuredBuffer my_buffer : register(t2, space4); + +export float4 test() +{ +return my_buffer[0].Color; +} + +[numthreads(1,1,1)] +void main() {} diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index 3c1cb76622bbb7..d2705ff4b30fb8 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -649,8 +649,14 @@ void TypePrinting::print(Type *Ty, raw_ostream &OS) { OS << "target(\""; printEscapedString(Ty->getTargetExtName(), OS); OS << "\""; -for (Type *Inner : TETy->type_params()) - OS << ", " << *Inner; +for (Type *Inner : TETy->type_params()) { + OS << ", "; + if (Inner->isStructTy()) { +StructType *STy = cast(Inner); +printStructBody(STy, OS); + } else +OS << *Inner; +} for (unsigned IntParam : TETy->int_params()) OS << ", " << IntParam; OS << ")"; `` https://github.com/llvm/llvm-project/pull/115971 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [NFC][Clang] Use StringRef instead of string in ClangDiagnosticEmitter (PR #115959)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Rahul Joshi (jurahul) Changes Use StringRef instead of std::string in ClangDiagnosticEmitter. --- Full diff: https://github.com/llvm/llvm-project/pull/115959.diff 1 Files Affected: - (modified) clang/utils/TableGen/ClangDiagnosticsEmitter.cpp (+36-52) ``diff diff --git a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index b7fd59090cd995..982809169e6bfd 100644 --- a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -55,11 +55,11 @@ class DiagGroupParentMap { }; } // end anonymous namespace. -static std::string +static StringRef getCategoryFromDiagGroup(const Record *Group, DiagGroupParentMap &DiagGroupParents) { // If the DiagGroup has a category, return it. - std::string CatName = std::string(Group->getValueAsString("CategoryName")); + StringRef CatName = Group->getValueAsString("CategoryName"); if (!CatName.empty()) return CatName; // The diag group may the subgroup of one or more other diagnostic groups, @@ -73,25 +73,26 @@ getCategoryFromDiagGroup(const Record *Group, /// getDiagnosticCategory - Return the category that the specified diagnostic /// lives in. -static std::string getDiagnosticCategory(const Record *R, - DiagGroupParentMap &DiagGroupParents) { +static StringRef getDiagnosticCategory(const Record *R, + DiagGroupParentMap &DiagGroupParents) { // If the diagnostic is in a group, and that group has a category, use it. if (const auto *Group = dyn_cast(R->getValueInit("Group"))) { // Check the diagnostic's diag group for a category. -std::string CatName = getCategoryFromDiagGroup(Group->getDef(), - DiagGroupParents); +StringRef CatName = +getCategoryFromDiagGroup(Group->getDef(), DiagGroupParents); if (!CatName.empty()) return CatName; } // If the diagnostic itself has a category, get it. - return std::string(R->getValueAsString("CategoryName")); + return R->getValueAsString("CategoryName"); } namespace { class DiagCategoryIDMap { const RecordKeeper &Records; StringMap CategoryIDs; -std::vector CategoryStrings; +std::vector CategoryStrings; + public: DiagCategoryIDMap(const RecordKeeper &records) : Records(records) { DiagGroupParentMap ParentInfo(Records); @@ -102,7 +103,7 @@ namespace { for (const Record *Diag : Records.getAllDerivedDefinitions("Diagnostic")) { -std::string Category = getDiagnosticCategory(Diag, ParentInfo); +StringRef Category = getDiagnosticCategory(Diag, ParentInfo); if (Category.empty()) continue; // Skip diags with no category. unsigned &ID = CategoryIDs[Category]; @@ -117,7 +118,7 @@ namespace { return CategoryIDs[CategoryString]; } -typedef std::vector::const_iterator const_iterator; +typedef std::vector::const_iterator const_iterator; const_iterator begin() const { return CategoryStrings.begin(); } const_iterator end() const { return CategoryStrings.end(); } }; @@ -125,7 +126,7 @@ namespace { struct GroupInfo { StringRef GroupName; std::vector DiagsInGroup; -std::vector SubGroups; +std::vector SubGroups; unsigned IDNo = 0; SmallVector Defs; @@ -145,7 +146,7 @@ static bool diagGroupBeforeByName(const Record *LHS, const Record *RHS) { RHS->getValueAsString("GroupName"); } -using DiagsInGroupTy = std::map>; +using DiagsInGroupTy = std::map>; /// Invert the 1-[0/1] mapping of diags to group into a one to many /// mapping of groups to diags in the group. @@ -158,21 +159,19 @@ static void groupDiagnostics(ArrayRef Diags, continue; assert(R->getValueAsDef("Class")->getName() != "CLASS_NOTE" && "Note can't be in a DiagGroup"); -std::string GroupName = -std::string(DI->getDef()->getValueAsString("GroupName")); +StringRef GroupName = DI->getDef()->getValueAsString("GroupName"); DiagsInGroup[GroupName].DiagsInGroup.push_back(R); } // Add all DiagGroup's to the DiagsInGroup list to make sure we pick up empty // groups (these are warnings that GCC supports that clang never produces). for (const Record *Group : DiagGroups) { -GroupInfo &GI = -DiagsInGroup[std::string(Group->getValueAsString("GroupName"))]; +GroupInfo &GI = DiagsInGroup[Group->getValueAsString("GroupName")]; GI.GroupName = Group->getName(); GI.Defs.push_back(Group); for (const Record *SubGroup : Group->getValueAsListOfDefs("SubGroups")) - GI.SubGroups.push_back(SubGroup->getValueAsString("GroupName").str()); + GI.SubGroups.push_back(SubGroup->getValueAsString("GroupName")); } // Assign unique ID numbers to the groups. @@ -281,8 +28
[clang] [NFC][Clang] Use StringRef instead of string in ClangDiagnosticEmitter (PR #115959)
https://github.com/jurahul ready_for_review https://github.com/llvm/llvm-project/pull/115959 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Support `norelax` attribute for RISCV (PR #115981)
https://github.com/BeMg created https://github.com/llvm/llvm-project/pull/115981 Base on https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94. This patch support the `norelax` attribute for RISC-V target in clang. >From 9dc14ca1e5d026c05390c728c9512994e05d8be7 Mon Sep 17 00:00:00 2001 From: Piyou Chen Date: Mon, 11 Nov 2024 02:43:35 -0800 Subject: [PATCH] [clang][RISCV] Support `norelax` attribute for RISCV --- clang/include/clang/Basic/Attr.td | 8 clang/include/clang/Basic/AttrDocs.td | 9 + clang/include/clang/Sema/SemaRISCV.h | 1 + clang/lib/CodeGen/Targets/RISCV.cpp| 5 + clang/lib/Sema/SemaDeclAttr.cpp| 3 +++ clang/lib/Sema/SemaRISCV.cpp | 11 +++ clang/test/CodeGen/RISCV/riscv-norelax.c | 19 +++ clang/test/CodeGen/RISCV/riscv-norelax.cpp | 19 +++ clang/test/Sema/riscv-norelax.c| 12 9 files changed, 87 insertions(+) create mode 100644 clang/test/CodeGen/RISCV/riscv-norelax.c create mode 100644 clang/test/CodeGen/RISCV/riscv-norelax.cpp create mode 100644 clang/test/Sema/riscv-norelax.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index a631e81d40aa68..74ba9c7a730066 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3220,6 +3220,14 @@ def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr { let Documentation = [RISCVVectorCCDocs]; } +def RISCVNoRelax: DeclOrTypeAttr, TargetSpecificAttr { + let Spellings = [CXX11<"riscv", "norelax">, + C23<"riscv", "norelax">, + Clang<"norelax">]; + let Documentation = [RISCVNoRelaxDocs]; +} + + def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"featuresStr">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b64dbef6332e6a..3df8af853b8665 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5818,6 +5818,15 @@ them if they use them. }]; } +def RISCVNoRelaxDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``riscv_norelax`` attribute can be applied to a function to disable the +relax optimization for that specific function. + }]; +} + + def PreferredNameDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Sema/SemaRISCV.h b/clang/include/clang/Sema/SemaRISCV.h index d7f17797283b86..51d6b8540b80a8 100644 --- a/clang/include/clang/Sema/SemaRISCV.h +++ b/clang/include/clang/Sema/SemaRISCV.h @@ -44,6 +44,7 @@ class SemaRISCV : public SemaBase { void handleInterruptAttr(Decl *D, const ParsedAttr &AL); bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName); bool isValidFMVExtension(StringRef Ext); + void handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL); /// Indicate RISC-V vector builtin functions enabled or not. bool DeclareRVVBuiltins = false; diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index b04e436c665f52..d982fb4f83e907 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -599,6 +599,11 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo { if (CGM.getCodeGenOpts().CFProtectionReturn) Fn->addFnAttr("hw-shadow-stack"); +const auto *NoRelaxAttr = FD->getAttr(); + +if (NoRelaxAttr) + Fn->addFnAttr("norelax"); + const auto *Attr = FD->getAttr(); if (!Attr) return; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index d05d326178e1b8..7045e765cf9fa6 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6911,6 +6911,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_RISCVVectorCC: handleCallConvAttr(S, D, AL); break; + case ParsedAttr::AT_RISCVNoRelax: +S.RISCV().handleRISCVNoRelaxAttr(S, D, AL); +break; case ParsedAttr::AT_Suppress: handleSuppressAttr(S, D, AL); break; diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp index 163f7129a7b42b..86b7539b0c80d2 100644 --- a/clang/lib/Sema/SemaRISCV.cpp +++ b/clang/lib/Sema/SemaRISCV.cpp @@ -1494,6 +1494,17 @@ bool SemaRISCV::isValidFMVExtension(StringRef Ext) { return -1 != RISCVISAInfo::getRISCVFeaturesBitsInfo(Ext).second; } +void SemaRISCV::handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + + if (!isa(D)) { +S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) +<< AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod; +return; + } + + D->addAttr(::new (S.Context) RISCVNoRelaxAttr(S.Context, AL)); +} + SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {} } // namespace clang diff --git a/clang/test/CodeGen/RISCV/riscv-norelax
[clang] [clang][RISCV] Support `norelax` attribute for RISCV (PR #115981)
llvmbot wrote: @llvm/pr-subscribers-clang Author: Piyou Chen (BeMg) Changes Base on https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94. This patch support the `norelax` attribute for RISC-V target in clang. --- Full diff: https://github.com/llvm/llvm-project/pull/115981.diff 9 Files Affected: - (modified) clang/include/clang/Basic/Attr.td (+8) - (modified) clang/include/clang/Basic/AttrDocs.td (+9) - (modified) clang/include/clang/Sema/SemaRISCV.h (+1) - (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+5) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+3) - (modified) clang/lib/Sema/SemaRISCV.cpp (+11) - (added) clang/test/CodeGen/RISCV/riscv-norelax.c (+19) - (added) clang/test/CodeGen/RISCV/riscv-norelax.cpp (+19) - (added) clang/test/Sema/riscv-norelax.c (+12) ``diff diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index a631e81d40aa68..74ba9c7a730066 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3220,6 +3220,14 @@ def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr { let Documentation = [RISCVVectorCCDocs]; } +def RISCVNoRelax: DeclOrTypeAttr, TargetSpecificAttr { + let Spellings = [CXX11<"riscv", "norelax">, + C23<"riscv", "norelax">, + Clang<"norelax">]; + let Documentation = [RISCVNoRelaxDocs]; +} + + def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"featuresStr">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b64dbef6332e6a..3df8af853b8665 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5818,6 +5818,15 @@ them if they use them. }]; } +def RISCVNoRelaxDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``riscv_norelax`` attribute can be applied to a function to disable the +relax optimization for that specific function. + }]; +} + + def PreferredNameDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Sema/SemaRISCV.h b/clang/include/clang/Sema/SemaRISCV.h index d7f17797283b86..51d6b8540b80a8 100644 --- a/clang/include/clang/Sema/SemaRISCV.h +++ b/clang/include/clang/Sema/SemaRISCV.h @@ -44,6 +44,7 @@ class SemaRISCV : public SemaBase { void handleInterruptAttr(Decl *D, const ParsedAttr &AL); bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName); bool isValidFMVExtension(StringRef Ext); + void handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL); /// Indicate RISC-V vector builtin functions enabled or not. bool DeclareRVVBuiltins = false; diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index b04e436c665f52..d982fb4f83e907 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -599,6 +599,11 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo { if (CGM.getCodeGenOpts().CFProtectionReturn) Fn->addFnAttr("hw-shadow-stack"); +const auto *NoRelaxAttr = FD->getAttr(); + +if (NoRelaxAttr) + Fn->addFnAttr("norelax"); + const auto *Attr = FD->getAttr(); if (!Attr) return; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index d05d326178e1b8..7045e765cf9fa6 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6911,6 +6911,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_RISCVVectorCC: handleCallConvAttr(S, D, AL); break; + case ParsedAttr::AT_RISCVNoRelax: +S.RISCV().handleRISCVNoRelaxAttr(S, D, AL); +break; case ParsedAttr::AT_Suppress: handleSuppressAttr(S, D, AL); break; diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp index 163f7129a7b42b..86b7539b0c80d2 100644 --- a/clang/lib/Sema/SemaRISCV.cpp +++ b/clang/lib/Sema/SemaRISCV.cpp @@ -1494,6 +1494,17 @@ bool SemaRISCV::isValidFMVExtension(StringRef Ext) { return -1 != RISCVISAInfo::getRISCVFeaturesBitsInfo(Ext).second; } +void SemaRISCV::handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + + if (!isa(D)) { +S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) +<< AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod; +return; + } + + D->addAttr(::new (S.Context) RISCVNoRelaxAttr(S.Context, AL)); +} + SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {} } // namespace clang diff --git a/clang/test/CodeGen/RISCV/riscv-norelax.c b/clang/test/CodeGen/RISCV/riscv-norelax.c new file mode 100644 index 00..e9a2db1c05aae7 --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-norelax.c @@ -0,0 +1,19 @@ +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 \ +// RUN: -emit-llvm -o - %s | FileCheck %s + +// CHECK-LABEL: define dso_local void @func1( +//
[clang-tools-extra] [clang-tidy] Create bugprone-incorrect-enable-shared-from-this check (PR #102299)
MichelleCDjunaidi wrote: @PiotrZSL @njames93 can I get your review on the latest state of this pull request? https://github.com/llvm/llvm-project/pull/102299 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][RISCV] Support `norelax` attribute for RISCV (PR #115981)
llvmbot wrote: @llvm/pr-subscribers-clang-codegen Author: Piyou Chen (BeMg) Changes Base on https://github.com/riscv-non-isa/riscv-c-api-doc/pull/94. This patch support the `norelax` attribute for RISC-V target in clang. --- Full diff: https://github.com/llvm/llvm-project/pull/115981.diff 9 Files Affected: - (modified) clang/include/clang/Basic/Attr.td (+8) - (modified) clang/include/clang/Basic/AttrDocs.td (+9) - (modified) clang/include/clang/Sema/SemaRISCV.h (+1) - (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+5) - (modified) clang/lib/Sema/SemaDeclAttr.cpp (+3) - (modified) clang/lib/Sema/SemaRISCV.cpp (+11) - (added) clang/test/CodeGen/RISCV/riscv-norelax.c (+19) - (added) clang/test/CodeGen/RISCV/riscv-norelax.cpp (+19) - (added) clang/test/Sema/riscv-norelax.c (+12) ``diff diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index a631e81d40aa68..74ba9c7a730066 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -3220,6 +3220,14 @@ def RISCVVectorCC: DeclOrTypeAttr, TargetSpecificAttr { let Documentation = [RISCVVectorCCDocs]; } +def RISCVNoRelax: DeclOrTypeAttr, TargetSpecificAttr { + let Spellings = [CXX11<"riscv", "norelax">, + C23<"riscv", "norelax">, + Clang<"norelax">]; + let Documentation = [RISCVNoRelaxDocs]; +} + + def Target : InheritableAttr { let Spellings = [GCC<"target">]; let Args = [StringArgument<"featuresStr">]; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b64dbef6332e6a..3df8af853b8665 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -5818,6 +5818,15 @@ them if they use them. }]; } +def RISCVNoRelaxDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``riscv_norelax`` attribute can be applied to a function to disable the +relax optimization for that specific function. + }]; +} + + def PreferredNameDocs : Documentation { let Category = DocCatDecl; let Content = [{ diff --git a/clang/include/clang/Sema/SemaRISCV.h b/clang/include/clang/Sema/SemaRISCV.h index d7f17797283b86..51d6b8540b80a8 100644 --- a/clang/include/clang/Sema/SemaRISCV.h +++ b/clang/include/clang/Sema/SemaRISCV.h @@ -44,6 +44,7 @@ class SemaRISCV : public SemaBase { void handleInterruptAttr(Decl *D, const ParsedAttr &AL); bool isAliasValid(unsigned BuiltinID, llvm::StringRef AliasName); bool isValidFMVExtension(StringRef Ext); + void handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL); /// Indicate RISC-V vector builtin functions enabled or not. bool DeclareRVVBuiltins = false; diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp index b04e436c665f52..d982fb4f83e907 100644 --- a/clang/lib/CodeGen/Targets/RISCV.cpp +++ b/clang/lib/CodeGen/Targets/RISCV.cpp @@ -599,6 +599,11 @@ class RISCVTargetCodeGenInfo : public TargetCodeGenInfo { if (CGM.getCodeGenOpts().CFProtectionReturn) Fn->addFnAttr("hw-shadow-stack"); +const auto *NoRelaxAttr = FD->getAttr(); + +if (NoRelaxAttr) + Fn->addFnAttr("norelax"); + const auto *Attr = FD->getAttr(); if (!Attr) return; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index d05d326178e1b8..7045e765cf9fa6 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6911,6 +6911,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_RISCVVectorCC: handleCallConvAttr(S, D, AL); break; + case ParsedAttr::AT_RISCVNoRelax: +S.RISCV().handleRISCVNoRelaxAttr(S, D, AL); +break; case ParsedAttr::AT_Suppress: handleSuppressAttr(S, D, AL); break; diff --git a/clang/lib/Sema/SemaRISCV.cpp b/clang/lib/Sema/SemaRISCV.cpp index 163f7129a7b42b..86b7539b0c80d2 100644 --- a/clang/lib/Sema/SemaRISCV.cpp +++ b/clang/lib/Sema/SemaRISCV.cpp @@ -1494,6 +1494,17 @@ bool SemaRISCV::isValidFMVExtension(StringRef Ext) { return -1 != RISCVISAInfo::getRISCVFeaturesBitsInfo(Ext).second; } +void SemaRISCV::handleRISCVNoRelaxAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + + if (!isa(D)) { +S.Diag(AL.getLoc(), diag::warn_attribute_wrong_decl_type) +<< AL << AL.isRegularKeywordAttribute() << ExpectedFunctionOrMethod; +return; + } + + D->addAttr(::new (S.Context) RISCVNoRelaxAttr(S.Context, AL)); +} + SemaRISCV::SemaRISCV(Sema &S) : SemaBase(S) {} } // namespace clang diff --git a/clang/test/CodeGen/RISCV/riscv-norelax.c b/clang/test/CodeGen/RISCV/riscv-norelax.c new file mode 100644 index 00..e9a2db1c05aae7 --- /dev/null +++ b/clang/test/CodeGen/RISCV/riscv-norelax.c @@ -0,0 +1,19 @@ +// REQUIRES: riscv-registered-target +// RUN: %clang_cc1 -triple riscv64 \ +// RUN: -emit-llvm -o - %s | FileCheck %s + +// CHECK-LABEL: define dso_local void @fun
[clang] [llvm] [RISCV] Inline Assembly Support for GPR Pairs ('Pr') (PR #112983)
@@ -21351,6 +21372,17 @@ bool RISCVTargetLowering::splitValueIntoRegisterParts( unsigned NumParts, MVT PartVT, std::optional CC) const { bool IsABIRegCopy = CC.has_value(); EVT ValueVT = Val.getValueType(); + + if (ValueVT == (Subtarget.is64Bit() ? MVT::i128 : MVT::i64) && + NumParts == 1 && PartVT == MVT::Untyped) { +// Pairs in Inline Assembly +MVT XLenVT = Subtarget.getXLenVT(); +SDValue Lo, Hi; +std::tie(Lo, Hi) = DAG.SplitScalar(Val, DL, XLenVT, XLenVT); wangpc-pp wrote: ```suggestion auto [Lo, Hi] = DAG.SplitScalar(Val, DL, XLenVT, XLenVT); ``` https://github.com/llvm/llvm-project/pull/112983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Inline Assembly Support for GPR Pairs ('Pr') (PR #112983)
https://github.com/wangpc-pp approved this pull request. Cheers! It seems using `untyped` saves some lines as well! LGTM with nits. https://github.com/llvm/llvm-project/pull/112983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [llvm] [RISCV] Inline Assembly Support for GPR Pairs ('Pr') (PR #112983)
https://github.com/wangpc-pp edited https://github.com/llvm/llvm-project/pull/112983 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [PAC][clang][Driver] Add signed GOT flag (PR #96160)
https://github.com/kovdan01 updated https://github.com/llvm/llvm-project/pull/96160 >From 1ca6cf823585b03a6c580b23caafd1ff44d83aa7 Mon Sep 17 00:00:00 2001 From: Daniil Kovalev Date: Tue, 6 Aug 2024 20:02:07 +0300 Subject: [PATCH 1/3] [PAC][clang][Driver] Add signed GOT flag Depends on #96159 Add `-fptrauth-elf-got` clang driver flag and set `ptrauth_elf_got` preprocessor feature and `PointerAuthELFGOT` LangOption correspondingly. For non-ELF triples, the driver flag is ignored and a warning is emitted. --- .../clang/Basic/DiagnosticDriverKinds.td | 4 +++ clang/include/clang/Basic/Features.def| 1 + clang/include/clang/Driver/Options.td | 1 + clang/lib/Driver/ToolChains/Clang.cpp | 8 + clang/lib/Frontend/CompilerInvocation.cpp | 4 +++ clang/test/CodeGen/aarch64-elf-pauthabi.c | 13 ++-- clang/test/Driver/aarch64-ptrauth.c | 9 +- clang/test/Preprocessor/ptrauth_feature.c | 31 +-- 8 files changed, 57 insertions(+), 14 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticDriverKinds.td b/clang/include/clang/Basic/DiagnosticDriverKinds.td index 3d8240f8357b40..ff8e6dae8cf424 100644 --- a/clang/include/clang/Basic/DiagnosticDriverKinds.td +++ b/clang/include/clang/Basic/DiagnosticDriverKinds.td @@ -751,6 +751,10 @@ def warn_drv_fjmc_for_elf_only : Warning< "-fjmc works only for ELF; option ignored">, InGroup; +def warn_drv_ptrauth_elf_got_for_elf_only : Warning< + "-fptrauth-elf-got works only for ELF; option ignored">, + InGroup; + def warn_target_override_arm64ec : Warning< "/arm64EC has been overridden by specified target: %0; option ignored">, InGroup; diff --git a/clang/include/clang/Basic/Features.def b/clang/include/clang/Basic/Features.def index 10538f555b418e..af847ca70381dd 100644 --- a/clang/include/clang/Basic/Features.def +++ b/clang/include/clang/Basic/Features.def @@ -114,6 +114,7 @@ FEATURE(ptrauth_function_pointer_type_discrimination, LangOpts.PointerAuthFuncti FEATURE(ptrauth_indirect_gotos, LangOpts.PointerAuthIndirectGotos) FEATURE(ptrauth_init_fini, LangOpts.PointerAuthInitFini) FEATURE(ptrauth_init_fini_address_discrimination, LangOpts.PointerAuthInitFiniAddressDiscrimination) +FEATURE(ptrauth_elf_got, LangOpts.PointerAuthELFGOT) EXTENSION(swiftcc, PP.getTargetInfo().checkCallingConvention(CC_Swift) == clang::TargetInfo::CCCR_OK) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 9bc84168c29608..552cb668661888 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -4263,6 +4263,7 @@ defm ptrauth_indirect_gotos : OptInCC1FFlag<"ptrauth-indirect-gotos", defm ptrauth_init_fini : OptInCC1FFlag<"ptrauth-init-fini", "Enable signing of function pointers in init/fini arrays">; defm ptrauth_init_fini_address_discrimination : OptInCC1FFlag<"ptrauth-init-fini-address-discrimination", "Enable address discrimination of function pointers in init/fini arrays">; +defm ptrauth_elf_got : OptInCC1FFlag<"ptrauth-elf-got", "Enable authentication of pointers from GOT (ELF only)">; } def fenable_matrix : Flag<["-"], "fenable-matrix">, Group, diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 2054c8fe928e2e..bb1d5cc4f7171a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -1858,6 +1858,14 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args, Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_init_fini_address_discrimination, options::OPT_fno_ptrauth_init_fini_address_discrimination); + + Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_elf_got, +options::OPT_fno_ptrauth_elf_got); + + if (Args.hasArg(options::OPT_fptrauth_elf_got) && + Triple.getObjectFormat() != llvm::Triple::ELF) +getToolChain().getDriver().Diag( +diag::warn_drv_ptrauth_elf_got_for_elf_only); } void Clang::AddLoongArchTargetArgs(const ArgList &Args, diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 225bd6416ce5fc..8f28408116501c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3437,6 +3437,8 @@ static void GeneratePointerAuthArgs(const LangOptions &Opts, GenerateArg(Consumer, OPT_fptrauth_init_fini); if (Opts.PointerAuthInitFiniAddressDiscrimination) GenerateArg(Consumer, OPT_fptrauth_init_fini_address_discrimination); + if (Opts.PointerAuthELFGOT) +GenerateArg(Consumer, OPT_fptrauth_elf_got); } static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, @@ -3457,6 +3459,7 @@ static void ParsePointerAuthArgs(LangOptions &Opts, ArgList &Args, Opts.PointerAuthInitFini = Args.hasArg(OPT_fptrauth_init_fini); Opts.PointerAuthInitFiniAddressDiscrimination = Args.hasArg(OPT_fptra