https://github.com/vikramRH updated https://github.com/llvm/llvm-project/pull/108497
>From 6afc2e91d8877cc330f6e317a404a74990d9c607 Mon Sep 17 00:00:00 2001 From: vikhegde <vikhe...@amd.com> Date: Wed, 4 Sep 2024 10:34:54 +0000 Subject: [PATCH 1/2] [clang][TableGen] Support specifying address space in clang builtin prototypes --- .../target-builtins-prototype-parser.td | 71 +++++++++++++++++++ clang/utils/TableGen/ClangBuiltinsEmitter.cpp | 52 ++++++++++++-- 2 files changed, 119 insertions(+), 4 deletions(-) diff --git a/clang/test/TableGen/target-builtins-prototype-parser.td b/clang/test/TableGen/target-builtins-prototype-parser.td index 555aebb3ccfb1f..dcff11046603ef 100644 --- a/clang/test/TableGen/target-builtins-prototype-parser.td +++ b/clang/test/TableGen/target-builtins-prototype-parser.td @@ -6,6 +6,12 @@ // RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_B 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_B // RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_C 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_C // RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_D 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_D +// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_E 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_E +// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_F 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_F +// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_G 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_G +// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_H 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_H +// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_I 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_I +// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_J 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_J include "clang/Basic/BuiltinsBase.td" @@ -113,3 +119,68 @@ def : Builtin { } #endif +def : Builtin { +// CHECK: BUILTIN(__builtin_test_addrspace_attribute_01, "di*3", "") + let Prototype = "double( [[addrspace[3]]] int*)"; + let Spellings = ["__builtin_test_addrspace_attribute_01"]; +} + +def : Builtin { +// CHECK: BUILTIN(__builtin_test_addrspace_attribute_02, "Ii*5i*d", "") + let Prototype = "_Constant [[addrspace[5]]] int* (int*, double)"; + let Spellings = ["__builtin_test_addrspace_attribute_02"]; +} + +def : Builtin { +// CHECK: BUILTIN(__builtin_test_addrspace_attribute_04, "Ii&4id*7", "") + let Prototype = "_Constant [[addrspace[4]]] int& (int , [[addrspace[7]]] double*)"; + let Spellings = ["__builtin_test_addrspace_attribute_04"]; +} + +#ifdef ERROR_EXPECTED_E +def : Builtin { +// ERROR_EXPECTED_E: :[[# @LINE + 1]]:7: error: Expected opening bracket '[' after 'addrspace' + let Prototype = "_Constant [[addrspace]] int& (int , double*)"; + let Spellings = ["__builtin_test_addrspace_attribute_04"]; +} +#endif + +#ifdef ERROR_EXPECTED_F +def : Builtin { +// ERROR_EXPECTED_F: :[[# @LINE + 1]]:7: error: Address space attribute can only be specified with a pointer or reference type + let Prototype = "_Constant [[addrspace[4]]] int (int , double*)"; + let Spellings = ["__builtin_test_addrspace_attribute_04"]; +} +#endif + +#ifdef ERROR_EXPECTED_G +def : Builtin { +// ERROR_EXPECTED_G: :[[# @LINE + 1]]:7: error: Expecetd valid integer for 'addrspace' attribute + let Prototype = "_Constant [[addrspace[k]]] int* (int , double*)"; + let Spellings = ["__builtin_test_addrspace_attribute_04"]; +} +#endif + +#ifdef ERROR_EXPECTED_H +def : Builtin { +// ERROR_EXPECTED_H: :[[# @LINE + 1]]:7: error: Expected closing bracket ']' after address space specification + let Prototype = "_Constant [[addrspace[6 int* (int , double*)"; + let Spellings = ["__builtin_test_addrspace_attribute_04"]; +} +#endif + +#ifdef ERROR_EXPECTED_I +def : Builtin { +// ERROR_EXPECTED_I: :[[# @LINE + 1]]:7: error: Expected closing brackets ']]' for attribute list + let Prototype = "_Constant [[addrspace[6] int* (int , double*)"; + let Spellings = ["__builtin_test_addrspace_attribute_04"]; +} +#endif + +#ifdef ERROR_EXPECTED_J +def : Builtin { +// ERROR_EXPECTED_J: :[[# @LINE + 1]]:7: error: Unknown attribute name specified + let Prototype = "_Constant [[invalid]] int* (int , double*)"; + let Spellings = ["__builtin_test_addrspace_attribute_04"]; +} +#endif diff --git a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp index 4ae7600a392b8f..c088806795079c 100644 --- a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp +++ b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp @@ -40,9 +40,31 @@ class PrototypeParser { ParseTypes(Prototype); } + void ParseTypeAttributeList(StringRef &T, SMLoc Loc) { + if (T.consume_front("addrspace")) { + unsigned long long AS = 0; + if (!T.consume_front("[")) + PrintFatalError(Loc, "Expected opening bracket '[' after 'addrspace'"); + + if (llvm::consumeUnsignedInteger(T, 10, AS)) + PrintFatalError(Loc, + "Expecetd valid integer for 'addrspace' attribute"); + + if (!T.consume_front("]")) + PrintFatalError( + Loc, + "Expected closing bracket ']' after address space specification"); + AddrSpace = AS; + } else + PrintFatalError(Loc, "Unknown attribute name specified"); + + if (!T.consume_front("]]")) + PrintFatalError(Loc, "Expected closing brackets ']]' for attribute list"); + } + void ParseTypes(StringRef &Prototype) { auto ReturnType = Prototype.take_until([](char c) { return c == '('; }); - ParseType(ReturnType); + ParseTypeAndValidateAttributes(ReturnType); Prototype = Prototype.drop_front(ReturnType.size() + 1); if (!Prototype.ends_with(")")) PrintFatalError(Loc, "Expected closing brace at end of prototype"); @@ -66,7 +88,7 @@ class PrototypeParser { // we cannot have nested _ExtVector. if (Current.starts_with("_ExtVector<")) { const size_t EndTemplate = Current.find('>', 0); - ParseType(Current.substr(0, EndTemplate + 1)); + ParseTypeAndValidateAttributes(Current.substr(0, EndTemplate + 1)); // Move the prototype beyond _ExtVector<...> I += EndTemplate + 1; continue; @@ -77,7 +99,7 @@ class PrototypeParser { if (size_t CommaPos = Current.find(',', 0)) { if (CommaPos != StringRef::npos) { StringRef T = Current.substr(0, CommaPos); - ParseType(T); + ParseTypeAndValidateAttributes(T); // Move the prototype beyond the comma. I += CommaPos + 1; continue; @@ -85,16 +107,30 @@ class PrototypeParser { } // No more commas, parse final parameter. - ParseType(Current); + ParseTypeAndValidateAttributes(Current); I = end; } } + void ParseTypeAndValidateAttributes(StringRef T) { + ParseType(T); + if (!IsPointerOrReference && AddrSpace) + PrintFatalError( + Loc, "Address space attribute can only be specified with a pointer" + " or reference type"); + + IsPointerOrReference = false; + AddrSpace = std::nullopt; + } + void ParseType(StringRef T) { T = T.trim(); if (T.consume_back("*")) { ParseType(T); Type += "*"; + IsPointerOrReference = true; + if (AddrSpace) + Type += std::to_string(*AddrSpace); } else if (T.consume_back("const")) { ParseType(T); Type += "C"; @@ -107,6 +143,12 @@ class PrototypeParser { } else if (T.consume_back("&")) { ParseType(T); Type += "&"; + IsPointerOrReference = true; + if (AddrSpace) + Type += std::to_string(*AddrSpace); + } else if (T.consume_front("[[")) { + ParseTypeAttributeList(T, Loc); + ParseType(T); } else if (T.consume_front("long")) { Type += "L"; ParseType(T); @@ -193,6 +235,8 @@ class PrototypeParser { SMLoc Loc; StringRef Substitution; std::string Type; + std::optional<unsigned long long> AddrSpace; + bool IsPointerOrReference = false; }; class HeaderNameParser { >From 5ab4003804653cdf3d87048c43bd839ef84b18a9 Mon Sep 17 00:00:00 2001 From: vikhegde <vikhe...@amd.com> Date: Tue, 24 Sep 2024 10:39:31 +0000 Subject: [PATCH 2/2] design changes according to review comments --- clang/include/clang/Basic/BuiltinsBase.td | 7 +++ .../target-builtins-prototype-parser.td | 57 ++++------------- clang/utils/TableGen/ClangBuiltinsEmitter.cpp | 63 +++++++++---------- 3 files changed, 51 insertions(+), 76 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsBase.td b/clang/include/clang/Basic/BuiltinsBase.td index 58dee22fc0a450..e7629e944c143c 100644 --- a/clang/include/clang/Basic/BuiltinsBase.td +++ b/clang/include/clang/Basic/BuiltinsBase.td @@ -73,6 +73,13 @@ def Constexpr : Attribute<"E">; // Builtin is immediate and must be constant evaluated. Implies Constexpr, and will only be supported in C++20 mode. def Consteval : Attribute<"EG">; +// Address space attribute, only valid for pointer or reference arguments. +// ArgIdx - argument to which the attribute refers. value 0 is for return type. +// AddrSpaceNum - Address space number for the argument. +class AddressSpace<int ArgIdx, int AddrSpaceNum> : IndexedAttribute<"", ArgIdx> { + int SpaceNum = AddrSpaceNum; +} + // Builtin kinds // ============= diff --git a/clang/test/TableGen/target-builtins-prototype-parser.td b/clang/test/TableGen/target-builtins-prototype-parser.td index dcff11046603ef..0c4494a02b546c 100644 --- a/clang/test/TableGen/target-builtins-prototype-parser.td +++ b/clang/test/TableGen/target-builtins-prototype-parser.td @@ -8,10 +8,6 @@ // RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_D 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_D // RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_E 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_E // RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_F 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_F -// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_G 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_G -// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_H 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_H -// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_I 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_I -// RUN: not clang-tblgen -I %p/../../include/ %s --gen-clang-builtins -DERROR_EXPECTED_J 2>&1 | FileCheck %s --check-prefix=ERROR_EXPECTED_J include "clang/Basic/BuiltinsBase.td" @@ -121,66 +117,39 @@ def : Builtin { def : Builtin { // CHECK: BUILTIN(__builtin_test_addrspace_attribute_01, "di*3", "") - let Prototype = "double( [[addrspace[3]]] int*)"; + let Prototype = "double(int*)"; let Spellings = ["__builtin_test_addrspace_attribute_01"]; + let Attributes = [AddressSpace<1, 3>]; } def : Builtin { -// CHECK: BUILTIN(__builtin_test_addrspace_attribute_02, "Ii*5i*d", "") - let Prototype = "_Constant [[addrspace[5]]] int* (int*, double)"; +// CHECK: BUILTIN(__builtin_test_addrspace_attribute_02, "Ii*5i*d", "n") + let Prototype = "_Constant int* (int*, double)"; let Spellings = ["__builtin_test_addrspace_attribute_02"]; + let Attributes = [AddressSpace<0, 5>, NoThrow]; } def : Builtin { -// CHECK: BUILTIN(__builtin_test_addrspace_attribute_04, "Ii&4id*7", "") - let Prototype = "_Constant [[addrspace[4]]] int& (int , [[addrspace[7]]] double*)"; +// CHECK: BUILTIN(__builtin_test_addrspace_attribute_04, "Ii&4id*7", "En") + let Prototype = "_Constant int& (int , double*)"; let Spellings = ["__builtin_test_addrspace_attribute_04"]; + let Attributes = [AddressSpace<0, 4>, Constexpr, AddressSpace<2, 7>, NoThrow]; } #ifdef ERROR_EXPECTED_E def : Builtin { -// ERROR_EXPECTED_E: :[[# @LINE + 1]]:7: error: Expected opening bracket '[' after 'addrspace' - let Prototype = "_Constant [[addrspace]] int& (int , double*)"; +// ERROR_EXPECTED_E: :[[# @LINE + 1]]:7: error: Address space attribute for argument 2 repeated + let Prototype = "_Constant int& (int , double*)"; let Spellings = ["__builtin_test_addrspace_attribute_04"]; + let Attributes = [AddressSpace<2, 4>, AddressSpace<2, 7>]; } #endif #ifdef ERROR_EXPECTED_F def : Builtin { // ERROR_EXPECTED_F: :[[# @LINE + 1]]:7: error: Address space attribute can only be specified with a pointer or reference type - let Prototype = "_Constant [[addrspace[4]]] int (int , double*)"; - let Spellings = ["__builtin_test_addrspace_attribute_04"]; -} -#endif - -#ifdef ERROR_EXPECTED_G -def : Builtin { -// ERROR_EXPECTED_G: :[[# @LINE + 1]]:7: error: Expecetd valid integer for 'addrspace' attribute - let Prototype = "_Constant [[addrspace[k]]] int* (int , double*)"; - let Spellings = ["__builtin_test_addrspace_attribute_04"]; -} -#endif - -#ifdef ERROR_EXPECTED_H -def : Builtin { -// ERROR_EXPECTED_H: :[[# @LINE + 1]]:7: error: Expected closing bracket ']' after address space specification - let Prototype = "_Constant [[addrspace[6 int* (int , double*)"; - let Spellings = ["__builtin_test_addrspace_attribute_04"]; -} -#endif - -#ifdef ERROR_EXPECTED_I -def : Builtin { -// ERROR_EXPECTED_I: :[[# @LINE + 1]]:7: error: Expected closing brackets ']]' for attribute list - let Prototype = "_Constant [[addrspace[6] int* (int , double*)"; - let Spellings = ["__builtin_test_addrspace_attribute_04"]; -} -#endif - -#ifdef ERROR_EXPECTED_J -def : Builtin { -// ERROR_EXPECTED_J: :[[# @LINE + 1]]:7: error: Unknown attribute name specified - let Prototype = "_Constant [[invalid]] int* (int , double*)"; + let Prototype = "_Constant int (int , double*)"; let Spellings = ["__builtin_test_addrspace_attribute_04"]; + let Attributes = [AddressSpace<1, 7>]; } #endif diff --git a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp index c088806795079c..3d5a6f7adc7a09 100644 --- a/clang/utils/TableGen/ClangBuiltinsEmitter.cpp +++ b/clang/utils/TableGen/ClangBuiltinsEmitter.cpp @@ -31,6 +31,7 @@ class PrototypeParser { public: PrototypeParser(StringRef Substitution, const Record *Builtin) : Loc(Builtin->getFieldLoc("Prototype")), Substitution(Substitution) { + populateAddrSpaceAttrMap(Builtin); ParsePrototype(Builtin->getValueAsString("Prototype")); } @@ -40,31 +41,22 @@ class PrototypeParser { ParseTypes(Prototype); } - void ParseTypeAttributeList(StringRef &T, SMLoc Loc) { - if (T.consume_front("addrspace")) { - unsigned long long AS = 0; - if (!T.consume_front("[")) - PrintFatalError(Loc, "Expected opening bracket '[' after 'addrspace'"); - - if (llvm::consumeUnsignedInteger(T, 10, AS)) - PrintFatalError(Loc, - "Expecetd valid integer for 'addrspace' attribute"); - - if (!T.consume_front("]")) - PrintFatalError( - Loc, - "Expected closing bracket ']' after address space specification"); - AddrSpace = AS; - } else - PrintFatalError(Loc, "Unknown attribute name specified"); - - if (!T.consume_front("]]")) - PrintFatalError(Loc, "Expected closing brackets ']]' for attribute list"); + void populateAddrSpaceAttrMap(const Record *Builtin) { + for (const auto *Attr : Builtin->getValueAsListOfDefs("Attributes")) { + if (Attr->isSubClassOf("AddressSpace")) { + uint32_t ArgIdx = Attr->getValueAsInt("Index"); + uint32_t ASpaceNum = Attr->getValueAsInt("SpaceNum"); + if (ArgToAddrSpaceMap.find(ArgIdx) != ArgToAddrSpaceMap.end()) + PrintFatalError(Loc, "Address space attribute for argument " + + std::to_string(ArgIdx) + " repeated"); + ArgToAddrSpaceMap[ArgIdx] = ASpaceNum; + } + } } void ParseTypes(StringRef &Prototype) { auto ReturnType = Prototype.take_until([](char c) { return c == '('; }); - ParseTypeAndValidateAttributes(ReturnType); + ParseTypeAndValidateAttributes(ReturnType, /*Return type ID*/ 0); Prototype = Prototype.drop_front(ReturnType.size() + 1); if (!Prototype.ends_with(")")) PrintFatalError(Loc, "Expected closing brace at end of prototype"); @@ -72,7 +64,7 @@ class PrototypeParser { // Look through the input parameters. const size_t end = Prototype.size(); - for (size_t I = 0; I != end;) { + for (size_t I = 0, CurArgIdx = 1; I != end;) { const StringRef Current = Prototype.substr(I, end); // Skip any leading space or commas if (Current.starts_with(" ") || Current.starts_with(",")) { @@ -88,9 +80,11 @@ class PrototypeParser { // we cannot have nested _ExtVector. if (Current.starts_with("_ExtVector<")) { const size_t EndTemplate = Current.find('>', 0); - ParseTypeAndValidateAttributes(Current.substr(0, EndTemplate + 1)); + ParseTypeAndValidateAttributes(Current.substr(0, EndTemplate + 1), + CurArgIdx); // Move the prototype beyond _ExtVector<...> I += EndTemplate + 1; + CurArgIdx++; continue; } @@ -99,28 +93,31 @@ class PrototypeParser { if (size_t CommaPos = Current.find(',', 0)) { if (CommaPos != StringRef::npos) { StringRef T = Current.substr(0, CommaPos); - ParseTypeAndValidateAttributes(T); + ParseTypeAndValidateAttributes(T, CurArgIdx); // Move the prototype beyond the comma. I += CommaPos + 1; + CurArgIdx++; continue; } } // No more commas, parse final parameter. - ParseTypeAndValidateAttributes(Current); + ParseTypeAndValidateAttributes(Current, CurArgIdx); I = end; } } - void ParseTypeAndValidateAttributes(StringRef T) { + void ParseTypeAndValidateAttributes(StringRef T, uint32_t ArgIdx) { + if (ArgToAddrSpaceMap.find(ArgIdx) != ArgToAddrSpaceMap.end()) + AddrSpace = ArgToAddrSpaceMap[ArgIdx]; ParseType(T); if (!IsPointerOrReference && AddrSpace) PrintFatalError( Loc, "Address space attribute can only be specified with a pointer" " or reference type"); - IsPointerOrReference = false; AddrSpace = std::nullopt; + IsPointerOrReference = false; } void ParseType(StringRef T) { @@ -146,9 +143,6 @@ class PrototypeParser { IsPointerOrReference = true; if (AddrSpace) Type += std::to_string(*AddrSpace); - } else if (T.consume_front("[[")) { - ParseTypeAttributeList(T, Loc); - ParseType(T); } else if (T.consume_front("long")) { Type += "L"; ParseType(T); @@ -235,7 +229,8 @@ class PrototypeParser { SMLoc Loc; StringRef Substitution; std::string Type; - std::optional<unsigned long long> AddrSpace; + std::unordered_map<uint32_t, uint32_t> ArgToAddrSpaceMap; + std::optional<uint32_t> AddrSpace; bool IsPointerOrReference = false; }; @@ -279,8 +274,12 @@ void PrintAttributes(const Record *Builtin, BuiltinType BT, for (const auto *Attr : Builtin->getValueAsListOfDefs("Attributes")) { OS << Attr->getValueAsString("Mangling"); - if (Attr->isSubClassOf("IndexedAttribute")) + if (Attr->isSubClassOf("IndexedAttribute")) { + // Address space attributes are already processed + if (Attr->isSubClassOf("AddressSpace")) + continue; OS << ':' << Attr->getValueAsInt("Index") << ':'; + } } OS << '\"'; } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits