Edit

kc3-lang/angle/src/compiler/translator/Symbol.h

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2021-06-13 01:09:27
    Hash : 8b869a95
    Message : Translator: Generate Ops for all built-in functions EOpCallBuiltInFunction is removed in this change, as well as the "op": "auto" property in builtin_function_declarations.txt. Instead, gen_builtin_symbols.py automatically generates Ops for every built-in function and generates the TOperator enum accordingly. This simplifies SPIR-V code generation by allowing switches to be used on operators instead of string comparisons. Bug: angleproject:4589 Bug: angleproject:4889 Change-Id: Ia351524400b0e12a10a5572e27e9b88c6ec2e61c Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2958869 Commit-Queue: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jonah Ryan-Davis <jonahr@google.com> Reviewed-by: Tim Van Patten <timvp@google.com>

  • src/compiler/translator/Symbol.h
  • //
    // Copyright 2017 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    // Symbol.h: Symbols representing variables, functions, structures and interface blocks.
    //
    
    #ifndef COMPILER_TRANSLATOR_SYMBOL_H_
    #define COMPILER_TRANSLATOR_SYMBOL_H_
    
    #include "common/angleutils.h"
    #include "compiler/translator/ExtensionBehavior.h"
    #include "compiler/translator/ImmutableString.h"
    #include "compiler/translator/IntermNode.h"
    #include "compiler/translator/SymbolUniqueId.h"
    
    namespace sh
    {
    
    class TSymbolTable;
    
    // Symbol base class. (Can build functions or variables out of these...)
    class TSymbol : angle::NonCopyable
    {
      public:
        POOL_ALLOCATOR_NEW_DELETE
        TSymbol(TSymbolTable *symbolTable,
                const ImmutableString &name,
                SymbolType symbolType,
                SymbolClass symbolClass,
                TExtension extension = TExtension::UNDEFINED);
    
        TSymbol(TSymbolTable *symbolTable,
                const ImmutableString &name,
                SymbolType symbolType,
                SymbolClass symbolClass,
                const std::array<TExtension, 3u> &extensions);
    
        // Note that we can't have a virtual destructor in order to support constexpr symbols. Data is
        // either statically allocated or pool allocated.
        ~TSymbol() = default;
    
        // Calling name() for empty symbols (symbolType == SymbolType::Empty) generates a similar name
        // as for internal variables.
        ImmutableString name() const;
        // Don't call getMangledName() for empty symbols (symbolType == SymbolType::Empty).
        ImmutableString getMangledName() const;
    
        bool isFunction() const { return mSymbolClass == SymbolClass::Function; }
        bool isVariable() const { return mSymbolClass == SymbolClass::Variable; }
        bool isStruct() const { return mSymbolClass == SymbolClass::Struct; }
        bool isInterfaceBlock() const { return mSymbolClass == SymbolClass::InterfaceBlock; }
    
        const TSymbolUniqueId &uniqueId() const { return mUniqueId; }
        SymbolType symbolType() const { return mSymbolType; }
        const std::array<TExtension, 3u> extensions() const { return mExtensions; }
    
        template <size_t ExtensionCount>
        constexpr const std::array<TExtension, 3u> CreateExtensionList(
            const std::array<TExtension, ExtensionCount> &extensions)
        {
            switch (extensions.size())
            {
                case 1:
                    return std::array<TExtension, 3u>{
                        {extensions[0], TExtension::UNDEFINED, TExtension::UNDEFINED}};
                case 2:
                    return std::array<TExtension, 3u>{
                        {extensions[0], extensions[1], TExtension::UNDEFINED}};
                case 3:
                    return std::array<TExtension, 3u>{{extensions[0], extensions[1], extensions[2]}};
                default:
                    UNREACHABLE();
                    return std::array<TExtension, 3u>{
                        {TExtension::UNDEFINED, TExtension::UNDEFINED, TExtension::UNDEFINED}};
            }
        }
    
      protected:
        template <size_t ExtensionCount>
        constexpr TSymbol(const TSymbolUniqueId &id,
                          const ImmutableString &name,
                          SymbolType symbolType,
                          const std::array<TExtension, ExtensionCount> &extensions,
                          SymbolClass symbolClass)
            : mName(name),
              mUniqueId(id),
              mExtensions(CreateExtensionList(extensions)),
              mSymbolType(symbolType),
              mSymbolClass(symbolClass)
        {}
    
        const ImmutableString mName;
    
      private:
        const TSymbolUniqueId mUniqueId;
        const std::array<TExtension, 3u> mExtensions;
        const SymbolType mSymbolType : 4;
    
        // We use this instead of having virtual functions for querying the class in order to support
        // constexpr symbols.
        const SymbolClass mSymbolClass : 4;
    };
    
    static_assert(sizeof(TSymbol) <= 24, "Size check failed");
    
    // Variable.
    // May store the value of a constant variable of any type (float, int, bool or struct).
    class TVariable : public TSymbol
    {
      public:
        TVariable(TSymbolTable *symbolTable,
                  const ImmutableString &name,
                  const TType *type,
                  SymbolType symbolType,
                  TExtension ext = TExtension::UNDEFINED);
    
        TVariable(TSymbolTable *symbolTable,
                  const ImmutableString &name,
                  const TType *type,
                  SymbolType symbolType,
                  const std::array<TExtension, 3u> &extensions);
    
        const TType &getType() const { return *mType; }
    
        const TConstantUnion *getConstPointer() const { return unionArray; }
    
        void shareConstPointer(const TConstantUnion *constArray) { unionArray = constArray; }
    
        // Note: only to be used for built-in variables with autogenerated ids!
        constexpr TVariable(const TSymbolUniqueId &id,
                            const ImmutableString &name,
                            SymbolType symbolType,
                            TExtension extension,
                            const TType *type)
            : TSymbol(id,
                      name,
                      symbolType,
                      std::array<TExtension, 1u>{{extension}},
                      SymbolClass::Variable),
              mType(type),
              unionArray(nullptr)
        {}
    
        template <size_t ExtensionCount>
        constexpr TVariable(const TSymbolUniqueId &id,
                            const ImmutableString &name,
                            SymbolType symbolType,
                            const std::array<TExtension, ExtensionCount> &extensions,
                            const TType *type)
            : TSymbol(id, name, symbolType, extensions, SymbolClass::Variable),
              mType(type),
              unionArray(nullptr)
        {}
    
      private:
        const TType *mType;
        const TConstantUnion *unionArray;
    };
    
    // Struct type.
    class TStructure : public TSymbol, public TFieldListCollection
    {
      public:
        TStructure(TSymbolTable *symbolTable,
                   const ImmutableString &name,
                   const TFieldList *fields,
                   SymbolType symbolType);
    
        // The char arrays passed in must be pool allocated or static.
        void createSamplerSymbols(const char *namePrefix,
                                  const TString &apiNamePrefix,
                                  TVector<const TVariable *> *outputSymbols,
                                  TMap<const TVariable *, TString> *outputSymbolsToAPINames,
                                  TSymbolTable *symbolTable) const;
    
        void setAtGlobalScope(bool atGlobalScope) { mAtGlobalScope = atGlobalScope; }
        bool atGlobalScope() const { return mAtGlobalScope; }
    
      private:
        friend class TSymbolTable;
        // For creating built-in structs.
        TStructure(const TSymbolUniqueId &id,
                   const ImmutableString &name,
                   TExtension extension,
                   const TFieldList *fields)
            : TSymbol(id,
                      name,
                      SymbolType::BuiltIn,
                      std::array<TExtension, 1u>{{extension}},
                      SymbolClass::Struct),
              TFieldListCollection(fields)
        {}
    
        template <size_t ExtensionCount>
        TStructure(const TSymbolUniqueId &id,
                   const ImmutableString &name,
                   const std::array<TExtension, ExtensionCount> &extensions,
                   const TFieldList *fields)
            : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Struct),
              TFieldListCollection(fields)
        {}
    
        // TODO(zmo): Find a way to get rid of the const_cast in function
        // setName().  At the moment keep this function private so only
        // friend class RegenerateStructNames may call it.
        friend class RegenerateStructNamesTraverser;
        void setName(const ImmutableString &name);
    
        bool mAtGlobalScope;
    };
    
    // Interface block. Note that this contains the block name, not the instance name. Interface block
    // instances are stored as TVariable.
    class TInterfaceBlock : public TSymbol, public TFieldListCollection
    {
      public:
        TInterfaceBlock(TSymbolTable *symbolTable,
                        const ImmutableString &name,
                        const TFieldList *fields,
                        const TLayoutQualifier &layoutQualifier,
                        SymbolType symbolType,
                        TExtension extension = TExtension::UNDEFINED);
    
        TInterfaceBlock(TSymbolTable *symbolTable,
                        const ImmutableString &name,
                        const TFieldList *fields,
                        const TLayoutQualifier &layoutQualifier,
                        SymbolType symbolType,
                        const std::array<TExtension, 3u> &extensions);
    
        TLayoutBlockStorage blockStorage() const { return mBlockStorage; }
        int blockBinding() const { return mBinding; }
    
      private:
        friend class TSymbolTable;
        // For creating built-in interface blocks.
        TInterfaceBlock(const TSymbolUniqueId &id,
                        const ImmutableString &name,
                        TExtension extension,
                        const TFieldList *fields)
            : TSymbol(id,
                      name,
                      SymbolType::BuiltIn,
                      std::array<TExtension, 1u>{{extension}},
                      SymbolClass::InterfaceBlock),
              TFieldListCollection(fields),
              mBlockStorage(EbsUnspecified),
              mBinding(0)
        {}
    
        template <size_t ExtensionCount>
        TInterfaceBlock(const TSymbolUniqueId &id,
                        const ImmutableString &name,
                        const std::array<TExtension, ExtensionCount> &extensions,
                        const TFieldList *fields)
            : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::InterfaceBlock),
              TFieldListCollection(fields),
              mBlockStorage(EbsUnspecified),
              mBinding(0)
        {}
    
        TLayoutBlockStorage mBlockStorage;
        int mBinding;
    
        // Note that we only record matrix packing on a per-field granularity.
    };
    
    // Parameter class used for parsing user-defined function parameters.
    struct TParameter
    {
        // Destructively converts to TVariable.
        // This method resets name and type to nullptrs to make sure
        // their content cannot be modified after the call.
        const TVariable *createVariable(TSymbolTable *symbolTable)
        {
            const ImmutableString constName(name);
            const TType *constType = type;
            name                   = nullptr;
            type                   = nullptr;
            return new TVariable(symbolTable, constName, constType,
                                 constName.empty() ? SymbolType::Empty : SymbolType::UserDefined);
        }
    
        const char *name;  // either pool allocated or static.
        TType *type;
    };
    
    // The function sub-class of a symbol.
    class TFunction : public TSymbol
    {
      public:
        // User-defined function
        TFunction(TSymbolTable *symbolTable,
                  const ImmutableString &name,
                  SymbolType symbolType,
                  const TType *retType,
                  bool knownToNotHaveSideEffects);
    
        void addParameter(const TVariable *p);
        void shareParameters(const TFunction &parametersSource);
    
        ImmutableString getFunctionMangledName() const
        {
            ASSERT(symbolType() != SymbolType::BuiltIn);
            if (mMangledName.empty())
            {
                mMangledName = buildMangledName();
            }
            return mMangledName;
        }
    
        const TType &getReturnType() const { return *returnType; }
    
        TOperator getBuiltInOp() const { return mOp; }
    
        void setDefined() { defined = true; }
        bool isDefined() const { return defined; }
        void setHasPrototypeDeclaration() { mHasPrototypeDeclaration = true; }
        bool hasPrototypeDeclaration() const { return mHasPrototypeDeclaration; }
    
        size_t getParamCount() const { return mParamCount; }
        const TVariable *getParam(size_t i) const { return mParameters[i]; }
    
        bool isKnownToNotHaveSideEffects() const { return mKnownToNotHaveSideEffects; }
    
        bool isMain() const;
        bool isImageFunction() const;
        bool isAtomicCounterFunction() const;
    
        // Note: Only to be used for static built-in functions!
        constexpr TFunction(const TSymbolUniqueId &id,
                            const ImmutableString &name,
                            TExtension extension,
                            const TVariable *const *parameters,
                            size_t paramCount,
                            const TType *retType,
                            TOperator op,
                            bool knownToNotHaveSideEffects)
            : TSymbol(id,
                      name,
                      SymbolType::BuiltIn,
                      std::array<TExtension, 1u>{{extension}},
                      SymbolClass::Function),
              mParametersVector(nullptr),
              mParameters(parameters),
              returnType(retType),
              mMangledName(nullptr),
              mParamCount(paramCount),
              mOp(op),
              defined(false),
              mHasPrototypeDeclaration(false),
              mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
        {}
    
        template <size_t ExtensionCount>
        constexpr TFunction(const TSymbolUniqueId &id,
                            const ImmutableString &name,
                            const std::array<TExtension, ExtensionCount> &extensions,
                            const TVariable *const *parameters,
                            size_t paramCount,
                            const TType *retType,
                            TOperator op,
                            bool knownToNotHaveSideEffects)
            : TSymbol(id, name, SymbolType::BuiltIn, extensions, SymbolClass::Function),
              mParametersVector(nullptr),
              mParameters(parameters),
              returnType(retType),
              mMangledName(nullptr),
              mParamCount(paramCount),
              mOp(op),
              defined(false),
              mHasPrototypeDeclaration(false),
              mKnownToNotHaveSideEffects(knownToNotHaveSideEffects)
        {}
    
      private:
        ImmutableString buildMangledName() const;
    
        typedef TVector<const TVariable *> TParamVector;
        TParamVector *mParametersVector;
        const TVariable *const *mParameters;
        const TType *const returnType;
        mutable ImmutableString mMangledName;
        size_t mParamCount : 32;
        const TOperator mOp;  // Only set for built-ins
        bool defined : 1;
        bool mHasPrototypeDeclaration : 1;
        bool mKnownToNotHaveSideEffects : 1;
    };
    
    }  // namespace sh
    
    #endif  // COMPILER_TRANSLATOR_SYMBOL_H_