[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
This commit is contained in:
Sven van Haastregt 2022-02-24 15:17:24 +00:00
parent 5910150140
commit 28cdcf8e3c
1 changed files with 56 additions and 1 deletions

View File

@ -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 @@ protected:
// 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;