llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: David Rivera (RiverDave) <details> <summary>Changes</summary> Introducing the LangAddressSpace enum with offload address space kinds (offload_private, offload_local, offload_global, offload_constant, offload_generic) and the `LangAddressSpaceAttr` attribute. This starts a series of patches with the purpose of bringing complete address spaces support features for CIR. Most of the test coverage is provided in subsequent patches further down the stack. --- Full diff: https://github.com/llvm/llvm-project/pull/179054.diff 6 Files Affected: - (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.h (+1) - (modified) clang/include/clang/CIR/Dialect/IR/CIRAttrs.td (+51-2) - (modified) clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td (+19) - (modified) clang/include/clang/CIR/Dialect/IR/CIRTypes.h (+4) - (modified) clang/lib/CIR/Dialect/IR/CIRAttrs.cpp (+104-4) - (modified) clang/lib/CIR/Dialect/IR/CIRTypes.cpp (+111-1) ``````````diff diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h index 858d4d6350bed..1d61bd998c216 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.h @@ -13,6 +13,7 @@ #ifndef CLANG_CIR_DIALECT_IR_CIRATTRS_H #define CLANG_CIR_DIALECT_IR_CIRATTRS_H +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/BuiltinAttributeInterfaces.h" #include "clang/Basic/AddressSpaces.h" diff --git a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td index 2309811815f27..4fbab2e83663d 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td +++ b/clang/include/clang/CIR/Dialect/IR/CIRAttrs.td @@ -14,6 +14,7 @@ #define CLANG_CIR_DIALECT_IR_CIRATTRS_TD include "mlir/IR/BuiltinAttributeInterfaces.td" +include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.td" include "clang/CIR/Dialect/IR/CIRAttrConstraints.td" include "clang/CIR/Dialect/IR/CIRDialect.td" @@ -766,16 +767,64 @@ def CIR_DynamicCastInfoAttr : CIR_Attr<"DynamicCastInfo", "dyn_cast_info"> { }]; } +//===----------------------------------------------------------------------===// +// LangAddressSpaceAttr +//===----------------------------------------------------------------------===// + +def CIR_LangAddressSpaceAttr : CIR_EnumAttr<CIR_LangAddressSpace, + "lang_address_space", [ + DeclareAttrInterfaceMethods<MemorySpaceAttrInterface> +]> { + let summary = "Represents a language address space"; + let description = [{ + Encodes the semantic address spaces defined by the front-end language + (e.g. `__shared__`, `__constant__`, `__local__`). Values are stored using the + `cir::LangAddressSpace` enum, keeping the representation compact and + preserving the qualifier until it is mapped onto target/LLVM address-space + numbers. + + Example: + ```mlir + !cir.ptr<!s32i, lang_address_space(offload_local)> + cir.global constant external lang_address_space(offload_constant) + ``` + }]; + + let builders = [ + AttrBuilder<(ins "clang::LangAS":$langAS), [{ + return $_get($_ctxt, cir::toCIRLangAddressSpace(langAS)); + }]> + ]; + + let assemblyFormat = [{ + `(` custom<AddressSpaceValue>($value) `)` + }]; + + let defaultValue = "cir::LangAddressSpace::Default"; + + let extraClassDeclaration = [{ + unsigned getAsUnsignedValue() const; + }]; + + let extraClassDefinition = [{ + unsigned $cppClass::getAsUnsignedValue() const { + return static_cast<unsigned>(getValue()); + } + }]; +} + //===----------------------------------------------------------------------===// // TargetAddressSpaceAttr //===----------------------------------------------------------------------===// def CIR_TargetAddressSpaceAttr : CIR_Attr< "TargetAddressSpace", - "target_address_space"> { + "target_address_space", [ + DeclareAttrInterfaceMethods<MemorySpaceAttrInterface> + ]> { let summary = "Represents a target-specific numeric address space"; let description = [{ The TargetAddressSpaceAttr represents a target-specific numeric address space, - corresponding to the LLVM IR `addressspace` qualifier and the clang + corresponding to the LLVM IR `addrspace` qualifier and the clang `address_space` attribute. A value of zero represents the default address space. The semantics of non-zero diff --git a/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td b/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td index 98b8a31d2a18a..1de6ffdc08d72 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td +++ b/clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td @@ -14,6 +14,7 @@ #define CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD include "mlir/IR/EnumAttr.td" +include "clang/CIR/Dialect/IR/CIRDialect.td" class CIR_I32EnumAttr<string name, string summary, list<I32EnumAttrCase> cases> : I32EnumAttr<name, summary, cases> { @@ -35,4 +36,22 @@ class CIR_DefaultValuedEnumParameter<EnumAttrInfo info, string value = ""> let defaultValue = value; } +def CIR_LangAddressSpace : CIR_I32EnumAttr< + "LangAddressSpace", "language address space kind", [ + I32EnumAttrCase<"Default", 0, "default">, + I32EnumAttrCase<"OffloadPrivate", 1, "offload_private">, + I32EnumAttrCase<"OffloadLocal", 2, "offload_local">, + I32EnumAttrCase<"OffloadGlobal", 3, "offload_global">, + I32EnumAttrCase<"OffloadConstant", 4, "offload_constant">, + I32EnumAttrCase<"OffloadGeneric", 5, "offload_generic"> +]> { + let description = [{ + Enumerates language-specific address spaces used by CIR. These represent + semantic qualifiers from source languages (e.g., CUDA `__shared__`, + OpenCL `__local`) before target lowering. + }]; + + let genSpecializedAttr = 0; +} + #endif // CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h index 939e774a6ea67..16c48ba4fb4e9 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -13,6 +13,7 @@ #ifndef CLANG_CIR_DIALECT_IR_CIRTYPES_H #define CLANG_CIR_DIALECT_IR_CIRTYPES_H +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/MLIRContext.h" @@ -43,6 +44,9 @@ bool isSized(mlir::Type ty); //===----------------------------------------------------------------------===// // AddressSpace helpers //===----------------------------------------------------------------------===// + +cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS); + cir::TargetAddressSpaceAttr toCIRTargetAddressSpace(mlir::MLIRContext &context, clang::LangAS langAS); diff --git a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp index 2f4240c385cab..f528f54511a57 100644 --- a/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRAttrs.cpp @@ -10,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" #include "mlir/IR/DialectImplementation.h" @@ -47,11 +48,21 @@ parseFloatLiteral(mlir::AsmParser &parser, // AddressSpaceAttr //===----------------------------------------------------------------------===// -mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p, - cir::TargetAddressSpaceAttr &attr); +mlir::ParseResult parseAddressSpaceValue(mlir::AsmParser &p, + cir::LangAddressSpace &addrSpace) { + llvm::SMLoc loc = p.getCurrentLocation(); + mlir::FailureOr<cir::LangAddressSpace> result = + mlir::FieldParser<cir::LangAddressSpace>::parse(p); + if (mlir::failed(result)) + return p.emitError(loc, "expected address space keyword"); + addrSpace = result.value(); + return mlir::success(); +} -void printTargetAddressSpace(mlir::AsmPrinter &p, - cir::TargetAddressSpaceAttr attr); +void printAddressSpaceValue(mlir::AsmPrinter &p, + cir::LangAddressSpace addrSpace) { + p << cir::stringifyEnum(addrSpace); +} static mlir::ParseResult parseConstPtr(mlir::AsmParser &parser, mlir::IntegerAttr &value); @@ -64,6 +75,95 @@ static void printConstPtr(mlir::AsmPrinter &p, mlir::IntegerAttr value); using namespace mlir; using namespace cir; +//===----------------------------------------------------------------------===// +// MemorySpaceAttrInterface implementations for Lang and Target address space +// attributes +//===----------------------------------------------------------------------===// + +bool LangAddressSpaceAttr::isValidLoad( + mlir::Type type, mlir::ptr::AtomicOrdering ordering, + std::optional<int64_t> alignment, const mlir::DataLayout *dataLayout, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidLoad for LangAddressSpaceAttr NYI"); +} + +bool LangAddressSpaceAttr::isValidStore( + mlir::Type type, mlir::ptr::AtomicOrdering ordering, + std::optional<int64_t> alignment, const mlir::DataLayout *dataLayout, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidStore for LangAddressSpaceAttr NYI"); +} + +bool LangAddressSpaceAttr::isValidAtomicOp( + mlir::ptr::AtomicBinOp op, mlir::Type type, + mlir::ptr::AtomicOrdering ordering, std::optional<int64_t> alignment, + const mlir::DataLayout *dataLayout, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidAtomicOp for LangAddressSpaceAttr NYI"); +} + +bool LangAddressSpaceAttr::isValidAtomicXchg( + mlir::Type type, mlir::ptr::AtomicOrdering successOrdering, + mlir::ptr::AtomicOrdering failureOrdering, std::optional<int64_t> alignment, + const mlir::DataLayout *dataLayout, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidAtomicXchg for LangAddressSpaceAttr NYI"); +} + +bool LangAddressSpaceAttr::isValidAddrSpaceCast( + mlir::Type tgt, mlir::Type src, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidAddrSpaceCast for LangAddressSpaceAttr NYI"); +} + +bool LangAddressSpaceAttr::isValidPtrIntCast( + mlir::Type intLikeTy, mlir::Type ptrLikeTy, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidPtrIntCast for LangAddressSpaceAttr NYI"); +} + +bool TargetAddressSpaceAttr::isValidLoad( + mlir::Type type, mlir::ptr::AtomicOrdering ordering, + std::optional<int64_t> alignment, const mlir::DataLayout *dataLayout, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidLoad for TargetAddressSpaceAttr NYI"); +} + +bool TargetAddressSpaceAttr::isValidStore( + mlir::Type type, mlir::ptr::AtomicOrdering ordering, + std::optional<int64_t> alignment, const mlir::DataLayout *dataLayout, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidStore for TargetAddressSpaceAttr NYI"); +} + +bool TargetAddressSpaceAttr::isValidAtomicOp( + mlir::ptr::AtomicBinOp op, mlir::Type type, + mlir::ptr::AtomicOrdering ordering, std::optional<int64_t> alignment, + const mlir::DataLayout *dataLayout, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidAtomicOp for TargetAddressSpaceAttr NYI"); +} + +bool TargetAddressSpaceAttr::isValidAtomicXchg( + mlir::Type type, mlir::ptr::AtomicOrdering successOrdering, + mlir::ptr::AtomicOrdering failureOrdering, std::optional<int64_t> alignment, + const mlir::DataLayout *dataLayout, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidAtomicXchg for TargetAddressSpaceAttr NYI"); +} + +bool TargetAddressSpaceAttr::isValidAddrSpaceCast( + mlir::Type tgt, mlir::Type src, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidAddrSpaceCast for TargetAddressSpaceAttr NYI"); +} + +bool TargetAddressSpaceAttr::isValidPtrIntCast( + mlir::Type intLikeTy, mlir::Type ptrLikeTy, + llvm::function_ref<mlir::InFlightDiagnostic()> emitError) const { + llvm_unreachable("isValidPtrIntCast for TargetAddressSpaceAttr NYI"); +} + //===----------------------------------------------------------------------===// // General CIR parsing / printing //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index 43853b6696a94..8d97a8d5c88cd 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -60,6 +60,14 @@ static void printFuncTypeParams(mlir::AsmPrinter &p, // AddressSpace //===----------------------------------------------------------------------===// +mlir::ParseResult +parseAddressSpaceValue(mlir::AsmParser &p, + mlir::ptr::MemorySpaceAttrInterface &attr); + +void printAddressSpaceValue(mlir::AsmPrinter &printer, + mlir::ptr::MemorySpaceAttrInterface attr); + +// Custom parser/printer for the `addrSpace` parameter in `!cir.ptr`. mlir::ParseResult parseTargetAddressSpace(mlir::AsmParser &p, cir::TargetAddressSpaceAttr &attr); @@ -930,9 +938,111 @@ void cir::VectorType::print(mlir::AsmPrinter &odsPrinter) const { } //===----------------------------------------------------------------------===// -// TargetAddressSpace definitions +// AddressSpace definitions //===----------------------------------------------------------------------===// +cir::LangAddressSpace cir::toCIRLangAddressSpace(clang::LangAS langAS) { + using clang::LangAS; + switch (langAS) { + case LangAS::Default: + return LangAddressSpace::Default; + case LangAS::opencl_global: + return LangAddressSpace::OffloadGlobal; + case LangAS::opencl_local: + case LangAS::cuda_shared: + // Local means local among the work-group (OpenCL) or block (CUDA). + // All threads inside the kernel can access local memory. + return LangAddressSpace::OffloadLocal; + case LangAS::cuda_device: + return LangAddressSpace::OffloadGlobal; + case LangAS::opencl_constant: + case LangAS::cuda_constant: + return LangAddressSpace::OffloadConstant; + case LangAS::opencl_private: + return LangAddressSpace::OffloadPrivate; + case LangAS::opencl_generic: + return LangAddressSpace::OffloadGeneric; + case LangAS::opencl_global_device: + case LangAS::opencl_global_host: + case LangAS::sycl_global: + case LangAS::sycl_global_device: + case LangAS::sycl_global_host: + case LangAS::sycl_local: + case LangAS::sycl_private: + case LangAS::ptr32_sptr: + case LangAS::ptr32_uptr: + case LangAS::ptr64: + case LangAS::hlsl_groupshared: + case LangAS::wasm_funcref: + llvm_unreachable("NYI"); + default: + llvm_unreachable("unknown/unsupported clang language address space"); + } +} + +mlir::ParseResult +parseAddressSpaceValue(mlir::AsmParser &p, + mlir::ptr::MemorySpaceAttrInterface &attr) { + + llvm::SMLoc loc = p.getCurrentLocation(); + + // Try to parse target address space first. + attr = nullptr; + if (p.parseOptionalKeyword("target_address_space").succeeded()) { + unsigned val; + if (p.parseLParen()) + return p.emitError(loc, "expected '(' after 'target_address_space'"); + + if (p.parseInteger(val)) + return p.emitError(loc, "expected target address space value"); + + if (p.parseRParen()) + return p.emitError(loc, "expected ')'"); + + attr = cir::TargetAddressSpaceAttr::get( + p.getContext(), p.getBuilder().getUI32IntegerAttr(val)); + return mlir::success(); + } + + // Try to parse language specific address space. + if (p.parseOptionalKeyword("lang_address_space").succeeded()) { + if (p.parseLParen()) + return p.emitError(loc, "expected '(' after 'lang_address_space'"); + + mlir::FailureOr<cir::LangAddressSpace> result = + mlir::FieldParser<cir::LangAddressSpace>::parse(p); + if (mlir::failed(result)) + return p.emitError(loc, "expected language address space keyword"); + + if (p.parseRParen()) + return p.emitError(loc, "expected ')'"); + + attr = cir::LangAddressSpaceAttr::get(p.getContext(), result.value()); + return mlir::success(); + } + + return mlir::success(); +} + +void printAddressSpaceValue(mlir::AsmPrinter &p, + mlir::ptr::MemorySpaceAttrInterface attr) { + if (!attr) + return; + + if (auto language = dyn_cast<cir::LangAddressSpaceAttr>(attr)) { + p << "lang_address_space(" + << cir::stringifyLangAddressSpace(language.getValue()) << ')'; + return; + } + + if (auto target = dyn_cast<cir::TargetAddressSpaceAttr>(attr)) { + p << "target_address_space(" << target.getValue() << ')'; + return; + } + + llvm_unreachable("unexpected address-space attribute kind"); +} + cir::TargetAddressSpaceAttr cir::toCIRTargetAddressSpace(mlir::MLIRContext &context, clang::LangAS langAS) { return cir::TargetAddressSpaceAttr::get( `````````` </details> https://github.com/llvm/llvm-project/pull/179054 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
