Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
762b392
[CIR][AddrSpace] Backport TargetAddressSpaceAttr and Support both lan…
RiverDave Nov 15, 2025
2cd5a0d
Polish and remove redundant functions
RiverDave Nov 17, 2025
7fc63cd
Handle hybrid AS approach with GlobalOps
RiverDave Nov 17, 2025
3f68045
Correct comma on global asm format by providing an optional parser
RiverDave Nov 18, 2025
3c6657f
Change Builder for globalOps to take an empty attr to represent defau…
RiverDave Nov 19, 2025
c1cc66e
Remove Target AS handling from `cir::AddressSpace`
RiverDave Nov 19, 2025
64b297a
Rename AddressSpace to ClangAddressSpace for clarity
RiverDave Nov 20, 2025
ce44c84
Fix crash on runnin isa on empty attr
RiverDave Nov 20, 2025
2c3b64e
Polish comments and docs description
RiverDave Nov 20, 2025
ff5614b
Bring Assertion guards for data ptr size based on AS
RiverDave Nov 20, 2025
665c55c
Fix formatting
RiverDave Nov 20, 2025
d460031
Fix more formatting errors
RiverDave Nov 20, 2025
1599157
rename AS conversion fn for clarity
RiverDave Nov 20, 2025
21d9ece
Implement MemorySpaceInterface for Clang and Target AS attributes
RiverDave Nov 26, 2025
3d97922
Rename ClangAddressspace -> LangAddressSpace throughout CIR codebase
RiverDave Nov 26, 2025
c643bb0
rename AS asm format: clang_address_space -> language_address_space
RiverDave Nov 26, 2025
4a993e8
Delete nit comment and delete unused headers
RiverDave Nov 26, 2025
860ac4d
address comments on renaming
RiverDave Nov 26, 2025
115c9f7
Fix formatting
RiverDave Nov 26, 2025
22cc615
fix formatting once again
RiverDave Nov 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,23 @@

#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/CIR/Dialect/IR/CIRAttrs.h"
#include "clang/CIR/Dialect/IR/CIRDialect.h"
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/Dialect/IR/FPEnv.h"
#include "clang/CIR/MissingFeatures.h"

#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/Location.h"
#include "mlir/IR/Types.h"
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FloatingPointMode.h"
Expand Down Expand Up @@ -105,20 +108,30 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
return cir::PointerType::get(ty);
}

cir::PointerType getPointerTo(mlir::Type ty, cir::AddressSpace as) {
return cir::PointerType::get(ty, as);
/// Create a pointer type with an address space attribute.
cir::PointerType
getPointerTo(mlir::Type ty, mlir::ptr::MemorySpaceAttrInterface memorySpace) {
if (!memorySpace)
return cir::PointerType::get(ty);
return cir::PointerType::get(ty, memorySpace);
}

cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
return getPointerTo(ty, cir::toCIRAddressSpace(langAS));
if (langAS == clang::LangAS::Default)
return getPointerTo(ty);

mlir::ptr::MemorySpaceAttrInterface addrSpaceAttr =
cir::toCIRLangAddressSpaceAttr(getContext(), langAS);
return getPointerTo(ty, addrSpaceAttr);
}

cir::PointerType getVoidPtrTy(clang::LangAS langAS = clang::LangAS::Default) {
return getPointerTo(cir::VoidType::get(getContext()), langAS);
}

cir::PointerType getVoidPtrTy(cir::AddressSpace as) {
return getPointerTo(cir::VoidType::get(getContext()), as);
cir::PointerType
getVoidPtrTy(mlir::ptr::MemorySpaceAttrInterface memorySpace) {
return getPointerTo(cir::VoidType::get(getContext()), memorySpace);
}

cir::MethodAttr getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
Expand Down Expand Up @@ -419,7 +432,8 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global,
bool threadLocal = false) {
return cir::GetGlobalOp::create(
*this, loc, getPointerTo(global.getSymType(), global.getAddrSpace()),
*this, loc,
getPointerTo(global.getSymType(), global.getAddrSpaceAttr()),
global.getName(), threadLocal);
}

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
64 changes: 49 additions & 15 deletions clang/include/clang/CIR/Dialect/IR/CIRAttrs.td
Original file line number Diff line number Diff line change
Expand Up @@ -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/CIREnumAttr.td"

include "clang/CIR/Dialect/IR/CIRDialect.td"
Expand Down Expand Up @@ -963,43 +964,76 @@ def CIR_DynamicCastInfoAttr : CIR_Attr<"DynamicCastInfo", "dyn_cast_info"> {
// AddressSpaceAttr
//===----------------------------------------------------------------------===//

def CIR_AddressSpaceAttr : CIR_EnumAttr<CIR_AddressSpace, "address_space"> {
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 while and
preserves 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::toCIRAddressSpace(langAS));
return $_get($_ctxt, cir::toCIRLangAddressSpace(langAS));
}]>
];

let assemblyFormat = [{
`(` custom<AddressSpaceValue>($value) `)`
}];

let defaultValue = "cir::AddressSpace::Default";
let defaultValue = "cir::LangAddressSpace::Default";

let extraClassDeclaration = [{
bool isLang() const;
bool isTarget() const;
unsigned getTargetValue() const;
unsigned getAsUnsignedValue() const;
}];

let extraClassDefinition = [{
unsigned $cppClass::getAsUnsignedValue() const {
return static_cast<unsigned>(getValue());
}
}];
}

bool $cppClass::isLang() const {
return cir::isLangAddressSpace(getValue());
}
//===----------------------------------------------------------------------===//
// TargetAddressSpaceAttr
//===----------------------------------------------------------------------===//

bool $cppClass::isTarget() const {
return cir::isTargetAddressSpace(getValue());
}
def CIR_TargetAddressSpaceAttr : CIR_Attr< "TargetAddressSpace",
"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
`address_space` attribute.

A value of zero represents the default address space. The semantics of non-zero
address spaces are target-specific.

unsigned $cppClass::getTargetValue() const {
return cir::getTargetAddressSpaceValue(getValue());
}
Example:
```mlir
// Target-specific numeric address spaces
!cir.ptr<!s32i, target_address_space(1)>
!cir.ptr<!s32i, target_address_space(1)>
```
}];

let parameters = (ins "unsigned":$value);
let assemblyFormat = "`<` `target` `<` $value `>` `>`";
}

//===----------------------------------------------------------------------===//
Expand Down
9 changes: 4 additions & 5 deletions clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,14 @@ class CIR_DefaultValuedEnumParameter<EnumAttrInfo info, string value = "">
let defaultValue = value;
}

def CIR_AddressSpace : CIR_I32EnumAttr<
"AddressSpace", "address space kind", [
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">,
I32EnumAttrCase<"Target", 6, "target">
I32EnumAttrCase<"OffloadGeneric", 5, "offload_generic">
]> {
let description = [{
The `address_space` attribute is used to represent address spaces for
Expand All @@ -58,7 +57,7 @@ def CIR_AddressSpace : CIR_I32EnumAttr<

The `value` parameter is an extensible enum, which encodes target address
space as an offset to the last language address space. For that reason, the
attribute is implemented as custom AddressSpaceAttr, which provides custom
attribute is implemented as custom LangAddressSpaceAttr, which provides custom
printer and parser for the `value` parameter.
}];

Expand Down
9 changes: 3 additions & 6 deletions clang/include/clang/CIR/Dialect/IR/CIROps.td
Original file line number Diff line number Diff line change
Expand Up @@ -2618,10 +2618,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
OptionalAttr<StrAttr>:$sym_visibility,
TypeAttr:$sym_type,
CIR_GlobalLinkageKind:$linkage,
DefaultValuedAttr<
CIR_AddressSpaceAttr,
"AddressSpace::Default"
>:$addr_space,
OptionalAttr<MemorySpaceAttrInterface>:$addr_space,
OptionalAttr<CIR_TLSModel>:$tls_model,
// Note this can also be a FlatSymbolRefAttr
OptionalAttr<AnyAttr>:$initial_value,
Expand All @@ -2644,7 +2641,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
(`comdat` $comdat^)?
($tls_model^)?
(`dso_local` $dso_local^)?
(`addrspace` `` $addr_space^)?
(` ` custom<GlobalAddressSpaceValue>($addr_space)^ )?
$sym_name
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, $ctorRegion, $dtorRegion)
($annotations^)?
Expand All @@ -2668,7 +2665,7 @@ def CIR_GlobalOp : CIR_Op<"global", [
// CIR defaults to external linkage.
CArg<"cir::GlobalLinkageKind",
"cir::GlobalLinkageKind::ExternalLinkage">:$linkage,
CArg<"cir::AddressSpace", "cir::AddressSpace::Default">:$addrSpace,
CArg<"mlir::ptr::MemorySpaceAttrInterface", "{}">:$addrSpace,
CArg<"llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>",
"nullptr">:$ctorBuilder,
CArg<"llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>",
Expand Down
38 changes: 10 additions & 28 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -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/BuiltinAttributes.h"
#include "mlir/IR/Types.h"
#include "mlir/Interfaces/DataLayoutInterfaces.h"
Expand All @@ -34,37 +35,18 @@ bool isSized(mlir::Type ty);
// AddressSpace helpers
//===----------------------------------------------------------------------===//

cir::AddressSpace toCIRAddressSpace(clang::LangAS langAS);
cir::LangAddressSpace toCIRLangAddressSpace(clang::LangAS langAS);

constexpr unsigned getAsUnsignedValue(cir::AddressSpace as) {
return static_cast<unsigned>(as);
}

inline constexpr unsigned TargetAddressSpaceOffset =
cir::getMaxEnumValForAddressSpace();

// Target address space is used for target-specific address spaces that are not
// part of the enum. Its value is represented as an offset from the maximum
// value of the enum. Make sure that it is always the last enum value.
static_assert(getAsUnsignedValue(cir::AddressSpace::Target) ==
cir::getMaxEnumValForAddressSpace(),
"Target address space must be the last enum value");

constexpr bool isTargetAddressSpace(cir::AddressSpace as) {
return getAsUnsignedValue(as) >= cir::getMaxEnumValForAddressSpace();
}
/// Convert a LangAS to the appropriate address space attribute interface.
/// Returns a MemorySpaceAttrInterface.
mlir::ptr::MemorySpaceAttrInterface
toCIRLangAddressSpaceAttr(mlir::MLIRContext *ctx, clang::LangAS langAS);

constexpr bool isLangAddressSpace(cir::AddressSpace as) {
return !isTargetAddressSpace(as);
}
bool isSupportedCIRMemorySpaceAttr(
mlir::ptr::MemorySpaceAttrInterface memorySpace);

constexpr unsigned getTargetAddressSpaceValue(cir::AddressSpace as) {
assert(isTargetAddressSpace(as) && "expected target address space");
return getAsUnsignedValue(as) - TargetAddressSpaceOffset;
}

constexpr cir::AddressSpace computeTargetAddressSpace(unsigned v) {
return static_cast<cir::AddressSpace>(v + TargetAddressSpaceOffset);
constexpr unsigned getAsUnsignedValue(cir::LangAddressSpace as) {
return static_cast<unsigned>(as);
}

} // namespace cir
Expand Down
15 changes: 8 additions & 7 deletions clang/include/clang/CIR/Dialect/IR/CIRTypes.td
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
include "clang/CIR/Dialect/IR/CIRDialect.td"
include "clang/CIR/Dialect/IR/CIREnumAttr.td"
include "clang/CIR/Dialect/IR/CIRTypeConstraints.td"
include "clang/CIR/Dialect/IR/CIRAttrConstraints.td"
include "clang/CIR/Interfaces/ASTAttrInterfaces.td"
include "clang/CIR/Interfaces/CIRTypeInterfaces.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/EnumAttr.td"
include "mlir/IR/CommonAttrConstraints.td"

//===----------------------------------------------------------------------===//
// CIR Types
Expand Down Expand Up @@ -231,32 +233,31 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
```
}];

let genVerifyDecl = 1;

let parameters = (ins
"mlir::Type":$pointee,
CIR_DefaultValuedEnumParameter<
CIR_AddressSpace,
"cir::AddressSpace::Default"
>:$addrSpace
OptionalParameter<"mlir::ptr::MemorySpaceAttrInterface">:$addrSpace
);

let skipDefaultBuilders = 1;
let builders = [
TypeBuilderWithInferredContext<(ins
"mlir::Type":$pointee,
CArg<"cir::AddressSpace", "cir::AddressSpace::Default">:$addrSpace), [{
CArg<"mlir::ptr::MemorySpaceAttrInterface", "{}">:$addrSpace), [{
return $_get(pointee.getContext(), pointee, addrSpace);
}]>,
TypeBuilder<(ins
"mlir::Type":$pointee,
CArg<"cir::AddressSpace", "cir::AddressSpace::Default">:$addrSpace), [{
CArg<"mlir::ptr::MemorySpaceAttrInterface", "{}">:$addrSpace), [{
return $_get($_ctxt, pointee, addrSpace);
}]>
];

let assemblyFormat = [{
`<`
$pointee
( `,` `addrspace` `(` `` custom<AddressSpaceValue>($addrSpace)^ `)` )?
( `,` ` ` custom<AddressSpaceValue>($addrSpace)^ )?
`>`
}];

Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/CIR/MissingFeatures.h
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,8 @@ struct MissingFeatures {
static bool mustProgress() { return false; }

static bool skipTempCopy() { return false; }

static bool dataLayoutPtrHandlingBasedOnLangAS() { return false; }
};

} // namespace cir
Expand Down
12 changes: 7 additions & 5 deletions clang/lib/CIR/CodeGen/CIRGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "clang/CIR/Dialect/IR/CIRTypes.h"
#include "clang/CIR/Dialect/IR/FPEnv.h"

#include "mlir/Dialect/Ptr/IR/MemorySpaceInterfaces.h"
#include "mlir/IR/Attributes.h"
#include "mlir/IR/Builders.h"
#include "mlir/IR/BuiltinAttributes.h"
Expand Down Expand Up @@ -749,7 +750,7 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
[[nodiscard]] cir::GlobalOp
createGlobal(mlir::ModuleOp module, mlir::Location loc, mlir::StringRef name,
mlir::Type type, bool isConst, cir::GlobalLinkageKind linkage,
cir::AddressSpace addrSpace = cir::AddressSpace::Default) {
mlir::ptr::MemorySpaceAttrInterface addrSpace = {}) {
mlir::OpBuilder::InsertionGuard guard(*this);
setInsertionPointToStart(module.getBody());
return cir::GlobalOp::create(*this, loc, name, type, isConst, linkage,
Expand All @@ -759,10 +760,11 @@ class CIRGenBuilderTy : public cir::CIRBaseBuilderTy {
/// Creates a versioned global variable. If the symbol is already taken, an ID
/// will be appended to the symbol. The returned global must always be queried
/// for its name so it can be referenced correctly.
[[nodiscard]] cir::GlobalOp createVersionedGlobal(
mlir::ModuleOp module, mlir::Location loc, mlir::StringRef name,
mlir::Type type, bool isConst, cir::GlobalLinkageKind linkage,
cir::AddressSpace addrSpace = cir::AddressSpace::Default) {
[[nodiscard]] cir::GlobalOp
createVersionedGlobal(mlir::ModuleOp module, mlir::Location loc,
mlir::StringRef name, mlir::Type type, bool isConst,
cir::GlobalLinkageKind linkage,
mlir::ptr::MemorySpaceAttrInterface addrSpace = {}) {
// Create a unique name if the given name is already taken.
std::string uniqueName;
if (unsigned version = GlobalsVersioning[name.str()]++)
Expand Down
Loading