//===- ClangOpenCLBuiltinEmitter.cpp - Generate Clang OpenCL Builtin handling // // The LLVM Compiler Infrastructure // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // These backends consume the definitions of OpenCL builtin functions in // clang/lib/Sema/OpenCLBuiltins.td and produce builtin handling code for // inclusion in SemaLookup.cpp, or a test file that calls all declared builtins. // //===----------------------------------------------------------------------===// #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" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" #include "llvm/TableGen/Error.h" #include "llvm/TableGen/Record.h" #include "llvm/TableGen/StringMatcher.h" #include "llvm/TableGen/TableGenBackend.h" usingnamespacellvm; namespace { // A list of signatures that are shared by one or more builtin functions. struct BuiltinTableEntries { … }; // This tablegen backend emits code for checking whether a function is an // OpenCL builtin function. If so, all overloads of this function are // added to the LookupResult. The generated include file is used by // SemaLookup.cpp // // For a successful lookup of e.g. the "cos" builtin, isOpenCLBuiltin("cos") // returns a pair <Index, Len>. // BuiltinTable[Index] to BuiltinTable[Index + Len] contains the pairs // <SigIndex, SigLen> of the overloads of "cos". // SignatureTable[SigIndex] to SignatureTable[SigIndex + SigLen] contains // one of the signatures of "cos". The SignatureTable entry can be // referenced by other functions, e.g. "sin", to exploit the fact that // many OpenCL builtins share the same signature. // // The file generated by this TableGen emitter contains the following: // // * Structs and enums to represent types and function signatures. // // * const char *FunctionExtensionTable[] // List of space-separated OpenCL extensions. A builtin references an // entry in this table when the builtin requires a particular (set of) // extension(s) to be enabled. // // * OpenCLTypeStruct TypeTable[] // Type information for return types and arguments. // // * unsigned SignatureTable[] // A list of types representing function signatures. Each entry is an index // into the above TypeTable. Multiple entries following each other form a // signature, where the first entry is the return type and subsequent // entries are the argument types. // // * OpenCLBuiltinStruct BuiltinTable[] // Each entry represents one overload of an OpenCL builtin function and // consists of an index into the SignatureTable and the number of arguments. // // * std::pair<unsigned, unsigned> isOpenCLBuiltin(llvm::StringRef Name) // Find out whether a string matches an existing OpenCL builtin function // name and return an index into BuiltinTable and the number of overloads. // // * void OCL2Qual(Sema&, OpenCLTypeStruct, std::vector<QualType>&) // Convert an OpenCLTypeStruct type to a list of QualType instances. // One OpenCLTypeStruct can represent multiple types, primarily when using // GenTypes. // class BuiltinNameEmitter { … }; /// Base class for emitting a file (e.g. header or test) from OpenCLBuiltins.td class OpenCLBuiltinFileEmitterBase { … }; // OpenCL builtin test generator. This class processes the same TableGen input // as BuiltinNameEmitter, but generates a .cl file that contains a call to each // builtin function described in the .td input. class OpenCLBuiltinTestEmitter : public OpenCLBuiltinFileEmitterBase { … }; // OpenCL builtin header generator. This class processes the same TableGen // input as BuiltinNameEmitter, but generates a .h file that contains a // prototype for each builtin function described in the .td input. class OpenCLBuiltinHeaderEmitter : public OpenCLBuiltinFileEmitterBase { … }; } // namespace void BuiltinNameEmitter::Emit() { … } void BuiltinNameEmitter::ExtractEnumTypes(ArrayRef<const Record *> Types, StringMap<bool> &TypesSeen, std::string &Output, std::vector<const Record *> &List) { … } void BuiltinNameEmitter::EmitDeclarations() { … } // Verify that the combination of GenTypes in a signature is supported. // To simplify the logic for creating overloads in SemaLookup, only allow // a signature to contain different GenTypes if these GenTypes represent // the same number of actual scalar or vector types. // // Exit with a fatal error if an unsupported construct is encountered. static void VerifySignature(const std::vector<Record *> &Signature, const Record *BuiltinRec) { … } void BuiltinNameEmitter::GetOverloads() { … } void BuiltinNameEmitter::EmitExtensionTable() { … } void BuiltinNameEmitter::EmitTypeTable() { … } void BuiltinNameEmitter::EmitSignatureTable() { … } // Encode a range MinVersion..MaxVersion into a single bit mask that can be // checked against LangOpts using isOpenCLVersionContainedInMask(). // This must be kept in sync with OpenCLVersionID in OpenCLOptions.h. // (Including OpenCLOptions.h here would be a layering violation.) static unsigned short EncodeVersions(unsigned int MinVersion, unsigned int MaxVersion) { … } void BuiltinNameEmitter::EmitBuiltinTable() { … } bool BuiltinNameEmitter::CanReuseSignature( BuiltinIndexListTy *Candidate, std::vector<std::pair<const Record *, unsigned>> &SignatureList) { … } void BuiltinNameEmitter::GroupBySignature() { … } void BuiltinNameEmitter::EmitStringMatcher() { … } // Emit an if-statement with an isMacroDefined call for each extension in // the space-separated list of extensions. static void EmitMacroChecks(raw_ostream &OS, StringRef Extensions) { … } void BuiltinNameEmitter::EmitQualTypeFinder() { … } std::string OpenCLBuiltinFileEmitterBase::getTypeString(const Record *Type, TypeFlags Flags, int VectorSize) const { … } void OpenCLBuiltinFileEmitterBase::getTypeLists( Record *Type, TypeFlags &Flags, std::vector<Record *> &TypeList, std::vector<int64_t> &VectorList) const { … } void OpenCLBuiltinFileEmitterBase::expandTypesInSignature( const std::vector<Record *> &Signature, SmallVectorImpl<SmallVector<std::string, 2>> &Types) { … } void OpenCLBuiltinFileEmitterBase::emitExtensionSetup() { … } std::string OpenCLBuiltinFileEmitterBase::emitExtensionGuard(const Record *Builtin) { … } std::string OpenCLBuiltinFileEmitterBase::emitVersionGuard(const Record *Builtin) { … } StringRef OpenCLBuiltinFileEmitterBase::emitTypeExtensionGuards( const SmallVectorImpl<std::string> &Signature) { … } void OpenCLBuiltinTestEmitter::emit() { … } void OpenCLBuiltinHeaderEmitter::emit() { … } void clang::EmitClangOpenCLBuiltins(const RecordKeeper &Records, raw_ostream &OS) { … } void clang::EmitClangOpenCLBuiltinHeader(const RecordKeeper &Records, raw_ostream &OS) { … } void clang::EmitClangOpenCLBuiltinTests(const RecordKeeper &Records, raw_ostream &OS) { … }