llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clangir Author: Sirui Mu (Lancern) <details> <summary>Changes</summary> This patch sets up a framework to properly lower atomic sync scopes from CIR to LLVM. Since the lowering is target-specific, this patch first upstreams a minimum implementation of the TargetLoweringInfo class. It then adds a virtual function there to handle the lowering of atomic sync scopes in a target-specific way. --- Full diff: https://github.com/llvm/llvm-project/pull/173393.diff 8 Files Affected: - (modified) clang/include/clang/CIR/MissingFeatures.h (+1) - (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt (+1) - (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp (+13) - (modified) clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h (+4) - (added) clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp (+25) - (added) clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h (+31) - (modified) clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp (+14-6) - (modified) clang/test/CIR/CodeGen/atomic-scoped.c (+4-4) ``````````diff diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index acfc937a11993..fbfb47070f95f 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -193,6 +193,7 @@ struct MissingFeatures { // LowerModule handling static bool lowerModuleCodeGenOpts() { return false; } static bool lowerModuleLangOpts() { return false; } + static bool targetLoweringInfo() { return false; } // Misc static bool aarch64SIMDIntrinsics() { return false; } diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt index 158c42e729536..17941359a5e83 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/CMakeLists.txt @@ -2,6 +2,7 @@ add_clang_library(MLIRCIRTargetLowering CIRCXXABI.cpp LowerModule.cpp LowerItaniumCXXABI.cpp + TargetLoweringInfo.cpp DEPENDS clangBasic diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp index 7576e20ac8f54..e39b764f6a838 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.cpp @@ -20,6 +20,7 @@ #include "clang/Basic/TargetOptions.h" #include "clang/CIR/MissingFeatures.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" namespace cir { @@ -43,6 +44,12 @@ static std::unique_ptr<CIRCXXABI> createCXXABI(LowerModule &lm) { llvm_unreachable("invalid C++ ABI kind"); } +static std::unique_ptr<TargetLoweringInfo> +createTargetLoweringInfo(LowerModule &lm) { + assert(!cir::MissingFeatures::targetLoweringInfo()); + return std::make_unique<TargetLoweringInfo>(); +} + LowerModule::LowerModule(clang::LangOptions langOpts, clang::CodeGenOptions codeGenOpts, mlir::ModuleOp &module, @@ -51,6 +58,12 @@ LowerModule::LowerModule(clang::LangOptions langOpts, : module(module), target(std::move(target)), abi(createCXXABI(*this)), rewriter(rewriter) {} +const TargetLoweringInfo &LowerModule::getTargetLoweringInfo() { + if (!targetLoweringInfo) + targetLoweringInfo = createTargetLoweringInfo(*this); + return *targetLoweringInfo; +} + // TODO: not to create it every time std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module, mlir::PatternRewriter &rewriter) { diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h index 440e307f571e9..560bf87c76c11 100644 --- a/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/LowerModule.h @@ -15,6 +15,7 @@ #define CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_LOWERMODULE_H #include "CIRCXXABI.h" +#include "TargetLoweringInfo.h" #include "mlir/IR/BuiltinOps.h" #include "clang/Basic/CodeGenOptions.h" #include "clang/Basic/LangOptions.h" @@ -28,6 +29,7 @@ namespace cir { class LowerModule { mlir::ModuleOp module; const std::unique_ptr<clang::TargetInfo> target; + std::unique_ptr<TargetLoweringInfo> targetLoweringInfo; std::unique_ptr<CIRCXXABI> abi; [[maybe_unused]] mlir::PatternRewriter &rewriter; @@ -45,6 +47,8 @@ class LowerModule { CIRCXXABI &getCXXABI() const { return *abi; } const clang::TargetInfo &getTarget() const { return *target; } mlir::MLIRContext *getMLIRContext() { return module.getContext(); } + + const TargetLoweringInfo &getTargetLoweringInfo(); }; std::unique_ptr<LowerModule> createLowerModule(mlir::ModuleOp module, diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp new file mode 100644 index 0000000000000..b9b756077da04 --- /dev/null +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.cpp @@ -0,0 +1,25 @@ +//===---- TargetLoweringInfo.cpp - Encapsulate target details ---*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file partially mimics the TargetCodeGenInfo class from the file +// clang/lib/CodeGen/TargetInfo.cpp. +// +//===----------------------------------------------------------------------===// + +#include "TargetLoweringInfo.h" + +namespace cir { + +TargetLoweringInfo::~TargetLoweringInfo() = default; + +std::string +TargetLoweringInfo::getLLVMSyncScope(cir::SyncScopeKind syncScope) const { + return ""; // default sync scope +} + +} // namespace cir diff --git a/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h new file mode 100644 index 0000000000000..91e7eb79ec83e --- /dev/null +++ b/clang/lib/CIR/Dialect/Transforms/TargetLowering/TargetLoweringInfo.h @@ -0,0 +1,31 @@ +//===---- TargetLoweringInfo.h - Encapsulate target details -----*- 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 +// +//===----------------------------------------------------------------------===// +// +// This file partially mimics the TargetCodeGenInfo class from the file +// clang/lib/CodeGen/TargetInfo.h. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_TARGETLOWERINGINFO_H +#define LLVM_CLANG_LIB_CIR_DIALECT_TRANSFORMS_TARGETLOWERING_TARGETLOWERINGINFO_H + +#include "clang/CIR/Dialect/IR/CIROpsEnums.h" +#include <string> + +namespace cir { + +class TargetLoweringInfo { +public: + virtual ~TargetLoweringInfo(); + + virtual std::string getLLVMSyncScope(cir::SyncScopeKind syncScope) const; +}; + +} // namespace cir + +#endif diff --git a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp index 998c93efb768a..1406c12b424c1 100644 --- a/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp +++ b/clang/lib/CIR/Lowering/DirectToLLVM/LowerToLLVM.cpp @@ -1721,13 +1721,17 @@ mlir::LogicalResult CIRToLLVMLoadOpLowering::matchAndRewrite( // TODO: nontemporal. assert(!cir::MissingFeatures::opLoadStoreNontemporal()); - std::optional<llvm::StringRef> syncScope = - getLLVMSyncScope(op.getSyncScope()); + + std::optional<std::string> llvmSyncScope; + if (std::optional<cir::SyncScopeKind> syncScope = op.getSyncScope()) + llvmSyncScope = + lowerMod->getTargetLoweringInfo().getLLVMSyncScope(*syncScope); + mlir::LLVM::LoadOp newLoad = mlir::LLVM::LoadOp::create( rewriter, op->getLoc(), llvmTy, adaptor.getAddr(), alignment, op.getIsVolatile(), /*isNonTemporal=*/false, /*isInvariant=*/false, /*isInvariantGroup=*/false, ordering, - syncScope.value_or(llvm::StringRef())); + llvmSyncScope.value_or(std::string())); // Convert adapted result to its original type if needed. mlir::Value result = @@ -1755,13 +1759,17 @@ mlir::LogicalResult CIRToLLVMStoreOpLowering::matchAndRewrite( // TODO: nontemporal. assert(!cir::MissingFeatures::opLoadStoreNontemporal()); assert(!cir::MissingFeatures::opLoadStoreTbaa()); - std::optional<llvm::StringRef> syncScope = - getLLVMSyncScope(op.getSyncScope()); + + std::optional<std::string> llvmSyncScope; + if (std::optional<cir::SyncScopeKind> syncScope = op.getSyncScope()) + llvmSyncScope = + lowerMod->getTargetLoweringInfo().getLLVMSyncScope(*syncScope); + mlir::LLVM::StoreOp storeOp = mlir::LLVM::StoreOp::create( rewriter, op->getLoc(), value, adaptor.getAddr(), alignment, op.getIsVolatile(), /*isNonTemporal=*/false, /*isInvariantGroup=*/false, memorder, - syncScope.value_or(llvm::StringRef())); + llvmSyncScope.value_or(std::string())); rewriter.replaceOp(op, storeOp); assert(!cir::MissingFeatures::opLoadStoreTbaa()); return mlir::LogicalResult::success(); diff --git a/clang/test/CIR/CodeGen/atomic-scoped.c b/clang/test/CIR/CodeGen/atomic-scoped.c index 5b8c868d6c9d6..62d075c21a893 100644 --- a/clang/test/CIR/CodeGen/atomic-scoped.c +++ b/clang/test/CIR/CodeGen/atomic-scoped.c @@ -13,7 +13,7 @@ void scoped_atomic_load(int *ptr) { int x; __scoped_atomic_load(ptr, &x, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE); // CIR: %{{.+}} = cir.load align(4) syncscope(single_thread) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i - // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} syncscope("singlethread") monotonic, align 4 + // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4 // OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4 __scoped_atomic_load(ptr, &x, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); @@ -30,7 +30,7 @@ void scoped_atomic_load_n(int *ptr) { int x; x = __scoped_atomic_load_n(ptr, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE); // CIR: %{{.+}} = cir.load align(4) syncscope(single_thread) atomic(relaxed) %{{.+}} : !cir.ptr<!s32i>, !s32i - // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} syncscope("singlethread") monotonic, align 4 + // LLVM: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4 // OGCG: %{{.+}} = load atomic i32, ptr %{{.+}} monotonic, align 4 x = __scoped_atomic_load_n(ptr, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); @@ -46,7 +46,7 @@ void scoped_atomic_store(int *ptr, int value) { __scoped_atomic_store(ptr, &value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE); // CIR: cir.store align(4) syncscope(single_thread) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> - // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} syncscope("singlethread") monotonic, align 4 + // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4 // OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4 __scoped_atomic_store(ptr, &value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); @@ -62,7 +62,7 @@ void scoped_atomic_store_n(int *ptr, int value) { __scoped_atomic_store_n(ptr, value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SINGLE); // CIR: cir.store align(4) syncscope(single_thread) atomic(relaxed) %{{.+}}, %{{.+}} : !s32i, !cir.ptr<!s32i> - // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} syncscope("singlethread") monotonic, align 4 + // LLVM: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4 // OGCG: store atomic i32 %{{.+}}, ptr %{{.+}} monotonic, align 4 __scoped_atomic_store_n(ptr, value, __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM); `````````` </details> https://github.com/llvm/llvm-project/pull/173393 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
