|
14 | 14 | #define MLIR_CIR_DIALECT_CIR_ATTRS |
15 | 15 |
|
16 | 16 | include "mlir/IR/BuiltinAttributeInterfaces.td" |
17 | | -include "mlir/IR/EnumAttr.td" |
| 17 | +include "clang/CIR/Dialect/IR/CIREnumAttr.td" |
18 | 18 |
|
19 | 19 | include "clang/CIR/Dialect/IR/CIRDialect.td" |
20 | 20 | include "clang/CIR/Dialect/IR/CIRAttrConstraints.td" |
@@ -45,21 +45,6 @@ class CIR_TypedAttr<string name, string attrMnemonic, list<Trait> traits = []> |
45 | 45 | let assemblyFormat = [{}]; |
46 | 46 | } |
47 | 47 |
|
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 | | - |
63 | 48 | class CIRUnitAttr<string name, string attrMnemonic, list<Trait> traits = []> |
64 | 49 | : CIR_Attr<name, attrMnemonic, traits> { |
65 | 50 | let returnType = "bool"; |
@@ -972,133 +957,41 @@ def DynamicCastInfoAttr |
972 | 957 | // AddressSpaceAttr |
973 | 958 | //===----------------------------------------------------------------------===// |
974 | 959 |
|
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"> { |
1004 | 961 | let builders = [ |
1005 | 962 | 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)); |
1009 | 964 | }]> |
1010 | 965 | ]; |
1011 | 966 |
|
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 | + }]; |
1024 | 970 |
|
1025 | | - I32EnumAttrCase targetASCase = AS_Target; |
| 971 | + let defaultValue = "cir::AddressSpace::Default"; |
1026 | 972 |
|
1027 | 973 | let extraClassDeclaration = [{ |
1028 | | - static constexpr char kTargetKeyword[] = "}]#targetASCase.symbol#[{"; |
1029 | | - static constexpr int32_t kFirstTargetASValue = }]#targetASCase.value#[{; |
1030 | | - |
1031 | 974 | bool isLang() const; |
1032 | 975 | bool isTarget() const; |
1033 | 976 | 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; |
1052 | 978 | }]; |
1053 | 979 |
|
1054 | 980 | let extraClassDefinition = [{ |
| 981 | + unsigned $cppClass::getAsUnsignedValue() const { |
| 982 | + return static_cast<unsigned>(getValue()); |
| 983 | + } |
| 984 | + |
1055 | 985 | bool $cppClass::isLang() const { |
1056 | | - return !isTarget(); |
| 986 | + return cir::isLangAddressSpace(getValue()); |
1057 | 987 | } |
1058 | 988 |
|
1059 | 989 | bool $cppClass::isTarget() const { |
1060 | | - return getValue() >= kFirstTargetASValue; |
| 990 | + return cir::isTargetAddressSpace(getValue()); |
1061 | 991 | } |
1062 | 992 |
|
1063 | 993 | 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()); |
1102 | 995 | } |
1103 | 996 | }]; |
1104 | 997 | } |
|
0 commit comments