[clang] 28cdcf8 - [OpenCL] Handle TypeExtensions in OpenCLBuiltinFileEmitter

Sven van Haastregt via cfe-commits cfe-commits at lists.llvm.org
Thu Feb 24 07:17:52 PST 2022


Author: Sven van Haastregt
Date: 2022-02-24T15:17:24Z
New Revision: 28cdcf8e3c8e6c51d42051b54f67c6920b5d8cf3

URL: https://github.com/llvm/llvm-project/commit/28cdcf8e3c8e6c51d42051b54f67c6920b5d8cf3
DIFF: https://github.com/llvm/llvm-project/commit/28cdcf8e3c8e6c51d42051b54f67c6920b5d8cf3.diff

LOG: [OpenCL] Handle TypeExtensions in OpenCLBuiltinFileEmitter

Until now, any types that had TypeExtensions attached to them were not
guarded with those extensions.  Extend the OpenCLBuiltinFileEmitter
such that all required extensions are emitted for the types of a
builtin function.

The `clang-tblgen -gen-clang-opencl-builtin-tests` emitter will now
produce e.g.:

  #if defined(cl_khr_fp16) && defined(cl_khr_fp64)
  half8 test11802_convert_half8_rtp(double8 arg1) {
    return convert_half8_rtp(arg1);
  }
  #endif // TypeExtension

Differential Revision: https://reviews.llvm.org/D120262

Added: 
    

Modified: 
    clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
index 34ca6cb36738c..a2d0cfb0b6ca9 100644
--- a/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
+++ b/clang/utils/TableGen/ClangOpenCLBuiltinEmitter.cpp
@@ -17,6 +17,7 @@
 #include "TableGenBackends.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringMap.h"
@@ -293,6 +294,15 @@ class OpenCLBuiltinFileEmitterBase {
   // was emitted.
   std::string emitVersionGuard(const Record *Builtin);
 
+  // Emit an #if guard for all type extensions required for the given type
+  // strings.  Return the corresponding closing #endif, or an empty string
+  // if no extension #if guard was emitted.
+  StringRef
+  emitTypeExtensionGuards(const SmallVectorImpl<std::string> &Signature);
+
+  // Map type strings to type extensions (e.g. "half2" -> "cl_khr_fp16").
+  StringMap<StringRef> TypeExtMap;
+
   // Contains OpenCL builtin functions and related information, stored as
   // Record instances. They are coming from the associated TableGen file.
   RecordKeeper &Records;
@@ -1057,7 +1067,16 @@ void OpenCLBuiltinFileEmitterBase::expandTypesInSignature(
     // Insert the Cartesian product of the types and vector sizes.
     for (const auto &Vector : VectorList) {
       for (const auto &Type : TypeList) {
-        ExpandedArg.push_back(getTypeString(Type, Flags, Vector));
+        std::string FullType = getTypeString(Type, Flags, Vector);
+        ExpandedArg.push_back(FullType);
+
+        // If the type requires an extension, add a TypeExtMap entry mapping
+        // the full type name to the extension.
+        StringRef Ext =
+            Arg->getValueAsDef("Extension")->getValueAsString("ExtName");
+        if (!Ext.empty() && TypeExtMap.find(FullType) == TypeExtMap.end()) {
+          TypeExtMap.insert({FullType, Ext});
+        }
       }
     }
     NumSignatures = std::max<unsigned>(NumSignatures, ExpandedArg.size());
@@ -1141,6 +1160,39 @@ OpenCLBuiltinFileEmitterBase::emitVersionGuard(const Record *Builtin) {
   return OptionalEndif;
 }
 
+StringRef OpenCLBuiltinFileEmitterBase::emitTypeExtensionGuards(
+    const SmallVectorImpl<std::string> &Signature) {
+  SmallSet<StringRef, 2> ExtSet;
+
+  // Iterate over all types to gather the set of required TypeExtensions.
+  for (const auto &Ty : Signature) {
+    StringRef TypeExt = TypeExtMap.lookup(Ty);
+    if (!TypeExt.empty()) {
+      // The TypeExtensions are space-separated in the .td file.
+      SmallVector<StringRef, 2> ExtVec;
+      TypeExt.split(ExtVec, " ");
+      for (const auto Ext : ExtVec) {
+        ExtSet.insert(Ext);
+      }
+    }
+  }
+
+  // Emit the #if only when at least one extension is required.
+  if (ExtSet.empty())
+    return "";
+
+  OS << "#if ";
+  bool isFirst = true;
+  for (const auto Ext : ExtSet) {
+    if (!isFirst)
+      OS << " && ";
+    OS << "defined(" << Ext << ")";
+    isFirst = false;
+  }
+  OS << "\n";
+  return "#endif // TypeExtension\n";
+}
+
 void OpenCLBuiltinTestEmitter::emit() {
   emitSourceFileHeader("OpenCL Builtin exhaustive testing", OS);
 
@@ -1163,6 +1215,8 @@ void OpenCLBuiltinTestEmitter::emit() {
     std::string OptionalVersionEndif = emitVersionGuard(B);
 
     for (const auto &Signature : FTypes) {
+      StringRef OptionalTypeExtEndif = emitTypeExtensionGuards(Signature);
+
       // Emit function declaration.
       OS << Signature[0] << " test" << TestID++ << "_" << Name << "(";
       if (Signature.size() > 1) {
@@ -1189,6 +1243,7 @@ void OpenCLBuiltinTestEmitter::emit() {
 
       // End of function body.
       OS << "}\n";
+      OS << OptionalTypeExtEndif;
     }
 
     OS << OptionalVersionEndif;


        


More information about the cfe-commits mailing list