Skip to content

Commit b7dffc3

Browse files
authored
[CIR] Refactor AddressSpace to use enum more thoroughly instead of attribute (#1733)
- Remove redundant custom printer and parser for AddressSpace, relying instead on MLIR's default EnumAttr handling. - Leverage AddressSpace::Default to omit the attribute from the assembly form when not needed. Therefore, an empty attribute is no longer needed to represent the default address space. - Update PointerType to use the AddressSpace enum directly, instead of a boxed attribute.
1 parent f9d47e9 commit b7dffc3

31 files changed

+424
-427
lines changed

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

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -93,27 +93,24 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
9393
return cir::IntType::get(getContext(), N, true);
9494
}
9595

96-
cir::AddressSpaceAttr getAddrSpaceAttr(clang::LangAS langAS) {
97-
if (langAS == clang::LangAS::Default)
98-
return {};
99-
return cir::AddressSpaceAttr::get(getContext(), langAS);
96+
cir::PointerType getPointerTo(mlir::Type ty) {
97+
return cir::PointerType::get(ty);
10098
}
10199

102-
cir::PointerType getPointerTo(mlir::Type ty,
103-
cir::AddressSpaceAttr cirAS = {}) {
104-
return cir::PointerType::get(ty, cirAS);
100+
cir::PointerType getPointerTo(mlir::Type ty, cir::AddressSpace as) {
101+
return cir::PointerType::get(ty, as);
105102
}
106103

107104
cir::PointerType getPointerTo(mlir::Type ty, clang::LangAS langAS) {
108-
return getPointerTo(ty, getAddrSpaceAttr(langAS));
105+
return getPointerTo(ty, cir::toCIRAddressSpace(langAS));
109106
}
110107

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

115-
cir::PointerType getVoidPtrTy(cir::AddressSpaceAttr cirAS) {
116-
return getPointerTo(cir::VoidType::get(getContext()), cirAS);
112+
cir::PointerType getVoidPtrTy(cir::AddressSpace as) {
113+
return getPointerTo(cir::VoidType::get(getContext()), as);
117114
}
118115

119116
cir::MethodAttr getMethodAttr(cir::MethodType ty, cir::FuncOp methodFuncOp) {
@@ -396,7 +393,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
396393
mlir::Value createGetGlobal(mlir::Location loc, cir::GlobalOp global,
397394
bool threadLocal = false) {
398395
return create<cir::GetGlobalOp>(
399-
loc, getPointerTo(global.getSymType(), global.getAddrSpaceAttr()),
396+
loc, getPointerTo(global.getSymType(), global.getAddrSpace()),
400397
global.getName(), threadLocal);
401398
}
402399

@@ -774,9 +771,7 @@ class CIRBaseBuilderTy : public mlir::OpBuilder {
774771
auto methodFuncInputTypes = methodFuncTy.getInputs();
775772

776773
auto objectPtrTy = mlir::cast<cir::PointerType>(objectPtr.getType());
777-
auto objectPtrAddrSpace = mlir::cast_if_present<cir::AddressSpaceAttr>(
778-
objectPtrTy.getAddrSpace());
779-
auto adjustedThisTy = getVoidPtrTy(objectPtrAddrSpace);
774+
auto adjustedThisTy = getVoidPtrTy(objectPtrTy.getAddrSpace());
780775

781776
llvm::SmallVector<mlir::Type, 8> calleeFuncInputTypes{adjustedThisTy};
782777
calleeFuncInputTypes.insert(calleeFuncInputTypes.end(),

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

Lines changed: 15 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
#define MLIR_CIR_DIALECT_CIR_ATTRS
1515

1616
include "mlir/IR/BuiltinAttributeInterfaces.td"
17-
include "mlir/IR/EnumAttr.td"
17+
include "clang/CIR/Dialect/IR/CIREnumAttr.td"
1818

1919
include "clang/CIR/Dialect/IR/CIRDialect.td"
2020
include "clang/CIR/Dialect/IR/CIRAttrConstraints.td"
@@ -45,21 +45,6 @@ class CIR_TypedAttr<string name, string attrMnemonic, list<Trait> traits = []>
4545
let assemblyFormat = [{}];
4646
}
4747

48-
class CIR_I32EnumAttr<string name, string summary, list<I32EnumAttrCase> cases>
49-
: I32EnumAttr<name, summary, cases> {
50-
let cppNamespace = "::cir";
51-
}
52-
53-
class CIR_I64EnumAttr<string name, string summary, list<I64EnumAttrCase> cases>
54-
: I64EnumAttr<name, summary, cases> {
55-
let cppNamespace = "::cir";
56-
}
57-
58-
class CIR_EnumAttr<EnumAttrInfo info, string name = "", list<Trait> traits = []>
59-
: EnumAttr<CIR_Dialect, info, name, traits> {
60-
let assemblyFormat = "`<` $value `>`";
61-
}
62-
6348
class CIRUnitAttr<string name, string attrMnemonic, list<Trait> traits = []>
6449
: CIR_Attr<name, attrMnemonic, traits> {
6550
let returnType = "bool";
@@ -972,133 +957,41 @@ def DynamicCastInfoAttr
972957
// AddressSpaceAttr
973958
//===----------------------------------------------------------------------===//
974959

975-
def AS_OffloadPrivate : I32EnumAttrCase<"offload_private", 1>;
976-
def AS_OffloadLocal : I32EnumAttrCase<"offload_local", 2>;
977-
def AS_OffloadGlobal : I32EnumAttrCase<"offload_global", 3>;
978-
def AS_OffloadConstant : I32EnumAttrCase<"offload_constant", 4>;
979-
def AS_OffloadGeneric : I32EnumAttrCase<"offload_generic", 5>;
980-
def AS_Target : I32EnumAttrCase<"target", 6>;
981-
982-
def AddressSpaceAttr : CIR_Attr<"AddressSpace", "addrspace"> {
983-
984-
let summary = "Address space attribute for pointer types";
985-
let description = [{
986-
The address space attribute is used in pointer types. It essentially
987-
provides a unified model on top of `clang::LangAS`, rather than LLVM address
988-
spaces.
989-
990-
The representation is further simplified: `LangAS::Default` is encoded as
991-
a null attribute; many address spaces from different offloading languages
992-
are unified as `offload_*`; etc.
993-
994-
The meaning of `value` parameter is defined as an extensible enum `Kind`,
995-
which encodes target AS as offset to the last language AS.
996-
}];
997-
998-
let parameters = (ins "int32_t":$value);
999-
1000-
let assemblyFormat = [{
1001-
`<` $value `>`
1002-
}];
1003-
960+
def CIR_AddressSpaceAttr : CIR_EnumAttr<CIR_AddressSpace, "address_space"> {
1004961
let builders = [
1005962
AttrBuilder<(ins "clang::LangAS":$langAS), [{
1006-
assert(langAS != clang::LangAS::Default &&
1007-
"Default address space is encoded as null attribute");
1008-
return $_get($_ctxt, getValueFromLangAS(langAS).value());
963+
return $_get($_ctxt, cir::toCIRAddressSpace(langAS));
1009964
}]>
1010965
];
1011966

1012-
let cppNamespace = "::cir";
1013-
1014-
// The following codes implement these conversions:
1015-
// clang::LangAS -> int32_t <-> text-form CIR
1016-
1017-
// CIR_PointerType manipulates the parse- and stringify- methods to provide
1018-
// simplified assembly format `custom<PointerAddrSpace>`.
1019-
1020-
list<I32EnumAttrCase> langASCases = [
1021-
AS_OffloadPrivate, AS_OffloadLocal, AS_OffloadGlobal, AS_OffloadConstant,
1022-
AS_OffloadGeneric
1023-
];
967+
let assemblyFormat = [{
968+
`` custom<AddressSpaceValue>($value)
969+
}];
1024970

1025-
I32EnumAttrCase targetASCase = AS_Target;
971+
let defaultValue = "cir::AddressSpace::Default";
1026972

1027973
let extraClassDeclaration = [{
1028-
static constexpr char kTargetKeyword[] = "}]#targetASCase.symbol#[{";
1029-
static constexpr int32_t kFirstTargetASValue = }]#targetASCase.value#[{;
1030-
1031974
bool isLang() const;
1032975
bool isTarget() const;
1033976
unsigned getTargetValue() const;
1034-
1035-
/// Convert a clang LangAS to its corresponding CIR AS storage value. This
1036-
/// helper does not perform any language-specific mappings (e.g. determining
1037-
/// the default AS for offloading languages), so these must be handled in
1038-
/// the caller.
1039-
static std::optional<int32_t> getValueFromLangAS(clang::LangAS v);
1040-
1041-
/// Helper methods for the assembly format `custom<PointerAddrSpace>`.
1042-
static std::optional<int32_t> parseValueFromString(llvm::StringRef s);
1043-
static std::optional<llvm::StringRef> stringifyValue(int32_t v);
1044-
1045-
struct Kind {
1046-
}]#!interleave(
1047-
!foreach(case, langASCases,
1048-
"static constexpr int32_t "#case.symbol#" = "#case.value#";"
1049-
), "\n"
1050-
)#[{
1051-
};
977+
unsigned getAsUnsignedValue() const;
1052978
}];
1053979

1054980
let extraClassDefinition = [{
981+
unsigned $cppClass::getAsUnsignedValue() const {
982+
return static_cast<unsigned>(getValue());
983+
}
984+
1055985
bool $cppClass::isLang() const {
1056-
return !isTarget();
986+
return cir::isLangAddressSpace(getValue());
1057987
}
1058988

1059989
bool $cppClass::isTarget() const {
1060-
return getValue() >= kFirstTargetASValue;
990+
return cir::isTargetAddressSpace(getValue());
1061991
}
1062992

1063993
unsigned $cppClass::getTargetValue() const {
1064-
assert(isTarget() && "Not a target address space");
1065-
return getValue() - kFirstTargetASValue;
1066-
}
1067-
1068-
std::optional<int32_t>
1069-
$cppClass::parseValueFromString(llvm::StringRef str) {
1070-
return llvm::StringSwitch<::std::optional<int32_t>>(str)
1071-
}]
1072-
#
1073-
!interleave(
1074-
!foreach(case, langASCases,
1075-
".Case(\""#case.symbol# "\", "#case.value # ")\n"
1076-
),
1077-
"\n"
1078-
)
1079-
#
1080-
[{
1081-
// Target address spaces are not parsed here
1082-
.Default(std::nullopt);
1083-
}
1084-
1085-
std::optional<llvm::StringRef>
1086-
$cppClass::stringifyValue(int32_t value) {
1087-
switch (value) {
1088-
}]
1089-
#
1090-
!interleave(
1091-
!foreach(case, langASCases,
1092-
"case "#case.value
1093-
# ": return \""#case.symbol # "\";" ),
1094-
"\n"
1095-
)
1096-
#
1097-
[{
1098-
default:
1099-
// Target address spaces are not processed here
1100-
return std::nullopt;
1101-
}
994+
return cir::getTargetAddressSpaceValue(getValue());
1102995
}
1103996
}];
1104997
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the CIR dialect enum base classes
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD
14+
#define CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD
15+
16+
include "mlir/IR/EnumAttr.td"
17+
18+
class CIR_I32EnumAttr<string name, string summary, list<I32EnumAttrCase> cases>
19+
: I32EnumAttr<name, summary, cases> {
20+
let cppNamespace = "::cir";
21+
}
22+
23+
class CIR_I64EnumAttr<string name, string summary, list<I64EnumAttrCase> cases>
24+
: I64EnumAttr<name, summary, cases> {
25+
let cppNamespace = "::cir";
26+
}
27+
28+
class CIR_EnumAttr<EnumAttrInfo info, string name = "", list<Trait> traits = []>
29+
: EnumAttr<CIR_Dialect, info, name, traits> {
30+
let assemblyFormat = "`<` $value `>`";
31+
}
32+
33+
class CIR_DefaultValuedEnumParameter<EnumAttrInfo info, string value = "">
34+
: EnumParameter<info> {
35+
let defaultValue = value;
36+
}
37+
38+
#endif // CLANG_CIR_DIALECT_IR_CIRENUMATTR_TD

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

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2347,7 +2347,6 @@ def ForOp : CIR_Op<"for", [CIR_LoopOpInterface, NoRegionArguments]> {
23472347
// currently handy as part of forwarding appropriate linkage types for LLVM
23482348
// lowering, specially useful for C++ support.
23492349

2350-
23512350
/// An enumeration for the kinds of linkage for global values.
23522351
def CIR_GlobalLinkageKind : CIR_I32EnumAttr<
23532352
"GlobalLinkageKind", "linkage kind", [
@@ -2396,10 +2395,11 @@ def CIR_TLSModel : CIR_I32EnumAttr<"TLS_Model", "TLS model", [
23962395
I32EnumAttrCase<"LocalExec", 3, "tls_local_exec">
23972396
]>;
23982397

2399-
def GlobalOp : CIR_Op<"global",
2400-
[DeclareOpInterfaceMethods<RegionBranchOpInterface>,
2401-
DeclareOpInterfaceMethods<CIRGlobalValueInterface>,
2402-
NoRegionArguments]> {
2398+
def CIR_GlobalOp : CIR_Op<"global", [
2399+
DeclareOpInterfaceMethods<RegionBranchOpInterface>,
2400+
DeclareOpInterfaceMethods<CIRGlobalValueInterface>,
2401+
NoRegionArguments
2402+
]> {
24032403
let summary = "Declares or defines a global variable";
24042404
let description = [{
24052405
The `cir.global` operation declares or defines a named global variable.
@@ -2431,26 +2431,33 @@ def GlobalOp : CIR_Op<"global",
24312431
// Note that both sym_name and sym_visibility are tied to Symbol trait.
24322432
// TODO: sym_visibility can possibly be represented by implementing the
24332433
// necessary Symbol's interface in terms of linkage instead.
2434-
let arguments = (ins SymbolNameAttr:$sym_name,
2435-
DefaultValuedAttr<
2436-
CIR_VisibilityAttr,
2437-
"VisibilityKind::Default"
2438-
>:$global_visibility,
2439-
OptionalAttr<StrAttr>:$sym_visibility,
2440-
TypeAttr:$sym_type,
2441-
CIR_GlobalLinkageKind:$linkage,
2442-
OptionalAttr<AddressSpaceAttr>:$addr_space,
2443-
OptionalAttr<CIR_TLSModel>:$tls_model,
2444-
// Note this can also be a FlatSymbolRefAttr
2445-
OptionalAttr<AnyAttr>:$initial_value,
2446-
UnitAttr:$comdat,
2447-
UnitAttr:$constant,
2448-
UnitAttr:$dso_local,
2449-
OptionalAttr<I64Attr>:$alignment,
2450-
OptionalAttr<ASTVarDeclInterface>:$ast,
2451-
OptionalAttr<StrAttr>:$section,
2452-
OptionalAttr<ArrayAttr>:$annotations);
2434+
let arguments = (ins
2435+
SymbolNameAttr:$sym_name,
2436+
DefaultValuedAttr<
2437+
CIR_VisibilityAttr,
2438+
"VisibilityKind::Default"
2439+
>:$global_visibility,
2440+
OptionalAttr<StrAttr>:$sym_visibility,
2441+
TypeAttr:$sym_type,
2442+
CIR_GlobalLinkageKind:$linkage,
2443+
DefaultValuedAttr<
2444+
CIR_AddressSpaceAttr,
2445+
"AddressSpace::Default"
2446+
>:$addr_space,
2447+
OptionalAttr<CIR_TLSModel>:$tls_model,
2448+
// Note this can also be a FlatSymbolRefAttr
2449+
OptionalAttr<AnyAttr>:$initial_value,
2450+
UnitAttr:$comdat,
2451+
UnitAttr:$constant,
2452+
UnitAttr:$dso_local,
2453+
OptionalAttr<I64Attr>:$alignment,
2454+
OptionalAttr<ASTVarDeclInterface>:$ast,
2455+
OptionalAttr<StrAttr>:$section,
2456+
OptionalAttr<ArrayAttr>:$annotations
2457+
);
2458+
24532459
let regions = (region AnyRegion:$ctorRegion, AnyRegion:$dtorRegion);
2460+
24542461
let assemblyFormat = [{
24552462
($sym_visibility^)?
24562463
(`` $global_visibility^)?
@@ -2459,7 +2466,7 @@ def GlobalOp : CIR_Op<"global",
24592466
(`comdat` $comdat^)?
24602467
($tls_model^)?
24612468
(`dso_local` $dso_local^)?
2462-
(`addrspace` `(` custom<GlobalOpAddrSpace>($addr_space)^ `)`)?
2469+
( `addrspace` `(` $addr_space^ `)` )?
24632470
$sym_name
24642471
custom<GlobalOpTypeAndInitialValue>($sym_type, $initial_value, $ctorRegion, $dtorRegion)
24652472
($annotations^)?
@@ -2483,7 +2490,7 @@ def GlobalOp : CIR_Op<"global",
24832490
// CIR defaults to external linkage.
24842491
CArg<"cir::GlobalLinkageKind",
24852492
"cir::GlobalLinkageKind::ExternalLinkage">:$linkage,
2486-
CArg<"cir::AddressSpaceAttr", "{}">:$addrSpace,
2493+
CArg<"cir::AddressSpace", "cir::AddressSpace::Default">:$addrSpace,
24872494
CArg<"llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>",
24882495
"nullptr">:$ctorBuilder,
24892496
CArg<"llvm::function_ref<void(mlir::OpBuilder &, mlir::Location)>",

0 commit comments

Comments
 (0)