diff options
author | Sven van Haastregt <sven.vanhaastregt@arm.com> | 2019-09-05 10:01:24 +0000 |
---|---|---|
committer | Sven van Haastregt <sven.vanhaastregt@arm.com> | 2019-09-05 10:01:24 +0000 |
commit | 988f1e3e32a95df46da4f98b5652b0dc8b444c7f (patch) | |
tree | 09ffc70a811a474dea273dced8d133ca7bcbad0d /clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp | |
parent | aff45e4b235dd7f369c7054761ccb3853fafdfac (diff) | |
download | bcm5719-llvm-988f1e3e32a95df46da4f98b5652b0dc8b444c7f.tar.gz bcm5719-llvm-988f1e3e32a95df46da4f98b5652b0dc8b444c7f.zip |
[OpenCL] Add image type handling for builtins
Image types were previously available, but not working. This patch
adds image type handling.
Rename the image type definitions in the .td file to make them
consistent with other type names. Use abstract types to represent the
unqualified types. Instantiate access-qualified image types at the
point of use using, e.g. `ImageType<Image2d, "RO">`.
Add/update TableGen definitions for the read_image/write_image
builtin functions.
Patch by Pierre Gondois and Sven van Haastregt.
Differential Revision: https://reviews.llvm.org/D63480
llvm-svn: 371046
Diffstat (limited to 'clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp')
-rw-r--r-- | clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp | 70 |
1 files changed, 67 insertions, 3 deletions
diff --git a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp index d8f60894b00..b93a68fb309 100644 --- a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp +++ b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp @@ -56,6 +56,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Error.h" @@ -233,6 +234,13 @@ void BuiltinNameEmitter::EmitDeclarations() { // Structure definitions. OS << R"( +// Image access qualifier. +enum OpenCLAccessQual : unsigned char { + OCLAQ_None, + OCLAQ_ReadOnly, + OCLAQ_WriteOnly, + OCLAQ_ReadWrite +}; // Represents a return type or argument type. struct OpenCLTypeStruct { @@ -246,6 +254,8 @@ struct OpenCLTypeStruct { const bool IsConst; // 0 if the type is not volatile. const bool IsVolatile; + // Access qualifier. + const OpenCLAccessQual AccessQualifier; // Address space of the pointer (if applicable). const LangAS AS; }; @@ -347,12 +357,20 @@ void BuiltinNameEmitter::GetOverloads() { void BuiltinNameEmitter::EmitTypeTable() { OS << "static const OpenCLTypeStruct TypeTable[] = {\n"; for (const auto &T : TypeMap) { - OS << " // " << T.second << "\n"; - OS << " {OCLT_" << T.first->getValueAsString("Name") << ", " + const char *AccessQual = + StringSwitch<const char *>(T.first->getValueAsString("AccessQualifier")) + .Case("RO", "OCLAQ_ReadOnly") + .Case("WO", "OCLAQ_WriteOnly") + .Case("RW", "OCLAQ_ReadWrite") + .Default("OCLAQ_None"); + + OS << " // " << T.second << "\n" + << " {OCLT_" << T.first->getValueAsString("Name") << ", " << T.first->getValueAsInt("VecWidth") << ", " << T.first->getValueAsBit("IsPointer") << ", " << T.first->getValueAsBit("IsConst") << ", " << T.first->getValueAsBit("IsVolatile") << ", " + << AccessQual << ", " << T.first->getValueAsString("AddrSpace") << "},\n"; } OS << "};\n\n"; @@ -455,6 +473,47 @@ static void OCL2Qual(ASTContext &Context, const OpenCLTypeStruct &Ty, // Start of switch statement over all types. OS << "\n switch (Ty.ID) {\n"; + // Switch cases for image types (Image2d, Image3d, ...) + std::vector<Record *> ImageTypes = + Records.getAllDerivedDefinitions("ImageType"); + + // Map an image type name to its 3 access-qualified types (RO, WO, RW). + std::map<StringRef, SmallVector<Record *, 3>> ImageTypesMap; + for (auto *IT : ImageTypes) { + auto Entry = ImageTypesMap.find(IT->getValueAsString("Name")); + if (Entry == ImageTypesMap.end()) { + SmallVector<Record *, 3> ImageList; + ImageList.push_back(IT); + ImageTypesMap.insert( + std::make_pair(IT->getValueAsString("Name"), ImageList)); + } else { + Entry->second.push_back(IT); + } + } + + // Emit the cases for the image types. For an image type name, there are 3 + // corresponding QualTypes ("RO", "WO", "RW"). The "AccessQualifier" field + // tells which one is needed. Emit a switch statement that puts the + // corresponding QualType into "QT". + for (const auto &ITE : ImageTypesMap) { + OS << " case OCLT_" << ITE.first.str() << ":\n" + << " switch (Ty.AccessQualifier) {\n" + << " case OCLAQ_None:\n" + << " llvm_unreachable(\"Image without access qualifier\");\n"; + for (const auto &Image : ITE.second) { + OS << StringSwitch<const char *>( + Image->getValueAsString("AccessQualifier")) + .Case("RO", " case OCLAQ_ReadOnly:\n") + .Case("WO", " case OCLAQ_WriteOnly:\n") + .Case("RW", " case OCLAQ_ReadWrite:\n") + << " QT.push_back(Context." + << Image->getValueAsDef("QTName")->getValueAsString("Name") << ");\n" + << " break;\n"; + } + OS << " }\n" + << " break;\n"; + } + // Switch cases for generic types. for (const auto *GenType : Records.getAllDerivedDefinitions("GenericType")) { OS << " case OCLT_" << GenType->getValueAsString("Name") << ":\n"; @@ -495,6 +554,9 @@ static void OCL2Qual(ASTContext &Context, const OpenCLTypeStruct &Ty, StringMap<bool> TypesSeen; for (const auto *T : Types) { + // Check this is not an image type + if (ImageTypesMap.find(T->getValueAsString("Name")) != ImageTypesMap.end()) + continue; // Check we have not seen this Type if (TypesSeen.find(T->getValueAsString("Name")) != TypesSeen.end()) continue; @@ -512,7 +574,9 @@ static void OCL2Qual(ASTContext &Context, const OpenCLTypeStruct &Ty, } // End of switch statement. - OS << " } // end of switch (Ty.ID)\n\n"; + OS << " default:\n" + << " llvm_unreachable(\"OpenCL builtin type not handled yet\");\n" + << " } // end of switch (Ty.ID)\n\n"; // Step 2. // Add ExtVector types if this was a generic type, as the switch statement |