Skip to content

Commit 91950f7

Browse files
committed
[CIR] Upstream AddressSpace support for PointerType
1 parent 378b6d5 commit 91950f7

File tree

15 files changed

+370
-44
lines changed

15 files changed

+370
-44
lines changed

clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,20 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
129129
return cir::PointerType::get(ty);
130130
}
131131

132-
cir::PointerType getVoidPtrTy() {
133-
return getPointerTo(cir::VoidType::get(getContext()));
132+
cir::PointerType getPointerTo(mlir::Type ty, cir::AddressSpace as) {
133+
return cir::PointerType::get(ty, as);
134+
}
135+
136+
cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
137+
return getPointerTo(ty, cir::toCIRAddressSpace(langAS));
138+
}
139+
140+
cir::PointerType getVoidPtrTy(clang::LangAS langAS = clang::LangAS::Default) {
141+
return getPointerTo(cir::VoidType::get(getContext()), langAS);
142+
}
143+
144+
cir::PointerType getVoidPtrTy(cir::AddressSpace as) {
145+
return getPointerTo(cir::VoidType::get(getContext()), as);
134146
}
135147

136148
cir::BoolAttr getCIRBoolAttr(bool state) {

clang/include/clang/CIR/Dialect/IR/CIRAttrs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include "mlir/IR/Attributes.h"
1717
#include "mlir/IR/BuiltinAttributeInterfaces.h"
18+
#include "clang/Basic/AddressSpaces.h"
1819

1920
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
2021

clang/include/clang/CIR/Dialect/IR/CIRAttrs.td

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,47 @@ def CIR_VTableAttr : CIR_Attr<"VTable", "vtable", [TypedAttrInterface]> {
601601
}];
602602
}
603603

604+
//===----------------------------------------------------------------------===//
605+
// AddressSpaceAttr
606+
//===----------------------------------------------------------------------===//
607+
608+
def CIR_AddressSpaceAttr : CIR_EnumAttr<CIR_AddressSpace, "address_space"> {
609+
let builders = [AttrBuilder<(ins "clang::LangAS":$langAS), [{
610+
return $_get($_ctxt, cir::toCIRAddressSpace(langAS));
611+
}]>];
612+
613+
let assemblyFormat = [{
614+
`` custom<AddressSpaceValue>($value)
615+
}];
616+
617+
let defaultValue = "cir::AddressSpace::Default";
618+
619+
let extraClassDeclaration = [{
620+
bool isLang() const;
621+
bool isTarget() const;
622+
unsigned getTargetValue() const;
623+
unsigned getAsUnsignedValue() const;
624+
}];
625+
626+
let extraClassDefinition = [{
627+
unsigned $cppClass::getAsUnsignedValue() const {
628+
return static_cast<unsigned>(getValue());
629+
}
630+
631+
bool $cppClass::isLang() const {
632+
return cir::isLangAddressSpace(getValue());
633+
}
634+
635+
bool $cppClass::isTarget() const {
636+
return cir::isTargetAddressSpace(getValue());
637+
}
638+
639+
unsigned $cppClass::getTargetValue() const {
640+
return cir::getTargetAddressSpaceValue(getValue());
641+
}
642+
}];
643+
}
644+
604645
//===----------------------------------------------------------------------===//
605646
// ConstComplexAttr
606647
//===----------------------------------------------------------------------===//

clang/include/clang/CIR/Dialect/IR/CIREnumAttr.td

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,28 @@ class CIR_DefaultValuedEnumParameter<EnumAttrInfo info, string value = "">
3535
let defaultValue = value;
3636
}
3737

38+
def CIR_AddressSpace
39+
: CIR_I32EnumAttr<
40+
"AddressSpace", "address space kind",
41+
[I32EnumAttrCase<"Default", 0, "default">,
42+
I32EnumAttrCase<"OffloadPrivate", 1, "offload_private">,
43+
I32EnumAttrCase<"OffloadLocal", 2, "offload_local">,
44+
I32EnumAttrCase<"OffloadGlobal", 3, "offload_global">,
45+
I32EnumAttrCase<"OffloadConstant", 4, "offload_constant">,
46+
I32EnumAttrCase<"OffloadGeneric", 5, "offload_generic">,
47+
I32EnumAttrCase<"Target", 6, "target">]> {
48+
let description = [{
49+
The `address_space` attribute is used to represent address spaces for
50+
pointer types in CIR. It provides a unified model on top of `clang::LangAS`
51+
and simplifies the representation of address spaces.
52+
53+
The `value` parameter is an extensible enum, which encodes target address
54+
space as an offset to the last language address space. For that reason, the
55+
attribute is implemented as custom AddressSpaceAttr, which provides custom
56+
printer and parser for the `value` parameter.
57+
}];
58+
59+
let genSpecializedAttr = 0;
60+
}
61+
3862
#endif // CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD

clang/include/clang/CIR/Dialect/IR/CIRTypes.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include "mlir/IR/BuiltinAttributes.h"
1717
#include "mlir/IR/Types.h"
1818
#include "mlir/Interfaces/DataLayoutInterfaces.h"
19+
#include "clang/Basic/AddressSpaces.h"
20+
#include "clang/CIR/Dialect/IR/CIROpsEnums.h"
1921
#include "clang/CIR/Interfaces/CIRTypeInterfaces.h"
2022

2123
namespace cir {
@@ -35,6 +37,42 @@ bool isValidFundamentalIntWidth(unsigned width);
3537
/// void, or abstract types.
3638
bool isSized(mlir::Type ty);
3739

40+
//===----------------------------------------------------------------------===//
41+
// AddressSpace helpers
42+
//===----------------------------------------------------------------------===//
43+
44+
cir::AddressSpace toCIRAddressSpace(clang::LangAS langAS);
45+
46+
constexpr unsigned getAsUnsignedValue(cir::AddressSpace as) {
47+
return static_cast<unsigned>(as);
48+
}
49+
50+
inline constexpr unsigned targetAddressSpaceOffset =
51+
cir::getMaxEnumValForAddressSpace();
52+
53+
// Target address space is used for target-specific address spaces that are not
54+
// part of the enum. Its value is represented as an offset from the maximum
55+
// value of the enum. Make sure that it is always the last enum value.
56+
static_assert(getAsUnsignedValue(cir::AddressSpace::Target) ==
57+
cir::getMaxEnumValForAddressSpace(),
58+
"Target address space must be the last enum value");
59+
60+
constexpr bool isTargetAddressSpace(cir::AddressSpace as) {
61+
return getAsUnsignedValue(as) >= cir::getMaxEnumValForAddressSpace();
62+
}
63+
64+
constexpr bool isLangAddressSpace(cir::AddressSpace as) {
65+
return !isTargetAddressSpace(as);
66+
}
67+
68+
constexpr unsigned getTargetAddressSpaceValue(cir::AddressSpace as) {
69+
assert(isTargetAddressSpace(as) && "expected target address space");
70+
return getAsUnsignedValue(as) - targetAddressSpaceOffset;
71+
}
72+
73+
constexpr cir::AddressSpace computeTargetAddressSpace(unsigned v) {
74+
return static_cast<cir::AddressSpace>(v + targetAddressSpaceOffset);
75+
}
3876
} // namespace cir
3977

4078
//===----------------------------------------------------------------------===//

clang/include/clang/CIR/Dialect/IR/CIRTypes.td

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@
1414
#define CLANG_CIR_DIALECT_IR_CIRTYPES_TD
1515

1616
include "clang/CIR/Dialect/IR/CIRDialect.td"
17+
include "clang/CIR/Dialect/IR/CIREnumAttr.td"
1718
include "clang/CIR/Dialect/IR/CIRTypeConstraints.td"
1819
include "clang/CIR/Interfaces/CIRTypeInterfaces.td"
1920
include "mlir/Interfaces/DataLayoutInterfaces.td"
2021
include "mlir/IR/AttrTypeBase.td"
22+
include "mlir/IR/EnumAttr.td"
2123

2224
//===----------------------------------------------------------------------===//
2325
// CIR Types
@@ -226,31 +228,57 @@ def CIR_PointerType : CIR_Type<"Pointer", "ptr", [
226228
]> {
227229
let summary = "CIR pointer type";
228230
let description = [{
229-
The `!cir.ptr` type represents C and C++ pointer types and C++ reference
230-
types, other than pointers-to-members. The `pointee` type is the type
231-
pointed to.
231+
The `!cir.ptr` type is a typed pointer type. It is used to represent
232+
pointers to objects in C/C++. The type of the pointed-to object is given by
233+
the `pointee` parameter. The `addrSpace` parameter is an optional address
234+
space attribute that specifies the address space of the pointer. If not
235+
specified, the pointer is assumed to be in the default address space.
232236

233-
TODO(CIR): The address space attribute is not yet implemented.
234-
}];
237+
The `!cir.ptr` type can point to any type, including fundamental types,
238+
records, arrays, vectors, functions, and other pointers. It can also point
239+
to incomplete types, such as incomplete records.
235240

236-
let parameters = (ins "mlir::Type":$pointee);
241+
Note: Data-member pointers and method pointers are represented by
242+
`!cir.data_member` and `!cir.method` types, respectively not by
243+
`!cir.ptr` type.
237244

238-
let builders = [
239-
TypeBuilderWithInferredContext<(ins "mlir::Type":$pointee), [{
240-
return $_get(pointee.getContext(), pointee);
241-
}]>,
242-
TypeBuilder<(ins "mlir::Type":$pointee), [{
243-
return $_get($_ctxt, pointee);
244-
}]>
245-
];
245+
Examples:
246246

247-
let assemblyFormat = [{
248-
`<` $pointee `>`
247+
```mlir
248+
!cir.ptr<!cir.int<u, 8>>
249+
!cir.ptr<!cir.float>
250+
!cir.ptr<!cir.record<struct "MyStruct">>
251+
!cir.ptr<!cir.record<struct "MyStruct">, addrspace(offload_private)>
252+
!cir.ptr<!cir.int<u, 8>, addrspace(target<1>)>
253+
```
249254
}];
250255

251-
let genVerifyDecl = 1;
256+
let parameters = (ins "mlir::Type":$pointee,
257+
CIR_DefaultValuedEnumParameter<CIR_AddressSpace,
258+
"cir::AddressSpace::Default">:$addrSpace);
252259

253260
let skipDefaultBuilders = 1;
261+
let builders = [TypeBuilderWithInferredContext<
262+
(ins "mlir::Type":$pointee,
263+
CArg<"cir::AddressSpace",
264+
"cir::AddressSpace::Default">:$addrSpace),
265+
[{
266+
return $_get(pointee.getContext(), pointee, addrSpace);
267+
}]>,
268+
TypeBuilder<
269+
(ins "mlir::Type":$pointee,
270+
CArg<"cir::AddressSpace",
271+
"cir::AddressSpace::Default">:$addrSpace),
272+
[{
273+
return $_get($_ctxt, pointee, addrSpace);
274+
}]>];
275+
276+
let assemblyFormat = [{
277+
`<`
278+
$pointee
279+
( `,` `addrspace` `(` custom<AddressSpaceValue>($addrSpace)^ `)` )?
280+
`>`
281+
}];
254282

255283
let extraClassDeclaration = [{
256284
template <typename ...Types>

clang/lib/CIR/CodeGen/CIRGenExpr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2053,7 +2053,8 @@ mlir::Value CIRGenFunction::emitAlloca(StringRef name, mlir::Type ty,
20532053
// layout like original CodeGen. The data layout awareness should be done in
20542054
// the lowering pass instead.
20552055
assert(!cir::MissingFeatures::addressSpace());
2056-
cir::PointerType localVarPtrTy = builder.getPointerTo(ty);
2056+
cir::PointerType localVarPtrTy =
2057+
builder.getPointerTo(ty, getCIRAllocaAddressSpace());
20572058
mlir::IntegerAttr alignIntAttr = cgm.getSize(alignment);
20582059

20592060
mlir::Value addr;

clang/lib/CIR/CodeGen/CIRGenTypeCache.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,19 @@ struct CIRGenTypeCache {
7373
/// The alignment of size_t.
7474
unsigned char SizeAlignInBytes;
7575

76+
cir::AddressSpace cirAllocaAddressSpace;
77+
7678
clang::CharUnits getSizeAlign() const {
7779
return clang::CharUnits::fromQuantity(SizeAlignInBytes);
7880
}
7981

8082
clang::CharUnits getPointerAlign() const {
8183
return clang::CharUnits::fromQuantity(PointerAlignInBytes);
8284
}
85+
86+
cir::AddressSpace getCIRAllocaAddressSpace() const {
87+
return cirAllocaAddressSpace;
88+
}
8389
};
8490

8591
} // namespace clang::CIRGen

clang/lib/CIR/CodeGen/CIRGenTypes.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ mlir::Type CIRGenTypes::convertType(QualType type) {
417417

418418
mlir::Type pointeeType = convertType(elemTy);
419419

420-
resultType = builder.getPointerTo(pointeeType);
420+
resultType = builder.getPointerTo(pointeeType, elemTy.getAddressSpace());
421421
break;
422422
}
423423

clang/lib/CIR/CodeGen/TargetInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ bool isEmptyFieldForLayout(const ASTContext &context, const FieldDecl *fd);
3232
/// if the [[no_unique_address]] attribute would have made them empty.
3333
bool isEmptyRecordForLayout(const ASTContext &context, QualType t);
3434

35+
class CIRGenFunction;
36+
3537
class TargetCIRGenInfo {
3638
std::unique_ptr<ABIInfo> info;
3739

0 commit comments

Comments
 (0)